DragonNest/Server/DNGameServer/PvPRoundMode.cpp
Cussrro 47f7895977 Revert "修复编码问题"
This reverts commit 9e69c01767.
2024-12-21 10:04:04 +08:00

480 lines
14 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<CDnPlayerActor *>(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 ; i<GetGameRoom()->GetUserCount() ; ++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 ; i<GetGameRoom()->GetUserCount() ; ++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 ; i<GetGameRoom()->GetUserCount() ; ++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<UINT&>(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<CDNPvPGameRoom*>(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<int>(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<CDnPlayerActor *>(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 ; i<GetGameRoom()->GetUserCount() ; ++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<CDNPvPGameRoom*>(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 ; i<GetGameRoom()->GetUserCount() ; ++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<int>(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<CDNPvPGameRoom*>(m_pGameRoom)->CmdPvPStartAddStateEffect( hActor, -1, true );
else
{
// 3-2. ¿ÉÁ®¹ö Blow °É¾îÁØ´Ù.
static_cast<CDNPvPGameRoom*>(m_pGameRoom)->CmdObserverAddStateEffect( hActor );
}
}
}
}
}
OnFinishRound();
}