using Content.Server._CP14.MagicEnergy; using Content.Server.Chat.Systems; using Content.Shared._CP14.MagicEnergy.Components; using Content.Shared._CP14.MagicSpell; using Content.Shared._CP14.MagicSpell.Components; using Content.Shared._CP14.MagicSpell.Events; using Content.Shared._CP14.MagicSpell.Spells; using Content.Shared.Whitelist; using Robust.Server.GameObjects; namespace Content.Server._CP14.MagicSpell; public sealed partial class CP14MagicSystem : CP14SharedMagicSystem { [Dependency] private readonly ChatSystem _chat = default!; [Dependency] private readonly TransformSystem _transform = default!; [Dependency] private readonly CP14MagicEnergySystem _magicEnergy = default!; [Dependency] private readonly EntityLookupSystem _lookup = default!; [Dependency] private readonly EntityWhitelistSystem _whitelist = default!; public override void Initialize() { base.Initialize(); SubscribeLocalEvent(OnAoEMapInit); SubscribeLocalEvent(OnSpellSpoken); SubscribeLocalEvent(OnSpawnMagicVisualEffect); SubscribeLocalEvent(OnDespawnMagicVisualEffect); SubscribeLocalEvent(OnManaConsume); } private void OnAoEMapInit(Entity ent, ref MapInitEvent args) { var entitiesAround = _lookup.GetEntitiesInRange(ent, ent.Comp.Range, LookupFlags.Uncontained); var count = 0; foreach (var entity in entitiesAround) { if (ent.Comp.Whitelist is not null && !_whitelist.IsValid(ent.Comp.Whitelist, entity)) continue; foreach (var effect in ent.Comp.Effects) { effect.Effect(EntityManager, new CP14SpellEffectBaseArgs(ent, null, entity, Transform(entity).Coordinates)); } count++; if (ent.Comp.MaxTargets > 0 && count >= ent.Comp.MaxTargets) break; } } private void OnSpellSpoken(Entity ent, ref CP14VerbalAspectSpeechEvent args) { if (args.Performer is not null && args.Speech is not null) _chat.TrySendInGameICMessage(args.Performer.Value, args.Speech, args.Emote ? InGameICChatType.Emote : InGameICChatType.Speak, true); } private void OnSpawnMagicVisualEffect(Entity ent, ref CP14StartCastMagicEffectEvent args) { var vfx = SpawnAttachedTo(ent.Comp.Proto, Transform(args.Performer).Coordinates); _transform.SetParent(vfx, args.Performer); ent.Comp.SpawnedEntity = vfx; } private void OnDespawnMagicVisualEffect(Entity ent, ref CP14EndCastMagicEffectEvent args) { QueueDel(ent.Comp.SpawnedEntity); ent.Comp.SpawnedEntity = null; } private void OnManaConsume(Entity ent, ref CP14MagicEffectConsumeResourceEvent args) { if (!TryComp(ent, out var magicEffect)) return; var requiredMana = CalculateManacost(ent, args.Performer); 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); if (magicStorage.Energy > 0) { var cashedEnergy = magicStorage.Energy; if (_magicEnergy.TryConsumeEnergy(magicEffect.SpellStorage.Value, requiredMana, magicStorage, false)) requiredMana = MathF.Max(0, (float)(requiredMana - cashedEnergy)); } } if (requiredMana > 0 && TryComp(args.Performer, out var playerMana)) { _magicEnergy.TryConsumeEnergy(args.Performer.Value, requiredMana, safe: false); } } }