diff --git a/Content.Server/Chemistry/TileReactions/EnsureTileReaction.cs b/Content.Server/Chemistry/TileReactions/EnsureTileReaction.cs new file mode 100644 index 00000000000000..7be3803e743afe --- /dev/null +++ b/Content.Server/Chemistry/TileReactions/EnsureTileReaction.cs @@ -0,0 +1,47 @@ +using Content.Server.Fluids.EntitySystems; +using Content.Shared.Chemistry.Components; +using Content.Shared.Chemistry.Reaction; +using Content.Shared.Chemistry.Reagent; +using Content.Shared.FixedPoint; +using Content.Shared.Tag; +using JetBrains.Annotations; +using Robust.Shared.Map; +using Robust.Shared.Prototypes; + +namespace Content.Server.Chemistry.TileReactions +{ + [UsedImplicitly] + [DataDefinition] + public sealed partial class EnsureTileReaction : ITileReaction + { + [DataField, ViewVariables] + public ComponentRegistry Components = new(); + + [DataField, ViewVariables] + public HashSet> Tags = new(); + + [DataField, ViewVariables] + public bool Override = false; + + public FixedPoint2 TileReact(TileRef tile, + ReagentPrototype reagent, + FixedPoint2 reactVolume, + IEntityManager entityManager, + List? data) + { + if (reactVolume < 5) + return FixedPoint2.Zero; + + if (entityManager.EntitySysManager.GetEntitySystem() + .TrySpillAt(tile, new Solution(reagent.ID, reactVolume, data), out var puddleUid, false, false)) + { + entityManager.AddComponents(puddleUid, Components, Override); + entityManager.EntitySysManager.GetEntitySystem().AddTags(puddleUid, Tags); + + return reactVolume; + } + + return FixedPoint2.Zero; + } + } +} diff --git a/Content.Shared/Fluids/Components/PropulsedByComponent.cs b/Content.Shared/Fluids/Components/PropulsedByComponent.cs new file mode 100644 index 00000000000000..4a0f0ea8dd3230 --- /dev/null +++ b/Content.Shared/Fluids/Components/PropulsedByComponent.cs @@ -0,0 +1,11 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Fluids.Components +{ + [RegisterComponent, NetworkedComponent] + public sealed partial class PropulsedByComponent : Component + { + [ViewVariables(VVAccess.ReadOnly)] + public HashSet> Sources = new(); + } +} \ No newline at end of file diff --git a/Content.Shared/Fluids/Components/PropulsionComponent.cs b/Content.Shared/Fluids/Components/PropulsionComponent.cs new file mode 100644 index 00000000000000..bef8ddc5439bbb --- /dev/null +++ b/Content.Shared/Fluids/Components/PropulsionComponent.cs @@ -0,0 +1,35 @@ +using Content.Shared.Whitelist; +using Robust.Shared.GameStates; + +namespace Content.Shared.Fluids.Components +{ + /// + /// This object will speed up the movement speed of entities + /// when collided with + /// + /// Used for mucin + /// + /// This partially replicates SpeedModifierContactsComponent because that + /// component is already heavily coupled with existing puddle code. + /// + [RegisterComponent, NetworkedComponent] + [AutoGenerateComponentState] + public sealed partial class PropulsionComponent : Component + { + [DataField, ViewVariables] + [AutoNetworkedField] + public float WalkSpeedModifier = 1.0f; + + [AutoNetworkedField] + [DataField, ViewVariables] + public float SprintSpeedModifier = 1.0f; + + /// + /// If an entity passes this, apply the speed modifier. + /// Passes all entities if not defined. + /// + [AutoNetworkedField] + [DataField, ViewVariables] + public EntityWhitelist? Whitelist; + } +} diff --git a/Content.Shared/Fluids/EntitySystems/PropulsionSystem.cs b/Content.Shared/Fluids/EntitySystems/PropulsionSystem.cs new file mode 100644 index 00000000000000..982ae2fa78ed42 --- /dev/null +++ b/Content.Shared/Fluids/EntitySystems/PropulsionSystem.cs @@ -0,0 +1,62 @@ +using System.Linq; +using Content.Shared.Fluids.Components; +using Content.Shared.Movement.Components; +using Content.Shared.Movement.Systems; +using Content.Shared.Whitelist; +using Robust.Shared.Physics.Events; + +namespace Content.Shared.Fluids.EntitySystems; + +public sealed class PropulsionSystem : EntitySystem +{ + [Dependency] private readonly SpeedModifierContactsSystem _speedModifier = default!; + [Dependency] private readonly EntityWhitelistSystem _whitelistSystem = default!; + + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnComponentInit); + SubscribeLocalEvent(OnStartCollide); + SubscribeLocalEvent(OnEndCollide); + SubscribeLocalEvent(OnRefreshSpeed); + } + + public void OnComponentInit(Entity ent, ref ComponentInit args) + { + EnsureComp(ent); + } + + public void OnStartCollide(Entity ent, ref StartCollideEvent args) + { + if (!HasComp(args.OtherEntity)) + return; + + if (_whitelistSystem.IsWhitelistFail(ent.Comp.Whitelist, args.OtherEntity)) + return; + + _speedModifier.AddModifiedEntity(args.OtherEntity); + + var propulse = EnsureComp(args.OtherEntity); + propulse.Sources.Add(ent); + } + + public void OnEndCollide(Entity ent, ref EndCollideEvent args) + { + if (TryComp(args.OtherEntity, out var propulse)) + { + propulse.Sources.Remove(ent); + } + } + + public static void OnRefreshSpeed(Entity ent, ref RefreshMovementSpeedModifiersEvent args) + { + ent.Comp.Sources.RemoveWhere((ent) => !ent.Owner.IsValid() || ent.Comp.Deleted); + + if (ent.Comp.Sources.Count == 0) + return; + + var modifier = ent.Comp.Sources.First(); + args.ModifySpeed(modifier.Comp.WalkSpeedModifier, modifier.Comp.SprintSpeedModifier); + } +} diff --git a/Resources/Audio/Effects/Footsteps/snailstep.ogg b/Resources/Audio/Effects/Footsteps/snailstep.ogg index baa64c211ee166..0aa236a61750d3 100644 Binary files a/Resources/Audio/Effects/Footsteps/snailstep.ogg and b/Resources/Audio/Effects/Footsteps/snailstep.ogg differ diff --git a/Resources/Prototypes/Entities/Effects/puddle.yml b/Resources/Prototypes/Entities/Effects/puddle.yml index 825c68d3cf5241..8ef5e1e3835e71 100644 --- a/Resources/Prototypes/Entities/Effects/puddle.yml +++ b/Resources/Prototypes/Entities/Effects/puddle.yml @@ -76,9 +76,6 @@ parent: PuddleTemporary suffix: Mucin components: - - type: TimedDespawn - lifetime: 5 - - type: EvaporationSparkle - type: SolutionContainerManager solutions: puddle: @@ -86,6 +83,12 @@ reagents: - ReagentId: Mucin Quantity: 20 + - type: Propulsion + walkSpeedModifier: 2.0 + sprintSpeedModifier: 2.0 + whitelist: + components: + - SnailSpeed - type: entity id: PuddleFlour diff --git a/Resources/Prototypes/Reagents/biological.yml b/Resources/Prototypes/Reagents/biological.yml index 3b6215432fce3d..2c67917033eff1 100644 --- a/Resources/Prototypes/Reagents/biological.yml +++ b/Resources/Prototypes/Reagents/biological.yml @@ -92,7 +92,7 @@ recognizable: true physicalDesc: reagent-physical-desc-viscous slippery: false - viscosity: -0.5 + viscosity: 0.1 metabolisms: Food: effects: @@ -103,7 +103,14 @@ params: volume: 6 tileReactions: - - !type:SpillTileReaction + - !type:EnsureTileReaction + components: + - type: Propulsion + walkSpeedModifier: 2.0 + sprintSpeedModifier: 2.0 + whitelist: + components: + - SnailSpeed - type: reagent id: Sap