diff --git a/Content.Server/Magic/Events/SmiteSpellEvent.cs b/Content.Server/Magic/Events/SmiteSpellEvent.cs new file mode 100644 index 0000000000..e6aa36a908 --- /dev/null +++ b/Content.Server/Magic/Events/SmiteSpellEvent.cs @@ -0,0 +1,12 @@ +using Content.Shared.Actions; + +namespace Content.Server.Magic.Events; + +public sealed class SmiteSpellEvent : EntityTargetActionEvent +{ + /// + /// Should this smite delete all parts/mechanisms gibbed except for the brain? + /// + [DataField("deleteNonBrainParts")] + public bool DeleteNonBrainParts = true; +} diff --git a/Content.Server/Magic/MagicSystem.cs b/Content.Server/Magic/MagicSystem.cs index bfb4127bf5..f7974e9593 100644 --- a/Content.Server/Magic/MagicSystem.cs +++ b/Content.Server/Magic/MagicSystem.cs @@ -1,4 +1,5 @@ using System.Threading; +using Content.Server.Body.Components; using Content.Server.Coordinates.Helpers; using Content.Server.Decals; using Content.Server.DoAfter; @@ -9,6 +10,7 @@ using Content.Server.Spawners.Components; using Content.Server.Weapon.Ranged.Systems; using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; +using Content.Shared.Body.Components; using Content.Shared.Doors.Components; using Content.Shared.Doors.Systems; using Content.Shared.Interaction.Events; @@ -49,6 +51,7 @@ public sealed class MagicSystem : EntitySystem SubscribeLocalEvent(OnInstantSpawn); SubscribeLocalEvent(OnTeleportSpell); SubscribeLocalEvent(OnKnockSpell); + SubscribeLocalEvent(OnSmiteSpell); SubscribeLocalEvent(OnWorldSpawn); SubscribeLocalEvent(OnProjectileSpell); } @@ -264,6 +267,30 @@ public sealed class MagicSystem : EntitySystem args.Handled = true; } + private void OnSmiteSpell(SmiteSpellEvent ev) + { + if (ev.Handled) + return; + + if (!TryComp(ev.Target, out var body)) + return; + + var ents = body.Gib(true); + + if (!ev.DeleteNonBrainParts) + return; + + foreach (var part in ents) + { + // just leaves a brain and clothes + if ((HasComp(part) || HasComp(part)) + && !HasComp(part)) + { + QueueDel(part); + } + } + } + /// /// Spawns entity prototypes from a list within range of click. /// diff --git a/Content.Shared/Body/Components/SharedBodyComponent.cs b/Content.Shared/Body/Components/SharedBodyComponent.cs index 47b9272df9..76cf0ca4c2 100644 --- a/Content.Shared/Body/Components/SharedBodyComponent.cs +++ b/Content.Shared/Body/Components/SharedBodyComponent.cs @@ -397,7 +397,7 @@ namespace Content.Shared.Body.Components RemovePart(part); if (gibParts) - part.Gib(); + gibs.UnionWith(part.Gib()); } return gibs; diff --git a/Content.Shared/Body/Components/SharedBodyPartComponent.cs b/Content.Shared/Body/Components/SharedBodyPartComponent.cs index 0c0b9bd8f6..875ffe4179 100644 --- a/Content.Shared/Body/Components/SharedBodyPartComponent.cs +++ b/Content.Shared/Body/Components/SharedBodyPartComponent.cs @@ -287,12 +287,17 @@ namespace Content.Shared.Body.Components /// /// Gibs the body part. /// - public virtual void Gib() + public virtual HashSet Gib() { + var gibs = new HashSet(); + foreach (var mechanism in _mechanisms) { + gibs.Add(mechanism.Owner); RemoveMechanism(mechanism); } + + return gibs; } } diff --git a/Resources/Audio/Magic/disintegrate.ogg b/Resources/Audio/Magic/disintegrate.ogg new file mode 100644 index 0000000000..568a1b43e4 Binary files /dev/null and b/Resources/Audio/Magic/disintegrate.ogg differ diff --git a/Resources/Audio/Magic/licenses.txt b/Resources/Audio/Magic/licenses.txt index 90b77db0c7..c8e93f558b 100644 --- a/Resources/Audio/Magic/licenses.txt +++ b/Resources/Audio/Magic/licenses.txt @@ -3,5 +3,6 @@ https://github.com/Citadel-Station-13/Citadel-Station-13/blob/master/sound/magic https://github.com/Citadel-Station-13/Citadel-Station-13/blob/master/sound/magic/Knock.ogg fireball.ogg taken from /tg/station at https://github.com/tgstation/tgstation/commit/906fb0682bab6a0975b45036001c54f021f58ae7 +disintegrate.ogg from /tg/station at https://github.com/tgstation/tgstation/commit/6fde7a49fcd56d6edb844cd31a04ce026065de8b -copyright: CC BY-SA 3.0 \ No newline at end of file +copyright: CC BY-SA 3.0 diff --git a/Resources/Locale/en-US/magic/spells-actions.ftl b/Resources/Locale/en-US/magic/spells-actions.ftl index 50faf279c5..8368770507 100644 --- a/Resources/Locale/en-US/magic/spells-actions.ftl +++ b/Resources/Locale/en-US/magic/spells-actions.ftl @@ -9,6 +9,10 @@ action-name-spell-knock = Knock action-description-spell-knock = This spell opens nearby doors. action-speech-spell-knock = AULIE OXIN FIERA +action-name-spell-smite = Smite +action-description-spell-smite = Instantly gibs a target. +action-speech-spell-smite = EI NATH! + action-name-spell-blink = Blink action-description-spell-blink = Teleport to the clicked location. diff --git a/Resources/Prototypes/Entities/Objects/Magic/books.yml b/Resources/Prototypes/Entities/Objects/Magic/books.yml index 0992c03c81..67333112e2 100644 --- a/Resources/Prototypes/Entities/Objects/Magic/books.yml +++ b/Resources/Prototypes/Entities/Objects/Magic/books.yml @@ -50,6 +50,20 @@ worldSpells: Blink: -1 +- type: entity + id: SmiteBook + name: smite spellbook + parent: BaseSpellbook + components: + - type: Sprite + netsync: false + sprite: Objects/Magic/spellbooks.rsi + layers: + - state: spellbook + - type: Spellbook + entitySpells: + Smite: -1 + - type: entity id: KnockSpellbook name: knock spellbook diff --git a/Resources/Prototypes/Magic/smite_spells.yml b/Resources/Prototypes/Magic/smite_spells.yml new file mode 100644 index 0000000000..c2e31f301c --- /dev/null +++ b/Resources/Prototypes/Magic/smite_spells.yml @@ -0,0 +1,18 @@ +- type: entityTargetAction + id: Smite + name: action-name-spell-smite + description: action-description-spell-smite + useDelay: 60 + speech: action-speech-spell-smite + itemIconStyle: BigAction + whitelist: + components: + - Body + canTargetSelf: false + interactOnMiss: false + sound: !type:SoundPathSpecifier + path: /Audio/Magic/disintegrate.ogg + icon: + sprite: Objects/Magic/magicactions.rsi + state: gib + serverEvent: !type:SmiteSpellEvent