using Content.Shared._CP14.Actions.Components; using Content.Shared._CP14.MagicEnergy.Components; using Content.Shared._CP14.MagicSpell.Components; using Content.Shared._CP14.MagicSpell.Events; using Content.Shared._CP14.Religion.Systems; using Content.Shared._CP14.Skill; using Content.Shared.FixedPoint; using Content.Shared.Hands.EntitySystems; namespace Content.Shared._CP14.MagicSpell; public abstract partial class CP14SharedMagicSystem { [Dependency] private readonly CP14SharedReligionGodSystem _god = default!; [Dependency] private readonly SharedHandsSystem _hand = default!; [Dependency] private readonly CP14SharedSkillSystem _skill = default!; private void InitializeChecks() { //Verbal speaking SubscribeLocalEvent(OnVerbalAspectStartCast); SubscribeLocalEvent(OnVerbalAspectAfterCast); SubscribeLocalEvent(OnEmoteStartCast); SubscribeLocalEvent(OnEmoteEndCast); //Consuming resources SubscribeLocalEvent(OnMaterialAspectEndCast); SubscribeLocalEvent(OnStaminaConsume); SubscribeLocalEvent(OnManaConsume); SubscribeLocalEvent(OnSkillPointConsume); } private void OnVerbalAspectStartCast(Entity ent, ref CP14StartCastMagicEffectEvent args) { var ev = new CP14ActionSpeechEvent { Performer = args.Performer, Speech = Loc.GetString(ent.Comp.StartSpeech), Emote = false, }; RaiseLocalEvent(ent, ref ev); } private void OnVerbalAspectAfterCast(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { var ev = new CP14ActionSpeechEvent { Performer = args.Performer, Speech = Loc.GetString(ent.Comp.EndSpeech), Emote = false }; RaiseLocalEvent(ent, ref ev); } private void OnEmoteStartCast(Entity ent, ref CP14StartCastMagicEffectEvent args) { var ev = new CP14ActionSpeechEvent { Performer = args.Performer, Speech = Loc.GetString(ent.Comp.StartEmote), Emote = true, }; RaiseLocalEvent(ent, ref ev); } private void OnEmoteEndCast(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { var ev = new CP14ActionSpeechEvent { Performer = args.Performer, Speech = Loc.GetString(ent.Comp.EndEmote), Emote = true }; 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); } private void OnStaminaConsume(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { if (args.Performer is null) return; _stamina.TakeStaminaDamage(args.Performer.Value, ent.Comp.Stamina, visual: false); } private void OnManaConsume(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { if (!TryComp(ent, out var magicEffect)) return; var requiredMana = CalculateManacost(ent, args.Performer); //First - used object if (magicEffect.SpellStorage is not null && TryComp(magicEffect.SpellStorage, out var magicStorage)) { var spellEv = new CP14SpellFromSpellStorageUsedEvent(args.Performer, (ent, magicEffect), requiredMana); RaiseLocalEvent(magicEffect.SpellStorage.Value, ref spellEv); _magicEnergy.ChangeEnergy((magicEffect.SpellStorage.Value, magicStorage), -requiredMana, out var changedEnergy, out var overloadedEnergy, safe: false); requiredMana -= FixedPoint2.Abs(changedEnergy + overloadedEnergy); } //Second - action user if (requiredMana > 0 && TryComp(args.Performer, out var playerMana)) _magicEnergy.ChangeEnergy((args.Performer.Value, playerMana), -requiredMana, out _, out _, safe: false); } private void OnSkillPointConsume(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { if (ent.Comp.SkillPoint is null || args.Performer is null) return; _skill.RemoveSkillPoints(args.Performer.Value, ent.Comp.SkillPoint.Value, ent.Comp.Count); } }