From: Hannah Giovanna Dawson Date: Fri, 24 Oct 2025 21:18:08 +0000 (+0100) Subject: LaunchOnTriggerComponent (#39871) X-Git-Url: https://git.smokeofanarchy.ru/gitweb.cgi?a=commitdiff_plain;h=891f5a8f6ba76701dd447d6f33e27cc9029a673d;p=space-station-14.git LaunchOnTriggerComponent (#39871) * 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 --- diff --git a/Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs new file mode 100644 index 0000000000..eae877d7b6 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/LaunchOnTriggerComponent.cs @@ -0,0 +1,14 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// 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). +/// +[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 index 0000000000..45b794d6ff --- /dev/null +++ b/Content.Shared/Trigger/Systems/LaunchOnTriggerSystem.cs @@ -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(OnTrigger); + } + + private void OnTrigger(Entity 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; + } +} diff --git a/Resources/Prototypes/Entities/Objects/Fun/toys.yml b/Resources/Prototypes/Entities/Objects/Fun/toys.yml index f1b8679cae..0e26b1761a 100644 --- a/Resources/Prototypes/Entities/Objects/Fun/toys.yml +++ b/Resources/Prototypes/Entities/Objects/Fun/toys.yml @@ -497,32 +497,61 @@ 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