#include "stdafx.h" #include "gamesrv.h" #include "Duelobject.h" #include "Duel_Common.h" #include "DuelManager.h" #include "ObjectManager.h" #include "SkillManager.h" cDuelObject::cDuelObject() { } cDuelObject::~cDuelObject() { } void* cDuelObject::operator new( size_t n ) { if( n != sizeof(cDuelObject) ) { assert(0); return NULL; } return DUELMANAGER->AllocDuelObject(); } void cDuelObject::operator delete( void* ptr, size_t n ) { /// NULL Æ÷ÀÎÅÍ °Ë»ç if( ptr == 0 ) { assert(0); return; } if( n != sizeof(cDuelObject) ) { assert(0); return; } DUELMANAGER->FreeDuelObject( static_cast(ptr) ); return; } bool cDuelObject::Init( unsigned long duelIdx, unsigned long attackerIdx, unsigned long targetIdx ) { mDuelIdx = duelIdx; mAttackerIdx = attackerIdx; mTargetIdx = targetIdx; mDuelProcess = eDUELPROCESS_FIGHT_COUNT; mDelayTime = 0; mAttackerOutTime = 0; mTargetOutTime = 0; mAttacerRangeIn = true; mTargetRangeIn = true; mDieIdx = 0; cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( mAttackerIdx ); if( pAttacker == NULL ) return false; cPlayer* pTarget = OBJECTMANAGER->GetPlayer( mTargetIdx ); if( pTarget == NULL ) return false; pAttacker->SetDuelIdx( mDuelIdx ); pTarget->SetDuelIdx( mDuelIdx ); /// ¸Þ¼¼Áö ´ë±â»óÅ ³¡ pTarget->EndRequestRejection( eREQREJCT_DUELWAIT ); /// °áÅõ Áß½ÉÁ¡ »êÃâ mCenterPos = pAttacker->GetPos() - ( ( pAttacker->GetPos() - pTarget->GetPos() ) / 2); /// °áÅõ ½ÃÀÛ ½Ã°£ ¼³Á¤ mProcessWaitTime = NETWORK2->GetAccumTime() + DUEL_FIGHT_COUNT_TIME; ::wcsncpy( mAttackerName, pAttacker->GetName(), MAX_NAME_SIZE ); mAttackerName[MAX_NAME_SIZE] = 0; ::wcsncpy( mTargetName, pTarget->GetName(), MAX_NAME_SIZE ); mAttackerName[MAX_NAME_SIZE] = 0; return true; } void cDuelObject::Process( unsigned long elapsedTime, unsigned long accumTime ) { /// °áÅõ ½ÃÀÛ Àü Ä«¿îÆ® switch( mDuelProcess ) { case eDUELPROCESS_FIGHT_COUNT: { /// °áÅõ½ÃÀÛ ´ë±â Ä«¿îÆ® if( mProcessWaitTime > accumTime ) return; /// °áÅõ ½ÃÀÛ Ã³¸® mDuelProcess = eDUELPROCESS_FIGHT; FightStart(); } break; case eDUELPROCESS_FIGHT: { /// ÇÁ·Î¼¼½º ºÎÇÏ ¹æÁö - DUEL_FIGHT_DELAY_TIME ½Ã°£¸¶´Ù üũ if( mDelayTime > accumTime ) return; /// ´ÙÀ½¹ø üũ½Ã°£ ¼³Á¤ mDelayTime = accumTime + DUEL_FIGHT_DELAY_TIME; /// °áÅõ ÁøÇàÁß Ã¼Å© Ç׸ñ FightProcess( elapsedTime, accumTime ); } break; case eDUELPROCESS_FIGHT_END: { /// Á¢¼Ó Á¾·á°¡ ¾Æ´Ñ °ø°ÝÀ¸·Î ÀÎÇØ °áÅõ°¡ ³¡³­°æ¿ì FightEnd( mDieIdx ); } break; } } void cDuelObject::FightStart() { cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( mAttackerIdx ); if( pAttacker == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::Process pAttacker[%d] == NULL", mAttackerIdx ); FightEnd( mAttackerIdx ); return; } cPlayer* pTarget = OBJECTMANAGER->GetPlayer( mTargetIdx ); if( pTarget == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::Process pTarget[%d] == NULL", mTargetIdx ); FightEnd( mTargetIdx ); return; } NETWORK2->SendMsgRoot( pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_START_RES ); NETWORK2->SendMsgRoot( pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_START_RES ); } void cDuelObject::FightProcess( unsigned long /*elapsedTime*/, unsigned long accumTime ) { /// °áÅõ °Å¸® üũ mRangeCheck.SetRadius( DUEL_FIGHT_RANGE ); cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( mAttackerIdx ); if( pAttacker == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::Process pAttacker[%d] == NULL", mAttackerIdx ); FightEnd( mAttackerIdx ); return; } cPlayer* pTarget = OBJECTMANAGER->GetPlayer( mTargetIdx ); if( pTarget == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::Process pTarget[%d] == NULL", mTargetIdx ); FightEnd( mTargetIdx ); return; } if( mRangeCheck.IsNotRange( mCenterPos, pAttacker->GetPos() ) == true ) { /// À̹ø ÇÁ·¹ÀÓ¿¡¼­ ¾È¿¡ ÀÖ´Ù°¡ ³ª°¨ if( mAttacerRangeIn == true ) { /// ½Ã°£ ¼³Á¤ mAttackerOutTime = accumTime; mAttacerRangeIn = false; /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_FIGHT_OUTRANGE_RES ); } /// 10ÃÊÀÌ»ó ³ª°¡ÀÖÀ½ if( mAttackerOutTime + DUEL_FIGHT_RANGE_TIME <= accumTime ) { /// Ç÷¹À̾î1 ÆÐ¹è FightEnd( mAttackerIdx ); } } else { /// À̹ø ÇÁ·¹ÀÓ¿¡¼­ ¹Û¿¡ ÀÖ´Ù°¡ µé¾î¿È if( mAttacerRangeIn == false ) { mAttacerRangeIn = true; /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_FIGHT_INRANGE_RES ); } } if( mRangeCheck.IsNotRange( mCenterPos, pTarget->GetPos() ) == true ) { /// À̹ø ÇÁ·¹ÀÓ¿¡¼­ ¾È¿¡ ÀÖ´Ù°¡ ³ª°¨ if( mTargetRangeIn == true ) { /// ½Ã°£ ¼³Á¤ mTargetOutTime = accumTime; mTargetRangeIn = false; /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_FIGHT_OUTRANGE_RES ); } /// 10ÃÊÀÌ»ó ³ª°¡ÀÖÀ½ if( mTargetOutTime + DUEL_FIGHT_RANGE_TIME <= accumTime ) { /// Ç÷¹À̾î2 ÆÐ¹è FightEnd( mTargetIdx ); } } else { /// À̹ø ÇÁ·¹ÀÓ¿¡¼­ ¹Û¿¡ ÀÖ´Ù°¡ µé¾î¿È if( mTargetRangeIn == false ) { mTargetRangeIn = true; /// ¸Þ¼¼Áö ¹ß¼Û NETWORK2->SendMsgRoot( pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_FIGHT_INRANGE_RES ); } } } void cDuelObject::LastAttack( unsigned long dieIdx ) { /// ½ºÅ³ µ¥¹ÌÁö ¸Þ¼¼Áö ¸ÕÀú ¹ß¼ÛÇÑÈÄ¿¡ ÇÑÇÁ·Î¼¼½º µÚ¿¡ °áÅõÁ¾·á 󸮸¦ ÇÑ´Ù. mDuelProcess = eDUELPROCESS_FIGHT_END; mDieIdx = dieIdx; } void cDuelObject::FightEnd( unsigned long dieIdx ) { if( mDuelProcess == eDUELPROCESS_END ) return; sObject player; player.type = eOBJECTTYPE_PLAYER; HANDLE handle = NULL; /// ¿¬½Â unsigned short straightWin = 0; /// °´Ã¼ »èÁ¦ Àü¿¡ ¿©±â¼­ ¸ÕÀú È£ÃâµÇ¹Ç·Î °´Ã¼°¡ NULLÀϼö ¾ø´Ù. cPlayer* pTarget = OBJECTMANAGER->GetPlayer( mTargetIdx ); if( pTarget == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::FightEnd pTarget[%d] == NULL", mTargetIdx ); DUELMANAGER->DelDuel( mDuelIdx ); return; } cPlayer* pAttacker = OBJECTMANAGER->GetPlayer( mAttackerIdx ); if( pAttacker == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cDuelObject::FightEnd pAttacker[%d] == NULL", mAttackerIdx ); DUELMANAGER->DelDuel( mDuelIdx ); return; } pTarget->EndRequestRejection( eREQREJCT_DUELPLAY ); /// °áÅõ »óÅ Á¾·á pTarget->SetDuelIdx( 0 ); /// °áÅõ ¼³Á¤ Á¾·á pTarget->DuelEndDebuffClear( mAttackerIdx ); /// °ø°Ý ¹Þ¾Ò´ø µð¹öÇÁ Á¦°Å pTarget->SetDuelPlayerIdx( 0, false ); /// °áÅõ ´ë»ó Ŭ¸®¾î pTarget->MoveStop(); pAttacker->EndRequestRejection( eREQREJCT_DUELPLAY ); pAttacker->SetDuelIdx( 0 ); pAttacker->DuelEndDebuffClear( mTargetIdx ); pAttacker->SetDuelPlayerIdx( 0, false ); pAttacker->MoveStop(); /// °áÅõ Á¾·á ½ÃÁ¡¿¡ ä³Î¸µ ½ºÅ³ÀÌ ½áÁ®ÀÖÀ¸¸é °­Á¦ Á¾·á ½Ã۱â. bool isDuelEnd = true; SKILLMANAGER->ChannelingSkillCancel( pAttacker->GetObject(), true, eATTRIBUTETYPE_NONE, isDuelEnd ); SKILLMANAGER->ChannelingSkillCancel( pTarget->GetObject(), true, eATTRIBUTETYPE_NONE, isDuelEnd ); MSG_SYN_DUEL_END synMsg; /// ½Â¸®/ÆÐ¹è ó¸® if( dieIdx == mAttackerIdx ) { /// ´ë»óÀÚ ½Â¸® pTarget->SetDuelWin(); /// ½Â¸® ±â·Ï straightWin = (unsigned short)pTarget->GetDuelWin(); /// ¿¬½Â /// ½Â¸® ¹öÇÁ Ãß°¡ player.index = mTargetIdx; SKILLMANAGER->AddInfluence( player, player, DUEL_WIN_ADD_INFLUENCEIDX, 0, true ); /// ½Â¸® ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_DUEL_WINNER* winMsg = (MSG_SYN_DUEL_WINNER*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_WINNER_SYN ); if ( winMsg != NULL ) { winMsg->mWinnerIdx = mTargetIdx; ::wcsncpy( winMsg->mWinnerName, mTargetName, MAX_NAME_SIZE ); winMsg->mLoserIdx = mAttackerIdx; ::wcsncpy( winMsg->mLoserName, mAttackerName, MAX_NAME_SIZE ); winMsg->mStraightWin = straightWin; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_DUEL_WINNER) ); } /// ¿äûÀÚ ÆÐ¹è pAttacker->ClearDuelWin(); /// ¿¬½Â ±â·Ï Á¦°Å /// ÆÐ¹è ¹öÇÁ Ãß°¡ player.index = mAttackerIdx; SKILLMANAGER->AddInfluence( player, player, DUEL_LOSE_ADD_INFLUENCEIDX, 0, true ); /// ÆÐ¹è ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_DUEL_LOSER* loseMsg = (MSG_SYN_DUEL_LOSER*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_LOSER_SYN ); if ( loseMsg != NULL ) { loseMsg->mWinnerIdx = mTargetIdx; ::wcsncpy( loseMsg->mWinnerName, mTargetName, MAX_NAME_SIZE ); loseMsg->mLoserIdx = mAttackerIdx; ::wcsncpy( loseMsg->mLoserName, mAttackerName, MAX_NAME_SIZE ); loseMsg->mStraightWin = straightWin; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_DUEL_LOSER) ); } synMsg.Category = NM_DUEL; synMsg.Protocol = NM_DUEL_END_SYN; synMsg.mWinnerIdx = mTargetIdx; ::wcsncpy( synMsg.mWinnerName, mTargetName, MAX_NAME_SIZE ); synMsg.mLoserIdx = mAttackerIdx; ::wcsncpy( synMsg.mLoserName, mAttackerName, MAX_NAME_SIZE ); synMsg.mStraightWin = straightWin; } else { /// ¿äûÀÚ ½Â¸® pAttacker->SetDuelWin(); /// ½Â¸® ±â·Ï straightWin = (unsigned short)pAttacker->GetDuelWin(); /// ¿¬½Â /// ½Â¸® ¹öÇÁ Ãß°¡ player.index = mAttackerIdx; SKILLMANAGER->AddInfluence( player, player, DUEL_WIN_ADD_INFLUENCEIDX, 0, true ); /// ½Â¸® ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_DUEL_WINNER* winMsg = (MSG_SYN_DUEL_WINNER*)NETWORK2->GetMsgRoot( &handle, pAttacker->GetConnectionIdx(), NM_DUEL, NM_DUEL_WINNER_SYN ); if ( winMsg != NULL ) { winMsg->mWinnerIdx = mAttackerIdx; ::wcsncpy( winMsg->mWinnerName, mAttackerName, MAX_NAME_SIZE ); winMsg->mLoserIdx = mTargetIdx; ::wcsncpy( winMsg->mLoserName, mTargetName, MAX_NAME_SIZE ); winMsg->mStraightWin = straightWin; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_DUEL_WINNER) ); } /// ´ë»óÀÚ ÆÐ¹è pTarget->ClearDuelWin(); /// ¿¬½Â ±â·Ï Á¦°Å /// ÆÐ¹è µð¹öÇÁ Ãß°¡ player.index = mTargetIdx; SKILLMANAGER->AddInfluence( player, player, DUEL_LOSE_ADD_INFLUENCEIDX, 0, true ); /// ÆÐ¹è ¸Þ¼¼Áö ¹ß¼Û MSG_SYN_DUEL_LOSER* loseMsg = (MSG_SYN_DUEL_LOSER*)NETWORK2->GetMsgRoot( &handle, pTarget->GetConnectionIdx(), NM_DUEL, NM_DUEL_LOSER_SYN ); if ( loseMsg != NULL ) { loseMsg->mWinnerIdx = mAttackerIdx; ::wcsncpy( loseMsg->mWinnerName, mAttackerName, MAX_NAME_SIZE ); loseMsg->mLoserIdx = mTargetIdx; ::wcsncpy( loseMsg->mLoserName, mTargetName, MAX_NAME_SIZE ); loseMsg->mStraightWin = straightWin; NETWORK2->SendMsgRoot( handle, sizeof(MSG_SYN_DUEL_LOSER) ); } synMsg.Category = NM_DUEL; synMsg.Protocol = NM_DUEL_END_SYN; synMsg.mWinnerIdx = mAttackerIdx; ::wcsncpy( synMsg.mWinnerName, mAttackerName, MAX_NAME_SIZE ); synMsg.mLoserIdx = mTargetIdx; ::wcsncpy( synMsg.mLoserName, mTargetName, MAX_NAME_SIZE ); synMsg.mStraightWin = straightWin; } /// °áÅõÀÚ µÎ¸íÀ» Á¦¿ÜÇÑ Àüü¿¡°Ô ¸Ê´ÜÀ§ Àü¼Û NETWORK2->QuickSendExceptMap( pAttacker, pTarget, (char*)&synMsg, sizeof(synMsg) ); /// »èÁ¦ ¹è¿­¿¡ Ãß°¡ DUELMANAGER->DelDuel( mDuelIdx ); mDuelProcess = eDUELPROCESS_END; }