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
This commit is contained in:
Hannah Giovanna Dawson
2025-10-24 22:18:08 +01:00
committed by GitHub
parent 5dc60b4eb3
commit 891f5a8f6b
3 changed files with 117 additions and 26 deletions

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -508,21 +508,50 @@
position: "0,-0.2" position: "0,-0.2"
density: 20 density: 20
mask: mask:
- ItemMask - ThrownItem
restitution: 0.1 # not bouncy restitution: 0.2 # not bouncy
friction: 0.2 friction: 0.2
- type: Catchable - type: Catchable
catchChance: 0.8 catchChance: 0.8
catchSuccessSound: catchSuccessSound:
path: /Audio/Effects/Footsteps/bounce.ogg path: /Audio/Effects/Footsteps/bounce.ogg
- type: EmitSoundOnCollide
sound:
path: /Audio/Effects/Footsteps/bounce.ogg
- type: Item - type: Item
size: Normal size: Normal
sprite: Objects/Fun/Balls/beach_ball.rsi sprite: Objects/Fun/Balls/beach_ball.rsi
- type: TileFrictionModifier - type: TileFrictionModifier
modifier: 0.05 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 - type: entity
parent: BaseItem parent: BaseItem