using BrewMonster; using CSNetwork.GPDataType; using System; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using static CECAttacksMan; public class CECAttacksMan : MonoSingleton { private readonly LinkedList m_AttackLinkedList = new LinkedList(); private void Update() { var node = m_AttackLinkedList.First; while (node != null) { var next = node.Next; if (node.Value.m_bFinished) m_AttackLinkedList.Remove(node); else node.Value.Tick((uint)(Time.deltaTime * 1000)); node = next; } } public CECAttackerEvents FindAttackByAttacker(int idHost) { CECAttackerEvents result = new CECAttackerEvents(); foreach (var attack in m_AttackLinkedList) { if (attack.m_idHost == idHost) { result.Add(attack); } } return result; } public CECAttackEvent AddMeleeAttack(int idHost, int idTarget, int idWeapon, uint dwModifier, int nDamage, int nTimeFly = 10) { var newEvent = new CECAttackEvent( this, idHost, 0, // idCastTarget idTarget, idWeapon, 0, // idSkill 0, // nSkillLevel dwModifier, nDamage, 200, // timeToBeFired nTimeFly // timeToDoDamage ); m_AttackLinkedList.AddLast(newEvent); newEvent.UpdateTargetFlag(); return m_AttackLinkedList.Last.Value; } public CECAttackEvent AddSkillAttack(int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, int nDamage) { var newEvent = new CECAttackEvent( this, idHost, idCastTarget, idTarget, idWeapon, idSkill, nSkillLevel, dwModifier, nDamage, 200, // timeToBeFired 1000 // timeToDoDamage ); m_AttackLinkedList.AddLast(newEvent); newEvent.UpdateTargetFlag(); return m_AttackLinkedList.Last.Value; } // === thêm tạm để code có thể compile === public void AddAttack(CECAttackEvent evt) { m_AttackLinkedList.AddLast(evt); } public class TARGET_DATA { public int idTarget; public uint dwModifier; public int nDamage; } } public class CECAttackEvent { public CECAttacksMan? m_pManager; public bool m_bSignaled; public bool m_bDoFired; public bool m_bDoDamaged; public bool m_bFinished; public uint m_timeLived; public uint m_timeToBeFired; public uint m_timeToDoDamage; public int m_idHost; public int m_idCastTarget; public List m_targets = new List(); public int m_idWeapon; public int m_idSkill; public int m_nSkillLevel; public int m_nSkillSection; public CECAttackEvent() { } public CECAttackEvent(CECAttacksMan? pManager, int idHost, int idCastTarget, int idTarget, int idWeapon, int idSkill, int nSkillLevel, uint dwModifier, int nDamage, int nTimeToBeFired, int nTimeToDoDamage) { m_pManager = pManager; m_idHost = idHost; m_idCastTarget = idCastTarget; m_idWeapon = idWeapon; m_idSkill = idSkill; m_nSkillLevel = nSkillLevel; m_timeToBeFired = (uint)nTimeToBeFired; m_timeToDoDamage = (uint)nTimeToDoDamage; AddTarget(idTarget, dwModifier, nDamage); } public bool Tick(uint dwDeltaTime) { m_timeLived += dwDeltaTime; if (!m_bSignaled) { if (m_timeLived > 3500) { // too long time, this event will be deleted now m_bFinished = true; //DoFire(); DoDamage(); } return true; } else { if (m_timeToBeFired != 0) { if (m_timeToBeFired <= dwDeltaTime) { m_timeToBeFired = 0; // Fire here //DoFire(); } else m_timeToBeFired -= dwDeltaTime; } else if (m_timeToDoDamage != 0) { if (m_timeToDoDamage <= dwDeltaTime) { m_timeToDoDamage = 0; // Do damage here DoDamage(); } else m_timeToDoDamage -= dwDeltaTime; } } return true; } private bool DoDamage() { m_bDoDamaged = true; m_bFinished = true; /* CECGameRun pGameRun = g_pGame-GetGameRun(); int idHostPlayer = pGameRun->GetHostPlayer()->GetCharacterID();*/ // Get host name /* ACString strHostName; CECObject* pHostObject = pGameRun->GetWorld()->GetObject(m_idHost, 0); if (pHostObject) { if (ISNPCID(m_idHost)) strHostName = ((CECNPC*)pHostObject)->GetName(); else if (ISPLAYERID(m_idHost)) strHostName = GetPlayerName((CECPlayer*)pHostObject); }*/ int nNumTargets = m_targets.Count; for (int i = 0; i < nNumTargets; i++) { TARGET_DATA data = m_targets[i]; int idTarget = data.idTarget; string strName; if (GPDataTypeHelper.ISNPCID(idTarget)) { CECNPC pNPC = null; if ((data.dwModifier & (uint)MOD.MOD_SUCCESS) != 0) pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget); else { pNPC = EC_ManMessageMono.Instance._CECNPCMan.GetNPCFromAll(idTarget); if (!pNPC) return true; //strName = pNPC->GetNameToShow(); } if (!pNPC) return true; pNPC.Damaged(data.nDamage, data.dwModifier); } else if (GPDataTypeHelper.ISPLAYERID(idTarget)) { /* CECPlayer* pPlayer = pGameRun->GetWorld()->GetPlayerMan()->GetPlayer(idTarget); if (!pPlayer) return true; strName = GetPlayerName(pPlayer); pPlayer->Damaged(data.nDamage, data.dwModifier, m_idSkill);*/ } /* if (data.nDamage > 0) { if (m_idHost == idHostPlayer) { if (!strName.IsEmpty()) pGameRun->AddFixedChannelMsg(FIXMSG_DODAMAGE, GP_CHAT_DAMAGE, strName, data.nDamage); } else if (data.idTarget == idHostPlayer) { if (!strHostName.IsEmpty()) pGameRun->AddFixedChannelMsg(FIXMSG_BEDAMAGED, GP_CHAT_DAMAGE, strHostName, data.nDamage); } }*/ } return true; } public bool AddTarget(int idTarget, uint dwModifier, int nDamage) { m_targets.Add(new TARGET_DATA { idTarget = idTarget, dwModifier = dwModifier, nDamage = nDamage }); return true; } public bool UpdateTargetFlag() { // update all targets' bAboutToDie flag int nNumTargets = m_targets.Count; for (int i = 0; i < nNumTargets; i++) { TARGET_DATA data = m_targets[i]; /* if( data.dwModifier & MOD_DEADLYSTRIKE ) { int idTarget = data.idTarget; if (ISNPCID(idTarget)) { CECNPC* pNPC = g_pGame->GetGameRun()->GetWorld()->GetNPCMan()->GetNPC(idTarget); if (!pNPC) return true; pNPC->SetAboutToDie(true); } else if (ISPLAYERID(idTarget)) { CECPlayer* pPlayer = g_pGame->GetGameRun()->GetWorld()->GetPlayerMan()->GetPlayer(idTarget); if (!pPlayer) return true; pPlayer->SetAboutToDie(true); } }*/ } return true; } } public class CECAttackerEvents { private readonly List m_list = new List(); public void Add(CECAttackEvent? evt) { if (evt != null) m_list.Add(evt); } public bool IsEmpty() => m_list.Count == 0; public int Count() => m_list.Count; public CECAttackEvent? Find(int idSkill = 0, int nSkillSection = 0) { foreach (var evt in m_list) { if (evt.m_idSkill == idSkill && evt.m_nSkillSection == nSkillSection) return evt; } return null; } public void Signal() { foreach (var evt in m_list) evt.m_bSignaled = true; m_list.Clear(); } public static implicit operator bool(CECAttackerEvents events) { return !events.IsEmpty(); } } enum MOD { MOD_PHYSIC_ATTACK_RUNE = 0x0001, // ÎïÀí¹¥»÷ÓÅ»¯·ûÉúЧ MOD_MAGIC_ATTACK_RUNE = 0x0002, // ·¨Êõ¹¥»÷ÓÅ»¯·ûÉúЧ MOD_PHYSIC_DEFENCE_RUNE = 0x0004, // ÎïÀí·ÀÓùÓÅ»¯·ûÉúЧ MOD_MAGIC_DEFENCE_RUNE = 0x0008, // ·¨Êõ·ÀÓùÓÅ»¯·ûÉúЧ MOD_CRITICAL_STRIKE = 0x0010, // ±¬»÷ MOD_RETORT = 0x0020, // ·´Õð MOD_NULLITY = 0x0040, // ÎÞЧ¹¥»÷ MOD_IMMUNE = 0x0080, // ÃâÒßÁ˴˴ι¥»÷£¬ÓÅÏȼ¶¸ßÓÚÎÞЧ MOD_ENCHANT_FAILED = 0x0100, // enchant ʧ°Ü MOD_SUCCESS = 0x0200, // ³É¹¦ MOD_DODGE_DAMAGE = 0x0400, // É˺¦¶ãÉÁ MOD_DODGE_DEBUFF = 0x0800, // ״̬¶ãÉÁ MOD_ATTACK_AURA = 0x1000, // ¹â»·¹¥»÷ MOD_REBOUND = 0x2000, // ·´µ¯ MOD_BEAT_BACK = 0x4000, // ·´»÷ };