using System; using System.Threading; using System.Threading.Tasks; using PhoenixLib.Events; using WingsEmu.Core.Extensions; using WingsEmu.DTOs.Maps; using WingsEmu.Game; using WingsEmu.Game._enum; using WingsEmu.Game.Battle.Managers; using WingsEmu.Game.Entities; using WingsEmu.Game.Entities.Event; using WingsEmu.Game.Helpers.Damages; using WingsEmu.Game.Managers.StaticData; using WingsEmu.Game.Monster.Event; using WingsEmu.Game.Npcs; using WingsEmu.Game.Npcs.Event; using WingsEmu.Game.Triggers; using WingsEmu.Packets.Enums; namespace WingsEmu.Plugins.BasicImplementations.Event.Npcs; public class NpcSummonEventHandler : IAsyncEventProcessor { private readonly INpcEntityFactory _npcEntityFactory; private readonly INpcMonsterManager _npcMonsterManager; private readonly IPhantomPositionManager _phantomPositionManager; public NpcSummonEventHandler(INpcEntityFactory npcEntityFactory, INpcMonsterManager npcMonsterManager, IPhantomPositionManager phantomPositionManager) { _npcEntityFactory = npcEntityFactory; _npcMonsterManager = npcMonsterManager; _phantomPositionManager = phantomPositionManager; } public async Task HandleAsync(NpcSummonEvent e, CancellationToken cancellation) { foreach (ToSummon summon in e.Npcs) { var npcMonster = new MonsterData(_npcMonsterManager.GetNpc(summon.VNum)); INpcEntity mapNpc = _npcEntityFactory.CreateNpc(npcMonster, e.Map, npcAdditionalData: new NpcAdditionalData { CanMove = summon.IsMoving, CanAttack = summon.IsHostile, IsHostile = summon.IsHostile, NpcDirection = summon.Direction, NpcShouldRespawn = false, FactionType = e.Map.HasMapFlag(MapFlags.ACT_4) ? FactionType.Angel : FactionType.Neutral // Just random Faction }); mapNpc.Target = summon.Target; if (summon.TriggerEvents != null) { foreach ((string key, IAsyncEvent asyncEvent, bool removeOnUse) in summon.TriggerEvents) { mapNpc.AddEvent(key, asyncEvent, removeOnUse); } } Position? phantomPosition = e.MonsterId.HasValue ? _phantomPositionManager.GetPosition(e.MonsterId.Value) : null; Position spawnCell = phantomPosition ?? summon.SpawnCell ?? e.Map.GetRandomPosition(); await mapNpc.EmitEventAsync(new MapJoinNpcEntityEvent(mapNpc, spawnCell.X, spawnCell.Y)); CheckBeriosPhantom(mapNpc); if (!summon.RemoveTick) { continue; } mapNpc.NextTick = DateTime.UtcNow.AddSeconds(-1000); mapNpc.NextAttackReady = DateTime.UtcNow.AddSeconds(-1000); } } private void CheckBeriosPhantom(INpcEntity mapNpc) { switch ((MonsterVnum)mapNpc.MonsterVNum) { case MonsterVnum.EMERALD_SHADOW_PHANTOM: mapNpc.AddEvent(BattleTriggers.OnDeath, new MonsterSummonEvent(mapNpc.MapInstance, Lists.Create(new ToSummon { VNum = (short)MonsterVnum.EMERALD_PHANTOM, SpawnCell = mapNpc.Position, IsMoving = true, IsHostile = true })) { NpcId = mapNpc.UniqueId }, true); break; case MonsterVnum.SAPPHIRE_SHADOW_PHANTOM: mapNpc.AddEvent(BattleTriggers.OnDeath, new MonsterSummonEvent(mapNpc.MapInstance, Lists.Create(new ToSummon { VNum = (short)MonsterVnum.SAPPHIRE_PHANTOM, SpawnCell = mapNpc.Position, IsMoving = true, IsHostile = true })) { NpcId = mapNpc.UniqueId }, true); break; case MonsterVnum.RUBY_SHADOW_PHANTOM: mapNpc.AddEvent(BattleTriggers.OnDeath, new MonsterSummonEvent(mapNpc.MapInstance, Lists.Create(new ToSummon { VNum = (short)MonsterVnum.RUBY_PHANTOM, SpawnCell = mapNpc.Position, IsMoving = true, IsHostile = true })) { NpcId = mapNpc.UniqueId }, true); break; } } }