]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Jumpability collisions (#39710)
authorScarKy0 <106310278+ScarKy0@users.noreply.github.com>
Mon, 18 Aug 2025 12:22:36 +0000 (14:22 +0200)
committerGitHub <noreply@github.com>
Mon, 18 Aug 2025 12:22:36 +0000 (14:22 +0200)
Content.Shared/Movement/Components/ActiveLeaperComponent.cs [new file with mode: 0644]
Content.Shared/Movement/Components/JumpAbilityComponent.cs
Content.Shared/Movement/Systems/SharedJumpAbilitySystem.cs
Resources/Locale/en-US/jump-ability/jump-ability.ftl [new file with mode: 0644]
Resources/Prototypes/Entities/Mobs/Player/clone.yml

diff --git a/Content.Shared/Movement/Components/ActiveLeaperComponent.cs b/Content.Shared/Movement/Components/ActiveLeaperComponent.cs
new file mode 100644 (file)
index 0000000..cb5a237
--- /dev/null
@@ -0,0 +1,16 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Movement.Components;
+
+/// <summary>
+/// Marker component given to the users of the <see cref="JumpAbilityComponent"/> if they are meant to collide with environment.
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class ActiveLeaperComponent : Component
+{
+    /// <summary>
+    /// The duration to stun the owner on collide with environment.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public TimeSpan KnockdownDuration;
+}
index 6da91615787b69fd2ce5ef0dbfef22e3a28679e6..a6e33d5b870f7751949531abfe9a846ba677608f 100644 (file)
@@ -2,6 +2,7 @@ using Content.Shared.Actions;
 using Content.Shared.Movement.Systems;
 using Robust.Shared.Audio;
 using Robust.Shared.GameStates;
+using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Movement.Components;
 
@@ -13,6 +14,18 @@ namespace Content.Shared.Movement.Components;
 [RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedJumpAbilitySystem))]
 public sealed partial class JumpAbilityComponent : Component
 {
+    /// <summary>
+    /// The action prototype that allows you to jump.
+    /// </summary>
+    [DataField]
+    public EntProtoId Action = "ActionGravityJump";
+
+    /// <summary>
+    /// Entity to hold the action prototype.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public EntityUid? ActionEntity;
+
     /// <summary>
     /// How far you will jump (in tiles).
     /// </summary>
@@ -25,11 +38,29 @@ public sealed partial class JumpAbilityComponent : Component
     [DataField, AutoNetworkedField]
     public float JumpThrowSpeed = 10f;
 
+    /// <summary>
+    /// Whether this entity can collide with another entity, leading to it getting knocked down.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public bool CanCollide = false;
+
+    /// <summary>
+    /// The duration of the knockdown in case of a collision from CanCollide.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public TimeSpan CollideKnockdown = TimeSpan.FromSeconds(2);
+
     /// <summary>
     /// This gets played whenever the jump action is used.
     /// </summary>
     [DataField, AutoNetworkedField]
     public SoundSpecifier? JumpSound;
+
+    /// <summary>
+    /// The popup to show if the entity is unable to perform a jump.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public LocId? JumpFailedPopup = "jump-ability-failure";
 }
 
 public sealed partial class GravityJumpEvent : InstantActionEvent;
index ac720cae68f6140af2f36e5602264baeedf4efb0..598e4b564a12d06b5da50164e83a05328f141840 100644 (file)
@@ -1,7 +1,14 @@
+using Content.Shared.Actions;
+using Content.Shared.Actions.Components;
+using Content.Shared.Cloning.Events;
 using Content.Shared.Gravity;
 using Content.Shared.Movement.Components;
+using Content.Shared.Popups;
+using Content.Shared.Standing;
+using Content.Shared.Stunnable;
 using Content.Shared.Throwing;
 using Robust.Shared.Audio.Systems;
+using Robust.Shared.Physics.Events;
 
 namespace Content.Shared.Movement.Systems;
 
@@ -10,18 +17,64 @@ public sealed partial class SharedJumpAbilitySystem : EntitySystem
     [Dependency] private readonly ThrowingSystem _throwing = default!;
     [Dependency] private readonly SharedAudioSystem _audio = default!;
     [Dependency] private readonly SharedGravitySystem _gravity = default!;
