Skip to content

Commit fc9a283

Browse files
SpatisonVMSolidus
authored andcommitted
[Port] Hristov / Христов | [Port] Manual Sending Of The Cartridge / Ручное Досылание Патрона (Simple-Station#58)
* tweak: hristov * WD EDIT * fix
1 parent 9e85b73 commit fc9a283

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+543
-2
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
using Content.Shared._White.FootPrint;
2+
using Robust.Client.GameObjects;
3+
using Robust.Client.Graphics;
4+
using Robust.Shared.Random;
5+
6+
namespace Content.Client._White.FootPrint;
7+
8+
public sealed class FootPrintsVisualizerSystem : VisualizerSystem<FootPrintComponent>
9+
{
10+
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
11+
[Dependency] private readonly IRobustRandom _random = default!;
12+
13+
public override void Initialize()
14+
{
15+
base.Initialize();
16+
17+
SubscribeLocalEvent<FootPrintComponent, ComponentInit>(OnInitialized);
18+
SubscribeLocalEvent<FootPrintComponent, ComponentShutdown>(OnShutdown);
19+
}
20+
21+
private void OnInitialized(EntityUid uid, FootPrintComponent comp, ComponentInit args)
22+
{
23+
if (!TryComp<SpriteComponent>(uid, out var sprite))
24+
return;
25+
26+
sprite.LayerMapReserveBlank(FootPrintVisualLayers.Print);
27+
UpdateAppearance(uid, comp, sprite);
28+
}
29+
30+
private void OnShutdown(EntityUid uid, FootPrintComponent comp, ComponentShutdown args)
31+
{
32+
if (TryComp<SpriteComponent>(uid, out var sprite) &&
33+
sprite.LayerMapTryGet(FootPrintVisualLayers.Print, out var layer))
34+
{
35+
sprite.RemoveLayer(layer);
36+
}
37+
}
38+
39+
private void UpdateAppearance(EntityUid uid, FootPrintComponent component, SpriteComponent sprite)
40+
{
41+
if (!sprite.LayerMapTryGet(FootPrintVisualLayers.Print, out var layer)
42+
|| !TryComp<FootPrintsComponent>(component.PrintOwner, out var printsComponent)
43+
|| !TryComp<AppearanceComponent>(uid, out var appearance))
44+
return;
45+
46+
if (!_appearance.TryGetData<FootPrintVisuals>(uid, FootPrintVisualState.State, out var printVisuals, appearance))
47+
return;
48+
49+
sprite.LayerSetState(layer, new RSI.StateId(printVisuals switch
50+
{
51+
FootPrintVisuals.BareFootPrint => printsComponent.RightStep ? printsComponent.RightBarePrint : printsComponent.LeftBarePrint,
52+
FootPrintVisuals.ShoesPrint => printsComponent.ShoesPrint,
53+
FootPrintVisuals.SuitPrint => printsComponent.SuitPrint,
54+
FootPrintVisuals.Dragging => _random.Pick(printsComponent.DraggingPrint),
55+
_ => throw new ArgumentOutOfRangeException($"Unknown {printVisuals} parameter.")
56+
}), printsComponent.RsiPath);
57+
58+
if (_appearance.TryGetData<Color>(uid, FootPrintVisualState.Color, out var printColor, appearance))
59+
sprite.LayerSetColor(layer, printColor);
60+
}
61+
62+
protected override void OnAppearanceChange (EntityUid uid, FootPrintComponent component, ref AppearanceChangeEvent args)
63+
{
64+
if (args.Sprite is not { } sprite)
65+
return;
66+
67+
UpdateAppearance(uid, component, sprite);
68+
}
69+
}
Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
using Content.Server.Atmos.Components;
2+
using Content.Shared.Inventory;
3+
using Content.Shared.Mobs;
4+
using Content.Shared.Mobs.Components;
5+
using Content.Shared._White.FootPrint;
6+
using Content.Shared.Standing;
7+
using Content.Shared.Chemistry.Components.SolutionManager;
8+
using Content.Shared.Chemistry.EntitySystems;
9+
using Robust.Shared.Map;
10+
using Robust.Shared.Random;
11+
12+
namespace Content.Server._White.FootPrint;
13+
14+
public sealed class FootPrintsSystem : EntitySystem
15+
{
16+
[Dependency] private readonly IRobustRandom _random = default!;
17+
[Dependency] private readonly InventorySystem _inventory = default!;
18+
[Dependency] private readonly IMapManager _map = default!;
19+
20+
[Dependency] private readonly SharedSolutionContainerSystem _solution = default!;
21+
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
22+
[Dependency] private readonly SharedTransformSystem _transform = default!;
23+
24+
private EntityQuery<TransformComponent> _transformQuery;
25+
private EntityQuery<MobThresholdsComponent> _mobThresholdQuery;
26+
private EntityQuery<AppearanceComponent> _appearanceQuery;
27+
private EntityQuery<LayingDownComponent> _layingQuery;
28+
29+
public override void Initialize()
30+
{
31+
base.Initialize();
32+
33+
_transformQuery = GetEntityQuery<TransformComponent>();
34+
_mobThresholdQuery = GetEntityQuery<MobThresholdsComponent>();
35+
_appearanceQuery = GetEntityQuery<AppearanceComponent>();
36+
_layingQuery = GetEntityQuery<LayingDownComponent>();
37+
38+
SubscribeLocalEvent<FootPrintsComponent, ComponentStartup>(OnStartupComponent);
39+
SubscribeLocalEvent<FootPrintsComponent, MoveEvent>(OnMove);
40+
}
41+
42+
private void OnStartupComponent(EntityUid uid, FootPrintsComponent component, ComponentStartup args)
43+
{
44+
component.StepSize = Math.Max(0f, component.StepSize + _random.NextFloat(-0.05f, 0.05f));
45+
}
46+
47+
private void OnMove(EntityUid uid, FootPrintsComponent component, ref MoveEvent args)
48+
{
49+
if (component.PrintsColor.A <= 0f
50+
|| !_transformQuery.TryComp(uid, out var transform)
51+
|| !_mobThresholdQuery.TryComp(uid, out var mobThreshHolds)
52+
|| !_map.TryFindGridAt(_transform.GetMapCoordinates((uid, transform)), out var gridUid, out _))
53+
return;
54+
55+
var dragging = mobThreshHolds.CurrentThresholdState is MobState.Critical or MobState.Dead
56+
|| _layingQuery.TryComp(uid, out var laying) && laying.IsCrawlingUnder;
57+
var distance = (transform.LocalPosition - component.StepPos).Length();
58+
var stepSize = dragging ? component.DragSize : component.StepSize;
59+
60+
if (!(distance > stepSize))
61+
return;
62+
63+
component.RightStep = !component.RightStep;
64+
65+
var entity = Spawn(component.StepProtoId, CalcCoords(gridUid, component, transform, dragging));
66+
var footPrintComponent = EnsureComp<FootPrintComponent>(entity);
67+
68+
footPrintComponent.PrintOwner = uid;
69+
Dirty(entity, footPrintComponent);
70+
71+
if (_appearanceQuery.TryComp(entity, out var appearance))
72+
{
73+
_appearance.SetData(entity, FootPrintVisualState.State, PickState(uid, dragging), appearance);
74+
_appearance.SetData(entity, FootPrintVisualState.Color, component.PrintsColor, appearance);
75+
}
76+
77+
if (!_transformQuery.TryComp(entity, out var stepTransform))
78+
return;
79+
80+
stepTransform.LocalRotation = dragging
81+
? (transform.LocalPosition - component.StepPos).ToAngle() + Angle.FromDegrees(-90f)
82+
: transform.LocalRotation + Angle.FromDegrees(180f);
83+
84+
component.PrintsColor = component.PrintsColor.WithAlpha(Math.Max(0f, component.PrintsColor.A - component.ColorReduceAlpha));
85+
component.StepPos = transform.LocalPosition;
86+
87+
if (!TryComp<SolutionContainerManagerComponent>(entity, out var solutionContainer)
88+
|| !_solution.ResolveSolution((entity, solutionContainer), footPrintComponent.SolutionName, ref footPrintComponent.Solution, out var solution)
89+
|| string.IsNullOrWhiteSpace(component.ReagentToTransfer) || solution.Volume >= 1)
90+
return;
91+
92+
_solution.TryAddReagent(footPrintComponent.Solution.Value, component.ReagentToTransfer, 1, out _);
93+
}
94+
95+
private EntityCoordinates CalcCoords(EntityUid uid, FootPrintsComponent component, TransformComponent transform, bool state)
96+
{
97+
if (state)
98+
return new EntityCoordinates(uid, transform.LocalPosition);
99+
100+
var offset = component.RightStep
101+
? new Angle(Angle.FromDegrees(180f) + transform.LocalRotation).RotateVec(component.OffsetPrint)
102+
: new Angle(transform.LocalRotation).RotateVec(component.OffsetPrint);
103+
104+
return new EntityCoordinates(uid, transform.LocalPosition + offset);
105+
}
106+
107+
private FootPrintVisuals PickState(EntityUid uid, bool dragging)
108+
{
109+
var state = FootPrintVisuals.BareFootPrint;
110+
111+
if (_inventory.TryGetSlotEntity(uid, "shoes", out _))
112+
state = FootPrintVisuals.ShoesPrint;
113+
114+
if (_inventory.TryGetSlotEntity(uid, "outerClothing", out var suit) && TryComp<PressureProtectionComponent>(suit, out _))
115+
state = FootPrintVisuals.SuitPrint;
116+
117+
if (dragging)
118+
state = FootPrintVisuals.Dragging;
119+
120+
return state;
121+
}
122+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System.Linq;
2+
using Content.Shared._White.FootPrint;
3+
using Content.Shared.Chemistry.Components.SolutionManager;
4+
using Content.Shared.Chemistry.EntitySystems;
5+
using Content.Shared.Fluids;
6+
using Content.Shared.Fluids.Components;
7+
using Robust.Shared.Physics.Events;
8+
9+
namespace Content.Server._White.FootPrint;
10+
11+
public sealed class PuddleFootPrintsSystem : EntitySystem
12+
{
13+
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
14+
[Dependency] private readonly SharedSolutionContainerSystem _solutionContainer = default!;
15+
16+
public override void Initialize()
17+
{
18+
base.Initialize();
19+
SubscribeLocalEvent<PuddleFootPrintsComponent, EndCollideEvent>(OnStepTrigger);
20+
}
21+
22+
private void OnStepTrigger(EntityUid uid, PuddleFootPrintsComponent component, ref EndCollideEvent args)
23+
{
24+
if (!TryComp<AppearanceComponent>(uid, out var appearance)
25+
|| !TryComp<PuddleComponent>(uid, out var puddle)
26+
|| !TryComp<FootPrintsComponent>(args.OtherEntity, out var tripper)
27+
|| !TryComp<SolutionContainerManagerComponent>(uid, out var solutionManager)
28+
||!_solutionContainer.ResolveSolution((uid, solutionManager), puddle.SolutionName, ref puddle.Solution, out var solutions))
29+
return;
30+
31+
// alles gut!
32+
var totalSolutionQuantity = solutions.Contents.Sum(sol => (float)sol.Quantity);
33+
var waterQuantity = (from sol in solutions.Contents where sol.Reagent.Prototype == "Water" select (float) sol.Quantity).FirstOrDefault();
34+
35+
if (waterQuantity / (totalSolutionQuantity / 100f) > component.OffPercent || solutions.Contents.Count <= 0)
36+
return;
37+
38+
tripper.ReagentToTransfer =
39+
solutions.Contents.Aggregate((l, r) => l.Quantity > r.Quantity ? l : r).Reagent.Prototype;
40+
41+
if (_appearance.TryGetData(uid, PuddleVisuals.SolutionColor, out var color, appearance)
42+
&& _appearance.TryGetData(uid, PuddleVisuals.CurrentVolume, out var volume, appearance))
43+
AddColor((Color)color, (float)volume * component.SizeRatio, tripper);
44+
45+
_solutionContainer.RemoveEachReagent(puddle.Solution.Value, 1);
46+
}
47+
48+
private void AddColor(Color col, float quantity, FootPrintsComponent component)
49+
{
50+
component.PrintsColor = component.ColorQuantity == 0f ? col : Color.InterpolateBetween(component.PrintsColor, col, component.ColorInterpolationFactor);
51+
component.ColorQuantity += quantity;
52+
}
53+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using Content.Shared.Chemistry.Components;
2+
using Robust.Shared.GameStates;
3+
4+
namespace Content.Shared._White.FootPrint;
5+
6+
/// <summary>
7+
/// This is used for marking footsteps, handling footprint drawing.
8+
/// </summary>
9+
[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
10+
public sealed partial class FootPrintComponent : Component
11+
{
12+
/// <summary>
13+
/// Owner (with <see cref="FootPrintsComponent"/>) of a print (this component).
14+
/// </summary>
15+
[AutoNetworkedField]
16+
public EntityUid PrintOwner;
17+
18+
[DataField]
19+
public string SolutionName = "step";
20+
21+
[DataField]
22+
public Entity<SolutionComponent>? Solution;
23+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Robust.Shared.Serialization;
2+
3+
namespace Content.Shared._White.FootPrint;
4+
5+
[Serializable, NetSerializable]
6+
public enum FootPrintVisuals : byte
7+
{
8+
BareFootPrint,
9+
ShoesPrint,
10+
SuitPrint,
11+
Dragging
12+
}
13+
14+
[Serializable, NetSerializable]
15+
public enum FootPrintVisualState : byte
16+
{
17+
State,
18+
Color
19+
}
20+
21+
[Serializable, NetSerializable]
22+
public enum FootPrintVisualLayers : byte
23+
{
24+
Print
25+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
using System.Numerics;
2+
using Robust.Shared.Prototypes;
3+
using Robust.Shared.Utility;
4+
5+
namespace Content.Shared._White.FootPrint;
6+
7+
[RegisterComponent]
8+
public sealed partial class FootPrintsComponent : Component
9+
{
10+
[ViewVariables(VVAccess.ReadOnly), DataField]
11+
public ResPath RsiPath = new("/Textures/_White/Effects/footprints.rsi");
12+
13+
// all of those are set as a layer
14+
[ViewVariables(VVAccess.ReadOnly), DataField]
15+
public string LeftBarePrint = "footprint-left-bare-human";
16+
17+
[ViewVariables(VVAccess.ReadOnly), DataField]
18+
public string RightBarePrint = "footprint-right-bare-human";
19+
20+
[ViewVariables(VVAccess.ReadOnly), DataField]
21+
public string ShoesPrint = "footprint-shoes";
22+
23+
[ViewVariables(VVAccess.ReadOnly), DataField]
24+
public string SuitPrint = "footprint-suit";
25+
26+
[ViewVariables(VVAccess.ReadOnly), DataField]
27+
public string[] DraggingPrint =
28+
[
29+
"dragging-1",
30+
"dragging-2",
31+
"dragging-3",
32+
"dragging-4",
33+
"dragging-5",
34+
];
35+
// yea, those
36+
37+
[ViewVariables(VVAccess.ReadOnly), DataField]
38+
public EntProtoId<FootPrintComponent> StepProtoId = "Footstep";
39+
40+
[ViewVariables(VVAccess.ReadOnly), DataField]
41+
public Color PrintsColor = Color.FromHex("#00000000");
42+
43+
/// <summary>
44+
/// The size scaling factor for footprint steps. Must be positive.
45+
/// </summary>
46+
[DataField]
47+
public float StepSize = 0.7f;
48+
49+
/// <summary>
50+
/// The size scaling factor for drag marks. Must be positive.
51+
/// </summary>
52+
[DataField]
53+
public float DragSize = 0.5f;
54+
55+
/// <summary>
56+
/// The amount of color to transfer from the source (e.g., puddle) to the footprint.
57+
/// </summary>
58+
[DataField]
59+
public float ColorQuantity;
60+
61+
/// <summary>
62+
/// The factor by which the alpha channel is reduced in subsequent footprints.
63+
/// </summary>
64+
[DataField]
65+
public float ColorReduceAlpha = 0.1f;
66+
67+
[DataField]
68+
public string? ReagentToTransfer;
69+
70+
[DataField]
71+
public Vector2 OffsetPrint = new(0.1f, 0f);
72+
73+
/// <summary>
74+
/// Tracks which foot should make the next print. True for right foot, false for left.
75+
/// </summary>
76+
public bool RightStep = true;
77+
78+
/// <summary>
79+
/// The position of the last footprint in world coordinates.
80+
/// </summary>
81+
public Vector2 StepPos = Vector2.Zero;
82+
83+
/// <summary>
84+
/// Controls how quickly the footprint color transitions between steps.
85+
/// Value between 0 and 1, where higher values mean faster color changes.
86+
/// </summary>
87+
public float ColorInterpolationFactor = 0.2f;
88+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
namespace Content.Shared._White.FootPrint;
2+
3+
[RegisterComponent]
4+
public sealed partial class PuddleFootPrintsComponent : Component
5+
{
6+
[ViewVariables(VVAccess.ReadWrite)]
7+
public float SizeRatio = 0.2f;
8+
9+
[ViewVariables(VVAccess.ReadWrite)]
10+
public float OffPercent = 80f;
11+
}

0 commit comments

Comments
 (0)