]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
LaunchOnTriggerComponent (#39871)
authorHannah Giovanna Dawson <karakkaraz@gmail.com>
Fri, 24 Oct 2025 21:18:08 +0000 (22:18 +0100)
committerGitHub <noreply@github.com>
Fri, 24 Oct 2025 21:18:08 +0000 (21:18 +0000)
* LaunchOnTriggerComponent

Launches an object when a trigger on that
object is caused. The launch will be a certain
amount of force. The direction of the force
will be in the direction the object is facing.

* Fire stationary objects in the direction they're facing

* EVIL

* LESS EVIL

* Resolve @ScarKy0 comments

Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs [new file with mode: 0644]
Content.Shared/Trigger/Systems/LaunchOnTriggerSystem.cs [new file with mode: 0644]
Resources/Prototypes/Entities/Objects/Fun/toys.yml

diff --git a/Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs
new file mode 100644 (file)
index 0000000..eae877d
--- /dev/null
@@ -0,0 +1,14 @@
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Trigger.Components.Effects;
+
+/// <summary>
+/// Launches the owner of this component when triggered.
+/// If TargetUser is true, this launches the entity that was collided with instead (because the "user" is the thing that's caused the collision, i.e. the other object).
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+public sealed partial class LaunchOnTriggerComponent : BaseXOnTriggerComponent
+{
+    [DataField, AutoNetworkedField]
+    public float Speed = 10.0f;
+}
diff --git a/Content.Shared/Trigger/Systems/LaunchOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/LaunchOnTriggerSystem.cs
new file mode 100644 (file)
index 0000000..45b794d
--- /dev/null
@@ -0,0 +1,48 @@
+using System.Numerics;
+using Content.Shared.Trigger.Components.Effects;
+using Robust.Shared.Physics.Components;
+using Robust.Shared.Physics.Systems;
+
+namespace Content.Shared.Trigger.Systems;
+
+public sealed class LaunchOnTriggerSystem : EntitySystem
+{
+    [Dependency] private readonly SharedTransformSystem _transform = default!;
+    [Dependency] private readonly SharedPhysicsSystem _physics = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<LaunchOnTriggerComponent, TriggerEvent>(OnTrigger);
+    }
+
+    private void OnTrigger(Entity<LaunchOnTriggerComponent> ent, ref TriggerEvent args)
+    {
+        if (args.Key != null && !ent.Comp.KeysIn.Contains(args.Key))
+            return;
+
+        var target = ent.Comp.TargetUser ? args.User : ent.Owner;
+
+        if (target is null)
+            return;
+
+        if (!TryComp(target, out PhysicsComponent? phys))
+            return;
+
+        var linearVelocity = _physics.GetMapLinearVelocity(target.Value);
+        // If the linear velocity is length 0, this means it's not moving. Given we want to move it in some direction...
+        if (linearVelocity.IsLengthZero())
+            // An object that isn't moving is launched in the direction its facing, not the direction it's rotated (objects face away from their rotation).
+            linearVelocity = _transform.GetWorldRotation(target.Value).RotateVec(Vector2.UnitY) * -1;
+
+        // When triggered, take the direction the target is moving in (the normalized vector) and multiply it by the speed.
+        // Then apply an impulse to the target on the new vector.
+        // (If the target is moving NE at 10 m/s, this impulses it NE at speed m/s)
+        _physics.ApplyLinearImpulse(target.Value,
+            linearVelocity.Normalized() * ent.Comp.Speed,
+            body: phys);
+
+        args.Handled = true;
+    }
+}
index f1b8679caecac5716456aa5f89dccce2008e4e03..0e26b1761a2094bedbdaf95fe3d1c3851f400b9b 100644 (file)
   name: beach ball
   description: The simple beach ball is one of Nanotrasen's most popular products. 'Why do we make beach balls? Because we can! (TM)' - Nanotrasen
   components:
-  - type: Sprite
-    sprite: Objects/Fun/Balls/beach_ball.rsi
-    state: icon
-  - type: Fixtures
-    fixtures:
-      fix1:
-        shape: !type:PhysShapeCircle
-          radius: 0.3
-          position: "0,-0.2"
-        density: 20
-        mask:
-        - ItemMask
-        restitution: 0.1 # not bouncy
-        friction: 0.2
-  - type: Catchable
-    catchChance: 0.8
-    catchSuccessSound:
-      path: /Audio/Effects/Footsteps/bounce.ogg
-  - type: EmitSoundOnCollide
-    sound:
-      path: /Audio/Effects/Footsteps/bounce.ogg
-  - type: Item
-    size: Normal
-    sprite: Objects/Fun/Balls/beach_ball.rsi
-  - type: TileFrictionModifier
-    modifier: 0.05
+    - type: Sprite
+      sprite: Objects/Fun/Balls/beach_ball.rsi
+      state: icon
+    - type: Fixtures
+      fixtures:
+        fix1:
+          shape: !type:PhysShapeCircle
+            radius: 0.3
+            position: "0,-0.2"
+          density: 20
+          mask:
+            - ThrownItem
+          restitution: 0.2 # not bouncy
+          friction: 0.2
+    - type: Catchable
+      catchChance: 0.8
+      catchSuccessSound:
+        path: /Audio/Effects/Footsteps/bounce.ogg
+    - type: Item
+      size: Normal
+      sprite: Objects/Fun/Balls/beach_ball.rsi
+    - type: TileFrictionModifier
+      modifier: 0.05
+    - type: TriggerOnCollide
+      fixtureID: fix1
+      keyOut: OnCollide
+    - type: EmitSoundOnTrigger
+      sound:
+        path: /Audio/Effects/Footsteps/bounce.ogg
+      keysIn:
+        - OnCollide
+
+- type: entity
+  parent: BeachBall
+  id: EvilBeachBall
+  suffix: evil
+  name: beach ball
+  description: Someone's drawn ">:3c" on the side of this beach ball in indelible ink.
+  components:
+    - type: LaunchOnTrigger
+      speed: 100.0
+      keysIn:
+        - OnCollide
+    - type: StaminaDamageOnTrigger
+      stamina: 25.0
+      keysIn:
+        - OnCollide
+      targetUser: true
+    - type: DamageOnTrigger
+      damage:
+        types:
+          Blunt: 20
+      keysIn:
+        - OnCollide
+      targetUser: true
 
 - type: entity
   parent: BaseItem