]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Spacelube slide (#24801)
authorArendian <137322659+Arendian@users.noreply.github.com>
Thu, 1 Feb 2024 10:39:10 +0000 (11:39 +0100)
committerGitHub <noreply@github.com>
Thu, 1 Feb 2024 10:39:10 +0000 (21:39 +1100)
* Space lube now makes you slide

* review

* oh lord he slippin

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Content.Server/Chemistry/TileReactions/SpillTileReaction.cs
Content.Server/Fluids/EntitySystems/PuddleSystem.cs
Content.Shared/Slippery/SlidingComponent.cs [new file with mode: 0644]
Content.Shared/Slippery/SlidingSystem.cs [new file with mode: 0644]
Content.Shared/Slippery/SlipperyComponent.cs
Content.Shared/Slippery/SlipperySystem.cs
Resources/Prototypes/Reagents/cleaning.yml

index 87246927d75e0811fff0869963325c8c36fe53ad..49fdaa5c7ee7381f9640cd84acfff6c9abbb5488 100644 (file)
@@ -21,9 +21,15 @@ namespace Content.Server.Chemistry.TileReactions
         [DataField("requiredSlipSpeed")] private float _requiredSlipSpeed = 6;
         [DataField("paralyzeTime")] private float _paralyzeTime = 1;
 
+        /// <summary>
+        /// <see cref="SlipperyComponent.SuperSlippery"/>
+        /// </summary>
+        [DataField("superSlippery")] private bool _superSlippery;
+
         public FixedPoint2 TileReact(TileRef tile, ReagentPrototype reagent, FixedPoint2 reactVolume)
         {
-            if (reactVolume < 5) return FixedPoint2.Zero;
+            if (reactVolume < 5)
+                return FixedPoint2.Zero;
 
             var entityManager = IoCManager.Resolve<IEntityManager>();
 
@@ -33,7 +39,8 @@ namespace Content.Server.Chemistry.TileReactions
                 var slippery = entityManager.EnsureComponent<SlipperyComponent>(puddleUid);
                 slippery.LaunchForwardsMultiplier = _launchForwardsMultiplier;
                 slippery.ParalyzeTime = _paralyzeTime;
-                entityManager.Dirty(slippery);
+                slippery.SuperSlippery = _superSlippery;
+                entityManager.Dirty(puddleUid, slippery);
 
                 var step = entityManager.EnsureComponent<StepTriggerComponent>(puddleUid);
                 entityManager.EntitySysManager.GetEntitySystem<StepTriggerSystem>().SetRequiredTriggerSpeed(puddleUid, _requiredSlipSpeed, step);
index b6df3a171b849cff42ad626689ddff2e2a6e9100..44d28379aba5ad018200978413defeff1b66196e 100644 (file)
@@ -293,7 +293,7 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
     {
         // Reactive entities have a chance to get a touch reaction from slipping on a puddle
         // (i.e. it is implied they fell face first onto it or something)
-        if (!HasComp<ReactiveComponent>(args.Slipped))
+        if (!HasComp<ReactiveComponent>(args.Slipped) || HasComp<SlidingComponent>(args.Slipped))
             return;
 
         // Eventually probably have some system of 'body coverage' to tweak the probability but for now just 0.5
diff --git a/Content.Shared/Slippery/SlidingComponent.cs b/Content.Shared/Slippery/SlidingComponent.cs
new file mode 100644 (file)
index 0000000..e48c0f2
--- /dev/null
@@ -0,0 +1,22 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Slippery;
+
+/// <summary>
+/// Applies continuous movement to the attached entity when colliding with super slipper entities.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class SlidingComponent : Component
+{
+    /// <summary>
+    ///     A list of SuperSlippery entities the entity with this component is colliding with.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public HashSet<EntityUid> CollidingEntities = new ();
+
+    /// <summary>
+    ///     The friction modifier that will be applied to any friction calculations.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public float FrictionModifier;
+}
diff --git a/Content.Shared/Slippery/SlidingSystem.cs b/Content.Shared/Slippery/SlidingSystem.cs
new file mode 100644 (file)
index 0000000..0af6b20
--- /dev/null
@@ -0,0 +1,63 @@
+using Content.Shared.Movement.Events;
+using Content.Shared.Standing;
+using Content.Shared.Stunnable;
+using Robust.Shared.Physics.Events;
+
+namespace Content.Shared.Slippery;
+
+public sealed class SlidingSystem : EntitySystem
+{
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<SlidingComponent, TileFrictionEvent>(OnSlideAttempt);
+        SubscribeLocalEvent<SlidingComponent, StoodEvent>(OnStand);
+        SubscribeLocalEvent<SlidingComponent, StartCollideEvent>(OnStartCollide);
+        SubscribeLocalEvent<SlidingComponent, EndCollideEvent>(OnEndCollide);
+    }
+
+    /// <summary>
+    ///     Modify the friction by the frictionModifier stored on the component.
+    /// </summary>
+    private void OnSlideAttempt(EntityUid uid, SlidingComponent component, ref TileFrictionEvent args)
+    {
+        args.Modifier = component.FrictionModifier;
+    }
+
+    /// <summary>
+    ///     Remove the component when the entity stands up again.
+    /// </summary>
+    private void OnStand(EntityUid uid, SlidingComponent component, ref StoodEvent args)
+    {
+        RemComp<SlidingComponent>(uid);
+    }
+
+    /// <summary>
+    ///     Sets friction to 0 if colliding with a SuperSlippery Entity.
+    /// </summary>
+    private void OnStartCollide(EntityUid uid, SlidingComponent component, ref StartCollideEvent args)
+    {
+        if (!TryComp<SlipperyComponent>(args.OtherEntity, out var slippery) || !slippery.SuperSlippery)
+            return;
+
+        component.CollidingEntities.Add(args.OtherEntity);
+        component.FrictionModifier = 0;
+        Dirty(uid, component);
+    }
+
+    /// <summary>
+    ///     Set friction to normal when ending collision with a SuperSlippery entity.
+    /// </summary>
+    private void OnEndCollide(EntityUid uid, SlidingComponent component, ref EndCollideEvent args)
+    {
+        if (!component.CollidingEntities.Remove(args.OtherEntity))
+            return;
+
+        if (component.CollidingEntities.Count == 0)
+            component.FrictionModifier = SharedStunSystem.KnockDownModifier;
+
+        Dirty(uid, component);
+    }
+
+}
index b470e2cbbd5348c6cd2f8bcc7c837530113d9a99..b80a9b57e4d4a12cb3b15e10e5ad41ad08c0445e 100644 (file)
@@ -23,7 +23,6 @@ namespace Content.Shared.Slippery
         /// <summary>
         /// How many seconds the mob will be paralyzed for.
         /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
         [DataField, AutoNetworkedField]
         [Access(Other = AccessPermissions.ReadWrite)]
         public float ParalyzeTime = 3f;
@@ -31,9 +30,16 @@ namespace Content.Shared.Slippery
         /// <summary>
         /// The entity's speed will be multiplied by this to slip it forwards.
         /// </summary>
-        [ViewVariables(VVAccess.ReadWrite)]
         [DataField, AutoNetworkedField]
         [Access(Other = AccessPermissions.ReadWrite)]
         public float LaunchForwardsMultiplier = 1f;
+
+        /// <summary>
+        /// If this is true, any slipping entity loses its friction until
+        /// it's not colliding with any SuperSlippery entities anymore.
+        /// </summary>
+        [DataField, AutoNetworkedField]
+        [Access(Other = AccessPermissions.ReadWrite)]
+        public bool SuperSlippery;
     }
 }
