From 4f3b8d740cecfb736b018fd78a2be71f5397644d Mon Sep 17 00:00:00 2001 From: Arendian <137322659+Arendian@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:39:10 +0100 Subject: [PATCH] Spacelube slide (#24801) * Space lube now makes you slide * review * oh lord he slippin --------- Co-authored-by: metalgearsloth --- .../TileReactions/SpillTileReaction.cs | 11 +++- .../Fluids/EntitySystems/PuddleSystem.cs | 2 +- Content.Shared/Slippery/SlidingComponent.cs | 22 +++++++ Content.Shared/Slippery/SlidingSystem.cs | 63 +++++++++++++++++++ Content.Shared/Slippery/SlipperyComponent.cs | 10 ++- Content.Shared/Slippery/SlipperySystem.cs | 10 ++- Resources/Prototypes/Reagents/cleaning.yml | 3 +- 7 files changed, 112 insertions(+), 9 deletions(-) create mode 100644 Content.Shared/Slippery/SlidingComponent.cs create mode 100644 Content.Shared/Slippery/SlidingSystem.cs diff --git a/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs b/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs index 87246927d7..49fdaa5c7e 100644 --- a/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs +++ b/Content.Server/Chemistry/TileReactions/SpillTileReaction.cs @@ -21,9 +21,15 @@ namespace Content.Server.Chemistry.TileReactions [DataField("requiredSlipSpeed")] private float _requiredSlipSpeed = 6; [DataField("paralyzeTime")] private float _paralyzeTime = 1; + /// + /// + /// + [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(); @@ -33,7 +39,8 @@ namespace Content.Server.Chemistry.TileReactions var slippery = entityManager.EnsureComponent(puddleUid); slippery.LaunchForwardsMultiplier = _launchForwardsMultiplier; slippery.ParalyzeTime = _paralyzeTime; - entityManager.Dirty(slippery); + slippery.SuperSlippery = _superSlippery; + entityManager.Dirty(puddleUid, slippery); var step = entityManager.EnsureComponent(puddleUid); entityManager.EntitySysManager.GetEntitySystem().SetRequiredTriggerSpeed(puddleUid, _requiredSlipSpeed, step); diff --git a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs index b6df3a171b..44d28379ab 100644 --- a/Content.Server/Fluids/EntitySystems/PuddleSystem.cs +++ b/Content.Server/Fluids/EntitySystems/PuddleSystem.cs @@ -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(args.Slipped)) + if (!HasComp(args.Slipped) || HasComp(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 index 0000000000..e48c0f2e9e --- /dev/null +++ b/Content.Shared/Slippery/SlidingComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Slippery; + +/// +/// Applies continuous movement to the attached entity when colliding with super slipper entities. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class SlidingComponent : Component +{ + /// + /// A list of SuperSlippery entities the entity with this component is colliding with. + /// + [DataField, AutoNetworkedField] + public HashSet CollidingEntities = new (); + + /// + /// The friction modifier that will be applied to any friction calculations. + /// + [DataField, AutoNetworkedField] + public float FrictionModifier; +} diff --git a/Content.Shared/Slippery/SlidingSystem.cs b/Content.Shared/Slippery/SlidingSystem.cs new file mode 100644 index 0000000000..0af6b203cc --- /dev/null +++ b/Content.Shared/Slippery/SlidingSystem.cs @@ -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(OnSlideAttempt); + SubscribeLocalEvent(OnStand); + SubscribeLocalEvent(OnStartCollide); + SubscribeLocalEvent(OnEndCollide); + } + + /// + /// Modify the friction by the frictionModifier stored on the component. + /// + private void OnSlideAttempt(EntityUid uid, SlidingComponent component, ref TileFrictionEvent args) + { + args.Modifier = component.FrictionModifier; + } + + /// + /// Remove the component when the entity stands up again. + /// + private void OnStand(EntityUid uid, SlidingComponent component, ref StoodEvent args) + { + RemComp(uid); + } + + /// + /// Sets friction to 0 if colliding with a SuperSlippery Entity. + /// + private void OnStartCollide(EntityUid uid, SlidingComponent component, ref StartCollideEvent args) + { + if (!TryComp(args.OtherEntity, out var slippery) || !slippery.SuperSlippery) + return; + + component.CollidingEntities.Add(args.OtherEntity); + component.FrictionModifier = 0; + Dirty(uid, component); + } + + /// + /// Set friction to normal when ending collision with a SuperSlippery entity. + /// + 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); + } + +} diff --git a/Content.Shared/Slippery/SlipperyComponent.cs b/Content.Shared/Slippery/SlipperyComponent.cs index b470e2cbbd..b80a9b57e4 100644 --- a/Content.Shared/Slippery/SlipperyComponent.cs +++ b/Content.Shared/Slippery/SlipperyComponent.cs @@ -23,7 +23,6 @@ namespace Content.Shared.Slippery /// /// How many seconds the mob will be paralyzed for. /// - [ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] public float ParalyzeTime = 3f; @@ -31,9 +30,16 @@ namespace Content.Shared.Slippery /// /// The entity's speed will be multiplied by this to slip it forwards. /// - [ViewVariables(VVAccess.ReadWrite)] [DataField, AutoNetworkedField] [Access(Other = AccessPermissions.ReadWrite)] public float LaunchForwardsMultiplier = 1f; + + /// + /// If this is true, any slipping entity loses its friction until + /// it's not colliding with any SuperSlippery entities anymore. + /// + [DataField, AutoNetworkedField] + [Access(Other = AccessPermissions.ReadWrite)] + public bool SuperSlippery; } } diff --git a/Content.Shared/Slippery/SlipperySystem.cs b/Content.Shared/Slippery/SlipperySystem.cs index 60d53eb16f..59a1c208ed 100644 --- a/Content.Shared/Slippery/SlipperySystem.cs +++ b/Content.Shared/Slippery/SlipperySystem.cs @@ -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(other)) + if (HasComp(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(other)) + { _physics.SetLinearVelocity(other, physics.LinearVelocity * component.LaunchForwardsMultiplier, body: physics); + if (component.SuperSlippery) + EnsureComp(other); + } + var playSound = !_statusEffects.HasStatusEffect(other, "KnockedDown"); _stun.TryParalyze(other, TimeSpan.FromSeconds(component.ParalyzeTime), true); diff --git a/Resources/Prototypes/Reagents/cleaning.yml b/Resources/Prototypes/Reagents/cleaning.yml index 49af16d93d..24f0c033cf 100644 --- a/Resources/Prototypes/Reagents/cleaning.yml +++ b/Resources/Prototypes/Reagents/cleaning.yml @@ -110,6 +110,7 @@ paralyzeTime: 3 launchForwardsMultiplier: 2 requiredSlipSpeed: 1 + superSlippery: true - type: reagent id: SpaceGlue @@ -150,4 +151,4 @@ footstepSound: collection: FootstepSticky params: - volume: 6 \ No newline at end of file + volume: 6 -- 2.51.2