diff --git a/Content.Shared/Magic/SharedMagicSystem.cs b/Content.Shared/Magic/SharedMagicSystem.cs
index fe033f2498..878c4bdca4 100644
--- a/Content.Shared/Magic/SharedMagicSystem.cs
+++ b/Content.Shared/Magic/SharedMagicSystem.cs
@@ -7,7 +7,6 @@ using Content.Shared.Doors.Components;
using Content.Shared.Doors.Systems;
using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems;
-using Content.Shared.Humanoid;
using Content.Shared.Interaction;
using Content.Shared.Inventory;
using Content.Shared.Lock;
@@ -15,9 +14,6 @@ using Content.Shared.Magic.Components;
using Content.Shared.Magic.Events;
using Content.Shared.Maps;
using Content.Shared.Mind;
-using Content.Shared.Mind.Components;
-using Content.Shared.Mobs.Components;
-using Content.Shared.Mobs.Systems;
using Content.Shared.Physics;
using Content.Shared.Popups;
using Content.Shared.Speech.Muting;
@@ -37,6 +33,10 @@ using Robust.Shared.Spawners;
namespace Content.Shared.Magic;
+// TODO: Move BeforeCast & Prerequirements (like Wizard clothes) to action comp
+// Alt idea - make it its own comp and split, like the Charge PR
+// TODO: Move speech to actionComp or again, its own ECS
+// TODO: Use the MagicComp just for pure backend things like spawning patterns?
///
/// Handles learning and using spells (actions)
///
@@ -60,7 +60,6 @@ public abstract class SharedMagicSystem : EntitySystem
[Dependency] private readonly LockSystem _lock = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly TagSystem _tag = default!;
- [Dependency] private readonly MobStateSystem _mobState = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
[Dependency] private readonly SharedMindSystem _mind = default!;
[Dependency] private readonly SharedStunSystem _stun = default!;
@@ -81,79 +80,6 @@ public abstract class SharedMagicSystem : EntitySystem
SubscribeLocalEvent(OnRandomGlobalSpawnSpell);
SubscribeLocalEvent(OnMindSwapSpell);
SubscribeLocalEvent(OnVoidApplause);
-
- // Spell wishlist
- // A wishlish of spells that I'd like to implement or planning on implementing in a future PR
-
- // TODO: InstantDoAfterSpell and WorldDoafterSpell
- // Both would be an action that take in an event, that passes an event to trigger once the doafter is done
- // This would be three events:
- // 1 - Event that triggers from the action that starts the doafter
- // 2 - The doafter event itself, which passes the event with it
- // 3 - The event to trigger once the do-after finishes
-
- // TODO: Inanimate objects to life ECS
- // AI sentience
-
- // TODO: Flesh2Stone
- // Entity Target spell
- // Synergy with Inanimate object to life (detects player and allows player to move around)
-
- // TODO: Lightning Spell
- // Should just fire lightning, try to prevent arc back to caster
-
- // TODO: Magic Missile (homing projectile ecs)
- // Instant action, target any player (except self) on screen
-
- // TODO: Random projectile ECS for magic-carp, wand of magic
-
- // TODO: Recall Spell
- // mark any item in hand to recall
- // ItemRecallComponent
- // Event adds the component if it doesn't exist and the performer isn't stored in the comp
- // 2nd firing of the event checks to see if the recall comp has this uid, and if it does it calls it
- // if no free hands, summon at feet
- // if item deleted, clear stored item
-
- // TODO: Jaunt (should be its own ECS)
- // Instant action
- // When clicked, disappear/reappear (goes to paused map)
- // option to restrict to tiles
- // option for requiring entry/exit (blood jaunt)
- // speed option
-
- // TODO: Summon Events
- // List of wizard events to add into the event pool that frequently activate
- // floor is lava
- // change places
- // ECS that when triggered, will periodically trigger a random GameRule
- // Would need a controller/controller entity?
-
- // TODO: Summon Guns
- // Summon a random gun at peoples feet
- // Get every alive player (not in cryo, not a simplemob)
- // TODO: After Antag Rework - Rare chance of giving gun collector status to people
-
- // TODO: Summon Magic
- // Summon a random magic wand at peoples feet
- // Get every alive player (not in cryo, not a simplemob)
- // TODO: After Antag Rework - Rare chance of giving magic collector status to people
-
- // TODO: Bottle of Blood
- // Summons Slaughter Demon
- // TODO: Slaughter Demon
- // Also see Jaunt
-
- // TODO: Field Spells
- // Should be able to specify a grid of tiles (3x3 for example) that it effects
- // Timed despawn - so it doesn't last forever
- // Ignore caster - for spells that shouldn't effect the caster (ie if timestop should effect the caster)
-
- // TODO: Touch toggle spell
- // 1 - When toggled on, show in hand
- // 2 - Block hand when toggled on
- // - Require free hand
- // 3 - use spell event when toggled & click
}
private void OnBeforeCastSpell(Entity ent, ref BeforeCastSpellEvent args)
@@ -446,7 +372,7 @@ public abstract class SharedMagicSystem : EntitySystem
}
// End Spell Helpers
#endregion
- #region Smite Spells
+ #region Touch Spells
private void OnSmiteSpell(SmiteSpellEvent ev)
{
if (ev.Handled || !PassesSpellPrerequisites(ev.Action, ev.Performer))
@@ -465,7 +391,8 @@ public abstract class SharedMagicSystem : EntitySystem
_body.GibBody(ev.Target, true, body);
}
- // End Smite Spells
+
+ // End Touch Spells
#endregion
#region Knock Spells
///
diff --git a/Content.Shared/Slippery/SlipperySystem.cs b/Content.Shared/Slippery/SlipperySystem.cs
index 19cc19aa19..acf120ad1b 100644
--- a/Content.Shared/Slippery/SlipperySystem.cs
+++ b/Content.Shared/Slippery/SlipperySystem.cs
@@ -19,7 +19,7 @@ using Robust.Shared.Utility;
namespace Content.Shared.Slippery;
-[UsedImplicitly]
+[UsedImplicitly]
public sealed class SlipperySystem : EntitySystem
{
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
@@ -83,7 +83,7 @@ public sealed class SlipperySystem : EntitySystem
{
if (HasComp(args.OtherEntity))
_speedModifier.AddModifiedEntity(args.OtherEntity);
- }
+ }
private bool CanSlip(EntityUid uid, EntityUid toSlip)
{
diff --git a/Resources/Locale/en-US/magic/spells-actions.ftl b/Resources/Locale/en-US/magic/spells-actions.ftl
index faf5d77436..2216018018 100644
--- a/Resources/Locale/en-US/magic/spells-actions.ftl
+++ b/Resources/Locale/en-US/magic/spells-actions.ftl
@@ -6,3 +6,5 @@ action-speech-spell-fireball = ONI'SOMA!
action-speech-spell-summon-guns = YOR'NEE VES-KORFA
action-speech-spell-summon-magic = RYGOIN FEMA-VERECO
action-speech-spell-mind-swap = GIN'YU CAPAN!
+action-speech-spell-cluwne = !KNOH
+action-speech-spell-slip = SLEE PARRI!
diff --git a/Resources/Locale/en-US/store/spellbook-catalog.ftl b/Resources/Locale/en-US/store/spellbook-catalog.ftl
index 98d19817c6..b18cac4f9a 100644
--- a/Resources/Locale/en-US/store/spellbook-catalog.ftl
+++ b/Resources/Locale/en-US/store/spellbook-catalog.ftl
@@ -1,6 +1,6 @@
# Spells
spellbook-fireball-name = Fireball
-spellbook-fireball-desc = Get most crew exploding with rage when they see this fireball heading toward them!
+spellbook-fireball-desc = Get most crew exploding with rage when they see this fireball heading toward them! Upgradeable.
spellbook-blink-name = Blink
spellbook-blink-desc = Don't blink or you'll miss yourself teleporting away.
@@ -26,6 +26,15 @@ spellbook-ethereal-jaunt-description = Slip into the ethereal plane to slip away
spellbook-mind-swap-name = Mind Swap
spellbook-mind-swap-description = Exchange bodies with another person!
+spellbook-smite-name = Smite
+spellbook-smite-desc = Don't like them? EXPLODE them into giblets! Requires Wizard Robe & Hat.
+
+spellbook-cluwne-name = Cluwne's Curse
+spellbook-cluwne-desc = For when you really hate someone and Smite isn't enough. Requires Wizard Robe & Hat.
+
+spellbook-slip-name = Slippery Slope
+spellbook-slip-desc = Learn the ancient ways of the Janitor and curse your target to be slippery. Requires Wizard Robe & Hat.
+
# Equipment
spellbook-wand-polymorph-door-name = Wand of Entrance
diff --git a/Resources/Prototypes/Catalog/spellbook_catalog.yml b/Resources/Prototypes/Catalog/spellbook_catalog.yml
index 3246117e71..dfd171d9b2 100644
--- a/Resources/Prototypes/Catalog/spellbook_catalog.yml
+++ b/Resources/Prototypes/Catalog/spellbook_catalog.yml
@@ -26,6 +26,45 @@
- !type:ListingLimitedStockCondition
stock: 1
+- type: listing
+ id: SpellbookSmite
+ name: spellbook-smite-name
+ description: spellbook-smite-desc
+ productAction: ActionSmite
+ cost:
+ WizCoin: 3
+ categories:
+ - SpellbookOffensive
+ conditions:
+ - !type:ListingLimitedStockCondition
+ stock: 1
+
+- type: listing
+ id: SpellbookCluwne
+ name: spellbook-cluwne-name
+ description: spellbook-cluwne-desc
+ productAction: ActionCluwne
+ cost:
+ WizCoin: 3
+ categories:
+ - SpellbookOffensive
+ conditions:
+ - !type:ListingLimitedStockCondition
+ stock: 1
+
+- type: listing
+ id: SpellbookSlip
+ name: spellbook-slip-name
+ description: spellbook-slip-desc
+ productAction: ActionSlippery
+ cost:
+ WizCoin: 2
+ categories:
+ - SpellbookOffensive
+ conditions:
+ - !type:ListingLimitedStockCondition
+ stock: 1
+
# Defensive
- type: listing
id: SpellbookForceWall
diff --git a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
index 6cc13a00f2..6f6fa6afb3 100644
--- a/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
+++ b/Resources/Prototypes/Entities/Mobs/NPCs/space.yml
@@ -515,7 +515,7 @@
- type: MobStateActions
actions:
Alive:
- - ActionSmite
+ - ActionSmiteNoReq
Critical:
- ActionCritSuccumb
- ActionCritFakeDeath
diff --git a/Resources/Prototypes/Entities/Objects/Magic/books.yml b/Resources/Prototypes/Entities/Objects/Magic/books.yml
index e47fa00c45..d000f78429 100644
--- a/Resources/Prototypes/Entities/Objects/Magic/books.yml
+++ b/Resources/Prototypes/Entities/Objects/Magic/books.yml
@@ -136,7 +136,7 @@
- state: overlay_blood
- type: Spellbook
spellActions:
- ActionSmite: -1
+ ActionSmiteNoReq: -1
- type: entity
id: KnockSpellbook
diff --git a/Resources/Prototypes/Magic/smite_spells.yml b/Resources/Prototypes/Magic/smite_spells.yml
deleted file mode 100644
index 10f5bdd538..0000000000
--- a/Resources/Prototypes/Magic/smite_spells.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-- type: entity
- id: ActionSmite
- name: Smite
- description: Instantly gibs a target.
- components:
- - type: EntityTargetAction
- useDelay: 60
- 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
- event: !type:SmiteSpellEvent
- speech: action-speech-spell-smite
diff --git a/Resources/Prototypes/Magic/touch_spells.yml b/Resources/Prototypes/Magic/touch_spells.yml
new file mode 100644
index 0000000000..deb036f215
--- /dev/null
+++ b/Resources/Prototypes/Magic/touch_spells.yml
@@ -0,0 +1,83 @@
+- type: entity
+ id: ActionSmite
+ name: Smite
+ description: Instantly gibs a target.
+ components:
+ - type: EntityTargetAction
+ useDelay: 90
+ 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
+ event: !type:SmiteSpellEvent
+ speech: action-speech-spell-smite
+ - type: Magic
+ requiresClothes: true
+
+# For the Snail
+- type: entity
+ id: ActionSmiteNoReq
+ parent: ActionSmite
+ name: Smite
+ description: Instantly gibs a target.
+ components:
+ - type: Magic
+
+- type: entity
+ id: ActionCluwne
+ name: Cluwne's Curse
+ description: Turns someone into a Cluwne!
+ components:
+ - type: EntityTargetAction
+ useDelay: 120
+ itemIconStyle: BigAction
+ whitelist:
+ components:
+ - Body
+ canTargetSelf: false
+ interactOnMiss: false
+ sound: !type:SoundPathSpecifier
+ path: /Audio/Items/brokenbikehorn.ogg
+ icon:
+ sprite: Clothing/Mask/cluwne.rsi
+ state: icon
+ event: !type:ChangeComponentsSpellEvent
+ speech: action-speech-spell-cluwne
+ toAdd:
+ - type: Cluwne
+ - type: Magic
+ requiresClothes: true
+
+- type: entity
+ id: ActionSlippery
+ name: Slippery Slope
+ description: Make someone slippery.
+ components:
+ - type: EntityTargetAction
+ useDelay: 60
+ itemIconStyle: BigAction
+ whitelist:
+ components:
+ - Body
+ canTargetSelf: false
+ interactOnMiss: false
+ sound: !type:SoundPathSpecifier
+ path: /Audio/Effects/slip.ogg
+ icon:
+ sprite: Objects/Specific/Janitorial/soap.rsi
+ state: omega-4
+ event: !type:ChangeComponentsSpellEvent
+ speech: action-speech-spell-slip
+ toAdd:
+ - type: Slippery
+ - type: StepTrigger
+ requiredTriggeredSpeed: -1
+ - type: Magic
+ requiresClothes: true