]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Refactor magic speak system to be a component added to actions (#36328)
authorJ <billsmith116@gmail.com>
Sun, 4 May 2025 17:34:19 +0000 (18:34 +0100)
committerGitHub <noreply@github.com>
Sun, 4 May 2025 17:34:19 +0000 (13:34 -0400)
28 files changed:
Content.Server/Magic/MagicSystem.cs
Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs [new file with mode: 0644]
Content.Shared/Magic/Events/ChangeComponentSpellEvent.cs
Content.Shared/Magic/Events/ChargeSpellEvent.cs
Content.Shared/Magic/Events/InstantSpawnSpellEvent.cs
Content.Shared/Magic/Events/KnockSpellEvent.cs
Content.Shared/Magic/Events/MindSwapSpellEvent.cs
Content.Shared/Magic/Events/ProjectileSpellEvent.cs
Content.Shared/Magic/Events/RandomGlobalSpawnSpellEvent.cs
Content.Shared/Magic/Events/SmiteSpellEvent.cs
Content.Shared/Magic/Events/SpeakSpellEvent.cs [deleted file]
Content.Shared/Magic/Events/TeleportSpellEvent.cs
Content.Shared/Magic/Events/VoidApplauseSpellEvent.cs
Content.Shared/Magic/Events/WorldSpawnSpellEvent.cs
Content.Shared/Magic/ISpeakSpell.cs [deleted file]
Content.Shared/Magic/SharedMagicSystem.cs
Content.Shared/Speech/Components/SpeakOnActionComponent.cs [new file with mode: 0644]
Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs [new file with mode: 0644]
Resources/Locale/en-US/magic/spells-actions.ftl
Resources/Prototypes/Magic/animate_spell.yml
Resources/Prototypes/Magic/event_spells.yml
Resources/Prototypes/Magic/forcewall_spells.yml
Resources/Prototypes/Magic/knock_spell.yml
Resources/Prototypes/Magic/mindswap_spell.yml
Resources/Prototypes/Magic/projectile_spells.yml
Resources/Prototypes/Magic/spawn_spells.yml
Resources/Prototypes/Magic/touch_spells.yml
Resources/Prototypes/Magic/utility_spells.yml

index dafd88dd5f0b959e5c38f960bc2923578084a550..09f6fd143e4d5c0df101dc5d4385fe633c6c2b47 100644 (file)
@@ -21,13 +21,6 @@ public sealed class MagicSystem : SharedMagicSystem
     public override void Initialize()
     {
         base.Initialize();
-
-        SubscribeLocalEvent<SpeakSpellEvent>(OnSpellSpoken);
-    }
-
-    private void OnSpellSpoken(ref SpeakSpellEvent args)
-    {
-        _chat.TrySendInGameICMessage(args.Performer, Loc.GetString(args.Speech), InGameICChatType.Speak, false);
     }
 
     public override void OnVoidApplause(VoidApplauseSpellEvent ev)
diff --git a/Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs b/Content.Server/Speech/EntitySystems/SpeakOnActionSystem.cs
new file mode 100644 (file)
index 0000000..ba7043e
--- /dev/null
@@ -0,0 +1,39 @@
+using Content.Server.Chat.Systems;
+using Content.Shared.Speech.Components;
+using Content.Shared.Speech;
+using Content.Shared.Speech.EntitySystems;
+using Content.Shared.Speech.Muting;
+using Content.Shared.Actions.Events;
+
+
+namespace Content.Server.Speech.EntitySystems;
+
+/// <summary>
+/// As soon as the chat refactor moves to Shared
+/// the logic here can move to the shared <see cref="SharedSpeakOnActionSystem"/>
+/// </summary>
+public sealed class SpeakOnActionSystem : SharedSpeakOnActionSystem
+{
+    [Dependency] private readonly ChatSystem _chat = default!;
+
+    public override void Initialize()
+    {
+        base.Initialize();
+
+        SubscribeLocalEvent<SpeakOnActionComponent, ActionPerformedEvent>(OnActionPerformed);
+    }
+
+    private void OnActionPerformed(Entity<SpeakOnActionComponent> ent, ref ActionPerformedEvent args)
+    {
+        var user = args.Performer;
+
+        // If we can't speak, we can't speak
+        if (!HasComp<SpeechComponent>(user) || HasComp<MutedComponent>(user))
+            return;
+
+        if (string.IsNullOrWhiteSpace(ent.Comp.Sentence))
+            return;
+
+        _chat.TrySendInGameICMessage(user, Loc.GetString(ent.Comp.Sentence), InGameICChatType.Speak, false);
+    }
+}
index b2b1dc96e8b584a622114713889e81dc312308d2..0354a69911baf2a96c9f3bf09ceb0befaeb08637 100644 (file)
@@ -6,7 +6,7 @@ namespace Content.Shared.Magic.Events;
 /// <summary>
 ///     Spell that uses the magic of ECS to add & remove components. Components are first removed, then added.
 /// </summary>
-public sealed partial class ChangeComponentsSpellEvent : EntityTargetActionEvent, ISpeakSpell
+public sealed partial class ChangeComponentsSpellEvent : EntityTargetActionEvent
 {
     // TODO allow it to set component data-fields?
     // for now a Hackish way to do that is to remove & add, but that doesn't allow you to selectively set specific data fields.
@@ -19,9 +19,4 @@ public sealed partial class ChangeComponentsSpellEvent : EntityTargetActionEvent
     [AlwaysPushInheritance]
     public HashSet<string> ToRemove = new();
 
-    [DataField]
-    public string? Speech { get; private set; }
-
-    [DataField]
-    public bool DoSpeech { get; private set; }
 }
index 8898761ec2a5dea407481e602d61c78dfae18897..3d97de2dc7128939288d696d659506e49113838f 100644 (file)
@@ -1,18 +1,15 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 
 namespace Content.Shared.Magic.Events;
 
 /// <summary>
 /// Adds provided Charge to the held wand
 /// </summary>
-public sealed partial class ChargeSpellEvent : InstantActionEvent, ISpeakSpell
+public sealed partial class ChargeSpellEvent : InstantActionEvent
 {
     [DataField(required: true)]
     public int Charge;
 
     [DataField]
     public string WandTag = "WizardWand";
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
index 1405b158271c0cbe72fd4f71c427c2f61b6fb575..235a841636ec6d02a5f3b3ee1717a3590505e7aa 100644 (file)
@@ -1,9 +1,9 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class InstantSpawnSpellEvent : InstantActionEvent, ISpeakSpell
+public sealed partial class InstantSpawnSpellEvent : InstantActionEvent
 {
     /// <summary>
     /// What entity should be spawned.
@@ -14,9 +14,6 @@ public sealed partial class InstantSpawnSpellEvent : InstantActionEvent, ISpeakS
     [DataField]
     public bool PreventCollideWithCaster = true;
 
-    [DataField]
-    public string? Speech { get; private set; }
-
     /// <summary>
     /// Gets the targeted spawn positons; may lead to multiple entities being spawned.
     /// </summary>
index 24a1700d21f1609bda34535223fe3b88d6348db9..87c02806c9825a8145dcbcce103265200c5b0f76 100644 (file)
@@ -1,8 +1,8 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class KnockSpellEvent : InstantActionEvent, ISpeakSpell
+public sealed partial class KnockSpellEvent : InstantActionEvent
 {
     /// <summary>
     /// The range this spell opens doors in
@@ -11,7 +11,4 @@ public sealed partial class KnockSpellEvent : InstantActionEvent, ISpeakSpell
     /// </summary>
     [DataField]
     public float Range = 10f;
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
index 89319090c1c797d47b01f383955547e089924899..5b23047cfb51f7e4d25192fdb9304b4fa13374cf 100644 (file)
@@ -2,14 +2,11 @@ using Content.Shared.Actions;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class MindSwapSpellEvent : EntityTargetActionEvent, ISpeakSpell
+public sealed partial class MindSwapSpellEvent : EntityTargetActionEvent
 {
     [DataField]
     public TimeSpan PerformerStunDuration = TimeSpan.FromSeconds(10);
 
     [DataField]
     public TimeSpan TargetStunDuration = TimeSpan.FromSeconds(10);
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
index 336ea03346b14552fa3425fa1945fb847a030575..917f6ea8510ad5fa80f407b30132f1fd4a7a1c89 100644 (file)
@@ -1,16 +1,13 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class ProjectileSpellEvent : WorldTargetActionEvent, ISpeakSpell
+public sealed partial class ProjectileSpellEvent : WorldTargetActionEvent
 {
     /// <summary>
     /// What entity should be spawned.
     /// </summary>
     [DataField(required: true)]
     public EntProtoId Prototype;
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
index eb39c0cd08904863f459e09123330c7f1796095d..dedf5386964508d3d01262ed3db8e041a0b97bec 100644 (file)
@@ -4,7 +4,7 @@ using Robust.Shared.Audio;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent, ISpeakSpell
+public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent
 {
     /// <summary>
     /// The list of prototypes this spell can spawn, will select one randomly
@@ -18,9 +18,6 @@ public sealed partial class RandomGlobalSpawnSpellEvent : InstantActionEvent, IS
     [DataField]
     public SoundSpecifier Sound = new SoundPathSpecifier("/Audio/Magic/staff_animation.ogg");
 
-    [DataField]
-    public string? Speech { get; private set; }
-
     /// <summary>
     /// Should this Global spawn spell turn its targets into a Survivor Antagonist?
     /// Ignores the caster for this.
index 74ca116ad59642402589ca11581c97cee587f79a..801e65689dffc54537f0e931654783ad8c473ddc 100644 (file)
@@ -1,8 +1,8 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class SmiteSpellEvent : EntityTargetActionEvent, ISpeakSpell
+public sealed partial class SmiteSpellEvent : EntityTargetActionEvent
 {
     // TODO: Make part of gib method
     /// <summary>
@@ -10,7 +10,4 @@ public sealed partial class SmiteSpellEvent : EntityTargetActionEvent, ISpeakSpe
     /// </summary>
     [DataField]
     public bool DeleteNonBrainParts = true;
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
diff --git a/Content.Shared/Magic/Events/SpeakSpellEvent.cs b/Content.Shared/Magic/Events/SpeakSpellEvent.cs
deleted file mode 100644 (file)
index 1b3f7af..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-namespace Content.Shared.Magic.Events;
-
-[ByRefEvent]
-public readonly struct SpeakSpellEvent(EntityUid performer, string speech)
-{
-    public readonly EntityUid Performer = performer;
-    public readonly string Speech = speech;
-}
index 525c1e510524dd928f21bbe7e84baba68087b176..f4cbcecd8fa9ecdea46d1068b2ea185b66450702 100644 (file)
@@ -1,12 +1,10 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 
 namespace Content.Shared.Magic.Events;
 
 // TODO: Can probably just be an entity or something
-public sealed partial class TeleportSpellEvent : WorldTargetActionEvent, ISpeakSpell
+public sealed partial class TeleportSpellEvent : WorldTargetActionEvent
 {
-    [DataField]
-    public string? Speech { get; private set; }
 
     // TODO: Move to magic component
     // TODO: Maybe not since sound specifier is a thing
index c134790da88d07147877c8044d33c35c96bed6ce..bfab0411af41ed3d86ce60f4aa94e441d93c2500 100644 (file)
@@ -1,15 +1,12 @@
-using Content.Shared.Actions;
+using Content.Shared.Actions;
 using Content.Shared.Chat.Prototypes;
 using Robust.Shared.Prototypes;
 using Robust.Shared.Serialization;
 
 namespace Content.Shared.Magic.Events;
 
-public sealed partial class VoidApplauseSpellEvent : EntityTargetActionEvent, ISpeakSpell
+public sealed partial class VoidApplauseSpellEvent : EntityTargetActionEvent
 {
-    [DataField]
-    public string? Speech { get; private set; }
-
     /// <summary>
     ///     Emote to use.
     /// </summary>
index 2f50c67b3e71038689a2685b754e7e9b872f46bd..90bdcd01aaeae2334d278cec19e06af6d51d37e3 100644 (file)
@@ -1,4 +1,4 @@
-using System.Numerics;
+using System.Numerics;
 using Content.Shared.Actions;
 using Content.Shared.Storage;
 
@@ -6,7 +6,7 @@ namespace Content.Shared.Magic.Events;
 
 // TODO: This class needs combining with InstantSpawnSpellEvent
 
-public sealed partial class WorldSpawnSpellEvent : WorldTargetActionEvent, ISpeakSpell
+public sealed partial class WorldSpawnSpellEvent : WorldTargetActionEvent
 {
     /// <summary>
     /// The list of prototypes this spell will spawn
@@ -28,7 +28,4 @@ public sealed partial class WorldSpawnSpellEvent : WorldTargetActionEvent, ISpea
     /// </summary>
     [DataField]
     public float? Lifetime;
-
-    [DataField]
-    public string? Speech { get; private set; }
 }
diff --git a/Content.Shared/Magic/ISpeakSpell.cs b/Content.Shared/Magic/ISpeakSpell.cs
deleted file mode 100644 (file)
index 954b994..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace Content.Shared.Magic;
-
-public interface ISpeakSpell // The speak n spell interface
-{
-    /// <summary>
-    /// Localized string spoken by the caster when casting this spell.
-    /// </summary>
-    public string? Speech { get; }
-}
index 5bf1fee0906d5c6612ea8e5ad15f60ea17753611..b362b5aa90e45ec23c935832e268cf5b07debade 100644 (file)
@@ -1,5 +1,4 @@
 using System.Numerics;
-using Content.Shared.Actions;
 using Content.Shared.Body.Components;
 using Content.Shared.Body.Systems;
 using Content.Shared.Coordinates.Helpers;
@@ -141,7 +140,6 @@ public abstract class SharedMagicSystem : EntitySystem
             SpawnSpellHelper(args.Prototype, position, args.Performer, preventCollide: args.PreventCollideWithCaster);
         }
 
-        Speak(args);
         args.Handled = true;
     }
 
@@ -235,7 +233,6 @@ public abstract class SharedMagicSystem : EntitySystem
         var targetMapCoords = args.Target;
 
         WorldSpawnSpellHelper(args.Prototypes, targetMapCoords, args.Performer, args.Lifetime, args.Offset);
-        Speak(args);
         args.Handled = true;
     }
 
@@ -271,7 +268,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        Speak(ev);
 
         var xform = Transform(ev.Performer);
         var fromCoords = xform.Coordinates;
@@ -299,8 +295,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        if (ev.DoSpeech)
-            Speak(ev);
 
         RemoveComponents(ev.Target, ev.ToRemove);
         AddComponents(ev.Target, ev.ToAdd);
@@ -324,7 +318,6 @@ public abstract class SharedMagicSystem : EntitySystem
 
         _transform.SetCoordinates(args.Performer, args.Target);
         _transform.AttachToGridOrMap(args.Performer, transform);
-        Speak(args);
         args.Handled = true;
     }
 
@@ -334,7 +327,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        Speak(ev);
 
         _transform.SwapPositions(ev.Performer, ev.Target);
     }
@@ -392,7 +384,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        Speak(ev);
 
         var direction = _transform.GetMapCoordinates(ev.Target, Transform(ev.Target)).Position - _transform.GetMapCoordinates(ev.Performer, Transform(ev.Performer)).Position;
         var impulseVector = direction * 10000;
@@ -418,7 +409,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         args.Handled = true;
-        Speak(args);
 
         var transform = Transform(args.Performer);
 
@@ -457,7 +447,6 @@ public abstract class SharedMagicSystem : EntitySystem
         }
 
         ev.Handled = true;
-        Speak(ev);
 
         if (wand == null || !TryComp<BasicEntityAmmoProviderComponent>(wand, out var basicAmmoComp) || basicAmmoComp.Count == null)
             return;
@@ -475,7 +464,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        Speak(ev);
 
         var allHumans = _mind.GetAliveHumans();
 
@@ -509,7 +497,6 @@ public abstract class SharedMagicSystem : EntitySystem
             return;
 
         ev.Handled = true;
-        Speak(ev);
 
         // Need performer mind, but target mind is unnecessary, such as taking over a NPC
         // Need to get target mind before putting performer mind into their body if they have one
@@ -535,14 +522,4 @@ public abstract class SharedMagicSystem : EntitySystem
     // End Spells
     #endregion
 
-    // When any spell is cast it will raise this as an event, so then it can be played in server or something. At least until chat gets moved to shared
-    // TODO: Temp until chat is in shared
-    private void Speak(BaseActionEvent args)
-    {
-        if (args is not ISpeakSpell speak || string.IsNullOrWhiteSpace(speak.Speech))
-            return;
-
-        var ev = new SpeakSpellEvent(args.Performer, speak.Speech);
-        RaiseLocalEvent(ref ev);
-    }
 }
diff --git a/Content.Shared/Speech/Components/SpeakOnActionComponent.cs b/Content.Shared/Speech/Components/SpeakOnActionComponent.cs
new file mode 100644 (file)
index 0000000..3de0993
--- /dev/null
@@ -0,0 +1,17 @@
+using Content.Shared.Speech.EntitySystems;
+using Robust.Shared.GameStates;
+
+namespace Content.Shared.Speech.Components;
+
+/// <summary>
+/// Action components which should write a message to ICChat on use
+/// </summary>
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState, Access(typeof(SharedSpeakOnActionSystem))]
+public sealed partial class SpeakOnActionComponent : Component
+{
+    /// <summary>
+    /// The ftl id of the sentence that the user will speak.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public LocId? Sentence;
+}
diff --git a/Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs b/Content.Shared/Speech/EntitySystems/SharedSpeakOnActionSystem.cs
new file mode 100644 (file)
index 0000000..075d336
--- /dev/null
@@ -0,0 +1,13 @@
+using Content.Shared.Chasm;
+using Content.Shared.Speech.Components;
+using Content.Shared.Speech.Muting;
+using System;
+
+namespace Content.Shared.Speech.EntitySystems;
+
+/// <summary>
+/// Once the chat refactor has happened, move the code from
+/// <see cref="Content.Server.Speech.EntitySystems.SpeakOnUseSystem"/>
+/// to here and set this class to sealed.
+/// </summary>
+public abstract class SharedSpeakOnActionSystem : EntitySystem;
index 22160180189a9e51403043503573c6971d9d3640..11dceef536f5886950faf78fcace916a7b84dfe9 100644 (file)
@@ -8,3 +8,4 @@ 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!
+action-speech-spell-charge = DI'RI CEL!
\ No newline at end of file
index 6d1319944b4b5bf7392bc3b1f17b48f495217388..38c17e0517d5b09eab766d171df3ff8cba01fe9e 100644 (file)
@@ -74,5 +74,3 @@
       - BlockMovement
       - Item
       - MeleeRequiresWield
-      speech: action-speech-spell-animate
-      doSpeech: false
index 83bd853a217c11257b0f077db67d42f81690d84f..91db28bca2db156365ade75ee3ec6eab1d2e4dc7 100644 (file)
         orGroup: Guns
       - id: RevolverCapGunFake
         orGroup: Guns
-      speech: action-speech-spell-summon-guns
+  - type: SpeakOnAction
+    sentence: action-speech-spell-summon-guns
 
 - type: entity
   id: ActionSummonMagic
         orGroup: Magics
       - id: RGBStaff
         orGroup: Magics
-      speech: action-speech-spell-summon-magic
+  - type: SpeakOnAction
+    sentence: action-speech-spell-summon-magic
index 3001f71421e478bc9a23bac21d7a2e1de2ac40f5..7f501ae59b136efaf67fd2dab8de01452aaa8504 100644 (file)
@@ -14,4 +14,5 @@
     event: !type:InstantSpawnSpellEvent
       prototype: WallForce
       posData: !type:TargetInFront
-      speech: action-speech-spell-forcewall
+  - type: SpeakOnAction
+    sentence: action-speech-spell-forcewall
index 5ba456d3be991b8ca7762bbea49d3a333d44911f..e01c5a57af172fb063759d8a7a477621a005bb11 100644 (file)
@@ -12,4 +12,5 @@
       sprite: Objects/Magic/magicactions.rsi
       state: knock
     event: !type:KnockSpellEvent
-      speech: action-speech-spell-knock
+  - type: SpeakOnAction
+    sentence: action-speech-spell-knock
index bc2a8d11be01814d762bdee5715c3aa4df3d2867..ae0bfa87bccb4ccf0fe6bcc328ad3e06e2281fff 100644 (file)
@@ -18,4 +18,5 @@
       sprite: Mobs/Species/Human/organs.rsi
       state: brain
     event: !type:MindSwapSpellEvent
-      speech: action-speech-spell-mind-swap
+  - type: SpeakOnAction
+    sentence: action-speech-spell-mind-swap
index eee8b1fc8a449099613d12638e5ab06b83ee53af..1568b3ab6595ccc8704024cc79533f2fec40e556 100644 (file)
@@ -17,7 +17,8 @@
       state: fireball
     event: !type:ProjectileSpellEvent
       prototype: ProjectileFireball
-      speech: action-speech-spell-fireball
+  - type: SpeakOnAction
+    sentence: action-speech-spell-fireball
   - type: ActionUpgrade
     effectedLevels:
       2: ActionFireballII
@@ -41,7 +42,8 @@
       state: fireball
     event: !type:ProjectileSpellEvent
       prototype: ProjectileFireball
-      speech: action-speech-spell-fireball
+  - type: SpeakOnAction
+    sentence: action-speech-spell-fireball
 
 - type: entity
   id: ActionFireballIII
@@ -61,4 +63,5 @@
         state: fireball
       event: !type:ProjectileSpellEvent
         prototype: ProjectileFireball
-        speech: action-speech-spell-fireball
+    - type: SpeakOnAction
+      sentence: action-speech-spell-fireball
index 76674d5bfa88aefa4b46bb19c65c533ced246422..fb6755212a975da18986399990cc733792f043b5 100644 (file)
@@ -15,4 +15,5 @@
       - id: MobCarpMagic
         amount: 3
       offset: 0, 1
-      speech: action-speech-spell-summon-magicarp
+  - type: SpeakOnAction
+    sentence: action-speech-spell-summon-magicarp
index 5e20bc2b2babfea38b4337d4534ead6fc3d16065..3eba350dd0f26653828b66f68f73ad717f22cb37 100644 (file)
@@ -17,7 +17,8 @@
       sprite: Objects/Magic/magicactions.rsi
       state: gib
     event: !type:SmiteSpellEvent
-      speech: action-speech-spell-smite
+  - type: SpeakOnAction
+    sentence: action-speech-spell-smite
   - type: Magic
     requiresClothes: true
 
       sprite: Clothing/Mask/cluwne.rsi
       state: icon
     event: !type:ChangeComponentsSpellEvent
-      speech: action-speech-spell-cluwne
       toAdd:
       - type: Cluwne
+  - type: SpeakOnAction
+    sentence: action-speech-spell-cluwne
   - type: Magic
     requiresClothes: true
 
       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: SpeakOnAction
+    sentence: action-speech-spell-slip
   - type: Magic
     requiresClothes: true
index 90bcdc7487bd5ea325f0b778f97a3ed140f93f6e..c0074f496f76d1c36733bb7f60110d6b89f7ef59 100644 (file)
@@ -11,4 +11,5 @@
       state: nothing
     event: !type:ChargeSpellEvent
       charge: 1
-      speech: DI'RI CEL!
+  - type: SpeakOnAction
+    sentence: action-speech-spell-charge