#include "stdafx.h" #include "VirtualMonsterMgr.h" #include #include #include #include CVirtualMonsterMgr::CVirtualMonsterMgr() : m_usSummonCount(0) { } CVirtualMonsterMgr::~CVirtualMonsterMgr() { DestroyMonsterList(); } struct FnDeleteSecond { template bool operator() (PairType& pair) { if(NULL != pair.second) { delete pair.second; } return true; } }; struct FnLeaveParty { template bool operator() (PairType& pair) { if(NULL != pair.second) { CParty* lpParty = (pair.second)->GetParty(); if (lpParty) { lpParty->Leave((pair.second)->GetCID(), 0, (pair.second)->GetMapIndex()); } } return true; } }; void CVirtualMonsterMgr::DestroyMonsterList() { std::for_each(m_MonsterMap.begin(), m_MonsterMap.end(), FnLeaveParty()); std::for_each(m_MonsterMap.begin(), m_MonsterMap.end(), FnDeleteSecond()); m_MonsterMap.clear(); m_AdminMonsterUIDMap.clear(); } bool CVirtualMonsterMgr::AddMonster(CMonster* lpMonster) { if (NULL == lpMonster) return false; unsigned long dwCID = lpMonster->GetCID(); bool bResult = false; Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { bResult = m_MonsterMap.insert(std::make_pair(dwCID, reinterpret_cast(lpMonster))).second; unsigned short wKindID = static_cast( (dwCID & Creature::MONSTER_KIND_BIT) ); if ( bResult && m_AdminMonsterUIDMap.end() == m_AdminMonsterUIDMap.find(wKindID) ) { m_AdminMonsterUIDMap.insert(std::make_pair(wKindID, INIT_UID)).second; } } return bResult; } CCreature* CVirtualMonsterMgr::GetCreature(unsigned long dwCID) { Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) return (CCreature *)GetMonster(dwCID); return (CCreature *)NULL; } CAggresiveCreature* CVirtualMonsterMgr::GetAggresiveCreature(unsigned long dwCID) { Creature::CreatureType eCreatureType = Creature::GetCreatureType(dwCID); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) return (CAggresiveCreature *)GetMonster(dwCID); return (CAggresiveCreature *)NULL; } CMonster* CVirtualMonsterMgr::GetMonster(unsigned long dwCID) { MonsterMap::iterator pos = m_MonsterMap.find(dwCID); return (pos != m_MonsterMap.end()) ? pos->second : NULL; } void CVirtualMonsterMgr::ProcessAllMonster() { MonsterMap::iterator pos = m_MonsterMap.begin(); MonsterMap::iterator end = m_MonsterMap.end(); for (; pos != end; ) { CMonster* lpMonster = pos->second; if (lpMonster) { lpMonster->Process(); } ++pos; } } void CVirtualMonsterMgr::ProcessMonsterRegenHPAndMP() { MonsterMap::iterator pos = m_MonsterMap.begin(); MonsterMap::iterator end = m_MonsterMap.end(); for (; pos != end; ) { CMonster* lpMonster = pos->second; if (lpMonster) { lpMonster->RegenHPAndMP(0, 0, true); } ++pos; } } void CVirtualMonsterMgr::ProcessSummonMonsterDead(void) { MonsterMap::iterator pos = m_MonsterMap.begin(); MonsterMap::iterator end = m_MonsterMap.end(); for (; pos != end; ) { CMonster* lpMonster = pos->second; if (lpMonster && true == lpMonster->IsDeadSummonMonster()) { pos = m_MonsterMap.erase(pos); delete lpMonster; } ++pos; } } bool CVirtualMonsterMgr::IsSummonee(unsigned long dwCID) { return Creature::IsSummonMonster(dwCID); } bool CVirtualMonsterMgr::SummonMonster(int nKID, Position Pos, CCharacter* lpMaster) { CMonster::MonsterCreateInfo tempInfo; tempInfo.m_dwCID = Creature::SUMMON_MONSTER_BIT + (m_usSummonCount << 16) + nKID; if (0 != GetMonster(tempInfo.m_dwCID)) { ERRLOG0(g_Log, "¸ó½ºÅÍ ¼Òȯ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } tempInfo.m_nKID = nKID; tempInfo.m_Pos = Pos; CMonster* lpSummonMonster = 0; if (0 != lpMaster) { CAggresiveCreature* lpSummonee = lpMaster->GetSummonee(); if (0 != lpSummonee) { lpSummonee->Dead(0); } } lpSummonMonster = new CSummonMonster(tempInfo, lpMaster); if (0 == lpSummonMonster) { ERRLOG0(g_Log, "¸ó½ºÅÍ ¼Òȯ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } lpSummonMonster->SetMapIndex(lpMaster->GetMapIndex()); if (false == lpSummonMonster->InitMonster(tempInfo.m_Pos)) { ERRLOG0(g_Log, "¼Òȯ ¸ó½ºÅÍ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } AddMonster(lpSummonMonster); m_usSummonCount++; if (CMonster::MAX_MONSTER_UID == m_usSummonCount) { m_usSummonCount = 0; } if (0 != lpMaster) { lpMaster->SetSummonee(lpSummonMonster); GameClientSendPacket::SendCharSummon(lpMaster->GetCID(), lpSummonMonster); } else { lpSummonMonster->SendMove(CMonster::RUN_ANI_LIMIT_MIN); } return true; } bool CVirtualMonsterMgr::AdminSummonMonster(int nKID, Position Pos, unsigned short wMapIndex) { CMonster::MonsterCreateInfo tempInfo; CMonster* lpNewMonster = 0; // nKID °¡ Á¤»óÀÎÁö üũ const CMonsterMgr::MonsterProtoType* lpProtoType = CMonsterMgr::GetInstance().GetMonsterProtoType(nKID); if (0 == lpProtoType) { ERRLOG1(g_Log, "KID : %d ¸ó½ºÅ͸¦ ¼ÒȯÇϴµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", nKID); return false; } // Á¸´ç ÃÖ´ë ¸ó½ºÅÍ ¼ö¸¦ ÃʰúÇÏ´ÂÁö üũ if (GetMonsterNum() >= CMonster::MAX_MONSTER_UID) { ERRLOG0(g_Log, "ÇöÀç Á¸¿¡ ¸ó½ºÅÍ ¼ö°¡ ÃÖ´ëÀÔ´Ï´Ù. ´õÀÌ»ó ¸ó½ºÅ͸¦ »ý¼ºÇÒ ¼ö ¾ø½À´Ï´Ù."); return false; } // ¸ó½ºÅÍ ¸Ê¿¡¼­ Àû´çÇÑ ¼ýÀÚ¸¦ ³Ñ°ÜÁØ´Ù. (CID ¸¦ À¯´ÏÅ©ÇÏ°Ô Çϱâ À§Çؼ­) unsigned long dwUID = GetAvailableMonsterUID(static_cast(nKID)); if (dwUID == NO_BLANK_UID) { ERRLOG1(g_Log, "KindID:%d ÇØ´ç Á¾·ùÀÇ ¸ó½ºÅÍ ¼ö°¡ ÃÖ´ëÀÔ´Ï´Ù. ´õÀÌ»ó ¸ó½ºÅ͸¦ »ý¼ºÇÒ ¼ö ¾ø½À´Ï´Ù.", nKID); return false; } tempInfo.m_dwCID = (dwUID << 16) + nKID; tempInfo.m_nKID = nKID; tempInfo.m_dwPID = 0; tempInfo.m_Pos = Pos; tempInfo.m_bScout = false; tempInfo.m_nMovingPattern = 0; tempInfo.m_wRespawnArea = CCell::CELL_DISTANCE; // MON_TODO : ¸ó½ºÅÍ Å¸ÀÔ¿¡ ¸Â°Ô »ý¼º switch (lpProtoType->m_MonsterInfo.m_cSkillPattern) { case MonsterInfo::PATTERN_DEFENDER: lpNewMonster = new CDefenderMonster(tempInfo, true); break; case MonsterInfo::PATTERN_WARRIOR: lpNewMonster = new CWarriorMonster(tempInfo, true); break; case MonsterInfo::PATTERN_ACOLYTE: lpNewMonster = new CAcolyteMonster(tempInfo, true); break; case MonsterInfo::PATTERN_MAGE: lpNewMonster = new CMageMonster(tempInfo, true); break; case MonsterInfo::PATTERN_BOSS: lpNewMonster = new CBossMonster(tempInfo, true); break; case MonsterInfo::PATTERN_NAMED: lpNewMonster = new CNamedMonster(tempInfo, true); break; case MonsterInfo::PATTERN_CHIEF: lpNewMonster = new CChiefMonster(tempInfo, true); break; case MonsterInfo::PATTERN_OBJECT: lpNewMonster = new CObjectMonster(tempInfo, true); break; case MonsterInfo::PATTERN_GUARD: lpNewMonster = new CGuardMonster(tempInfo, true); break; case MonsterInfo::PATTERN_GATHER: lpNewMonster = new CGatherMonster(tempInfo, true); break; default: lpNewMonster = new CMonster(tempInfo, true); break; }; if (0 == lpNewMonster) { ERRLOG0(g_Log, "¸ó½ºÅÍ »ý¼º¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } lpNewMonster->SetMapIndex(wMapIndex); if (false == lpNewMonster->InitMonster(tempInfo.m_Pos)) { ERRLOG0(g_Log, "¸ó½ºÅÍ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } return AddMonster(lpNewMonster); } unsigned short CVirtualMonsterMgr::GetAvailableMonsterUID(unsigned short wKindID) { if (m_AdminMonsterUIDMap.end() == m_AdminMonsterUIDMap.find(wKindID)) { m_AdminMonsterUIDMap.insert(std::make_pair(wKindID, INIT_UID)).second; } unsigned long nUID = ((m_AdminMonsterUIDMap[wKindID] << 16) | wKindID); if (NULL != GetMonster(nUID)) { if (m_AdminMonsterUIDMap[wKindID] == INIT_UID) { // ¿©À¯ °ø°£ÀÌ ¾ø´Ù¸é... return NO_BLANK_UID; } m_AdminMonsterUIDMap[wKindID] = INIT_UID - 1; return INIT_UID; } return m_AdminMonsterUIDMap[wKindID]--; }