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

264 lines
7.8 KiB
C++

#include "stdafx.h"
#include "PvPCaptainMode.h"
#include "DnPlayerActor.h"
#include "DNUserSession.h"
#include "DNPvPGameRoom.h"
#include "TaskManager.h"
#include "DnGameTask.h"
#include "DnStateBlow.h"
#include "DNMissionSystem.h"
CPvPCaptainMode::CPvPCaptainMode( CDNGameRoom* pGameRoom, const TPvPGameModeTable* pPvPGameModeTable, const MAGAPVP_GAMEMODE* pPacket )
:CPvPRoundMode( pGameRoom, pPvPGameModeTable, pPacket )
{
}
CPvPCaptainMode::~CPvPCaptainMode()
{
}
void CPvPCaptainMode::Process( LOCAL_TIME LocalTime, float fDelta )
{
_ProcessSelectCaptain();
CPvPRoundMode::Process( LocalTime, fDelta );
// Playing 중일 때 대장 나갔는지 검사
if( bIsPlaying() )
OnCheckFinishRound( PvPCommon::FinishReason::OpponentCaptainGone );
}
void CPvPCaptainMode::OnFinishProcessDie( DnActorHandle hActor )
{
if( !bIsPlaying() )
return;
if( bIsCaptain( hActor ) )
return;
if( !bIsPlayingUser( hActor ) )
return;
if( hActor )
{
// 리스폰위치 설정
_SetRespawnPosition( hActor );
// 부활시킴
UINT uiRespawnHPPercent = GetPvPGameModeTable() ? GetPvPGameModeTable()->uiRespawnHPPercent : 100;
UINT uiRespawnMPPercent = GetPvPGameModeTable() ? GetPvPGameModeTable()->uiRespawnMPPercent : 100;
UINT uiImmortalTime = GetPvPGameModeTable() ? GetPvPGameModeTable()->uiRespawnNoDamageTimeSec : 5;
char szParam[32];
sprintf_s( szParam, "Coin/%d/%d/%d", uiRespawnHPPercent, uiRespawnMPPercent, uiImmortalTime );
hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_057, uiImmortalTime*1000, szParam );
}
}
void CPvPCaptainMode::OnCheckFinishRound( PvPCommon::FinishReason::eCode Reason )
{
UINT uiWinTeam = PvPCommon::Team::Max;
switch( Reason )
{
case PvPCommon::FinishReason::TimeOver:
{
if( m_hCaptain[PvPCommon::TeamIndex::A] && m_hCaptain[PvPCommon::TeamIndex::B] )
{
if( m_hCaptain[PvPCommon::TeamIndex::A]->GetHPPercent() > m_hCaptain[PvPCommon::TeamIndex::B]->GetHPPercent() )
uiWinTeam = PvPCommon::Team::A;
else if( m_hCaptain[PvPCommon::TeamIndex::A]->GetHPPercent() < m_hCaptain[PvPCommon::TeamIndex::B]->GetHPPercent() )
uiWinTeam = PvPCommon::Team::B;
CPvPRoundMode::_ProcessFinishRound( uiWinTeam, Reason );
}
return;
}
case PvPCommon::FinishReason::OpponentCaptainGone:
{
if( m_hCaptain[PvPCommon::TeamIndex::A] && m_hCaptain[PvPCommon::TeamIndex::B] )
return;
else if( m_hCaptain[PvPCommon::TeamIndex::A] && !m_hCaptain[PvPCommon::TeamIndex::B] )
uiWinTeam = PvPCommon::Team::A;
else if( !m_hCaptain[PvPCommon::TeamIndex::A] && m_hCaptain[PvPCommon::TeamIndex::B] )
uiWinTeam = PvPCommon::Team::B;
CPvPRoundMode::_ProcessFinishRound( uiWinTeam, Reason );
return;
}
case PvPCommon::FinishReason::OpponentCaptainDead:
{
if( m_hCaptain[PvPCommon::TeamIndex::A] && m_hCaptain[PvPCommon::TeamIndex::A]->IsDie() )
uiWinTeam = PvPCommon::Team::B;
else if( m_hCaptain[PvPCommon::TeamIndex::B] && m_hCaptain[PvPCommon::TeamIndex::B]->IsDie() )
uiWinTeam = PvPCommon::Team::A;
else
return;
// 속도조절
CDnGameTask *pGameTask = (CDnGameTask *)CTaskManager::GetInstance(GetGameRoom()).GetTask( "GameTask" );
if( pGameTask )
pGameTask->RequestChangeGameSpeed( 0.2f, 3000 );
CPvPRoundMode::_ProcessFinishRound( uiWinTeam, Reason );
return;
}
}
CPvPRoundMode::OnCheckFinishRound( Reason );
}
void CPvPCaptainMode::OnFinishRound()
{
for( UINT i=0 ; i<PvPCommon::TeamIndex::Max ; ++i )
m_hCaptain[i] = CDnActor::Identity();
}
void CPvPCaptainMode::OnDie( DnActorHandle hActor, DnActorHandle hHitter )
{
CPvPGameMode::OnDie( hActor, hHitter );
if( bIsCaptain( hActor ) )
{
if( hHitter && hHitter->IsPlayerActor() )
{
CDnPlayerActor* pPlayer = static_cast<CDnPlayerActor*>(hHitter.GetPointer());
if( pPlayer->GetUserSession() )
pPlayer->GetUserSession()->GetEventSystem()->OnEvent( EventSystem::OnPvPKillCaptain );
}
OnCheckFinishRound( PvPCommon::FinishReason::OpponentCaptainDead );
}
}
void CPvPCaptainMode::OnLeaveUser( DnActorHandle hActor )
{
CPvPRoundMode::OnLeaveUser( hActor );
if( hActor )
m_mSelectCaptainCount.erase( hActor->GetSessionID() );
OnCheckFinishRound( PvPCommon::FinishReason::OpponentCaptainGone );
}
void CPvPCaptainMode::OnSuccessBreakInto( CDNUserSession* pGameSession )
{
CPvPRoundMode::OnSuccessBreakInto( pGameSession );
// 난입 유저에게 대장 정보 알려준다.
if( m_hCaptain[PvPCommon::TeamIndex::A] )
pGameSession->SendPvPSelectCaptain( m_hCaptain[PvPCommon::TeamIndex::A]->GetSessionID(), m_hCaptain[PvPCommon::TeamIndex::A]->GetName() );
if( m_hCaptain[PvPCommon::TeamIndex::B] )
pGameSession->SendPvPSelectCaptain( m_hCaptain[PvPCommon::TeamIndex::B]->GetSessionID(), m_hCaptain[PvPCommon::TeamIndex::B]->GetName() );
}
void CPvPCaptainMode::_ProcessSelectCaptain()
{
// Starting 단계에서만 대장이 설정된다.
if( !bIsStarting() )
return;
for( UINT i=0 ; i<PvPCommon::TeamIndex::Max ; ++i )
{
// 이미 대장이 설정되어있으면 설정할 필요가 없다.
if( m_hCaptain[i] )
continue;
std::vector<DnActorHandle> vResult;
_GetCaptainCandidate( static_cast<PvPCommon::Team::eTeam>(PvPCommon::Team::A+i), vResult );
if( vResult.empty() )
continue;
m_hCaptain[i] = vResult[_rand(GetGameRoom())%vResult.size()];
if( m_hCaptain[i] )
{
_AddCaptainBlow( m_hCaptain[i] );
_UpdateSelectCaptainCount( m_hCaptain[i]->GetSessionID() );
_ASSERT( GetGameRoom()->bIsPvPRoom() );
static_cast<CDNPvPGameRoom*>(GetGameRoom())->SendSelectCaptain( m_hCaptain[i] );
}
}
}
void CPvPCaptainMode::_AddCaptainBlow( DnActorHandle hActor )
{
// 대장에게 대장 전용 상태효과를 걸어준다.
// 라운드가 끝나면 상태효과를 해제해주기 때문에 여기서는 시간은 무한으로 걸어준다.
//hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_002, -1, "1.0", true ); // 2) 물리 공격력 비율
hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_050, -1, "1.0", true ); // 50) 파이널 데미지 비율 변경.
//hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_029, -1, "1.0", true ); // 29) 마법 공격 비율
hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_058, -1, "0.5", true ); // 58) 최대 HP 비율
//hActor->CmdAddStateEffect( NULL, STATE_BLOW::BLOW_059, -1, "0.5", true ); // 59) 최대 SP 비율
hActor->GetStateBlow()->Process( 0, 0.f );
hActor->CmdRefreshHPSP( hActor->GetMaxHP(), hActor->GetMaxSP() );
}
bool CPvPCaptainMode::bIsCaptain( DnActorHandle hActor )
{
if( !hActor )
return false;
for( UINT i=0 ; i<PvPCommon::TeamIndex::Max ; ++i )
{
if( !m_hCaptain[i] )
continue;
if( m_hCaptain[i] == hActor )
return true;
}
return false;
}
void CPvPCaptainMode::_UpdateSelectCaptainCount( UINT uiSessionID )
{
std::map<UINT,UINT>::iterator itor = m_mSelectCaptainCount.find( uiSessionID );
if( itor != m_mSelectCaptainCount.end() )
{
++(*itor).second;
}
else
{
m_mSelectCaptainCount.insert( std::make_pair(uiSessionID,1) );
}
}
UINT CPvPCaptainMode::_GetSelectCaptainCount( UINT uiSessionID )
{
std::map<UINT,UINT>::iterator itor = m_mSelectCaptainCount.find( uiSessionID );
if( itor != m_mSelectCaptainCount.end() )
return (*itor).second;
return 0;
}
void CPvPCaptainMode::_GetCaptainCandidate( PvPCommon::Team::eTeam Team, std::vector<DnActorHandle>& vResult )
{
UINT uiMinValue = UINT_MAX;
std::vector<DnActorHandle> vCandidate;
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( !pSession || !pSession->GetActorHandle() )
continue;
if( pSession->GetTeam() != Team )
continue;
if( !bIsPlayingUser( pSession->GetActorHandle() ) )
continue;
UINT uiCount = _GetSelectCaptainCount( pSession->GetSessionID() );
if( uiCount < uiMinValue )
uiMinValue = uiCount;
vCandidate.push_back( pSession->GetActorHandle() );
}
for( UINT i=0 ; i<vCandidate.size() ; ++i )
{
if( _GetSelectCaptainCount( vCandidate[i]->GetSessionID() ) == uiMinValue )
vResult.push_back( vCandidate[i] );
}
}