+    [Dependency] private readonly SharedActionsSystem _actions = default!;
+    [Dependency] private readonly SharedStunSystem _stun = default!;
+    [Dependency] private readonly StandingStateSystem _standing = default!;
+    [Dependency] private readonly SharedPopupSystem _popup = default!;
 
     public override void Initialize()
     {
         base.Initialize();
 
+        SubscribeLocalEvent<JumpAbilityComponent, MapInitEvent>(OnInit);
+        SubscribeLocalEvent<JumpAbilityComponent, ComponentShutdown>(OnShutdown);
+
         SubscribeLocalEvent<JumpAbilityComponent, GravityJumpEvent>(OnGravityJump);
+
+        SubscribeLocalEvent<ActiveLeaperComponent, StartCollideEvent>(OnLeaperCollide);
+        SubscribeLocalEvent<ActiveLeaperComponent, LandEvent>(OnLeaperLand);
+        SubscribeLocalEvent<ActiveLeaperComponent, StopThrowEvent>(OnLeaperStopThrow);
+
+        SubscribeLocalEvent<JumpAbilityComponent, CloningEvent>(OnClone);
+    }
+
+    private void OnInit(Entity<JumpAbilityComponent> entity, ref MapInitEvent args)
+    {
+        if (!TryComp(entity, out ActionsComponent? comp))
+            return;
+
+        _actions.AddAction(entity, ref entity.Comp.ActionEntity, entity.Comp.Action, component: comp);
+    }
+
+    private void OnShutdown(Entity<JumpAbilityComponent> entity, ref ComponentShutdown args)
+    {
+        _actions.RemoveAction(entity.Owner, entity.Comp.ActionEntity);
+    }
+
+    private void OnLeaperCollide(Entity<ActiveLeaperComponent> entity, ref StartCollideEvent args)
+    {
+        _stun.TryKnockdown(entity.Owner, entity.Comp.KnockdownDuration, force: true);
+        RemCompDeferred<ActiveLeaperComponent>(entity);
+    }
+
+    private void OnLeaperLand(Entity<ActiveLeaperComponent> entity, ref LandEvent args)
+    {
+        RemCompDeferred<ActiveLeaperComponent>(entity);
+    }
+
+    private void OnLeaperStopThrow(Entity<ActiveLeaperComponent> entity, ref StopThrowEvent args)
+    {
+        RemCompDeferred<ActiveLeaperComponent>(entity);
     }
 
     private void OnGravityJump(Entity<JumpAbilityComponent> entity, ref GravityJumpEvent args)
     {
-        if (_gravity.IsWeightless(args.Performer))
+        if (_gravity.IsWeightless(args.Performer) || _standing.IsDown(args.Performer))
+        {
+            if (entity.Comp.JumpFailedPopup != null)
+                _popup.PopupClient(Loc.GetString(entity.Comp.JumpFailedPopup.Value), args.Performer, args.Performer);
             return;
+        }
 
         var xform = Transform(args.Performer);
         var throwing = xform.LocalRotation.ToWorldVec() * entity.Comp.JumpDistance;
@@ -30,6 +83,29 @@ public sealed partial class SharedJumpAbilitySystem : EntitySystem
         _throwing.TryThrow(args.Performer, direction, entity.Comp.JumpThrowSpeed);
 
         _audio.PlayPredicted(entity.Comp.JumpSound, args.Performer, args.Performer);
+
+        if (entity.Comp.CanCollide)
+        {
+            EnsureComp<ActiveLeaperComponent>(entity, out var leaperComp);
+            leaperComp.KnockdownDuration = entity.Comp.CollideKnockdown;
+            Dirty(entity.Owner, leaperComp);
+        }
+
         args.Handled = true;
     }
+
+    private void OnClone(Entity<JumpAbilityComponent> ent, ref CloningEvent args)
+    {
+        if (!args.Settings.EventComponents.Contains(Factory.GetRegistration(ent.Comp.GetType()).Name))
+            return;
+
+        var targetComp = Factory.GetComponent<JumpAbilityComponent>();
+        targetComp.Action = ent.Comp.Action;
+        targetComp.CanCollide = ent.Comp.CanCollide;
+        targetComp.JumpSound = ent.Comp.JumpSound;
+        targetComp.CollideKnockdown = ent.Comp.CollideKnockdown;
+        targetComp.JumpDistance = ent.Comp.JumpDistance;
+        targetComp.JumpThrowSpeed = ent.Comp.JumpThrowSpeed;
+        AddComp(args.CloneUid, targetComp, true);
+    }
 }
diff --git a/Resources/Locale/en-US/jump-ability/jump-ability.ftl b/Resources/Locale/en-US/jump-ability/jump-ability.ftl
new file mode 100644 (file)
index 0000000..a973745
--- /dev/null
@@ -0,0 +1 @@
+jump-ability-failure = You cannot jump right now.
index 907b694db9e7e825592c683f031c5f1c91c26797..43174cfffeabdd72dd9c770b0810d054472ea13a 100644 (file)
   - Rootable # diona
   - Sericulture # arachnids
   - MovementSpeedModifier # moths when weightless
+  - JumpAbility # vulp leaping
   copyEquipment: null
   copyInternalStorage: false
   copyImplants: false