index 60d53eb16f483ccd9857236834beaf04cbe0376f..59a1c208ed2ea9dfa17a3a565797ce5c0fb8debc 100644 (file)
@@ -5,7 +5,6 @@ using Content.Shared.StatusEffect;
 using Content.Shared.StepTrigger.Systems;
 using Content.Shared.Stunnable;
 using JetBrains.Annotations;
-using Robust.Shared.Audio;
 using Robust.Shared.Audio.Systems;
 using Robust.Shared.Containers;
 using Robust.Shared.Physics.Components;
@@ -60,7 +59,7 @@ public sealed class SlipperySystem : EntitySystem
 
     private void TrySlip(EntityUid uid, SlipperyComponent component, EntityUid other)
     {
-        if (HasComp<KnockedDownComponent>(other))
+        if (HasComp<KnockedDownComponent>(other) && !component.SuperSlippery)
             return;
 
         var attemptEv = new SlipAttemptEvent();
@@ -71,9 +70,14 @@ public sealed class SlipperySystem : EntitySystem
         var ev = new SlipEvent(other);
         RaiseLocalEvent(uid, ref ev);
 
-        if (TryComp(other, out PhysicsComponent? physics))
+        if (TryComp(other, out PhysicsComponent? physics) && !HasComp<SlidingComponent>(other))
+        {
             _physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics);
 
+            if (component.SuperSlippery)
+                EnsureComp<SlidingComponent>(other);
+        }
+
         var playSound = !_statusEffects.HasStatusEffect(other, "KnockedDown");
 
         _stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true);
index 49af16d93dd1adbb7d78f0cb04d2dc6b9aa345a5..24f0c033cf1eecb6b502dddde7a9af32cedb1a25 100644 (file)
       paralyzeTime: 3
       launchForwardsMultiplier: 2
       requiredSlipSpeed: 1
+      superSlippery: true
 
 - type: reagent
   id: SpaceGlue
   footstepSound:
     collection: FootstepSticky
     params:
-      volume: 6
\ No newline at end of file
+      volume: 6