bool ZBrain::FindTarget() { MUID uidTarget = MUID(0,0); float fDist = FLT_MAX; for ( ZCharacterManager::iterator itor = ZGetCharacterManager()->begin(); itor != ZGetCharacterManager()->end(); ++itor) { // 죽은 놈은 관심없다. ZCharacter* pCharacter = (*itor).second; if ( pCharacter->IsDie()) continue; // 제외 목록에 들어간 캐릭터는 건너뜀 if ( ZGetGame()->IsExceptedFromNpcTargetting( pCharacter)) continue; // 거리를 구한다. float dist = MagnitudeSq( pCharacter->GetPosition() - m_pBody->GetPosition()); // 더 가까운 놈이면 이놈을 타겟으로 정한다. if ( dist < fDist) { fDist = dist; uidTarget = pCharacter->GetUID(); } } m_uidTarget = uidTarget; if ( uidTarget == MUID(0,0)) return false; return true; }
void ZRoomListBox::RequestSelStageJoin() { MUID uidChar = ZGetGameClient()->GetPlayerUID(); if (GetSelRoomUID() != MUID(0,0)) { if ( (ZGetMyInfo()->IsAdminGrade() == false) && (m_pMapInfo[m_Selection].bPrivate) ) { char szStageName[SMI_ROOMNAME_LENGTH] = ""; MUID uidStage = MUID(0,0); const sMapInfo* pSelRoomInfo = GetSelMapInfo(); if (pSelRoomInfo != NULL) { strcpy_safe(szStageName, pSelRoomInfo->room_name); uidStage = pSelRoomInfo->uidStage; } SetPrivateStageUID(uidStage); // 비밀방 ZApplication::GetGameInterface()->ShowPrivateStageJoinFrame(szStageName); } else { ZPostRequestStageJoin(uidChar, GetSelRoomUID()); // 공개방 ZApplication::GetGameInterface()->EnableLobbyInterface(false); } } }
const MUID MMatchRuleAssassinate::ChooseCommander(int nTeam) { MMatchStage* pStage = GetStage(); if (pStage == NULL) return MUID(0,0); int nRedAliveCount, nBlueAliveCount, nChooseTeamCount; if (GetAliveCount(&nRedAliveCount, &nBlueAliveCount) == false) return MUID(0,0); if (nTeam == MMT_RED) { if (nRedAliveCount <= 0) return MUID(0,0); nChooseTeamCount = nRedAliveCount; } if (nTeam == MMT_BLUE) { if (nBlueAliveCount <= 0) return MUID(0,0); nChooseTeamCount = nBlueAliveCount; } if( m_bIsAdminCommander == true ) { for(MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++) { MMatchObject* pObj = (MMatchObject*)(*itor).second; if (pObj->GetEnterBattle() == false) continue; // 배틀참가하고 있는 플레이어만 체크 if (pObj->GetTeam() == nTeam && pObj->GetAccountInfo()->m_nUGrade == MMUG_ADMIN) { return pObj->GetUID(); } } } MTime time; int nChoose = time.MakeNumber(1, nChooseTeamCount); int nCount = 0; for(MUIDRefCache::iterator itor=pStage->GetObjBegin(); itor!=pStage->GetObjEnd(); itor++) { MMatchObject* pObj = (MMatchObject*)(*itor).second; if (pObj->GetEnterBattle() == false) continue; // 배틀참가하고 있는 플레이어만 체크 if (pObj->GetTeam() == nTeam) { nCount++; if (nCount == nChoose) { return pObj->GetUID(); } } } return MUID(0,0); }
MCommObject::MCommObject(MCommandCommunicator* pCommunicator) { m_uid = MUID(0,0); m_pDirectConnection = NULL; m_dwUserContext = 0; m_szIP[0] = 0; m_nPort = 0; m_bAllowed = true; m_pCommandBuilder = new MCommandBuilder(MUID(0, 0), pCommunicator->GetUID(), pCommunicator->GetCommandManager()); }
MUID MMatchPeerInfoList::FindUID(DWORD dwIP, int nPort) { MUID uidRet = MUID(0,0); Lock(); map<MUID, MMatchPeerInfo*>::iterator itor = m_IPnPortMap.find(MUID(dwIP, (unsigned long)nPort)); if (itor != m_IPnPortMap.end()) { MMatchPeerInfo* pPeerInfo = (*itor).second; uidRet = pPeerInfo->uidChar; } Unlock(); return uidRet; }
MUIDRANGE MUIDRefMap::GetReservedCount(void) { MUIDRANGE r; r.Start = MUID(0, 2); r.End = m_CurrentMUID; return r; }
void ZBirdDummyClient::OnStageLeave(const MUID& uidChar, const MUID& uidStage) { if (uidChar == GetPlayerUID()) { m_uidStage = MUID(0,0); } }
void MMatchNPCManager::RemovePlayerControl(const MUID& uidPlayer) { // Create 호출 전에.. 실행될 수도 있다. - By 홍기주 2009.08.17 // 더 깔끔한 방법을 강구해보자! - 일단은 이렇게 조치함 if( m_pPlayerManager == NULL ) return; MQuestPlayerInfo* pDelPlayerInfo = m_pPlayerManager->GetPlayerInfo(uidPlayer); if (pDelPlayerInfo) { pDelPlayerInfo->bEnableNPCControl = false; while (!pDelPlayerInfo->NPCObjects.empty()) { MMatchNPCObjectMap::iterator itorNPC = pDelPlayerInfo->NPCObjects.begin(); MMatchNPCObject* pNPCObject = (*itorNPC).second; MUID uidNPC = pNPCObject->GetUID(); // 여기서 뻑났음 - bird MUID uidController = MUID(0,0); if (FindSuitableController(uidController, pDelPlayerInfo)) { // 지울 플레이어에게 할당된 NPC를 다른 플레이어에게 옮겨준다. AssignControl(uidNPC, uidController); } else { // 적당한 사람이 없으면 재할당 포기 break; } } pDelPlayerInfo->bEnableNPCControl = true; } }
bool MMatchNPCManager::FindSuitableController(MUID& out, MQuestPlayerInfo* pSender) { int nScore = 999999; MUID uidChar = MUID(0,0); bool bExist = false; // Create 호출 전에.. 실행될 수도 있다. - By 홍기주 2009.08.17 // 더 깔끔한 방법을 강구해보자! - 일단은 이렇게 조치함 if( m_pPlayerManager == NULL ) return false; for (MQuestPlayerManager::iterator itor = m_pPlayerManager->begin(); itor != m_pPlayerManager->end(); ++itor) { MQuestPlayerInfo* pControllerInfo = (*itor).second; if ((pSender != NULL) && (pControllerInfo == pSender)) continue; if (pControllerInfo->bEnableNPCControl == false) continue; if (pControllerInfo->bMovedtoNewSector == true) continue; int nControllerScore = pControllerInfo->GetNPCControlScore(); if (nControllerScore < nScore) { bExist = true; nScore = nControllerScore; uidChar = (*itor).first; } } if (bExist) { out = uidChar; return true; } return false; }
bool MMatchPeerInfoList::Delete(MMatchPeerInfo* pPeerInfo) { bool ret = false; Lock(); iterator itor = find(pPeerInfo->uidChar); if (itor != end()) { erase(itor); map<MUID, MMatchPeerInfo*>::iterator itorIPPortNode = m_IPnPortMap.find(MUID(pPeerInfo->dwIP, (unsigned long)pPeerInfo->nPort)); if (itorIPPortNode != m_IPnPortMap.end()) { m_IPnPortMap.erase(itorIPPortNode); } delete pPeerInfo; pPeerInfo = NULL; ret = true; } Unlock(); return ret; }
void ZGameClient::OnClanAnswerJoinAgreement(const MUID& uidClanAdmin, const char* szJoiner, const bool bAnswer) { if (!IsWaitingClanJoiningAgree()) return; if (ZGetGameClient()->GetPlayerUID() != uidClanAdmin) return; if (bAnswer) { if (IsUpperClanGrade(ZGetMyInfo()->GetClanGrade(), MCG_ADMIN)) { char szClanName[256]; sprintf(szClanName, ZGetMyInfo()->GetClanName()); ZPostRequestAgreedJoinClan(uidClanAdmin, szClanName, (char*)szJoiner); } } else { // 동의창 지워줘야 한다. ShowClanJoinerAgreeWaitFrame(false); m_uidRequestPlayer = MUID(0,0); ZApplication::GetGameInterface()->ShowMessage( MSG_CLAN_JOINER_AGREEMENT_REJECT ); } }
void ZActor::CheckDead(float fDelta) { if (!CheckFlag(AF_MY_CONTROL)) return; if (!CheckFlag(AF_DEAD)) { if(m_pModule_HPAP->GetHP()<=0) { SetDeadTime(ZGetGame()->GetTime()); m_Animation.Input(ZA_EVENT_DEATH); SetFlag(AF_DEAD, true); MUID uidKiller = this->GetLastAttacker(); ZPostQuestPeerNPCDead(uidKiller, GetUID()); m_TaskManager.Clear(); } } else { if (!CheckFlag(AF_REQUESTED_DEAD)) { if (ZGetGame()->GetTime()-GetDeadTime() > GetNPCInfo()->fDyingTime) { MUID uidAttacker = GetLastAttacker(); if (uidAttacker == MUID(0, 0)) { uidAttacker = ZGetGameClient()->GetPlayerUID(); } ZPostQuestRequestNPCDead(uidAttacker, GetUID(), GetPosition()); SetFlag(AF_REQUESTED_DEAD, true); } } } }
bool ZObserver::OnKeyEvent(bool bCtrl, char nKey) { int nIndex = 0; if (m_QuickTarget.ConvertKeyToIndex(nKey, &nIndex) == false) return false; if (bCtrl) { m_QuickTarget.StoreTarget(nIndex, GetTargetCharacter()->GetUID()); } else { MUID uidTarget = m_QuickTarget.GetTarget(nIndex); // Å°ÅÁöÁ¤ Ư¼öÅ° »ç¿ë üũ if ((uidTarget == MUID(0,0)) && (nKey == OBSERVER_QUICK_TAGGER_TARGET_KEY)) { for (ZCharacterManager::iterator itor = g_pGame->m_CharacterManager.begin(); itor != g_pGame->m_CharacterManager.end(); ++itor) { ZCharacter* pChar = (*itor).second; if (pChar->IsTagger()) { uidTarget = pChar->GetUID(); break; } } } ZCharacter* pCharacter = g_pGame->m_CharacterManager.Find(uidTarget); if (pCharacter && pCharacter->IsDie() == false) { SetTarget(uidTarget); } } return true; }
MCommand* MMatchServer::CreateCmdMatchResponseLoginFailed(const MUID& uidComm, const int nResult) { MCommand* pCmd = CreateCommand(MC_MATCH_RESPONSE_LOGIN, uidComm); pCmd->AddParameter(new MCommandParameterInt(nResult)); pCmd->AddParameter(new MCommandParameterString(MGetServerConfig()->GetServerName())); pCmd->AddParameter(new MCommandParameterChar((char)MGetServerConfig()->GetServerMode())); pCmd->AddParameter(new MCommandParameterString("Ana")); pCmd->AddParameter(new MCommandParameterUChar((unsigned char)MMUG_FREE)); pCmd->AddParameter(new MCommandParameterInt((int)MMPG_FREE)); pCmd->AddParameter(new MCommandParameterInt(0)); pCmd->AddParameter(new MCommandParameterUID(MUID(0,0))); pCmd->AddParameter(new MCommandParameterBool((bool)MGetServerConfig()->IsEnabledSurvivalMode())); pCmd->AddParameter(new MCommandParameterBool((bool)MGetServerConfig()->IsEnabledDuelTournament())); // pCmd->AddParameter(new MCommandParameterString("A")); // unsigned char tmp1 = 'A'; // void* pBlob1 = MMakeBlobArray(sizeof(unsigned char), sizeof(unsigned char)); // unsigned char* pCmdBlock1 = (unsigned char*)MGetBlobArrayElement(pBlob1, 0); // CopyMemory(pCmdBlock1, &tmp1, sizeof(unsigned char)); // pCmd->AddParameter(new MCommandParameterBlob(pBlob1, MGetBlobArraySize(pBlob1))); // MEraseBlobArray(pBlob1); unsigned char tmp = 0; void* pBlob = MMakeBlobArray(sizeof(unsigned char), sizeof(unsigned char)); unsigned char* pCmdBlock = (unsigned char*)MGetBlobArrayElement(pBlob, 0); CopyMemory(pCmdBlock, &tmp, sizeof(unsigned char)); pCmd->AddParameter(new MCommandParameterBlob(pBlob, MGetBlobArraySize(pBlob))); MEraseBlobArray(pBlob); return pCmd; }
void ZEffectBillboardTexAniList::Add(rvector &pos, rvector& vel,int frame,float fAddTime,float fStartSize,float fEndSize,float fLifeTime, ZCharacter* pChar,RMeshPartsPosInfoType partstype) { ZEFFECTBILLBOARDTEXANIITEM *pNewItem = new ZEFFECTBILLBOARDTEXANIITEM; push_back(pNewItem); pNewItem->fElapsedTime=0; pNewItem->velocity = vel; pNewItem->normal=-RCameraDirection; pNewItem->up=rvector(0,0,1); pNewItem->accel = rvector(0,0,0); pNewItem->position=pos; pNewItem->fStartSize=fStartSize; pNewItem->fEndSize=fEndSize; pNewItem->fOpacity=1.f; pNewItem->dwColor = 0xffffff; pNewItem->fAddTime = fAddTime; if(fLifeTime==-1) pNewItem->fLifeTime = m_fLifeTime; else pNewItem->fLifeTime = fLifeTime; pNewItem->frame = frame; if(pChar) pNewItem->CharUID = pChar->GetUID(); else pNewItem->CharUID = MUID(0,0); pNewItem->partstype = partstype; }
void MMatchServer::OnAdminRequestKickPlayer(const MUID& uidAdmin, const char* szPlayer) { MMatchObject* pObj = GetObject(uidAdmin); if (pObj == NULL) return; if (!IsAdminGrade(pObj)) return; if ((strlen(szPlayer)) < 2) return; int nRet = MOK; MMatchObject* pTargetObj = GetPlayerByName(szPlayer); if (pTargetObj != NULL) { #ifdef LOCALE_KOREA pTargetObj->DisconnectHacker( MMHT_COMMAND_BLOCK_BY_ADMIN ); #else // Notify Message 필요 -> 관리자 전용 - 해결(특별한 메세지 필요 없음) Disconnect(pTargetObj->GetUID()); #endif } else { nRet = MERR_ADMIN_NO_TARGET; } MCommand* pNew = CreateCommand(MC_ADMIN_RESPONSE_KICK_PLAYER, MUID(0,0)); pNew->AddParameter(new MCmdParamInt(nRet)); RouteToListener(pObj, pNew); }
void MMatchServer::OnAsyncInsertEvent( MAsyncJob* pJobResult ) { if( 0 == pJobResult ) return; MAsyncDBJob_EventLog* pEventJob = reinterpret_cast< MAsyncDBJob_EventLog* >( pJobResult ); if( pEventJob->GetAnnounce().empty() ) return; if( MASYNC_RESULT_SUCCEED == pJobResult->GetResult() ) { MCommand* pCmd; AsyncEventObjVec::const_iterator it, end; const AsyncEventObjVec& EventObjList = pEventJob->GetEventObjList(); end = EventObjList.end(); for( it = EventObjList.begin(); it != end; ++it ) { if( MUID(0, 0) != it->uidUser ) { pCmd = CreateCommand( MC_MATCH_ANNOUNCE, it->uidUser ); if( 0 != pCmd ) { pCmd->AddParameter( new MCmdParamUInt(0) ); pCmd->AddParameter( new MCmdParamStr(pEventJob->GetAnnounce().c_str()) ); Post( pCmd ); } } } } }
MCommand* MMatchObjectCacheBuilder::GetResultCmd(MATCHCACHEMODE nMode, MCommandCommunicator* pCmdComm) { MCommand* pCmd = pCmdComm->CreateCommand(MC_MATCH_OBJECT_CACHE, MUID(0,0)); pCmd->AddParameter(new MCmdParamUChar(nMode)); int nCount = (int)m_ObjectCacheList.size(); void* pCacheArray = MMakeBlobArray(sizeof(MMatchObjCache), nCount); int nIndex=0; for (MMatchObjCacheList::iterator itor=m_ObjectCacheList.begin(); itor!=m_ObjectCacheList.end(); itor++) { MMatchObjCache* pTrgCache = (MMatchObjCache*)MGetBlobArrayElement(pCacheArray, nIndex++); MMatchObjCache* pSrcCache = (*itor); pTrgCache->SetInfo(pSrcCache->GetUID(), pSrcCache->GetName(), pSrcCache->GetClanName(), pSrcCache->GetLevel(), pSrcCache->GetUGrade(), pSrcCache->GetPGrade() , pSrcCache->GetRank(), pSrcCache->GetKillCount(), pSrcCache->GetDeathCount(), pSrcCache->GetDTGrade() ); pTrgCache->SetFlags(pSrcCache->GetFlags()); pTrgCache->SetCLID(pSrcCache->GetCLID()); pTrgCache->SetEmblemChecksum(pSrcCache->GetEmblemChecksum()); pTrgCache->AssignCostume(pSrcCache->GetCostume()); } pCmd->AddParameter(new MCmdParamBlob(pCacheArray, MGetBlobArraySize(pCacheArray))); MEraseBlobArray(pCacheArray); return pCmd; }
bool MBMatchServer::AddClanServerSwitchDownSchedule() { int a = 0; MCommand* pCmd = CreateCommand( MC_MATCH_SCHEDULE_CLAN_SERVER_SWITCH_DOWN, MUID(0, 0) ); if( 0 == pCmd ) return false; tm t; MMatchGetLocalTime(&t); MMatchScheduleData* pScheduleData = m_pScheduler->MakeOnceScheduleData( t.tm_year - 100, t.tm_mon + 1, GetMaxDay(), 23, 50, pCmd ); if( 0 == pScheduleData ){ delete pCmd; return false; } if( !m_pScheduler->AddDynamicSchedule(pScheduleData) ){ delete pCmd; delete pScheduleData; return false; } mlog( "MBMatchServer::AddClanServerSwitchDownSchedule - 클랜서버다운 커맨드 생성 성공. 다음실행시간:%d년%d월%d일 %d시%d분\n", pScheduleData->GetYear(), pScheduleData->GetMonth(), pScheduleData->GetDay(), pScheduleData->GetHour(), pScheduleData->GetMin() ); return true; }
MUID ZBirdDummyClient::GetSenderUIDBySocket(SOCKET socket) { if (m_ClientSocket.GetSocket() == socket) return m_Server; else return MUID(0,0); }
void MMatchServer::OnAdminRequestBlockPlayer(const MUID& uidAdmin, const char* szPlayer, const int nPenaltyHour) { MMatchObject* pObj = GetObject(uidAdmin); if (pObj == NULL) return; if (!IsAdminGrade(pObj)) return; if ((strlen(szPlayer)) < 2) return; int nRet = MOK; MMatchObject* pTargetObj = GetPlayerByName(szPlayer); if (pTargetObj != NULL) { pTargetObj->GetAccountPenaltyInfo()->SetPenaltyInfo(MPC_CONNECT_BLOCK, nPenaltyHour); const MPenaltyInfo* pPenaltyInfo = pTargetObj->GetAccountPenaltyInfo()->GetPenaltyInfo(MPC_CONNECT_BLOCK); if( m_MatchDBMgr.InsertAccountPenaltyInfo(pTargetObj->GetAccountInfo()->m_nAID , pPenaltyInfo->nPenaltyCode, nPenaltyHour, pObj->GetAccountName()) == false ) { pTargetObj->GetAccountPenaltyInfo()->ClearPenaltyInfo(MPC_CONNECT_BLOCK); nRet = MERR_ADNIN_CANNOT_PENALTY_ON_DB; } } else { nRet = MERR_ADMIN_NO_TARGET; } MCommand* pNew = CreateCommand(MC_ADMIN_RESPONSE_BLOCK_PLAYER, MUID(0,0)); pNew->AddParameter(new MCmdParamInt(nRet)); if( nRet == MOK ) { Disconnect(pTargetObj->GetUID()); } RouteToListener(pObj, pNew); }
bool ZCharacterItem::EquipItem(MMatchCharItemParts parts, int nItemDescID, int nItemCount) { if (nItemDescID == 0) { m_Items[parts].Create(MUID(0,0), NULL, 0); return true; } MMatchItemDesc* pDesc = MGetMatchItemDescMgr()->GetItemDesc(nItemDescID); if (pDesc == NULL) { _ASSERT(0); return false; } if (!Confirm(parts, pDesc)) { // _ASSERT(0); return false; } m_Items[parts].Create(MUID(0,0), pDesc, 1, nItemCount); return true; }
MBMatchServer::MBMatchServer(COutputView* pView) { #ifdef MFC m_pView = pView; m_pCmdLogView = NULL; #endif SetKeeperUID( MUID(0, 0) ); }
void MMatchClient::InitPeerCrypt(const MUID& uidStage, unsigned int nChecksum) { //mlog("Init Peer Crypt (%u,%u,%u)\n", uidStage.High, uidStage.Low, nChecksum); MPacketCrypterKey key; MMakeSeedKey(&key, MUID(3465, nChecksum), uidStage, 9578234); m_PeerPacketCrypter.InitKey(&key); }
void MMatchPeerInfoList::Add(MMatchPeerInfo* pPeerInfo) { Lock(); insert(value_type(pPeerInfo->uidChar, pPeerInfo)); MUID uidIPPort = MUID(pPeerInfo->dwIP, (unsigned long)pPeerInfo->nPort); m_IPnPortMap.insert(map<MUID, MMatchPeerInfo*>::value_type(uidIPPort, pPeerInfo)); Unlock(); }
MUID MMatchClient::GetSenderUIDBySocket(SOCKET socket) { if (m_ClientSocket.GetSocket() == socket) return m_Server; else if (m_AgentSocket.GetSocket() == socket) return GetAgentServerUID(); else return MUID(0,0); }
MUID ZRoomListBox::GetSelRoomUID() { if ((m_Selection >= 0) && (m_Selection < NUM_DISPLAY_ROOM)) { return m_pMapInfo[m_Selection].uidStage; } return MUID(0,0); }
MMatchClient::MMatchClient() { g_pMatchClient = this; SetServerAddr("", 6000); SetServerPeerPort(7777); m_uidAgentServer = MUID(0,0); m_uidAgentClient = MUID(0,0); SetAgentAddr("", 6000); SetAgentPeerPort(7776); m_szServerName[0] = 0; m_nServerMode = MSM_NORMAL; m_bEnabledSurvivalMode = false; m_bEnabledDuelTournament = false; // m_SafeUDP.Create(true, MATCHCLIENT_DEFAULT_UDP_PORT); }
MMatchNPCObject* MMatchNPCManager::CreateNPCObject(MQUEST_NPC nType, unsigned char nSpawnPositionIndex, bool bKeyNPC) { MQuestNPCInfo* pNPCInfo = MMatchServer::GetInstance()->GetQuest()->GetNPCInfo(nType); if (pNPCInfo == NULL) return NULL; MUID uidNPC = NewUID(); unsigned long int nNPCFlags=0; MMatchNPCObject* pNewNPC = new MMatchNPCObject(uidNPC, nType, nNPCFlags); m_NPCObjectMap.insert(MMatchNPCObjectMap::value_type(uidNPC, pNewNPC)); // keyNPC라면 기억해둔다 if (bKeyNPC) m_uidKeyNPC = uidNPC; // spawn별 NPC Count증가 MQuestNPCSpawnType nSpawnType = MNST_MELEE; if (pNPCInfo) { nSpawnType = pNPCInfo->GetSpawnType(); // 만약 보스이면 BossCount 증가 if ((pNPCInfo->nGrade == NPC_GRADE_BOSS) || (pNPCInfo->nGrade == NPC_GRADE_LEGENDARY)) { m_nBossCount++; } } m_nNPCCount[nSpawnType]++; // 컨트롤러 할당 MUID uidController = MUID(0,0); if (!FindSuitableController(uidController, NULL)) { // 적당한 사람이 없으면 무시 MQuestDropItem TempItem; DestroyNPCObject(uidNPC, TempItem); return NULL; } // 스폰 if (!Spawn(uidNPC, uidController, nSpawnPositionIndex)) { MQuestDropItem TempItem; DestroyNPCObject(uidNPC, TempItem); return NULL; } return pNewNPC; }
bool MMatchNPCManager::DestroyNPCObject(MUID& uidNPC, MQuestDropItem& outItem) { MMatchNPCObjectMap::iterator itor = m_NPCObjectMap.find(uidNPC); if (itor != m_NPCObjectMap.end()) { MMatchNPCObject* pNPCObject = (*itor).second; outItem.Assign(pNPCObject->GetDropItem()); #ifdef _MONSTER_BIBLE // outItem.nMonsetBibleIndex = pNPCObject->GetDropItem()->nMonsetBibleIndex; #ifdef _DEBUG // mlog( "MMatchNPCManager::DestroyNPCObject - Destroy npc's drop item monster bible index:%d\n", outItem.nMonsetBibleIndex ); #endif #endif // Controller가 있었으면 Controller에서도 지워준다. MUID uidController = pNPCObject->GetController(); if (uidController != MUID(0,0)) { DelNPCObjectToControllerInfo(uidController, pNPCObject); } // keyNPC였다면 죽음 표시 if (uidNPC == m_uidKeyNPC) m_bKeyNPCDie = true; // spawn별 NPC Count감수 MQuestNPCSpawnType nSpawnType = MNST_MELEE; MQuestNPCInfo* pNPCInfo = MMatchServer::GetInstance()->GetQuest()->GetNPCInfo(pNPCObject->GetType()); if (pNPCInfo) { nSpawnType = pNPCInfo->GetSpawnType(); // 만약 보스이면 BossCount 감소 if ((pNPCInfo->nGrade == NPC_GRADE_BOSS) || (pNPCInfo->nGrade == NPC_GRADE_LEGENDARY)) { m_nBossCount--; if ( m_nBossCount <= 0) m_bBossDie = true; } } m_nNPCCount[nSpawnType]--; delete pNPCObject; m_NPCObjectMap.erase(itor); return true; } return false; }