diff --git a/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs new file mode 100644 index 0000000000..bf4e1841b1 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/CleanContainersOnTriggerComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for removing and *deleting* all items in container(s) on the target. +/// +/// +/// Be very careful when setting to true or all your organs might fall out. +/// In fact, never set it to true. +/// +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class CleanContainersOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Names of containers to empty. + /// If null, all containers will be emptied. + /// + [DataField, AutoNetworkedField] + public List? Container; +} diff --git a/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs new file mode 100644 index 0000000000..de55e1f3ac --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/EmptyContainersOnTriggerComponent.cs @@ -0,0 +1,22 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for removing all items in container(s) on the target. +/// +/// +/// Be very careful when setting to true or all your organs might fall out. +/// In fact, never set it to true. +/// +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class EmptyContainersOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// Names of containers to empty. + /// If null, all containers will be emptied. + /// + [DataField, AutoNetworkedField] + public List? Container; +} diff --git a/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs new file mode 100644 index 0000000000..33809130c2 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/KnockdownOnTriggerComponent.cs @@ -0,0 +1,36 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for sending the target sidewise (crawling). +/// Knockdowns the user if is true. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class KnockdownOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// How long the target is forced to be on the ground. + /// + [DataField, AutoNetworkedField] + public TimeSpan KnockdownAmount = TimeSpan.FromSeconds(1); + + /// + /// If true, refresh the duration. + /// If false, time is added on-top of any existing forced knockdown. + /// + [DataField, AutoNetworkedField] + public bool Refresh = true; + + /// + /// Should the entity try and stand automatically? + /// + [DataField, AutoNetworkedField] + public bool AutoStand = true; + + /// + /// Should the entity drop their items upon first being knocked down? + /// + [DataField, AutoNetworkedField] + public bool Drop = true; +} diff --git a/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs b/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs new file mode 100644 index 0000000000..ebe55dc102 --- /dev/null +++ b/Content.Shared/Trigger/Components/Effects/StunOnTriggerComponent.cs @@ -0,0 +1,24 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Effects; + +/// +/// Trigger effect for stunning an entity. +/// Stuns the user if is true. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class StunOnTriggerComponent : BaseXOnTriggerComponent +{ + /// + /// How long to stun the target. + /// + [DataField, AutoNetworkedField] + public TimeSpan StunAmount = TimeSpan.FromSeconds(1); + + /// + /// If true, refresh the stun duration. + /// If false, stun is added on-top of any existing stun. + /// + [DataField, AutoNetworkedField] + public bool Refresh = true; +} diff --git a/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs b/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs new file mode 100644 index 0000000000..4e832993b5 --- /dev/null +++ b/Content.Shared/Trigger/Components/Triggers/TriggerOnThrowDoHitComponent.cs @@ -0,0 +1,10 @@ +using Robust.Shared.GameStates; + +namespace Content.Shared.Trigger.Components.Triggers; + +/// +/// Trigger for when this entity is thrown and then hits a second entity. +/// User is the entity hit. +/// +[RegisterComponent, NetworkedComponent, AutoGenerateComponentState] +public sealed partial class TriggerOnThrowDoHitComponent : BaseTriggerOnXComponent; diff --git a/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs new file mode 100644 index 0000000000..dbe1601022 --- /dev/null +++ b/Content.Shared/Trigger/Systems/EmptyContainersOnTriggerSystem.cs @@ -0,0 +1,81 @@ +using Content.Shared.Trigger.Components.Effects; +using Robust.Shared.Containers; + +namespace Content.Shared.Trigger.Systems; + +/// +/// Empty containers trigger system. +/// +public sealed class EmptyContainersOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedContainerSystem _container = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (!TryComp(target, out var containerComp)) + return; + + // Empty everything. Make sure a player isn't the target because they will get removed from their body along with their organs + if (ent.Comp.Container is null) + { + foreach (var container in _container.GetAllContainers(target, containerComp)) + { + _container.EmptyContainer(container); + } + + args.Handled = true; + } + + // Empty containers in a sane way + else + { + foreach (var containerId in ent.Comp.Container) + { + if (!_container.TryGetContainer(target, containerId, out var container, containerComp)) + continue; + + _container.EmptyContainer(container); + args.Handled = true; + } + } + } +} + +/// +/// Empty containers and delete items trigger system. +/// +public sealed class CleanContainersOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedContainerSystem _container = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (!TryComp(target, out var containerComp)) + return; + + // Empty everything. Make sure a player isn't the target because they will get DELETED + if (ent.Comp.Container is null) + { + foreach (var container in _container.GetAllContainers(target, containerComp)) + { + _container.CleanContainer(container); + } + + args.Handled = true; + } + + // Empty containers in a sane way + else + { + foreach (var containerId in ent.Comp.Container) + { + if (!_container.TryGetContainer(target, containerId, out var container, containerComp)) + continue; + + _container.CleanContainer(container); + args.Handled = true; + } + } + } +} + diff --git a/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs new file mode 100644 index 0000000000..815e00abc8 --- /dev/null +++ b/Content.Shared/Trigger/Systems/KnockdownOnTriggerSystem.cs @@ -0,0 +1,21 @@ +using Content.Shared.Stunnable; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class KnockdownOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedStunSystem _stun = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + args.Handled |= _stun.TryKnockdown( + target, + ent.Comp.KnockdownAmount, + ent.Comp.Refresh, + ent.Comp.AutoStand, + ent.Comp.Drop, + true + ); + } +} diff --git a/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs b/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs new file mode 100644 index 0000000000..ce86f971d3 --- /dev/null +++ b/Content.Shared/Trigger/Systems/StunOnTriggerSystem.cs @@ -0,0 +1,17 @@ +using Content.Shared.Stunnable; +using Content.Shared.Trigger.Components.Effects; + +namespace Content.Shared.Trigger.Systems; + +public sealed class StunOnTriggerSystem : XOnTriggerSystem +{ + [Dependency] private readonly SharedStunSystem _stun = default!; + + protected override void OnTrigger(Entity ent, EntityUid target, ref TriggerEvent args) + { + if (ent.Comp.Refresh) + args.Handled |= _stun.TryUpdateStunDuration(target, ent.Comp.StunAmount); + else + args.Handled |= _stun.TryAddStunDuration(target, ent.Comp.StunAmount); + } +} diff --git a/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs b/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs new file mode 100644 index 0000000000..ca57b517c6 --- /dev/null +++ b/Content.Shared/Trigger/Systems/TriggerOnThrowDoHitSystem.cs @@ -0,0 +1,19 @@ +using Content.Shared.Throwing; +using Content.Shared.Trigger.Components.Triggers; + +namespace Content.Shared.Trigger.Systems; + +public sealed partial class TriggerOnThrowDoHitSystem : TriggerOnXSystem +{ + public override void Initialize() + { + base.Initialize(); + + SubscribeLocalEvent(OnHit); + } + + private void OnHit(Entity ent, ref ThrowDoHitEvent args) + { + Trigger.Trigger(ent.Owner, args.Target, ent.Comp.KeyOut); + } +}