#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "CellManager.h" CCellManager::CCellManager(void) : m_CellData(0), m_wNumMoving(0), m_usSummonCount(0), m_bMoving(false), m_bAvoid(false), m_bLoadComplete(false) { } CCellManager::~CCellManager(void) { Destroy(); } void CCellManager::Destroy() { for (vector::iterator infoItr = m_vecSafetyZone.begin(); infoItr != m_vecSafetyZone.end(); ++infoItr) { SafetyZoneInfo* lpInfo = *infoItr; delete lpInfo; lpInfo = NULL; } m_vecSafetyZone.clear(); if (NULL != m_WeatherRate) { delete [] m_WeatherRate; m_WeatherRate = NULL; } if (NULL != m_CellData) { delete [] m_CellData; m_CellData = NULL; } } CCellManager& CCellManager::GetInstance() { static CCellManager cellManager; return cellManager; } bool CCellManager::CheckPositionInZone(Position Pos) { const Position ZoneMinPos[SERVER_ID::MAX_ZONE_NUM] = { Position(0, 0, 0), // NONE Position(473, 0, 184), // ZONE1 (±×·£µå ÄÚ½ºÆ®) Position(315, 0, 315), // ZONE2 (·¹ÇÑ ½ºÆý) Position(591, 0, 575), // ZONE3 Position(484, 0, 452), // ZONE4 (»çÀÌ³Ê ¾ÆÀÏ·£µå) Position(450, 0, 450), // ZONE5 (¾ÆÀÏ·£µå ¿Àºê ÆäÀÎ) Position(591, 0, 575), // BATTLE_ZONE (»ç¿ë ¾ÈÇÔ) Position(0, 0, 0), // ADMIN_TOOL_ZONE Position(630, 0, 630), // CAPITAL Position(630, 0, 630), // ZONE9 Position(945, 0, 945), // BATTLE_SERVER::FRAG_ZONE Position(1574, 0, 954), // BATTLE_SERVER Position(325, 0, 325), // ZONE12 (½ÅÀÇ ´ë·ú) Position(645, 0, 641), // BATTLE_SERVER::STATUE_ZONE Position(3090, 0, 3170), // °¨¿Á (°¨±Ý ½Ã½ºÅÛ) Position(0, 0, 0), // CHAR_SELECT (ij¸¯ÅÍ ¼±Åà ȭ¸é) Position(880, 0, 890), // STONE_WAR1 Position(880, 0, 890), // STONE_WAR2 Position(880, 0, 890) // STONE_WAR3 }; const Position ZoneMaxPos[SERVER_ID::MAX_ZONE_NUM] = { Position(0, 0, 0), // NONE Position(3387, 0, 3064), // ZONE1 (±×·£µå ÄÚ½ºÆ®) Position(3781, 0, 3781), // ZONE2 (·¹ÇÑ ½ºÆý) Position(2227, 0, 2250), // ZONE3 Position(2705, 0, 2706), // ZONE4 (»çÀÌ³Ê ¾ÆÀÏ·£µå) Position(3326, 0, 3347), // ZONE5 (¾ÆÀÏ·£µå ¿Àºê ÆäÀÎ) Position(2227, 0, 2250), // BATTLE_ZONE (»ç¿ë ¾ÈÇÔ) Position(0, 0, 0), // ADMIN_TOOL_ZONE Position(3465, 0, 3465), // CAPITAL Position(3780, 0, 3780), // ZONE9 Position(1259, 0, 1237), // BATTLE_SERVER::FRAG_ZONE Position(2250, 0, 1884), // BATTLE_SERVER Position(3769, 0, 3774), // ZONE12 (½ÅÀÇ ´ë·ú) Position(1523, 0, 1529), // BATTLE_SERVER::STATUE_ZONE Position(3360, 0, 3250), // °¨¿Á (°¨±Ý ½Ã½ºÅÛ) Position(0, 0, 0), // CHAR_SELECT (ij¸¯ÅÍ ¼±Åà ȭ¸é) Position(1970, 0, 1980), // STONE_WAR1 Position(1970, 0, 1980), // STONE_WAR2 Position(1970, 0, 1980) // STONE_WAR3 }; char cZoneNumber = CServerSetup::GetInstance().GetServerZone(); return (Pos.m_fPointX >= ZoneMinPos[cZoneNumber].m_fPointX && Pos.m_fPointX <= ZoneMaxPos[cZoneNumber].m_fPointX && Pos.m_fPointZ >= ZoneMinPos[cZoneNumber].m_fPointZ && Pos.m_fPointZ <= ZoneMaxPos[cZoneNumber].m_fPointZ) ? true : false; } void CCellManager::Load(void) { // ÁÖÀÇ : NPC¿¡ ¸µÅ©¸¦ °Å´Â ¸ó½ºÅ͵é(¼Òȯ ¿Ï·áµÈ ¸í¿¹ÀÇ ¼®»ó)ÀÌ ÀÖÀ¸¹Ç·Î NPC°¡ ¸ÕÀú ·ÎµùµÇ¾î¾ß ÇÑ´Ù. // NPC¿¡ Quest¸¦ µî·ÏÇϱ⠶§¹®¿¡ Quest¸¦ ¸ÕÀú ·ÎµåÇØ¾ß ÇÑ´Ù. DETLOG0(g_Log, "Quest Á¤º¸¸¦ ·ÎµùÇÕ´Ï´Ù."); CQuestMgr::LoadQuestInfo(); DETLOG0(g_Log, "NPC Á¤º¸¸¦ ·ÎµùÇÕ´Ï´Ù."); CNPC::LoadNPCInfo(); DETLOG0(g_Log, "¸ó½ºÅÍ Á¤º¸¸¦ ·ÎµùÇÕ´Ï´Ù."); CMonsterMgr::GetInstance().LoadMonstersFromFile(); InitAI(); DETLOG0(g_Log, "VirtualArea Á¤º¸¸¦ ·ÎµùÇÕ´Ï´Ù."); VirtualArea::CVirtualAreaMgr::GetInstance().LoadVirtualAreaProtoType(); DETLOG0(g_Log, "°¢ ¼¿À» ÃʱâÈ­ÇÕ´Ï´Ù."); CreateCell(); DETLOG0(g_Log, "°¢ ¼¿ÀÇ ³¯¾¾¸¦ ÃʱâÈ­ÇÕ´Ï´Ù."); char szWeather[MAX_PATH]; sprintf(szWeather, "./Script/Game/Weather/Weather%d.bmp", CServerSetup::GetInstance().GetServerZone()); SetWeather(szWeather); DETLOG0(g_Log, "¸ó½ºÅ͸¦ ·Î±ä½Ãŵ´Ï´Ù."); char szArrangement[MAX_PATH]; sprintf(szArrangement, "./Script/Game/Arrangement/Arrangement%d.txt", CServerSetup::GetInstance().GetServerZone()); LoginMonster(szArrangement); DETLOG0(g_Log, "¼­¹ö¿¡ ¼¼ÀÌÇÁƼ Á¸À» ¼³Á¤ÇÕ´Ï´Ù."); char szSafetyZone[MAX_PATH]; sprintf(szSafetyZone, "./Script/Game/SafetyZone/Zone%d.bgm", CServerSetup::GetInstance().GetServerZone()); LoadSafetyZone(szSafetyZone); m_bLoadComplete = true; } bool CCellManager::InitAI(void) { const int StateNum = 3; const int TriggerNum = 4; const int aryStateIDandTriggerNum[StateNum * 2] = { STATE_ID_NORMAL, 4, STATE_ID_ATTACK, 3, STATE_ID_RETURN, 3, }; const int aryTriggerandNextState[StateNum][TriggerNum * 2] = { // STATE_ID_NOMAL { INPUT_ID_SEEN_PLAYER, STATE_ID_ATTACK, INPUT_ID_ATTACKED_PLAYER, STATE_ID_ATTACK, INPUT_ID_ZERO_HP, STATE_ID_DIE, INPUT_ID_CMD_ATTACK, STATE_ID_ATTACK, }, // STATE_ID_ATTACK { INPUT_ID_LEAVE_PLAYER, STATE_ID_RETURN, INPUT_ID_ZERO_HP, STATE_ID_DIE, INPUT_ID_CMD_ESCAPE, STATE_ID_RETURN, STATE_ID_NULL, STATE_ID_NULL }, // STATE_ID_RETURN { INPUT_ID_ARRIVAL_SITE, STATE_ID_NORMAL, INPUT_ID_ATTACKED_PLAYER, STATE_ID_ATTACK, INPUT_ID_ZERO_HP, STATE_ID_DIE, STATE_ID_NULL, STATE_ID_NULL } }; int nIndexState; int nTriggerIndex, nTransitionIndex; for (nTriggerIndex = 0, nIndexState = 0; nIndexState < StateNum; nTriggerIndex += 2, ++nIndexState) { CFSMState* lpFSMstate = new CFSMState(aryStateIDandTriggerNum[nTriggerIndex], aryStateIDandTriggerNum[nTriggerIndex + 1]); if (0 == lpFSMstate) { ERRLOG0(g_Log, "¸Þ¸ð¸® ÇÒ´ç¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } for (nTransitionIndex = 0; nTransitionIndex < aryStateIDandTriggerNum[nTriggerIndex + 1] * 2; nTransitionIndex += 2) { lpFSMstate->AddTransition(aryTriggerandNextState[nIndexState][nTransitionIndex], aryTriggerandNextState[nIndexState][nTransitionIndex + 1]); } if (false == CFSM::GetInstance().AddState(lpFSMstate)) { ERRLOG0(g_Log, "State°¡ ³Ê¹« ¸¹½À´Ï´Ù."); delete lpFSMstate; break; } } return true; } bool CCellManager::CreateCell(void) { int nX = 0; int nZ = 0; // ¹èƲ ±×¶ó¿îµå Àü¿ë ¼­¹ö±ºÀÇ °æ¿ì BGServerMap ÀÇ Cell µéÀ» »ý¼ºÇØ¾ß ÇÑ´Ù. if (SERVER_ID::BATTLE_SERVER == CServerSetup::GetInstance().GetServerZone()) { CCell::ms_CellSize = CCell::CELL_SIZE_BATTLE_SERVER; // BGServerMap ÀÇ ¼¿À» »ý¼ºÇÑ´Ù. VirtualArea::CVirtualAreaMgr::GetInstance().CreateBGServer(); } m_CellData = new CCell[CCell::ms_CellSize * CCell::ms_CellSize]; if (NULL == m_CellData) { ERRLOG0(g_Log, "¼¿À» ÇÒ´çÇϴµ¥ ½ÇÆÐÇß½À´Ï´Ù."); return false; } CCell* lpCell = m_CellData; CCell* lpUpperCell = 0; CCell* lpLowerCell = 0; const int nCellSize = CCell::ms_CellSize; // Make Cell Link for (nZ = 0; nZ < nCellSize; ++nZ) { for (nX = 0; nX < nCellSize; ++nX, ++lpCell) { // UP, UpperLeft, UpperRight if (nZ > 0) { lpUpperCell = lpCell - nCellSize; lpCell->SetConnectCell(CCell::UP, lpUpperCell); if (nX > 0) { lpCell->SetConnectCell(CCell::UPPERLEFT, lpUpperCell - 1); } if (nX < CCell::ms_CellSize-1) { lpCell->SetConnectCell(CCell::UPPERRIGHT, lpUpperCell + 1); } } // Down, DnLeft, DnRight if (nZ < nCellSize - 1) { lpLowerCell = lpCell + nCellSize; lpCell->SetConnectCell(CCell::DOWN, lpLowerCell); if (nX > 0) { lpCell->SetConnectCell(CCell::LOWERLEFT, lpLowerCell - 1); } if (nX < CCell::ms_CellSize - 1) { lpCell->SetConnectCell(CCell::LOWERRIGHT, lpLowerCell + 1); } } // Left if (nX > 0) { lpCell->SetConnectCell(CCell::LEFT, lpCell - 1); } // Right if (nX < CCell::ms_CellSize - 1) { lpCell->SetConnectCell(CCell::RIGHT, lpCell + 1); } // itself lpCell->SetConnectCell(CCell::NO, lpCell); } } // ¼¿ ¸µÅ©°¡ ³¡³­ ´ÙÀ½ ÃʱâÈ­¸¦ ÇØ¾ß ÇÑ´Ù. lpCell = m_CellData; for (nZ = 0; nZ < nCellSize; ++nZ) { for (nX = 0; nX < nCellSize; ++nX, ++lpCell) { lpCell->Initialize(nX, nZ); } } return true; } bool CCellManager::SetWeather(const char* szFileName) { FILE *fpFile = fopen(szFileName, "rb"); if (NULL == fpFile) { ERRLOG1(g_Log, "%s ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù.", szFileName); return false; } BITMAPFILEHEADER bitmapHeader; if (NULL == fread(&bitmapHeader, sizeof(BITMAPFILEHEADER), 1, fpFile)) { ERRLOG1(g_Log, "%s ÆÄÀÏÀÇ Çì´õ¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù.", szFileName); return false; } BITMAPINFOHEADER bitmapInfoHeader; if (NULL == fread(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, fpFile)) { ERRLOG1(g_Log, "%s ÆÄÀÏÀÇ Á¤º¸ Çì´õ¸¦ ¿­ ¼ö ¾ø½À´Ï´Ù.", szFileName); return false; } int nWidth = bitmapInfoHeader.biWidth; int nHeight = abs(bitmapInfoHeader.biHeight); // 4¹ÙÀÌÆ® Á¤·ÄÀÌ µÇ¾î ÀÖÀ¸¹Ç·Î... int nRealWidth = (nWidth * (bitmapInfoHeader.biBitCount / 8) + 3) & ~3; m_WeatherRate = new unsigned char[nHeight * nRealWidth]; // À̹ÌÁö°¡ °Å²Ù·Î µÇ¾î ÀÖÀ¸¹Ç·Î µÞºÎºÐºÎÅÍ Àд´Ù. for (int y = nHeight - 1; y > -1; --y) { fread(m_WeatherRate + (y * nRealWidth), nRealWidth, 1, fpFile); } fclose(fpFile); return true; } bool CCellManager::LoginMonster(const char* szFileName, unsigned short wMapIndex) { CDelimitedFile DelimitedFile; if (false == DelimitedFile.Open(szFileName, 1)) { ERRLOG1(g_Log, "%s ÆÄÀÏÀ» ¿­ ¼ö ¾ø½À´Ï´Ù.", szFileName); return false; } char strTemp[MAX_PATH]; int iLine = 0; CMonster::MonsterCreateInfo tempInfo; CMonster* lpNewMonster = NULL; CCreatureManager& CreatureManager = CCreatureManager::GetInstance(); while (DelimitedFile.ReadLine()) { ++iLine; DelimitedFile.ReadString(strTemp, MAX_PATH); tempInfo.m_dwCID = Math::Convert::Atoi(strTemp); DelimitedFile.ReadData(tempInfo.m_nKID); DelimitedFile.ReadString(strTemp, MAX_PATH); tempInfo.m_dwPID = Math::Convert::Atoi(strTemp); DelimitedFile.ReadData(tempInfo.m_Pos.m_fPointX); DelimitedFile.ReadData(tempInfo.m_Pos.m_fPointY); DelimitedFile.ReadData(tempInfo.m_Pos.m_fPointZ); DelimitedFile.ReadData(tempInfo.m_bScout); DelimitedFile.ReadData(tempInfo.m_nMovingPattern); DelimitedFile.ReadData(tempInfo.m_wRespawnArea); Creature::CreatureType eCreatureType = Creature::GetCreatureType(tempInfo.m_dwCID); if (Creature::CT_MONSTER != eCreatureType && Creature::CT_SUMMON != eCreatureType && Creature::CT_STRUCT != eCreatureType) { ERRLOG2(g_Log, "À߸øµÈ CID(%d)¸¦ °¡Áø ¸ó½ºÅ͸¦ »ý¼ºÇÏ·Á ÇÕ´Ï´Ù. Line %d", tempInfo.m_dwCID, iLine); continue; } if ((tempInfo.m_dwCID & Creature::MONSTER_KIND_BIT) != tempInfo.m_nKID) { ERRLOG2(g_Log, "À߸øµÈ KID(%d)¸¦ °¡Áø ¸ó½ºÅ͸¦ »ý¼ºÇÏ·Á ÇÕ´Ï´Ù(CID(%d) Á¤º¸¿Í Ʋ¸³´Ï´Ù).", tempInfo.m_nKID, tempInfo.m_dwCID); continue; } switch (tempInfo.m_nKID) { // 1·¹º§ case MonsterInfo::STATUE_NEUTRALITY1: case MonsterInfo::STATUE_HUMAN_LOADING1: case MonsterInfo::STATUE_HUMAN_COMPLETE1: case MonsterInfo::STATUE_AKHAN_LOADING1: case MonsterInfo::STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::STATUE_NEUTRALITY2: case MonsterInfo::STATUE_HUMAN_LOADING2: case MonsterInfo::STATUE_HUMAN_COMPLETE2: case MonsterInfo::STATUE_AKHAN_LOADING2: case MonsterInfo::STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::BG_STATUE_NEUTRALITY1: case MonsterInfo::BG_STATUE_HUMAN_LOADING1: case MonsterInfo::BG_STATUE_HUMAN_COMPLETE1: case MonsterInfo::BG_STATUE_AKHAN_LOADING1: case MonsterInfo::BG_STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::BG_STATUE_NEUTRALITY2: case MonsterInfo::BG_STATUE_HUMAN_LOADING2: case MonsterInfo::BG_STATUE_HUMAN_COMPLETE2: case MonsterInfo::BG_STATUE_AKHAN_LOADING2: case MonsterInfo::BG_STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } //2 ·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::BG_STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::POWER_STATUE_NEUTRALITY1: case MonsterInfo::POWER_STATUE_HUMAN_LOADING1: case MonsterInfo::POWER_STATUE_HUMAN_COMPLETE1: case MonsterInfo::POWER_STATUE_AKHAN_LOADING1: case MonsterInfo::POWER_STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::POWER_STATUE_NEUTRALITY2: case MonsterInfo::POWER_STATUE_HUMAN_LOADING2: case MonsterInfo::POWER_STATUE_HUMAN_COMPLETE2: case MonsterInfo::POWER_STATUE_AKHAN_LOADING2: case MonsterInfo::POWER_STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::POWER_STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::INT_STATUE_NEUTRALITY1: case MonsterInfo::INT_STATUE_HUMAN_LOADING1: case MonsterInfo::INT_STATUE_HUMAN_COMPLETE1: case MonsterInfo::INT_STATUE_AKHAN_LOADING1: case MonsterInfo::INT_STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::INT_STATUE_NEUTRALITY2: case MonsterInfo::INT_STATUE_HUMAN_LOADING2: case MonsterInfo::INT_STATUE_HUMAN_COMPLETE2: case MonsterInfo::INT_STATUE_AKHAN_LOADING2: case MonsterInfo::INT_STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::INT_STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::EXP_STATUE_NEUTRALITY1: case MonsterInfo::EXP_STATUE_HUMAN_LOADING1: case MonsterInfo::EXP_STATUE_HUMAN_COMPLETE1: case MonsterInfo::EXP_STATUE_AKHAN_LOADING1: case MonsterInfo::EXP_STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::EXP_STATUE_NEUTRALITY2: case MonsterInfo::EXP_STATUE_HUMAN_LOADING2: case MonsterInfo::EXP_STATUE_HUMAN_COMPLETE2: case MonsterInfo::EXP_STATUE_AKHAN_LOADING2: case MonsterInfo::EXP_STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::EXP_STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::WEALTH_STATUE_NEUTRALITY1: case MonsterInfo::WEALTH_STATUE_HUMAN_LOADING1: case MonsterInfo::WEALTH_STATUE_HUMAN_COMPLETE1: case MonsterInfo::WEALTH_STATUE_AKHAN_LOADING1: case MonsterInfo::WEALTH_STATUE_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::WEALTH_STATUE_NEUTRALITY2: case MonsterInfo::WEALTH_STATUE_HUMAN_LOADING2: case MonsterInfo::WEALTH_STATUE_HUMAN_COMPLETE2: case MonsterInfo::WEALTH_STATUE_AKHAN_LOADING2: case MonsterInfo::WEALTH_STATUE_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::WEALTH_STATUE_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } // 1·¹º§ case MonsterInfo::LIFE_EXTRACT_NEUTRALITY1: case MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING1: case MonsterInfo::LIFE_EXTRACT_HUMAN_COMPLETE1: case MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING1: case MonsterInfo::LIFE_EXTRACT_AKHAN_COMPLETE1: // 2·¹º§ case MonsterInfo::LIFE_EXTRACT_NEUTRALITY2: case MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING2: case MonsterInfo::LIFE_EXTRACT_HUMAN_COMPLETE2: case MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING2: case MonsterInfo::LIFE_EXTRACT_AKHAN_COMPLETE2: { lpNewMonster = new CStatue(tempInfo, 0); lpNewMonster->SetMapIndex(wMapIndex); if (0 != lpNewMonster) { CStatue* lpStatue = reinterpret_cast(lpNewMonster); // 1·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_HUMAN_COMPLETE1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING1)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_AKHAN_COMPLETE1)) { delete lpNewMonster; return false; } // 2·¹º§ if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_HUMAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_HUMAN_COMPLETE2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_AKHAN_LOADING2)) { delete lpNewMonster; return false; } if (false == lpStatue->CreateLinkStatue(MonsterInfo::LIFE_EXTRACT_AKHAN_COMPLETE2)) { delete lpNewMonster; return false; } } break; } default: { // MON_TODO : ¸ó½ºÅÍ Å¸ÀÔ¿¡ ¸Â°Ô »ý¼º const CMonsterMgr::MonsterProtoType* pProtoType = CMonsterMgr::GetInstance().GetMonsterProtoType(tempInfo.m_nKID); if (NULL == pProtoType) { ERRLOG1(g_Log, "KID : %d ¿¡ ÇØ´çÇÏ´Â ¸ó½ºÅÍ ÇÁ·ÎÅäŸÀÔÀÌ ¾ø½À´Ï´Ù.", tempInfo.m_nKID); continue; } switch (pProtoType->m_MonsterInfo.m_cSkillPattern) { case MonsterInfo::PATTERN_DEFENDER: lpNewMonster = new CDefenderMonster(tempInfo); break; case MonsterInfo::PATTERN_WARRIOR: lpNewMonster = new CWarriorMonster(tempInfo); break; case MonsterInfo::PATTERN_ACOLYTE: lpNewMonster = new CAcolyteMonster(tempInfo); break; case MonsterInfo::PATTERN_MAGE: lpNewMonster = new CMageMonster(tempInfo); break; case MonsterInfo::PATTERN_BOSS: lpNewMonster = new CBossMonster(tempInfo); break; case MonsterInfo::PATTERN_NAMED: lpNewMonster = new CNamedMonster(tempInfo); break; case MonsterInfo::PATTERN_CHIEF: lpNewMonster = new CChiefMonster(tempInfo); break; case MonsterInfo::PATTERN_OBJECT: lpNewMonster = new CObjectMonster(tempInfo); break; case MonsterInfo::PATTERN_GATHER: lpNewMonster = new CGatherMonster(tempInfo); break; case MonsterInfo::PATTERN_GUARD: lpNewMonster = new CGuardMonster(tempInfo); break; default: lpNewMonster = new CMonster(tempInfo); break; } lpNewMonster->SetMapIndex(wMapIndex); break; } } if (NULL == lpNewMonster) { ERRLOG0(g_Log, "¸ó½ºÅÍ »ý¼º¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } if (false == lpNewMonster->InitMonster(tempInfo.m_Pos)) { ERRLOG0(g_Log, "¸ó½ºÅÍ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } if (0 != wMapIndex) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(wMapIndex); if (NULL != lpVirtualArea) { CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager(); if (lpVirtualMonsterMgr) { lpVirtualMonsterMgr->AddMonster(lpNewMonster); } } } else { CreatureManager.AddCreature(lpNewMonster); } // MON_TODO : ¸ó½ºÅÍ ÆÄƼ // ÆÄƼ ¼³Á¤ if (0 != lpNewMonster->GetPID()) { // ÆÄƼ°¡ ¾ø´Ù¸é »ý¼ºÇÑ´Ù. CParty* lpParty = CPartyMgr::GetInstance().GetParty( lpNewMonster->GetPID() ); if (0 == lpParty) { lpParty = new CMonsterParty(); lpParty->SetUID( lpNewMonster->GetPID() ); CPartyMgr::GetInstance().AddParty(lpParty); } // ÆÄƼ°¡ ¼³Á¤ ¹× ÆÄƼ¿ø Ãß°¡ lpNewMonster->SetParty(lpParty); lpParty->Join(lpNewMonster->GetCID(), 0, 0, wMapIndex); } // -------------------------------- } DelimitedFile.Close(); DETLOG0(g_Log, "¸ó½ºÅÍ ·Î±×ÀÎÀ» ¿Ï·áÇß½À´Ï´Ù."); return true; } bool CCellManager::LoadSafetyZone(const char* szFileName) { vector::iterator itr; FILE* lpFile = fopen(szFileName, "rb"); if (NULL == lpFile) { ERRLOG1(g_Log, "¼¼ÀÌÇÁƼÁ¸ ·Îµù¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù. ÆÄÀϸí:%s", szFileName); return false; } unsigned long dwTriggerNum; fread(&dwTriggerNum, sizeof(unsigned long), 1, lpFile); for (unsigned long dwTriggerIndex = 0; dwTriggerIndex < dwTriggerNum; ++dwTriggerIndex) { SafetyZoneInfo* lpInfo = new SafetyZoneInfo; fread(&(lpInfo->m_dwSectorX), sizeof(unsigned long), 1, lpFile); fread(&(lpInfo->m_dwSectorY), sizeof(unsigned long), 1, lpFile); fread(lpInfo->m_szFilename, sizeof(char), MAX_PATH, lpFile); fread(&(lpInfo->m_dwEventNum), sizeof(unsigned long), 1, lpFile); fread(lpInfo->m_aryColorTable[0], sizeof(unsigned long), BGM_TEXTURE_SIZE * BGM_TEXTURE_SIZE, lpFile); unsigned long dwIndex = 0; unsigned long dwEventKey = 0; for (dwIndex = 0; dwIndex < lpInfo->m_dwEventNum; ++dwIndex) { fread(&dwEventKey, sizeof(unsigned long), 1, lpFile); lpInfo->m_vecEventKey.push_back(dwEventKey); } unsigned long dwColorKey = 0; for (dwIndex = 0; dwIndex < lpInfo->m_dwEventNum; ++dwIndex) { fread(&dwColorKey, sizeof(unsigned long), 1, lpFile ); lpInfo->m_vecBGMColorKey.push_back(dwColorKey); } for (dwIndex = 0; dwIndex < lpInfo->m_dwEventNum; ++dwIndex) { char szFilePath[MAX_PATH]; fread(szFilePath, sizeof(char), MAX_PATH, lpFile); } m_vecSafetyZone.push_back(lpInfo); } fclose(lpFile); return true; } bool CCellManager::AdminSummonMonster(int nKID, Position Pos) { CMonster::MonsterCreateInfo tempInfo; CMonster* lpNewMonster = NULL; CCreatureManager& CreatureManager = CCreatureManager::GetInstance(); // nKID °¡ Á¤»óÀÎÁö üũ const CMonsterMgr::MonsterProtoType* lpProtoType = CMonsterMgr::GetInstance().GetMonsterProtoType(nKID); if (0 == lpProtoType) { ERRLOG1(g_Log, "KID : %d ¸ó½ºÅ͸¦ ¼ÒȯÇϴµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", nKID); return false; } // Á¸´ç ÃÖ´ë ¸ó½ºÅÍ ¼ö¸¦ ÃʰúÇÏ´ÂÁö üũ if (CreatureManager.GetMonsterNum() >= CMonster::MAX_MONSTER_UID) { ERRLOG0(g_Log, "ÇöÀç Á¸¿¡ ¸ó½ºÅÍ ¼ö°¡ ÃÖ´ëÀÔ´Ï´Ù. ´õÀÌ»ó ¸ó½ºÅ͸¦ »ý¼ºÇÒ ¼ö ¾ø½À´Ï´Ù."); return false; } // ¸ó½ºÅÍ ¸Ê¿¡¼­ Àû´çÇÑ ¼ýÀÚ¸¦ ³Ñ°ÜÁØ´Ù. (CID ¸¦ À¯´ÏÅ©ÇÏ°Ô Çϱâ À§Çؼ­) unsigned long dwUID = CreatureManager.GetAvailableMonsterUID(static_cast(nKID)); if (CCreatureManager::NO_BLANK_UID == dwUID) { 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_GATHER: lpNewMonster = new CGatherMonster(tempInfo); break; case MonsterInfo::PATTERN_GUARD: lpNewMonster = new CGuardMonster(tempInfo, true); break; default: lpNewMonster = new CMonster(tempInfo, true); break; } if (NULL == lpNewMonster) { ERRLOG0(g_Log, "¸ó½ºÅÍ »ý¼º¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } if (false == lpNewMonster->InitMonster(tempInfo.m_Pos)) { ERRLOG0(g_Log, "¸ó½ºÅÍ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } return CreatureManager.AddCreature(lpNewMonster); } bool CCellManager::SummonMonster(int nKID, Position Pos, CCharacter* lpMaster) { CMonster::MonsterCreateInfo tempInfo; tempInfo.m_dwCID = Creature::SUMMON_MONSTER_BIT + (m_usSummonCount << 16) + nKID; if (0 != CCreatureManager::GetInstance().GetCreature(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; } if (false == lpSummonMonster->InitMonster(tempInfo.m_Pos)) { delete lpSummonMonster; lpSummonMonster = NULL; ERRLOG0(g_Log, "¼Òȯ ¸ó½ºÅÍ ÃʱâÈ­¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); return false; } CCreatureManager::GetInstance().AddCreature(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; } CCell* CCellManager::GetCell(unsigned short wMapIndex, unsigned char cCellX, unsigned char cCellZ) { CCell* lpCell = 0; if (0 != wMapIndex) { VirtualArea::CVirtualArea* lpArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(wMapIndex); if (NULL == lpArea) { ERRLOG1(g_Log, "MapIndex:0x%04x, À妽ºÀÇ °¡»ó ¿µ¿ªÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù.", wMapIndex); return lpCell; } if (cCellX < 0 || cCellX >= lpArea->GetWidth() || cCellZ < 0 || cCellZ >= lpArea->GetHeight()) { ERRLOG5(g_Log, "MapIndex:0x%04x, X:%d(Max:%d), Z:%d(Max:%d) À妽ºÀÇ ¼¿À» ãÀ» ¼ö ¾ø½À´Ï´Ù.", wMapIndex, cCellX, lpArea->GetWidth(), cCellZ, lpArea->GetHeight()); return lpCell; } lpCell = lpArea->GetCell(cCellX + cCellZ * lpArea->GetWidth()); } else { if (cCellX < 0 || cCellX >= CCell::ms_CellSize || cCellZ < 0 || cCellZ >= CCell::ms_CellSize) { ERRLOG2(g_Log, "X:%d, Z:%d À妽ºÀÇ ¼¿À» ãÀ» ¼ö ¾ø½À´Ï´Ù.", cCellX, cCellZ); return lpCell; } lpCell = &m_CellData[cCellX + cCellZ * CCell::ms_CellSize]; } return lpCell; } CCell* CCellManager::GetCell(unsigned short wMapIndex, unsigned long dwPosX, unsigned long dwPosY, unsigned long dwPosZ) { CCell* lpCell = 0; if (0 != wMapIndex) { VirtualArea::CVirtualArea* lpArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(wMapIndex); if (NULL == lpArea) { ERRLOG1(g_Log, "MapIndex:0x%04x, À妽ºÀÇ °¡»ó ¿µ¿ªÀ» ãÀ» ¼ö ¾ø½À´Ï´Ù.", wMapIndex); return lpCell; } if (dwPosX < lpArea->GetStartX() || dwPosZ < lpArea->GetStartZ() || dwPosX > static_cast((lpArea->GetWidth() << CCell::CELL_RESOLUTION) + lpArea->GetStartX()) || dwPosZ > static_cast((lpArea->GetHeight() << CCell::CELL_RESOLUTION) + lpArea->GetStartZ())) { ERRLOG3(g_Log, "X:%d, Y:%d, Z:%d À§Ä¡ÀÇ Cell À» ãÀ» ¼ö ¾ø½À´Ï´Ù.", dwPosX, dwPosY, dwPosZ); return 0; } dwPosX -= lpArea->GetStartX(); dwPosZ -= lpArea->GetStartZ(); lpCell = lpArea->GetCell( (dwPosX >> CCell::CELL_RESOLUTION) + (dwPosZ >> CCell::CELL_RESOLUTION) * lpArea->GetWidth() ); } else { if (dwPosX < 0 || dwPosX > static_cast(CCell::ms_CellSize << CCell::CELL_RESOLUTION) || dwPosZ < 0 || dwPosZ > static_cast(CCell::ms_CellSize << CCell::CELL_RESOLUTION)) { ERRLOG3(g_Log, "X:%d, Y:%d, Z:%d À§Ä¡ÀÇ Cell À» ãÀ» ¼ö ¾ø½À´Ï´Ù.", dwPosX, dwPosY, dwPosZ); return 0; } lpCell = &m_CellData[(dwPosX >> CCell::CELL_RESOLUTION) + (dwPosZ >> CCell::CELL_RESOLUTION) * CCell::ms_CellSize]; } return lpCell; } // ------------------------------------------------------------------------------------- // ·Î±×¿ë ÇÔ¼öµé struct CheckInfo { int m_nCellX; int m_nCellZ; CheckInfo(int nIndex) : m_nCellX(nIndex % CCell::ms_CellSize), m_nCellZ(nIndex / CCell::ms_CellSize) { } }; typedef std::map CIDInCell; typedef std::multimap DUPCID; class CheckMap { public: CheckMap(CIDInCell& Map) : m_Map(Map) { } bool operator() (CAggresiveCreature* lpCreature) { m_Map.erase(lpCreature->GetCID()); return true; } protected: CIDInCell& m_Map; }; bool CCellManager::CheckCellAggresiveCreatures() { if (0 == m_CellData) { return false; } CIDInCell AggresiveCreatureMap; DUPCID DuplicateCID; unsigned long dwCID = 0; for (int nIndex = 0; nIndex < CCell::ms_CellSize * CCell::ms_CellSize; ++nIndex) { CCell& Cell = m_CellData[nIndex]; CCharacter* lpCharacter = Cell.GetFirstCharacter(); while (NULL != lpCharacter) { dwCID = lpCharacter->GetCID(); if (false == AggresiveCreatureMap.insert(CIDInCell::value_type(dwCID, CheckInfo(nIndex))).second) { DuplicateCID.insert(DUPCID::value_type(dwCID, CheckInfo(nIndex))); } lpCharacter = Cell.GetNextCharacter(); } CMonster* lpMonster = Cell.GetFirstMonster(); while (NULL != lpMonster) { dwCID = lpMonster->GetCID(); if (false == AggresiveCreatureMap.insert(CIDInCell::value_type(dwCID, CheckInfo(nIndex))).second) { DuplicateCID.insert(DUPCID::value_type(dwCID, CheckInfo(nIndex))); } lpMonster = Cell.GetNextMonster(); } } CheckMap check(AggresiveCreatureMap); CCreatureManager::GetInstance().ProcessAllCharacter(check); CCreatureManager::GetInstance().ProcessAllMonster(check); FILE* fFile = fopen("CellLog.txt", "wt"); if (NULL == fFile) { return false; } if (DuplicateCID.empty()) { fprintf(fFile, "¼¿ ³¢¸®´Â Áߺ¹µÇ´Â CID°¡ ¾ø½À´Ï´Ù."); } else { for (DUPCID::iterator itr = DuplicateCID.begin(); itr != DuplicateCID.end(); ++itr) { fprintf(fFile, "¼¿ ¾È¿¡¼­ Áߺ¹µÇ´Â CID:0x%08x - CellX:%d, CellZ:%d", itr->first, itr->second.m_nCellX, itr->second.m_nCellZ); } } if (AggresiveCreatureMap.empty()) { fprintf(fFile, "Å©¸®ÃÄ ¸Ê¿¡ ÀÖ´Â ¾ÆÀ̵ð »ÓÀÔ´Ï´Ù."); } else { for (CIDInCell::iterator itr = AggresiveCreatureMap.begin(); itr != AggresiveCreatureMap.end(); ++itr) { fprintf(fFile, "Å©¸®ÃÄ ¸Ê¿¡ ¾ø´Â CID:0x%08x - CellX:%d, CellZ:%d", itr->first, itr->second.m_nCellX, itr->second.m_nCellZ); } } fclose(fFile); return true; } bool CCellManager::CheckCellStatus(void) { if (NULL == m_CellData) { return false; } std::fstream file("CellStat.txt", ios_base::out); file << "X/Z/»ç¶÷¼ö/ÁÖº¯ »ç¶÷¼ö/¸ó½ºÅͼö/ÁÖº¯ ¸ó½ºÅͼö/" << "¾ÆÀÌÅÛ ¼ö/ÁÖº¯ ¾ÆÀÌÅÛ ¼ö/ÇöÀç Å©¸®ÃÄ ¼ö/ÁÖº¯ Å©¸®ÃÄ ¼ö/ÇöÀç °³Ã¼¼ö/ÁÖº¯ °³Ã¼¼ö" << std::endl; for (int nIndex = 0; nIndex < CCell::ms_CellSize * CCell::ms_CellSize; ++nIndex) { const int nCellX = nIndex % CCell::ms_CellSize; const int nCellZ = nIndex / CCell::ms_CellSize; CCell& CurrentCell = m_CellData[nIndex]; unsigned long nNearCharacters = 0; unsigned long nNearMonsters = 0; unsigned long nNearItems = 0; unsigned long nCurrentCharacter = static_cast(CurrentCell.GetCharacterNum()); unsigned long nCurrentMonster = static_cast(CurrentCell.GetMonsterNum()); unsigned long nCurrentItem = static_cast(CurrentCell.GetItemNum()); for (int nCell = 0; nCell < CCell::CONNECT_NUM; ++nCell) { CCell* lpCell = CurrentCell.GetConnectCell(nCell); if (0 != lpCell) { nNearCharacters += static_cast(lpCell->GetCharacterNum()); nNearMonsters += static_cast(lpCell->GetMonsterNum()); nNearItems += static_cast(lpCell->GetItemNum()); } } file << nCellX << '/' << nCellZ << '/' << nCurrentCharacter << '/' << nNearCharacters << '/' << nCurrentMonster << '/' << nNearMonsters << '/' << nCurrentItem << '/' << nNearItems << '/' << nCurrentCharacter + nCurrentMonster << '/' << nNearCharacters + nNearMonsters << '/' << nCurrentCharacter + nCurrentMonster + nCurrentItem << '/' << nNearCharacters + nNearMonsters + nNearItems << '/' << std::endl; } return true; } CCell* CCellManager::GetCell(unsigned __int64 nItemID) { CCell::ItemInfo itemInfo; itemInfo.UID.m_nUniqueID = nItemID; return GetCell(itemInfo.UID.m_Field.wMapIndex, itemInfo.UID.m_Field.cCellX, itemInfo.UID.m_Field.cCellZ); } CCell* CCellManager::GetCell(unsigned short wMapIndex, POS& Pos) { return GetCell(wMapIndex, static_cast(Pos.fPointX), static_cast(Pos.fPointY), static_cast(Pos.fPointZ)); } void CCellManager::LowerResolution(int nHighX, int nHighZ, int *nLowX, int *nLowZ) { *nLowX = nHighX >> CCell::CELL_RESOLUTION; *nLowZ = nHighZ >> CCell::CELL_RESOLUTION; } void CCellManager::HigherResolution(int nLowX, int nLowZ, int *nHighX, int *nHighZ) { *nHighX = nLowX << CCell::CELL_RESOLUTION; *nHighZ = nLowZ << CCell::CELL_RESOLUTION; } bool CCellManager::IsCampCreateArea(Position Pos) { unsigned char cSectorX = static_cast((Pos.m_fPointX * 100) / SECTOR_SIZE); unsigned char cSectorZ = static_cast((Pos.m_fPointZ * 100) / SECTOR_SIZE); float fMagnification = SECTOR_SIZE / static_cast(BGM_TEXTURE_SIZE); int nDestX = static_cast(static_cast(Pos.m_fPointX * 100) % SECTOR_SIZE / fMagnification); int nDestZ = static_cast(BGM_TEXTURE_SIZE - (static_cast(Pos.m_fPointZ * 100) % SECTOR_SIZE / fMagnification) - 1); for (vector::iterator infoItr = m_vecSafetyZone.begin(); infoItr != m_vecSafetyZone.end(); ++infoItr) { SafetyZoneInfo* lpInfo = *infoItr; if (lpInfo->m_dwSectorX != cSectorX || lpInfo->m_dwSectorY != cSectorZ) { continue; } unsigned long dwBGMColor = lpInfo->m_aryColorTable[nDestZ][nDestX] & 0x00FFFFFF; vector::iterator eventkeyItr = lpInfo->m_vecEventKey.begin(); for (vector::iterator colorkeyItr = lpInfo->m_vecBGMColorKey.begin(); colorkeyItr != lpInfo->m_vecBGMColorKey.end(); ++colorkeyItr, ++eventkeyItr) { if (dwBGMColor == *colorkeyItr) { // ¼¼ÀÌÇÁƼÁ¸À» Ç¥±âÇÏ´Â Ç÷¡±×µé (À½¾Ç Ãâ·Â ½ºÅ©¸³Æ®¸¦ ÇÔ²² ¾²¹Ç·Î...) if (SafetyZoneInfo::EK_CAMP_UNCREATE == *eventkeyItr) { return false; } } } } return true; } bool CCellManager::IsSafetyZone(Position Pos) { /* // Ãʺ¸Á¸Àº Àü¿ªÀÌ ¼¼ÀÌÇÁƼÁ¸ÀÔ´Ï´Ù. if (SERVER_ID::ZONE1 == CServerSetup::GetInstance().GetServerZone() || SERVER_ID::ZONE2 == CServerSetup::GetInstance().GetServerZone()) { return true; } */ unsigned char cSectorX = static_cast((Pos.m_fPointX * 100) / SECTOR_SIZE); unsigned char cSectorZ = static_cast((Pos.m_fPointZ * 100) / SECTOR_SIZE); float fMagnification = SECTOR_SIZE / static_cast(BGM_TEXTURE_SIZE); int nDestX = static_cast(static_cast(Pos.m_fPointX * 100) % SECTOR_SIZE / fMagnification); int nDestZ = static_cast(BGM_TEXTURE_SIZE - (static_cast(Pos.m_fPointZ * 100) % SECTOR_SIZE / fMagnification) - 1); for (vector::iterator infoItr = m_vecSafetyZone.begin(); infoItr != m_vecSafetyZone.end(); ++infoItr) { SafetyZoneInfo* lpInfo = *infoItr; if (lpInfo->m_dwSectorX != cSectorX || lpInfo->m_dwSectorY != cSectorZ) { continue; } unsigned long dwBGMColor = lpInfo->m_aryColorTable[nDestZ][nDestX] & 0x00FFFFFF; vector::iterator eventkeyItr = lpInfo->m_vecEventKey.begin(); for (vector::iterator colorkeyItr = lpInfo->m_vecBGMColorKey.begin(); colorkeyItr != lpInfo->m_vecBGMColorKey.end(); ++colorkeyItr, ++eventkeyItr) { if (dwBGMColor == *colorkeyItr) { // ¼¼ÀÌÇÁƼÁ¸À» Ç¥±âÇÏ´Â Ç÷¡±×µé (À½¾Ç Ãâ·Â ½ºÅ©¸³Æ®¸¦ ÇÔ²² ¾²¹Ç·Î...) if (SafetyZoneInfo::EK_BGM_ONCE_SAFE == *eventkeyItr || SafetyZoneInfo::EK_BGM_LOOP_SAFE == *eventkeyItr || SafetyZoneInfo::EK_NOTBGM_SAFE == *eventkeyItr || SafetyZoneInfo::EK_ESF_SAFE == *eventkeyItr || SafetyZoneInfo::EK_BGM_TURN_AMB_SAFE == *eventkeyItr) { return true; } } } } return false; }