From 02286f492a44c3747d0d52bc462865b6da316ca5 Mon Sep 17 00:00:00 2001 From: Red <96445749+TheShuEd@users.noreply.github.com> Date: Sat, 9 Aug 2025 00:27:23 +0300 Subject: [PATCH] material aspect support (#1643) --- .../CP14SharedMagicSystem.Checks.cs | 41 ++++++++++++++++++- .../_CP14/MagicSpell/CP14SharedMagicSystem.cs | 5 +++ .../CP14MagicEffectMaterialAspectComponent.cs | 13 ++++++ .../en-US/_CP14/magicEnergy/magic-spells.ftl | 2 + .../ru-RU/_CP14/magicEnergy/magic-spells.ftl | 2 + .../Actions/Spells/Earth/T1_earth_wall.yml | 4 ++ 6 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 Content.Shared/_CP14/MagicSpell/Components/CP14MagicEffectMaterialAspectComponent.cs diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs index 1dc30fa411..0c72174212 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.Checks.cs @@ -25,6 +25,7 @@ public abstract partial class CP14SharedMagicSystem { SubscribeLocalEvent(OnSomaticCheck); SubscribeLocalEvent(OnVerbalCheck); + SubscribeLocalEvent(OnMaterialCheck); SubscribeLocalEvent(OnManaCheck); SubscribeLocalEvent(OnStaminaCheck); SubscribeLocalEvent(OnPacifiedCheck); @@ -36,7 +37,7 @@ public abstract partial class CP14SharedMagicSystem SubscribeLocalEvent(OnVerbalAspectAfterCast); SubscribeLocalEvent(OnEmoteStartCast); SubscribeLocalEvent(OnEmoteEndCast); - + SubscribeLocalEvent(OnMaterialAspectEndCast); } /// @@ -109,6 +110,27 @@ public abstract partial class CP14SharedMagicSystem args.Cancel(); } + private void OnMaterialCheck(Entity ent, ref CP14CastMagicEffectAttemptEvent args) + { + if (ent.Comp.Requirement is null) + return; + + HashSet heldedItems = new(); + + foreach (var hand in _hand.EnumerateHands(args.Performer)) + { + var helded = _hand.GetHeldItem(args.Performer, hand); + if (helded is not null) + heldedItems.Add(helded.Value); + } + + if (!ent.Comp.Requirement.CheckRequirement(EntityManager, _proto, heldedItems)) + { + args.PushReason(Loc.GetString("cp14-magic-spell-need-material-component")); + args.Cancel(); + } + } + private void OnPacifiedCheck(Entity ent, ref CP14CastMagicEffectAttemptEvent args) { @@ -214,4 +236,21 @@ public abstract partial class CP14SharedMagicSystem }; RaiseLocalEvent(ent, ref ev); } + + private void OnMaterialAspectEndCast(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) + { + if (ent.Comp.Requirement is null || args.Performer is null) + return; + + HashSet heldedItems = new(); + + foreach (var hand in _hand.EnumerateHands(args.Performer.Value)) + { + var helded = _hand.GetHeldItem(args.Performer.Value, hand); + if (helded is not null) + heldedItems.Add(helded.Value); + } + + ent.Comp.Requirement.PostCraft(EntityManager, _proto, heldedItems); + } } diff --git a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs index 444c587e3e..120254eb39 100644 --- a/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs +++ b/Content.Shared/_CP14/MagicSpell/CP14SharedMagicSystem.cs @@ -137,6 +137,11 @@ public abstract partial class CP14SharedMagicSystem : EntitySystem sb.Append("\n" + Loc.GetString("cp14-magic-somatic-aspect") + " " + somatic.FreeHandRequired); } + if (TryComp(ent, out var material) && material.Requirement is not null) + { + sb.Append("\n" + Loc.GetString("cp14-magic-material-aspect") + " " + material.Requirement.GetRequirementTitle(_proto)); + } + if (TryComp(ent, out var music)) { sb.Append("\n" + Loc.GetString("cp14-magic-music-aspect")); diff --git a/Content.Shared/_CP14/MagicSpell/Components/CP14MagicEffectMaterialAspectComponent.cs b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicEffectMaterialAspectComponent.cs new file mode 100644 index 0000000000..434a5a4e72 --- /dev/null +++ b/Content.Shared/_CP14/MagicSpell/Components/CP14MagicEffectMaterialAspectComponent.cs @@ -0,0 +1,13 @@ +using Content.Shared._CP14.Workbench; + +namespace Content.Shared._CP14.MagicSpell.Components; + +/// +/// Requires the caster to hold a specific resource in their hand, which will be spent to use the spell. +/// +[RegisterComponent, Access(typeof(CP14SharedMagicSystem))] +public sealed partial class CP14MagicEffectMaterialAspectComponent : Component +{ + [DataField(required: true)] + public CP14WorkbenchCraftRequirement? Requirement; +} diff --git a/Resources/Locale/en-US/_CP14/magicEnergy/magic-spells.ftl b/Resources/Locale/en-US/_CP14/magicEnergy/magic-spells.ftl index 2923b1e1f2..493e8eff51 100644 --- a/Resources/Locale/en-US/_CP14/magicEnergy/magic-spells.ftl +++ b/Resources/Locale/en-US/_CP14/magicEnergy/magic-spells.ftl @@ -11,10 +11,12 @@ cp14-magic-spell-not-enough-mana-cast-warning-4 = Your head becomes heavy... cp14-magic-type = Type cp14-magic-verbal-aspect = Requires the ability to speak cp14-magic-somatic-aspect = Requires a free hand: +cp14-magic-material-aspect = The following material components are required: cp14-magic-music-aspect = You must play a musical instrument cp14-magic-spell-need-verbal-component = You can't cast the spell out loud. cp14-magic-spell-need-somatic-component = You don't have your hands free. +cp14-magic-spell-need-material-component = You need to hold the material component of the spell in your hands. cp14-magic-spell-stamina-not-enough = You don't have the energy to do it. cp14-magic-staminacost = Stamina cost diff --git a/Resources/Locale/ru-RU/_CP14/magicEnergy/magic-spells.ftl b/Resources/Locale/ru-RU/_CP14/magicEnergy/magic-spells.ftl index c554421f7f..c55d1a8d18 100644 --- a/Resources/Locale/ru-RU/_CP14/magicEnergy/magic-spells.ftl +++ b/Resources/Locale/ru-RU/_CP14/magicEnergy/magic-spells.ftl @@ -11,10 +11,12 @@ cp14-magic-spell-not-enough-mana-cast-warning-4 = Голова наливает cp14-magic-type = Тип cp14-magic-verbal-aspect = Требуется возможность говорить cp14-magic-somatic-aspect = Требуются свободные руки: +cp14-magic-material-aspect = Требуются материальный компонент: cp14-magic-music-aspect = Вы должны играть на музыкальном инструменте cp14-magic-spell-need-verbal-component = Вы не можете произнести заклинание вслух. cp14-magic-spell-need-somatic-component = Вам не хватает свободных рук. +cp14-magic-spell-need-material-component = Нужно держать материальный компонент заклинания в руках. cp14-magic-spell-stamina-not-enough = Вам не хватает сил, чтобы сделать это. cp14-magic-staminacost = Затраты энергии diff --git a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml index 487dad75a7..710be3439c 100644 --- a/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml +++ b/Resources/Prototypes/_CP14/Entities/Actions/Spells/Earth/T1_earth_wall.yml @@ -20,6 +20,10 @@ - !type:CP14SpellSpawnEntityOnTarget spawns: - CP14WallSpawnEarthWall + - type: CP14MagicEffectMaterialAspect + requirement: !type:StackResource + stack: CP14Dirt + count: 2 - type: CP14MagicEffectVerbalAspect startSpeech: "Surgite terram..." endSpeech: "de profundis terrae"