#include "stdafx.h" #include "gamesrv.h" #include "DuelManager.h" #include "ObjectManager.h" #include "PVPManager.h" #include "GridManager.h" #include "Totem.h" cDuelManager* cDuelManager::mpDuelManager = NULL; cDuelManager::cDuelManager() { if(mpDuelManager) { MessageBox(NULL,"cSkillManager : ÀÌ Å¬·¡½º´Â °´Ã¼°¡ À¯ÀÏÇѰ´Ã¼(singleton)À̾î¾ß ÇÕ´Ï´Ù.\ ÀÌÀü °´Ã¼¸¦ »ç¿ëÇÏ´øÁö ÀÌÀü °´Ã¼¸¦ Áö¿ì°í »ý¼ºÇϽʽÿÀ.","°æ°í",MB_OK); } else { mpDuelManager = this; } } cDuelManager::~cDuelManager() { Release(); } bool cDuelManager::Init() { mDuelObjectPool.Reserve(100,10); return true; } void cDuelManager::Release() { cPHashMap::cIterator start = mDuelMap.Begin(); cPHashMap::cIterator end = mDuelMap.End(); cDuelObject* pDuel = NULL; while( start != end ) { pDuel = (cDuelObject*)(*start++).mSecond; SAFE_DELETE( pDuel ); } mDuelMap.Clear(); } void cDuelManager::Process( unsigned long elapsedTime, unsigned long accumTime ) { for( unsigned long i = 0 ; i < mDelDuel.GetSize() ; ++i ) { cDuelObject* pDuel = (cDuelObject*)mDuelMap.GetAt( mDelDuel[i] ); if( pDuel == NULL ) { assert(NULL); NETWORK2->PostServerEvent( "cDuelManager::Process mDelDuel[i] cDuelObject == NULL", i ); continue; } SAFE_DELETE( pDuel ); mDuelMap.Erase( mDelDuel[i] ); } mDelDuel.Clear(); cPHashMap::cIterator start = mDuelMap.Begin(); cPHashMap::cIterator end = mDuelMap.End(); while( start != end ) { cDuelObject* pDuel = (cDuelObject*)(*start++).mSecond; if( pDuel == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelManager::Process mDuelMap cDuelObject == NULL"); continue; } pDuel->Process( elapsedTime, accumTime ); } } int cDuelManager::ReqDuel( unsigned long attackerIdx, unsigned long targetIdx ) { /// °´Ã¼ üũ cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( attackerIdx ); if( pAttacker == NULL || pAttacker->GetStateDie() == true || pAttacker->GetCheatHideMode() == true ) return ERR_DUEL_ADD_FAIL; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( targetIdx ); if( pTarget == NULL || pTarget->GetStateDie() == true ) return ERR_DUEL_ADD_FAIL; if( pAttacker->IsAutoTrial() == true || pTarget->IsAutoTrial() ) return ERR_DUEL_ADD_FAIL; if( pAttacker->IsRequestRejection() == true ) return ERR_DUEL_ADD_FAIL; /// 2Â÷»óÅ üũ if( pTarget->IsRequestRejection() == true ) return ERR_DUEL_ADD_FAIL; if( pTarget->GetPvPDMIdx() != 0 ) return ERR_DUEL_ADD_FAIL; if( pAttacker->GetPvPDMIdx() != 0 ) return ERR_DUEL_ADD_FAIL; /// ¿É¼Ç »óÅ·ΠÀÎÇÑ °ÅÀý sGameOption* targetOption = pTarget->GetOptionData(); if( targetOption->option1.rejectionDuel == true ) return ERR_DUEL_ADD_OPTIONREFUSE; if( IsDuel( pAttacker, pTarget ) == false ) return ERR_DUEL_ADD_FAIL; return ERR_DUEL_ADD_SUCCESS; } bool cDuelManager::IsDuel( cPlayer* pAttacker, cPlayer* pTarget ) { if( pAttacker == NULL ) return false; if( pTarget == NULL ) return false; if( pAttacker == pTarget ) return false; /// ÀüÅõÁßÀÎÁö üũ if( pAttacker->GetDuelIdx() != 0 ) return false; if( pTarget->GetDuelIdx() != 0 ) return false; /// °Å·¡ üũ if( pAttacker->GetExchangeStatus() > ItemExchangeAsk ) return false; if( pTarget->GetExchangeStatus() > ItemExchangeAsk ) return false; /// »óÅ üũ - º¯°æÀº ÇÏÁö ¾Ê´Â´Ù. if( pAttacker->IsChangeState( eOBJECT_STATE_STOP ) == false ) return false; if( pTarget->IsChangeState( eOBJECT_STATE_STOP ) == false ) return false; /// °Å¸® üũ mRangeCheck.SetRadius( DUEL_ACCEPT_READY_RANGE ); if( mRangeCheck.IsNotRange( pTarget->GetPos(), pAttacker->GetPos() ) == true ) return false; return true; } void cDuelManager::DuelAllReady( bool mIsAccept, cPlayer* pTarget ) { unsigned long attackerIdx = 0; unsigned long targetIdx = 0; cPlayer* pAttacker = NULL; try { attackerIdx = pTarget->GetDuelPlayerIdx(); targetIdx = pTarget->GetObjectID(); /// °´Ã¼ È®ÀÎ if( pTarget == NULL || pTarget->GetStateDie() == true ) throw ERR_DUEL_ACCEPT_RES_ERROR; pAttacker = OBJECTMANAGER->GetPlayer( attackerIdx ); if( pAttacker == NULL || pAttacker->GetStateDie() == true ) throw ERR_DUEL_ACCEPT_REQ_ERROR; if( mIsAccept == false ) { /// °áÅõ ¼³Á¤ ²û pTarget->SetDuelPlayerIdx( 0, false ); pAttacker->SetDuelPlayerIdx( 0, false ); throw ERR_DUEL_ACCEPT_RES_REJECTION; } if( CreateDuel( pAttacker, pTarget ) == false ) throw ERR_DUEL_ACCEPT_RES_ERROR; } catch ( int err ) { HANDLE handle = NULL; if( pAttacker != NULL ) { MSG_RES_DUEL_ACCEPT* sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = targetIdx; sendMsg->ErrorCode = err == ERR_DUEL_ACCEPT_RES_REJECTION ? ERR_DUEL_ACCEPT_RES_REJECTION : ERR_DUEL_ACCEPT_RES_REJECTION; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); } } if( pTarget != NULL ) { pTarget->EndRequestRejection( eREQREJCT_DUELWAIT ); /// ´ë»óÀÚ°¡ °ÅÀýÀΰæ¿ì ÀÌ¹Ì Å¬¶ó¿¡¼­ ó¸®ÇßÀ½ if( ERR_DUEL_ACCEPT_RES_REJECTION != err ) { MSG_RES_DUEL_ACCEPT* sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = attackerIdx; sendMsg->ErrorCode = ERR_DUEL_ACCEPT_RES_ERROR; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); } } } } } bool cDuelManager::CreateDuel( cPlayer* pAttacker, cPlayer* pTarget ) { if( pAttacker == NULL ) return false; if( pTarget == NULL ) return false; unsigned long attackerIdx = pAttacker->GetObjectID(); unsigned long targetIdx = pTarget->GetObjectID(); // ¿äûÀÚÀÇ »óÅ °Ë»ç if( pAttacker->IsRequestRejection() == true ) return false; if( IsDuel( pAttacker, pTarget ) == false ) return false; /// °íÀ¯Å° »ý¼º unsigned long duelIdx = mDuelGen.GeneratIdx(); if( duelIdx == 0 ) { assert(NULL); NETWORK2->PostServerEvent( "ERROR - CreateDuel GeneratIdx[%d]", duelIdx ); return false; } /// °áÅõ °´Ã¼ »ý¼º cDuelObject* pDuelObject = new cDuelObject; if( pDuelObject->Init( duelIdx, attackerIdx, targetIdx ) == false ) { SAFE_DELETE( pDuelObject ); assert(NULL); NETWORK2->PostServerEvent( "ERROR - CreateDuel new cDuelObject" ); return false; } /// °áÅõ °´Ã¼ µî·Ï if( mDuelMap.Insert( duelIdx, pDuelObject ) == false ) { SAFE_DELETE( pDuelObject ); assert(NULL); NETWORK2->PostServerEvent( "ERROR - CreateDuel mDuelMap.Insert Duplicate" ); return false; } HANDLE handle = NULL; /// °áÅõ ½ÃÀÛ Ä«¿îÆ® ¸Þ¼¼Áö ¹ß¼Û MSG_RES_DUEL_ACCEPT* sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = targetIdx; sendMsg->ErrorCode = ERR_DUEL_ACCEPT_SUCCESS; sendMsg->mCenterPos = pDuelObject->GetCenterPos(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); } sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = attackerIdx; sendMsg->ErrorCode = ERR_DUEL_ACCEPT_SUCCESS; sendMsg->mCenterPos = pDuelObject->GetCenterPos(); NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); } MSG_SYN_DUEL_ACCEPT synMsg; synMsg.Category = NM_DUEL; synMsg.Protocol = NM_DUEL_ACCEPT_SYN; synMsg.mAttackerIdx = attackerIdx; synMsg.mTargetIdx = targetIdx; TwoPlayerQuickSend( pAttacker, pTarget, (char*)&synMsg, sizeof(synMsg) ); /// °áÅõ »óÅ·Π¹Ù²Þ pAttacker->StartRequestRejection( eREQREJCT_DUELPLAY ); pTarget->StartRequestRejection( eREQREJCT_DUELPLAY ); return true; } void cDuelManager::DuelGiveUp( unsigned long duelIdx, unsigned long playerIdx ) { cDuelObject* pDuelObject = (cDuelObject*)mDuelMap.GetAt( duelIdx ); if( pDuelObject == NULL ) return; pDuelObject->FightEnd( playerIdx ); } void cDuelManager::DelDuel( unsigned long duelIdx ) { mDelDuel.PushBack( duelIdx ); mDuelGen.DelIdx( duelIdx ); } void cDuelManager::TwoPlayerQuickSend( cPlayer* pPlayer1, cPlayer* pPlayer2, char* msg, int length ) { /// Player1, Player2¿¡ ÇØ´çÇÏ´Â ¹ß¼ÛÀÚ ¸í´ÜÀ» ¸ðµÎ Àоî¿È - Áߺ¹À¯Àú 1°³·Î ÇÕħ(set) if( pPlayer1 != NULL ) { cPlayer* pPlayer = GRIDMANAGER->FindFirstPlayer( pPlayer1 ); while( pPlayer != NULL ) { mSendSet.Insert( pPlayer->GetConnectionIdx() ); pPlayer = GRIDMANAGER->FindNextPlayer(); } } if( pPlayer2 != NULL ) { cPlayer* pPlayer = GRIDMANAGER->FindFirstPlayer( pPlayer2 ); while( pPlayer != NULL ) { mSendSet.Insert( pPlayer->GetConnectionIdx() ); pPlayer = GRIDMANAGER->FindNextPlayer(); } } cHashSet::cIterator begin = mSendSet.Begin(); cHashSet::cIterator end = mSendSet.End(); unsigned long conIdx; while( begin != end ) { conIdx = (*begin++); if( pPlayer1->GetConnectionIdx() == conIdx ) continue; if( pPlayer2->GetConnectionIdx() == conIdx ) continue; NETWORK2->SendToUser( conIdx, msg, length ); } } bool cDuelManager::DuelLastAttack( sObject attacker, sObject target, unsigned long damage, bool isCri, unsigned long* appDamage ) { bool die; *appDamage = 0; sObject attackerPlayer = attacker; /// ÀϹÝÀûÀÎ °ø°Ý /// if( attacker.type != eOBJECTTYPE_PLAYER ) { if( attacker.type == eOBJECTTYPE_TOTEM ) { cTotem* pTotem = OBJECTMANAGER->GetTotem( attacker.type ); if( pTotem == NULL ) return false; attackerPlayer = pTotem->GetAttacker(); NETWORK2->PostServerEvent("cDuelManager::DuelLastAttack attacker.type == eOBJECTTYPE_TOTEM[%d,%d][%d,%d]", attacker.type, attacker.index, attackerPlayer.type, attackerPlayer.index ); } else return false; } if( attackerPlayer.type != eOBJECTTYPE_PLAYER ) return false; if( target.type != eOBJECTTYPE_PLAYER ) return false; cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( attackerPlayer.index ); if( pAttacker == NULL ) return false; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( target.index ); if( pTarget == NULL ) return false; unsigned long duelIdx = pAttacker->GetDuelIdx(); cDuelObject* pDuel = (cDuelObject*)mDuelMap.GetAt( duelIdx ); if( pDuel == NULL ) { if( attackerPlayer.index == target.index && attackerPlayer.type == target.type ) return false; /// pvp °ø°Ý üũ if( pAttacker->GetPvPDMIdx() == pTarget->GetPvPDMIdx() && pAttacker->GetPvPDMTeam() != pTarget->GetPvPDMTeam() ) return false; else return true; /// °áÅõ°¡ ¾Æ´Ñ(³¡) Ç÷¹À̾ °ø°Ý - °ø°ÝºÒ°¡ } if( pAttacker->IsAttack( target.index ) == false ) return true; if( pTarget->GetHP() > damage ) return false; /// °áÅõ ¸¶Áö¸· °ø°Ý ó¸® /// *appDamage = pTarget->GetHP() - 1; pTarget->HPDamage( attackerPlayer, *appDamage , &die, false, isCri ); pDuel->LastAttack( target.index ); return true; } void cDuelManager::DuelObjectEnd( unsigned long attackerIdx, unsigned long targetIdx, unsigned long duelIdx, bool isAttackerEnd ) { HANDLE handle = NULL; cDuelObject* pDuelObject = (cDuelObject*)mDuelMap.GetAt( duelIdx ); if( pDuelObject == NULL ) { /// °áÅõ ÁøÇà»óŰ¡ ¾Æ´Ñ °æ¿ì cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( attackerIdx ); if( pAttacker != NULL ) { MSG_RES_DUEL_ACCEPT* sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = targetIdx; sendMsg->ErrorCode = ERR_DUEL_ACCEPT_RES_ERROR; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); pAttacker->EndRequestRejection( eREQREJCT_DUELPLAY ); } } cPlayer* pTarget = OBJECTMANAGER->GetPlayer( targetIdx ); if( pTarget != NULL ) { MSG_RES_DUEL_ACCEPT* sendMsg = (MSG_RES_DUEL_ACCEPT*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_ACCEPT_RES ); if ( sendMsg != NULL ) { sendMsg->mEnemyIdx = attackerIdx; sendMsg->ErrorCode = ERR_DUEL_ACCEPT_REQ_ERROR; NETWORK2->SendMsgRoot( handle, sizeof(MSG_RES_DUEL_ACCEPT) ); pTarget->EndRequestRejection( eREQREJCT_DUELPLAY ); } } } /// °áÅõ ÁøÇà »óÅÂ¸é °áÅõ °´Ã¼¿¡ ½ÂÆÐ¸¦ ¼³Á¤ÇØÁØ´Ù. else { if( isAttackerEnd == true ) pDuelObject->FightEnd( attackerIdx ); else pDuelObject->FightEnd( targetIdx ); } }