#include "stdafx.h" #include #include #include #include #include #include #include #include #include #include #include #include "BGServerMap.h" using namespace VirtualArea; CBGServerMap::CBGServerMap(const VirtualArea::ProtoType* lpProtoType, unsigned short wMapNumber) : CVirtualArea(lpProtoType, VirtualArea::BGSERVERMAP | wMapNumber), m_MapInfo(lpProtoType->m_cMapType), m_cStatus(START_WAITING) { } CBGServerMap::~CBGServerMap(void) { } unsigned short CBGServerMap::Enter(CCharacter* lpCharacter, unsigned char cMoveType) { if (false == IsPlaying()) { return PktBase::SERVER_ERROR; } switch (cMoveType) { case TYPE_PLAYER: { return AddCharacter(lpCharacter); } case TYPE_SPECTATOR: { return AddSpectator(lpCharacter); } } return PktBase::SERVER_ERROR; } bool CBGServerMap::Leave(CCharacter* lpCharacter) { if (NULL == lpCharacter) return false; char szNation[8]; if (lpCharacter->GetRace() == CClass::HUMAN) strcpy(szNation, "HUMAN"); else strcpy(szNation, "AKHAN"); CharacterList::iterator pos = std::find(m_CharacterList.begin(), m_CharacterList.end(), lpCharacter); if (pos != m_CharacterList.end()) { --m_MapInfo.m_cCurrentCharNum[ lpCharacter->GetRace() ]; m_CharacterList.erase(pos); m_MapInfo.m_PersonalInfoMap.erase( lpCharacter->GetCID() ); // ·Î±× DETLOG5(g_Log, "Battle Server Log :: (Channel : %d, %s) - CID : 0x%08x ij¸¯ÅÍ(%s, %s)°¡ °ÔÀÓ¿¡¼­ ³ª°¡¼Ì½À´Ï´Ù.", (m_wMapIndex & ~VirtualArea::BGSERVERMAP), GetMapTypeName(), lpCharacter->GetCID(), lpCharacter->GetCharacterName(), szNation); return true; } pos = std::find(m_SpectatorList.begin(), m_SpectatorList.end(), lpCharacter); if (pos != m_SpectatorList.end()) { m_SpectatorList.erase(pos); // ·Î±× DETLOG5(g_Log, "Battle Server Log :: (Channel : %d, %s) - CID : 0x%08x ij¸¯ÅÍ(%s, %s)°¡ °ÔÀÓ¿¡¼­ ³ª°¡¼Ì½À´Ï´Ù.", (m_wMapIndex & ~VirtualArea::BGSERVERMAP), GetMapTypeName(), lpCharacter->GetCID(), lpCharacter->GetCharacterName(), szNation); return true; } return false; } unsigned short CBGServerMap::AddCharacter(CCharacter* lpCharacter) { if (NULL == lpCharacter) { return PktBase::SERVER_ERROR; } if (m_MapInfo.m_cMaxCharNumOfNation <= m_MapInfo.m_cCurrentCharNum[ lpCharacter->GetRace() ]) { return PktBGServerMoveZone::FAIL_FULL_MAP; } // ÁøÀÔ Àοø Á¦ÇÑ °É±â if (m_MapInfo.m_cCurrentCharNum[ lpCharacter->GetRace() ] >= 10) { if ( (lpCharacter->GetRace() == CClass::HUMAN && m_MapInfo.m_cCurrentCharNum[CClass::HUMAN] >= m_MapInfo.m_cCurrentCharNum[CClass::AKHAN] * 1.5) || (lpCharacter->GetRace() == CClass::AKHAN && m_MapInfo.m_cCurrentCharNum[CClass::AKHAN] >= m_MapInfo.m_cCurrentCharNum[CClass::HUMAN] * 1.5) ) { return PktBGServerMoveZone::FAIL_FIX_RATE; } } ++m_MapInfo.m_cCurrentCharNum[ lpCharacter->GetRace() ]; m_CharacterList.push_back(lpCharacter); // µé¾î¿ÔÀ»¶§ ³²Àº °æ±â½Ã°£À» ÀúÀåÇØµÐ´Ù. (³²Àº °æ±â½Ã°£¿¡ µû¸¥ Â÷µî Á¡¼ö¸¦ ÁÖ±âÀ§Çؼ­...) MapInfo::PersonalInfo personalInfo(m_MapInfo.m_cRemainPlayMin); m_MapInfo.m_PersonalInfoMap.insert( make_pair(lpCharacter->GetCID(), personalInfo) ); // ·Î±× ³²±â±â char szNation[8]; if (lpCharacter->GetRace() == CClass::HUMAN) { strcpy(szNation, "HUMAN"); } else { strcpy(szNation, "AKHAN"); } DETLOG5(g_Log, "Battle Server Log :: (Channel : %d, %s) - CID : 0x%08x ij¸¯ÅÍ(%s, %s)°¡ Player ·Î µé¾î¿Ô½À´Ï´Ù.", (m_wMapIndex & ~VirtualArea::BGSERVERMAP), GetMapTypeName(), lpCharacter->GetCID(), lpCharacter->GetCharacterName(), szNation); return PktBase::NO_SERVER_ERR; } unsigned short CBGServerMap::AddSpectator(CCharacter* lpSpectator) { if (NULL == lpSpectator) { return PktBase::SERVER_ERROR; } m_SpectatorList.push_back(lpSpectator); // ·Î±× ³²±â±â char szNation[8]; if (lpSpectator->GetRace() == CClass::HUMAN) strcpy(szNation, "HUMAN"); else strcpy(szNation, "AKHAN"); DETLOG5(g_Log, "Battle Server Log :: (Channel : %d, %s) - CID : 0x%08x ij¸¯ÅÍ(%s, %s)°¡ Spectator ·Î µé¾î¿Ô½À´Ï´Ù.", (m_wMapIndex & ~VirtualArea::BGSERVERMAP), GetMapTypeName(), lpSpectator->GetCID(), lpSpectator->GetCharacterName(), szNation); return PktBase::NO_SERVER_ERR; } bool CBGServerMap::IsPlayer(CCharacter* lpCharacter) { if (NULL == lpCharacter) return false; CharacterList::iterator pos = std::find(m_CharacterList.begin(), m_CharacterList.end(), lpCharacter); if (pos != m_CharacterList.end()) return true; return false; } bool CBGServerMap::IsSpectator(CCharacter* lpCharacter) { if (NULL == lpCharacter) return false; CharacterList::iterator pos = std::find(m_SpectatorList.begin(), m_SpectatorList.end(), lpCharacter); if (pos != m_SpectatorList.end()) return true; return false; } // ¸ðµÎ ´ë±â½Ç·Î À̵¿ bool CBGServerMap::AllRespawn() { if (0 == m_CharacterList.size() && 0 == m_SpectatorList.size()) return true; bool bResult = true; CharacterList::iterator pos = m_CharacterList.begin(); CharacterList::iterator end = m_CharacterList.end(); while (pos != end) { if (NULL == (*pos)) continue; CGameClientDispatch* lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { if (false == GameClientSendPacket::SendCharBGServerMoveZone(lpDispatch->GetSendStream(), SERVER_ID::BATTLE_SERVER, VirtualArea::TYPE_PLAYER, PktBase::NO_SERVER_ERR)) { ERRLOG2(g_Log, "CID:0x%08x ij¸¯ÅͰ¡ °¡»ó Á¸(MapIndex : %d)¿¡¼­ ³ª°¡´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", (*pos)->GetCID(), (*pos)->GetMapIndex()); bResult = false; } Position RespawnPos(VirtualArea::RespawnPos[ (*pos)->GetRace() ][ Math::Random::ComplexRandom(VirtualArea::MAX_LOBBY_RESPAWN_POS) ]); RespawnPos.m_fPointX += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; RespawnPos.m_fPointZ += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; (*pos)->SetMapIndex(0); (*pos)->GetEnchantInfo().ResetFlag(Skill::SpellID::Hide); (*pos)->MoveTo(RespawnPos, false); } else { ERRLOG2(g_Log, "CID:0x%08x ij¸¯ÅͰ¡ °¡»ó Á¸(MapIndex : %d)¿¡¼­ ³ª°¡´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", (*pos)->GetCID(), (*pos)->GetMapIndex()); bResult = false; } ++pos; } // ½ºÆåÅ×ÀÌÅÍ Ã³¸® pos = m_SpectatorList.begin(); end = m_SpectatorList.end(); while (pos != end) { if (NULL == (*pos)) continue; CGameClientDispatch* lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { if (false == GameClientSendPacket::SendCharBGServerMoveZone(lpDispatch->GetSendStream(), SERVER_ID::BATTLE_SERVER, VirtualArea::TYPE_PLAYER, PktBase::NO_SERVER_ERR)) { ERRLOG2(g_Log, "CID:0x%08x ij¸¯ÅͰ¡ °¡»ó Á¸(MapIndex : %d)¿¡¼­ ³ª°¡´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", (*pos)->GetCID(), (*pos)->GetMapIndex()); bResult = false; } Position RespawnPos(VirtualArea::RespawnPos[ (*pos)->GetRace() ][ Math::Random::ComplexRandom(VirtualArea::MAX_LOBBY_RESPAWN_POS) ]); RespawnPos.m_fPointX += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; RespawnPos.m_fPointZ += Math::Random::SimpleRandom(GetTickCount(), 20) - 10; (*pos)->SetMapIndex(0); (*pos)->GetEnchantInfo().ResetFlag(Skill::SpellID::Hide); (*pos)->MoveTo(RespawnPos, false); } else { ERRLOG2(g_Log, "CID:0x%08x ij¸¯ÅͰ¡ °¡»ó Á¸(MapIndex : %d)¿¡¼­ ³ª°¡´Âµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", (*pos)->GetCID(), (*pos)->GetMapIndex()); bResult = false; } ++pos; } // ¸®½ºÆ® Ŭ¸®¾î m_CharacterList.clear(); m_SpectatorList.clear(); return bResult; } void CBGServerMap::Process() { unsigned long dwCurrentTime = timeGetTime(); int nMin = 0, nSec = 0; if (m_dwRemainTime < dwCurrentTime) nMin = 0; else { nMin = (m_dwRemainTime - dwCurrentTime) / MILLISEC_PER_MINUTE; nSec = (m_dwRemainTime - dwCurrentTime) % MILLISEC_PER_MINUTE; if (nSec > 0) ++nMin; } switch (m_cStatus) { // ¾ÆÁ÷ Start µÇÁö ¾ÊÀº »óŶó¸é ¾Æ¹«°Íµµ ÇÏÁö ¾Ê´Â´Ù. case START_WAITING: return; case GAME_PLAYING: { // 1ºÐ¿¡ Çѹø¾¿ ³²Àº ½Ã°£À» º¸³»ÁØ´Ù. if (nMin < m_MapInfo.m_cRemainPlayMin) { // ³²Àº ½Ã°£ °»½Å m_MapInfo.m_cRemainPlayMin = static_cast(nMin); // ¹æ Á¤º¸ Àü¼Û SendMapInfo(); } // Á¦ÇÑ ½Ã°£ÀÌ ´Ù µÇ¾ú´Ù¸é, if (0 == m_MapInfo.m_cRemainPlayMin) { // ½ÂÆÐ¸¦ üũ ¹× °á°ú ÀúÀå m_ResultInfo.m_cWinRace = RuleCheck(true); std::copy(&m_MapInfo.m_wScore[0], &m_MapInfo.m_wScore[CClass::MAX_RACE], &m_ResultInfo.m_wScore[0]); // °á°ú Àü¼Û // À̱ä Á¾Á·, ȤÀº ¹«½ÂºÎ ij¸¯Å͵鿡°Ô º¸»óÀ» ÁØ´Ù. SendResultInfo(); } else { m_ResultInfo.m_cWinRace = RuleCheck(); // ÇÑ Á¾Á·ÀÌ ¸ñÇ¥ Á¡¼ö¸¦ ´Þ¼ºÇßÀ» °æ¿ì if (CClass::MAX_RACE != m_ResultInfo.m_cWinRace) { // °á°ú Á¡¼ö ÀúÀå std::copy(&m_MapInfo.m_wScore[0], &m_MapInfo.m_wScore[CClass::MAX_RACE], &m_ResultInfo.m_wScore[0]); // °á°ú Àü¼Û // À̱ä Á¾Á·ÀÇ Ä³¸¯Å͵鿡°Ô º¸»óÀ» ÁØ´Ù. SendResultInfo(); } } break; } case GAME_RESTING: { // ³²Àº ½Ã°£ °»½Å m_MapInfo.m_cRemainRestMin = static_cast(nMin); // ½¬´Â ½Ã°£ÀÌ ´Ù µÇ¾ú´Ù¸é, if (0 == m_MapInfo.m_cRemainRestMin) { GameStart(); } break; } case MOVEZONE_WAITING: { // Á¸À̵¿ ½Ãų ½Ã°£ÀÌ ´Ù µÇ¾ú´Ù¸é, if (m_dwRemainTime <= timeGetTime()) { SetStatus(GAME_RESTING); m_dwRemainTime = timeGetTime() + m_MapInfo.m_cRestMin * MILLISEC_PER_MINUTE; // ij¸¯Å͵éÀ» Á¸ À̵¿ ½ÃŲ´Ù. (·Îºñ·Î ¸®½ºÆù) AllRespawn(); // ItemÀ» ¸ðµÎ Áö¿î´Ù. DeleteAllItem(); // ¹æ Á¤º¸ ÃʱâÈ­ m_MapInfo.Initialize(); } break; } } } bool CBGServerMap::GameStart() // °ÔÀÓÀ» ½ÃÀÛÇÑ´Ù. { m_dwRemainTime = timeGetTime() + m_MapInfo.m_cLimitMin * MILLISEC_PER_MINUTE; InitializeGameObject(); SetStatus(GAME_PLAYING); return true; } bool CBGServerMap::InitializeGameObject() { m_CharacterList.clear(); m_SpectatorList.clear(); m_MapInfo.Initialize(); m_ResultInfo.Initialize(); if (STATUE == m_MapInfo.m_cMapType && NULL != GetMonsterManager()) { // ¸ðµç ¼®»óÀ» ´Ù Á×À̰í, ¾Æ¹«°Íµµ ¼ÒȯÇÏÁö ¾Ê´Â´Ù. CVirtualMonsterMgr::MonsterMap::iterator pos = m_pVirtualMonsterMgr->GetMonsterMap().begin(); CVirtualMonsterMgr::MonsterMap::iterator end = m_pVirtualMonsterMgr->GetMonsterMap().end(); while (pos != end) { CMonster* lpMonster = pos->second; if (NULL == lpMonster) continue; CStatue* lpStatue = lpMonster->DowncastToStatue(); if (NULL != lpStatue) { lpStatue->Rest(); } ++pos; } // ÈÞ¸Õ, Á߸³, ¾ÆÄ­ ¼®»óÀ» ¼ø¼­´ë·Î ¼ÒȯÇÑ´Ù. enum { HUMAN_STATUE = 0, NUETRALITY_STATUE1 = 1, AKHAN_STATUE = 2, NUETRALITY_STATUE2 = 3, NUETRALITY_STATUE3 = 4, NONE = 100 }; DWORD dwKind, dwOldKind = NONE; pos = m_pVirtualMonsterMgr->GetMonsterMap().begin(); end = m_pVirtualMonsterMgr->GetMonsterMap().end(); while (pos != end) { CMonster* lpMonster = pos->second; if (NULL == lpMonster) continue; CStatue* lpStatue = lpMonster->DowncastToStatue(); if (NULL != lpStatue) { // ¼®»ó ÃʱâÈ­ ½Ã۱â // !!ÁÖÀÇ!! ½ºÅ©¸³Æ®¿Í °ü·ÃÀÌ ÀÖ´Ù. ¼ø¼­ÁÖÀÇ // Á¾·ù¸¦ ¾ò¾î¿Â´Ù. (HUMAN_STATUE = 0, NUETRALITY_STATUE1 = 1, AKHAN_STATUE = 2, NUETRALITY_STATUE2 = 3, NUETRALITY_STATUE3 = 4) dwKind = (lpStatue->GetCID() & ~(Creature::MONSTER_BIT | Creature::MONSTER_KIND_BIT)) >> 16; if (dwOldKind != dwKind) { switch (dwKind) { case HUMAN_STATUE: lpStatue = lpStatue->GetLinkStatue(MonsterInfo::BG_STATUE_HUMAN_COMPLETE1); lpStatue->InitMonster(lpStatue->GetOriginalPos()); break; case NUETRALITY_STATUE1: case NUETRALITY_STATUE2: case NUETRALITY_STATUE3: lpStatue = lpStatue->GetLinkStatue(MonsterInfo::BG_STATUE_NEUTRALITY1); lpStatue->InitMonster(lpStatue->GetOriginalPos()); break; case AKHAN_STATUE: lpStatue = lpStatue->GetLinkStatue(MonsterInfo::BG_STATUE_AKHAN_COMPLETE1); lpStatue->InitMonster(lpStatue->GetOriginalPos()); break; } dwOldKind = dwKind; } } ++pos; } // ¼®»ó Á¡·ÉÀüÀ϶§ÀÇ Ãʱâ Á¡¼ö °è»ê CalculateScore(); // ·Î±× ³²±â±â DETLOG4(g_Log, "Battle Server Log :: (Channel : %d, %s) - ¼®»óÀüÀ» ÃʱâÈ­ ÇÕ´Ï´Ù. (ÇöÀç Score - HM: %d AK: %d)", (m_wMapIndex & ~VirtualArea::BGSERVERMAP), GetMapTypeName(), m_MapInfo.m_wScore[CClass::HUMAN], m_MapInfo.m_wScore[CClass::AKHAN]); } return true; } unsigned char CBGServerMap::RuleCheck(bool bTimeout) // ·êÀ» Ã¼Å©ÇØ¼­ À̱äÁ¾Á·À» ¸®ÅÏ { unsigned char cWinNation = CClass::MAX_RACE; // ½Ã°£ÀÌ ´Ù Áö³µ´Ù¸é, ȤÀº ¿î¿µÀÚ ¸í·ÉÀ¸·Î °ÔÀÓÀ» ÁßÁö ½Ãų°æ¿ì if (true == bTimeout) { if (m_MapInfo.m_wScore[CClass::HUMAN] > m_MapInfo.m_wScore[CClass::AKHAN]) { cWinNation = CClass::HUMAN; } else if (m_MapInfo.m_wScore[CClass::HUMAN] < m_MapInfo.m_wScore[CClass::AKHAN]) { cWinNation = CClass::AKHAN; } else { // À̰æ¿ìÀÇ CClass::MAX_RACE Àº ¹«½ÂºÎÀÌ´Ù. } SetStatus(MOVEZONE_WAITING); m_dwRemainTime = timeGetTime() + MOVEZONE_WAIT_TIME; } else { // ¸ñÇ¥ Á¡¼ö¿¡ µµ´ÞÇߴ°¡ üũ if (m_MapInfo.m_wScore[CClass::HUMAN] >= m_MapInfo.m_wTargetScore) { cWinNation = CClass::HUMAN; SetStatus(MOVEZONE_WAITING); m_dwRemainTime = timeGetTime() + MOVEZONE_WAIT_TIME; } else if (m_MapInfo.m_wScore[CClass::AKHAN] >= m_MapInfo.m_wTargetScore) { cWinNation = CClass::AKHAN; SetStatus(MOVEZONE_WAITING); m_dwRemainTime = timeGetTime() + MOVEZONE_WAIT_TIME; } // À̰æ¿ìÀÇ CClass::MAX_RACE Àº °ÔÀÓÀÌ ³¡³ªÁö ¾ÊÀº »óÅÂÀÌ´Ù. } return cWinNation; } void CBGServerMap::AwardToWinner() { unsigned short wAwardBase, wRealPlayMin; unsigned short wPlayMin = m_MapInfo.m_cLimitMin - m_MapInfo.m_cRemainPlayMin; if (0 == wPlayMin) wPlayMin = 1; CharacterList winnerList; CharacterList::iterator pos; CharacterList::iterator end; if (CClass::MAX_RACE == m_ResultInfo.m_cWinRace) { wAwardBase = m_MapInfo.m_cLimitMin * MILEAGE_PER_MINUTE_FOR_DRAW; pos = m_CharacterList.begin(); end = m_CharacterList.end(); } else { wAwardBase = m_MapInfo.m_cLimitMin * MILEAGE_PER_MINUTE_FOR_WIN; FindWinner(winnerList); pos = winnerList.begin(); end = winnerList.end(); } while (pos != end) { if (NULL != (*pos)) { MapInfo::PersonalInfoMap::iterator which = m_MapInfo.m_PersonalInfoMap.find( (*pos)->GetCID() ); if (which != m_MapInfo.m_PersonalInfoMap.end()) { wRealPlayMin = which->second.m_cEnteringMin - m_MapInfo.m_cRemainPlayMin; unsigned short wAward = wAwardBase * wRealPlayMin / wPlayMin; (*pos)->SetMileage((*pos)->GetMileage() + wAward); CGameClientDispatch* lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharFameInfo(lpDispatch->GetSendStream(), (*pos), "", "", 0, 0, PktFIAck::FAME_INFO, PktBase::NO_SERVER_ERR); } } } ++pos; } } void CBGServerMap::KillChar(unsigned long dwDeadCID, CCharacter* lpOffencer) { if (NULL == lpOffencer) return; AddScore(lpOffencer->GetRace(), FRAG_SCORE); // Kill Á¤º¸ ¾÷µ¥ÀÌÆ® UpdateKillInfo(dwDeadCID, lpOffencer->GetCID()); // ¹æ Á¤º¸ Àü¼Û SendMapInfo(); } void CBGServerMap::UpdateKillInfo(unsigned long dwDeadCID, unsigned long dwKillerCID) { MapInfo::PersonalInfoMap::iterator pos = m_MapInfo.m_PersonalInfoMap.find( dwDeadCID ); if (pos != m_MapInfo.m_PersonalInfoMap.end()) ++pos->second.m_cKilled; pos = m_MapInfo.m_PersonalInfoMap.find( dwKillerCID ); if (pos != m_MapInfo.m_PersonalInfoMap.end()) ++pos->second.m_cKill; } void CBGServerMap::AddScore(unsigned char cNation, short wScore) { if (cNation >= CClass::MAX_CLASS) return; m_MapInfo.m_wScore[cNation] += wScore; } void CBGServerMap::CalculateScore() // ¼®»ó Á¡·ÉÀüÀ϶§ Á¡¼ö °è»ê { if (STATUE == m_MapInfo.m_cMapType && NULL != GetMonsterManager()) { std::fill_n(m_MapInfo.m_wScore, int(CClass::MAX_RACE), 0); CVirtualMonsterMgr::MonsterMap::iterator pos = m_pVirtualMonsterMgr->GetMonsterMap().begin(); CVirtualMonsterMgr::MonsterMap::iterator end = m_pVirtualMonsterMgr->GetMonsterMap().end(); while (pos != end) { CMonster* lpMonster = pos->second; if (NULL != lpMonster && lpMonster->GetCurrentState() != STATE_ID_DIE) { switch (lpMonster->GetCID() & Creature::MONSTER_KIND_BIT) { case MonsterInfo::BG_STATUE_HUMAN_LOADING1: { AddScore(CClass::HUMAN, FRIENDLY_LOADING_STATUE_SCORE); break; } case MonsterInfo::BG_STATUE_HUMAN_COMPLETE1: { AddScore(CClass::HUMAN, FRIENDLY_STATUE_SCORE); break; } case MonsterInfo::BG_STATUE_AKHAN_LOADING1: { AddScore(CClass::AKHAN, FRIENDLY_LOADING_STATUE_SCORE); break; } case MonsterInfo::BG_STATUE_AKHAN_COMPLETE1: { AddScore(CClass::AKHAN, FRIENDLY_STATUE_SCORE); break; } case MonsterInfo::BG_STATUE_NEUTRALITY1: { AddScore(CClass::AKHAN, NEUTRALITY_STATUE_SCORE); AddScore(CClass::HUMAN, NEUTRALITY_STATUE_SCORE); break; } } } ++pos; } } } // Àڱ⠹æÀÇ Á¤º¸¸¦ º¸³»ÁÖ´Â ÇÔ¼ö bool CBGServerMap::SendMapInfo() { if (0 == m_CharacterList.size() && 0 == m_SpectatorList.size()) return true; const int MAX_BUFFER = sizeof(PktBGServerMapList) + sizeof(BGServerMapInfoNode); char szBuffer[MAX_BUFFER]; PktBGServerMapList* lpPktBGSMLAck = reinterpret_cast(szBuffer); BGServerMapInfoNode* lpMapInfoNode = reinterpret_cast(lpPktBGSMLAck + 1); lpPktBGSMLAck->m_bAll = false; lpPktBGSMLAck->m_cMapInfoNodeNum = 1; lpMapInfoNode->m_bPlaying = IsPlaying(); lpMapInfoNode->m_cMapType = m_MapInfo.m_cMapType; lpMapInfoNode->m_cMaxCharNumOfNation = m_MapInfo.m_cMaxCharNumOfNation; lpMapInfoNode->m_wTargetScore = m_MapInfo.m_wTargetScore; //lpMapInfoNode->m_cRemainMin = (IsPlaying() == true) ? m_MapInfo.m_cRemainPlayMin : m_MapInfo.m_cRemainRestMin; lpMapInfoNode->m_cRemainMin = (IsPlaying() == true) ? m_MapInfo.m_cRemainPlayMin : 0; lpMapInfoNode->m_cCurrentCharNum[CClass::HUMAN] = m_MapInfo.m_cCurrentCharNum[CClass::HUMAN]; lpMapInfoNode->m_cCurrentCharNum[CClass::AKHAN] = m_MapInfo.m_cCurrentCharNum[CClass::AKHAN]; lpMapInfoNode->m_wScore[CClass::HUMAN] = m_MapInfo.m_wScore[CClass::HUMAN]; lpMapInfoNode->m_wScore[CClass::AKHAN] = m_MapInfo.m_wScore[CClass::AKHAN]; // ij¸¯ÅÍ Ã³¸® CharacterList::iterator pos = m_CharacterList.begin(); CharacterList::iterator end = m_CharacterList.end(); CGameClientDispatch* lpDispatch = NULL; while (pos != end) { if (NULL == (*pos)) continue; lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { CSendStream& SendStream = lpDispatch->GetSendStream(); SendStream.WrapCompress(szBuffer, sizeof(PktBGServerMapList) + sizeof(BGServerMapInfoNode), CmdBGServerMapList, 0, 0); } ++pos; } // ½ºÆåÅ×ÀÌÅÍ Ã³¸® pos = m_SpectatorList.begin(); end = m_SpectatorList.end(); while (pos != end) { if (NULL == (*pos)) continue; lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { CSendStream& SendStream = lpDispatch->GetSendStream(); SendStream.WrapCompress(szBuffer, sizeof(PktBGServerMapList) + sizeof(BGServerMapInfoNode), CmdBGServerMapList, 0, 0); } ++pos; } return true; } bool CBGServerMap::SendResultInfo() { const int MAX_BUFFER = sizeof(PktBGServerResultList) + sizeof(BGServerResultInfoNode); char szBuffer[MAX_BUFFER]; PktBGServerResultList* lpPktBGSRLAck = reinterpret_cast(szBuffer); BGServerResultInfoNode* lpResultInfoNode = reinterpret_cast(lpPktBGSRLAck + 1); lpPktBGSRLAck->m_bAll = false; lpPktBGSRLAck->m_cResultInfoNodeNum = 1; lpResultInfoNode->m_cWinRace = m_ResultInfo.m_cWinRace; lpResultInfoNode->m_wScore[CClass::HUMAN] = m_ResultInfo.m_wScore[CClass::HUMAN]; lpResultInfoNode->m_wScore[CClass::AKHAN] = m_ResultInfo.m_wScore[CClass::AKHAN]; // ij¸¯ÅÍ(Ç÷¹À̾î) ó¸® CharacterList::iterator pos = m_CharacterList.begin(); CharacterList::iterator end = m_CharacterList.end(); CGameClientDispatch* lpDispatch = NULL; unsigned short wAwardBase; if (CClass::MAX_RACE == m_ResultInfo.m_cWinRace) wAwardBase = m_MapInfo.m_cLimitMin * MILEAGE_PER_MINUTE_FOR_DRAW; else wAwardBase = m_MapInfo.m_cLimitMin * MILEAGE_PER_MINUTE_FOR_WIN; unsigned short wPlayMin = m_MapInfo.m_cLimitMin - m_MapInfo.m_cRemainPlayMin; if (0 == wPlayMin) wPlayMin = 1; while (pos != end) { if (NULL == (*pos)) continue; lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { MapInfo::PersonalInfoMap::iterator which = m_MapInfo.m_PersonalInfoMap.find( (*pos)->GetCID() ); if (which != m_MapInfo.m_PersonalInfoMap.end()) { lpResultInfoNode->m_cPlayMin = which->second.m_cEnteringMin - m_MapInfo.m_cRemainPlayMin; lpResultInfoNode->m_cKill = which->second.m_cKill; lpResultInfoNode->m_cKilled = which->second.m_cKilled; RULLOG3(g_Log, "CID:0x%08x À̺¥Æ®·Î±× - %s, Kill : %d, Die : %d", (*pos)->GetCharacterName(), which->second.m_cKill, which->second.m_cKilled); // ¹«½ÂºÎ³ª ½Â¸®ÆÀÀÇ Ä³¸¯ÅÍÀÎ °æ¿ì ¾òÀº ¸¶Àϸ®Áö¸¦ º¸³»ÁØ´Ù. if (CClass::MAX_RACE == m_ResultInfo.m_cWinRace || (*pos)->GetRace() == m_ResultInfo.m_cWinRace) { unsigned short wAward = wAwardBase * lpResultInfoNode->m_cPlayMin / wPlayMin; lpResultInfoNode->m_wAward = wAward; (*pos)->SetMileage((*pos)->GetMileage() + wAward); CGameClientDispatch* lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharFameInfo(lpDispatch->GetSendStream(), (*pos), "", "", 0, 0, PktFIAck::FAME_INFO, PktBase::NO_SERVER_ERR); } } else lpResultInfoNode->m_wAward = 0; CSendStream& SendStream = lpDispatch->GetSendStream(); SendStream.WrapCompress(szBuffer, sizeof(PktBGServerResultList) + sizeof(BGServerResultInfoNode), CmdBGServerResultList, 0, 0); } } ++pos; } // ½ºÆåÅ×ÀÌÅÍ Ã³¸® lpResultInfoNode->m_cPlayMin = 0; lpResultInfoNode->m_wAward = 0; lpResultInfoNode->m_cKill = 0; lpResultInfoNode->m_cKilled = 0; pos = m_SpectatorList.begin(); end = m_SpectatorList.end(); while (pos != end) { if (NULL == (*pos)) continue; lpDispatch = (*pos)->GetDispatcher(); if (NULL != lpDispatch) { CSendStream& SendStream = lpDispatch->GetSendStream(); SendStream.WrapCompress(szBuffer, sizeof(PktBGServerResultList) + sizeof(BGServerResultInfoNode), CmdBGServerResultList, 0, 0); } ++pos; } return true; } void CBGServerMap::FindWinner(CharacterList& winnerList) { CharacterList::iterator pos = m_CharacterList.begin(); CharacterList::iterator end = m_CharacterList.end(); while (pos != end) { if (NULL != (*pos)) { if (m_ResultInfo.m_cWinRace == (*pos)->GetRace()) { winnerList.push_back((*pos)); } } ++pos; } } void CBGServerMap::DeleteAllItem() { if (NULL == m_CellData) { return; } CCell* lpCellPastEnd = m_CellData + GetWidth() * GetHeight(); for (CCell* lpCell = m_CellData; lpCell != lpCellPastEnd; ++lpCell) { lpCell->DeleteAllItem(); } } void CBGServerMap::ResetEnteringMin(unsigned char cMin) { if (m_MapInfo.m_PersonalInfoMap.empty()) return; MapInfo::PersonalInfoMap::iterator pos = m_MapInfo.m_PersonalInfoMap.begin(); MapInfo::PersonalInfoMap::iterator end = m_MapInfo.m_PersonalInfoMap.end(); while (pos != end) { pos->second.m_cEnteringMin = cMin; ++pos; } }