#include "stdafx.h" #include "PvPRoundMode.h" #include "DNPvPGameRoom.h" #include "DNUserSession.h" #include "DnActor.h" #include "DnPlayerActor.h" #include "DnPvPGameTask.h" #include "PvPRespawnLogic.h" #include "DnStateBlow.h" #include "DNMissionSystem.h" #include "DNDBConnection.h" CPvPRoundMode::CPvPRoundMode( CDNGameRoom* pGameRoom, const TPvPGameModeTable* pPvPGameModeTable, const MAGAPVP_GAMEMODE* pPacket ) :CPvPGameMode( pGameRoom, pPvPGameModeTable, pPacket ),m_bFinishRoundFlag(false) { m_dwCheckAllDeadTick = 0; m_fFinishRoundDelta = 0.f; #if defined(PRE_ADD_PVP_TOURNAMENT) m_cTournamentStep = pPacket->cMaxUser; m_cTournamentStepCount = 0 ; m_cCurrentTournamentStep = 0; #endif } CPvPRoundMode::~CPvPRoundMode() { } void CPvPRoundMode::Process( LOCAL_TIME LocalTime, float fDelta ) { if( m_bFinishRoundFlag && !m_bFinishGameModeFlag ) { bool bCheck = true; if( m_fFinishRoundDelta >= PvPCommon::Common::RoundModeFinishDelta ) bCheck = false; m_fFinishRoundDelta -= fDelta; if( bCheck && m_fFinishRoundDelta <= 0.f ) _OnStartRound(); else return; } if( _CanProcess() == false ) return; CPvPGameMode::Process( LocalTime, fDelta ); _OnAfterProcess(); } void CPvPRoundMode::_OnAfterProcess() { if( m_bStartGameModeFlag && m_fStartDelta <= 0.f && !m_bFinishRoundFlag ) { if( timeGetTime()-m_dwCheckAllDeadTick >= 500 ) { OnCheckFinishRound( PvPCommon::FinishReason::OpponentTeamAllDead ); m_dwCheckAllDeadTick = timeGetTime(); } } } bool CPvPRoundMode::bIsPlayingUser( DnActorHandle hActor ) { if( !hActor || !hActor->GetName() || !hActor->IsPlayerActor() ) return false; if( !CPvPGameMode::bIsPlayingUser( hActor ) ) return false; // SessionState °Ë»ç CDnPlayerActor* pPlayer = static_cast(hActor.GetPointer()); CDNUserSession* pGameSession = pPlayer->GetUserSession(); if( !pGameSession ) return false; if( pGameSession->GetState() != SESSION_STATE_GAME_PLAY ) return false; return (m_mBreakInto.find( hActor->GetName() ) == m_mBreakInto.end()) ? true : false; } bool CPvPRoundMode::bIsFirstRound() { UINT uiATeamScore, uiBTeamScore; m_pScoreSystem->GetGameModeScore( uiATeamScore, uiBTeamScore ); if( uiATeamScore == 0 && uiBTeamScore == 0 ) return true; return false; } // RoundMode¿¡¼­´Â ºÎȰÀ» ½ÃŰÁö ¾Ê´Â´Ù. void CPvPRoundMode::OnFinishProcessDie( DnActorHandle hActor ) { } void CPvPRoundMode::OnCheckFinishRound( PvPCommon::FinishReason::eCode Reason ) { UINT uiWinTeam = PvPCommon::Team::Max; switch( Reason ) { case PvPCommon::FinishReason::OpponentTeamAllGone: { uiWinTeam = OnCheckZeroUserWinTeam(); break; } case PvPCommon::FinishReason::TimeOver: { UINT uiATeamUser = 0; UINT uiBTeamUser = 0; for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNGameRoom::PartyStruct* pPartyStruct = GetGameRoom()->GetPartyData(i); if( !pPartyStruct->pSession ) continue; DnActorHandle hActor = pPartyStruct->pSession->GetActorHandle(); if( !hActor ) continue; if( !bIsPlayingUser( hActor ) ) continue; if( hActor->IsDie() ) continue; if( hActor->GetTeam() == PvPCommon::Team::A ) ++uiATeamUser; else if( hActor->GetTeam() == PvPCommon::Team::B ) ++uiBTeamUser; } if( uiATeamUser > uiBTeamUser ) uiWinTeam = PvPCommon::Team::A; else if( uiBTeamUser > uiATeamUser ) uiWinTeam = PvPCommon::Team::B; break; } case PvPCommon::FinishReason::OpponentTeamAllDead: { UINT uiCheckBit = 0; for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNGameRoom::PartyStruct* pPartyStruct = GetGameRoom()->GetPartyData(i); if( !pPartyStruct->pSession ) continue; DnActorHandle hActor = pPartyStruct->pSession->GetActorHandle(); if( !hActor ) continue; if( !bIsPlayingUser( hActor ) ) continue; if( hActor->IsDie() ) continue; if( hActor->GetTeam() == PvPCommon::Team::A ) uiCheckBit |= 1; else if( hActor->GetTeam() == PvPCommon::Team::B ) uiCheckBit |= 2; if( uiCheckBit == 3 ) return; } if( uiCheckBit ) uiWinTeam = (uiCheckBit==1) ? PvPCommon::Team::A : PvPCommon::Team::B; break; } case PvPCommon::FinishReason::LadderNoGame: { break; } default: { return; } } _ProcessFinishRound( uiWinTeam, Reason ); } void CPvPRoundMode::_ProcessFinishRound( const UINT uiWinTeam, PvPCommon::FinishReason::eCode Reason ) { // ÀÌ¹Ì ³¡³­¶ó¿îµå¸é ¸®ÅÏ if( m_bFinishRoundFlag ) return; // RoundÁ¾·á Ç÷¡±× ¼³Á¤ m_bFinishRoundFlag = true; m_fFinishRoundDelta = PvPCommon::Common::RoundModeFinishDelta; // ResapwnLogic ¿¡ °ÔÀÓ¸ðµå Á¾·á ¾Ë¸² if( m_pGameRoom && m_pGameRoom->GetGameTask() && ((CDnPvPGameTask*)m_pGameRoom->GetGameTask())->GetRespawnLogic() ) ((CDnPvPGameTask*)m_pGameRoom->GetGameTask())->GetRespawnLogic()->FinishRound(); //============================================================================================= // Score°è»ê //============================================================================================= UINT uiATeamScore, uiBTeamScore; GetGameModeScore( uiATeamScore, uiBTeamScore ); if( uiWinTeam == PvPCommon::Team::A ) ++uiATeamScore; else if( uiWinTeam == PvPCommon::Team::B ) ++uiBTeamScore; m_pScoreSystem->SetGameModeScore( uiATeamScore, uiBTeamScore ); m_pScoreSystem->FinishRound( GetGameRoom(), uiWinTeam ); //============================================================================================= // ¶ó¿îµå °á°ú Á¤¸® //============================================================================================= for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNGameRoom::PartyStruct* pPartyStruct = GetGameRoom()->GetPartyData(i); // SESSION_STATE_GAME_PLAY ÀÎ À¯Àú¿¡°Ô¸¸ º¸³»ÁØ´Ù. if( pPartyStruct->pSession && pPartyStruct->pSession->GetState() == SESSION_STATE_GAME_PLAY ) { DnActorHandle hActor = pPartyStruct->pSession->GetActorHandle(); if( hActor && bIsPlayingUser( hActor ) ) { bool bIsWin = false; if( uiWinTeam != PvPCommon::Team::Max ) bIsWin = (uiWinTeam == hActor->GetTeam() ? true : false); _ProcessFinishRoundMode( pPartyStruct->pSession, bIsWin, uiWinTeam, Reason ); m_pScoreSystem->OnFinishRound( hActor, bIsWin ); } } } //============================================================================================= // °ÔÀÓ¸ðµå Á¾·á °Ë»ç //============================================================================================= // 1.½Â¸®Á¶°Ç¿¡ µµ´ÞÇß´ÂÁö °Ë»çÇØº»´Ù. UINT uiMaxScore = max( uiATeamScore, uiBTeamScore ); UINT uiCheckScore = uiMaxScore; if( bIsZombieMode() == true ) uiCheckScore = uiATeamScore+uiBTeamScore; if( _CheckFinishGameMode( const_cast(uiWinTeam) ) || (_CheckWinContition()&& uiCheckScore >= m_uiWinCondition ) ) return FinishGameMode( uiWinTeam, PvPCommon::FinishReason::AchieveWinCondition ); // 2.»ó´ë¹æÀÌ ¸ðµÎ ³ª°¬À¸¸é ¹«Á¶°Ç ³²ÀºÆÀÀÌ À̱ä´Ù. else if( Reason == PvPCommon::FinishReason::OpponentTeamAllGone || Reason == PvPCommon::FinishReason::OpponentCaptainGone ) { bool bFinish = false; #if defined(PRE_ADD_PVP_TOURNAMENT) if (bIsZombieMode() == false && bIsTournamentMode() == false) #else if (bIsZombieMode() == false) #endif bFinish = true; else { //Á»ºñ¸ðµå¶ó¸é ´ÙÀ½ ¶ó¿îµå¸¦ üũÇÑ´Ù. 1¸íÀÌ ³²±âÀü±îÁö´Â ÁøÇà! if (GetGameRoom()->GetUserCountWithoutGM()-GetGameRoom()->GetUserCount(PvPCommon::Team::Observer) <= 1) bFinish = true; } // 3.´ÙÀ½ ¶ó¿îµå¸¦ ÇÒ ³­ÀÔ À¯Àú°¡ ÀÖ´ÂÁö °Ë»ç. if (bFinish) { if( OnCheckZeroUserWinTeam( false ) != PvPCommon::Team::Max ) return FinishGameMode( uiWinTeam, PvPCommon::FinishReason::OpponentTeamAllGone ); } } #if defined(PRE_ADD_DWC) if( GetGameRoom()->bIsLadderRoom() && !static_cast(GetGameRoom())->bIsDWCMatch() ) #else if( GetGameRoom()->bIsLadderRoom() ) #endif { if( Reason == PvPCommon::FinishReason::LadderNoGame ) return FinishGameMode( uiWinTeam, PvPCommon::FinishReason::LadderNoGame ); return FinishGameMode( uiWinTeam, PvPCommon::FinishReason::LadderDraw ); } //============================================================================================= // ´ÙÀ½ ¶ó¿îµå //============================================================================================= _FinishRound( uiWinTeam, Reason ); } void CPvPRoundMode::OnSuccessBreakInto( CDNUserSession* pGameSession ) { CPvPGameMode::OnSuccessBreakInto( pGameSession ); // 1.°ÔÀÓ¸ðµå°¡ Á¾·áµÈ °æ¿ì¸é PvPRound¸ðµå¶ó°í µû·Î ÇØÁÙ°ÍÀ̾ø´Ù. if( m_bFinishGameModeFlag ) return; // 2.PvPRound¸ðµå°¡ Á¾·áµÈ °æ¿ì¸é ¹«Àû »óÅÂÈ¿°ú ºÎ¿© if( m_bFinishRoundFlag ) { DnActorHandle hActor = pGameSession->GetActorHandle(); if( hActor ) { int iDurationTime = static_cast(m_fFinishRoundDelta*1000); if( iDurationTime > 0 ) hActor->CDnActor::AddStateBlow( STATE_BLOW::BLOW_099, NULL, iDurationTime, "-1" ); } } // 3.PvPRound¸ðµå°¡ ÁøÇàÁßÀ̶ó¸é À̹ø¶ó¿îµå´Â À¯·É»óÅ·ΠÀִ´Ù. else if( GetRemainStartTick() == 0 ) { // 4.ù¶ó¿îµåÀ̰í ÀÏÁ¤½Ã°£(10sec) À̳»ÀÇ ³­ÀÔÀ̶ó¸é Ç÷¹ÀÌ °¡´ÉÇÏ°Ô ÇÑ´Ù. if( bIsFirstRound() && bIsInPlayTime( 10 ) ) return; // 4.°¡ ¾Æ´Ï¶ó¸é ij¸¯ÅÍ À¯·É»óÅ·Î~~ DnActorHandle hActor = pGameSession->GetActorHandle(); if( hActor ) { m_mBreakInto.insert( std::make_pair( hActor->GetName(), pGameSession) ); CDnPlayerActor* pPlayer = static_cast(hActor.GetPointer()); pPlayer->CmdRefreshHPSP( 0,0 ); } } } void CPvPRoundMode::OnRebirth( DnActorHandle hActor, bool bForce/*=false*/ ) { if( m_bFinishRoundFlag ) CPvPGameMode::OnRebirth( hActor, true ); } void CPvPRoundMode::OnDie( DnActorHandle hActor, DnActorHandle hHitter ) { CPvPGameMode::OnDie( hActor, hHitter ); OnCheckFinishRound( PvPCommon::FinishReason::OpponentTeamAllDead ); } void CPvPRoundMode::OnLeaveUser( DnActorHandle hActor ) { CPvPGameMode::OnLeaveUser( hActor ); if( hActor ) { wchar_t* pwName = hActor->GetName(); if( pwName ) m_mBreakInto.erase( pwName ); } } #if defined( PRE_MOD_PVP_ROUNDMODE_PENALTY ) void CPvPRoundMode::GetFinishRoundPenalty( const UINT uiWinTeam, OUT UINT& uiPenaltyPercent ) { uiPenaltyPercent = 0; UINT uiWinConditionScore = GetSelectWinCondition(); UINT uiATeamScore = 0; UINT uiBTeamScore = 0; GetGameModeScore(uiATeamScore, uiBTeamScore); UINT uiWinTeamScore = 0; if( PvPCommon::Team::A == uiWinTeam ) uiWinTeamScore = uiATeamScore; if( PvPCommon::Team::B == uiWinTeam ) uiWinTeamScore = uiBTeamScore; UINT uiDefaultPercent = 100; if(0 < uiWinConditionScore) { uiDefaultPercent = uiWinTeamScore * 100 / uiWinConditionScore; uiDefaultPercent = min(uiDefaultPercent, 100); } uiPenaltyPercent = 100 - uiDefaultPercent; } #endif // #if defined( PRE_MOD_PVP_ROUNDMODE_PENALTY ) void CPvPRoundMode::_OnStartRound() { m_bFinishRoundFlag = false; m_bStartGameModeFlag = false; m_mBreakInto.clear(); m_pScoreSystem->OnStartRound(); for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNGameRoom::PartyStruct* pPartyStruct = GetGameRoom()->GetPartyData(i); if( pPartyStruct->pSession ) { DnActorHandle hActor = pPartyStruct->pSession->GetActorHandle(); // 1. ¸ðµç »óÅÂÈ¿°ú ¾ø¾ÖÁØ´Ù. if( hActor ) hActor->OnInitializePVPRoundRestart(); // 2. »õ·Î¿î ¶ó¿îµå ½ÃÀÛÀ» ¾Ë¸°´Ù. pPartyStruct->pSession->SendPvPRoundStart(); if( hActor && pPartyStruct->pSession->GetState() == SESSION_STATE_GAME_PLAY ) { DN_ASSERT( m_pGameRoom->bIsPvPRoom() == true, "CPvPRoundMode::_OnStartRound() m_pGameRoom->bIsPvPRoom() == true" ); // ÇÁ·ÎÁ§Å¸ÀÏ ¾ø¾Ø´Ù CDnWeapon::ReleaseClass( GetGameRoom(), CDnWeapon::Projectile ); // InstantItem ³¯¸°´Ù. pPartyStruct->pSession->GetItem()->RemoveInstantItemData( true ); CDNPvPGameRoom* pPvPGameRoom = static_cast(m_pGameRoom); pPvPGameRoom->CmdPvPStartAddStateEffect( hActor, _GetPvPRoundStartStateEffectDurationTick(), true ); // 4.Respawn Æ÷ÀÎÆ®·Î À̵¿ _OnStartRoundStartPosition( hActor ); hActor->GetStateBlow()->Process( 0, 0.f, true ); // 5.HP/SP ¼³Á¤ _OnRefreshHPSP( hActor ); } } } } void CPvPRoundMode::_OnStartRoundStartPosition( DnActorHandle hActor ) { _SetRespawnPosition( hActor, true ); } void CPvPRoundMode::_FinishRound( const UINT uiWinTeam, PvPCommon::FinishReason::eCode Reason ) { for( UINT i=0 ; iGetUserCount() ; ++i ) { CDNGameRoom::PartyStruct* pPartyStruct = GetGameRoom()->GetPartyData(i); if( pPartyStruct->pSession ) { if( pPartyStruct->pSession->GetState() == SESSION_STATE_GAME_PLAY ) { // Observer ´Â ActorHandle ÀÌ ¾ø±â ¶§¹®¿¡ »óÀ§¿¡¼­ ó¸®ÇÑ´Ù. - ±è¹ä - // 1. PvPRoundMode °á°ú¸¦ ¾Ë·ÁÁØ´Ù. #if defined(PRE_ADD_PVP_TOURNAMENT) pPartyStruct->pSession->SendPvPRoundFinish( uiWinTeam, Reason, this, m_uiWinSessionID, m_cCurrentTournamentStep ); #else pPartyStruct->pSession->SendPvPRoundFinish( uiWinTeam, Reason, this ); #endif // #if defined(PRE_ADD_PVP_TOURNAMENT) DnActorHandle hActor = pPartyStruct->pSession->GetActorHandle(); if( !hActor ) continue; INT64 iHP = hActor->GetHP(); // 2. ¸ðµç »óÅÂÈ¿°ú ¾ø¾ÖÁØ´Ù. // Ŭ¶óÀÌ¾ðÆ® SC_FINISH_PVPROUND ÂÊ Ã³¸®µµ °°ÀÌ ¹Ù²ãÁØ´Ù. hActor->OnInitializePVPRoundRestart(); INT64 iHP2 = hActor->GetHP(); // 3. Á×Áö ¾ÊÀº ij¸¯ÅÍ¿¡°Ô¸¸ if( !hActor->IsDie() ) { // 3-1. ´ÙÀ½¶ó¿îµå ´ë±â½Ã°£¸¸Å­ ¹«ÀûBlow °É¾îÁØ´Ù. int iDurationTime = static_cast(m_fFinishRoundDelta*1000); hActor->CDnActor::AddStateBlow( STATE_BLOW::BLOW_099, NULL, iDurationTime, "-1" ); #if defined(PRE_ADD_PVP_TOURNAMENT) if( bIsAllKillMode() || bIsTournamentMode() ) #else if( bIsAllKillMode() ) #endif // #if defined(PRE_ADD_PVP_TOURNAMENT) static_cast(m_pGameRoom)->CmdPvPStartAddStateEffect( hActor, -1, true ); else { // 3-2. ¿ÉÁ®¹ö Blow °É¾îÁØ´Ù. static_cast(m_pGameRoom)->CmdObserverAddStateEffect( hActor ); } } } } } OnFinishRound(); }