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

892 lines
No EOL
28 KiB
C++

#include "Stdafx.h"
#include "PvPTournamentMode.h"
#include "DNGameRoom.h"
#include "DNUserSession.h"
#include "PvPAllKillModeState.hpp"
#include "PvPScoreSystem.h"
#include "PvPAllKillScoreSystem.h"
#include "DNAggroSystem.h"
#include "DNMissionSystem.h"
#include "DNDBConnection.h"
#if defined(PRE_ADD_PVP_TOURNAMENT)
CPvPTournamentMode::CPvPTournamentMode( CDNGameRoom* pGameRoom, const TPvPGameModeTable* pPvPGameModeTable, const MAGAPVP_GAMEMODE* pPacket )
:CPvPAllKillMode( pGameRoom, pPvPGameModeTable, pPacket )
{
memset(m_sTournamentMatchInfo, 0, sizeof(m_sTournamentMatchInfo));
memset(m_cTournamentActorIndex, 0, sizeof(m_cTournamentActorIndex));
m_cTournamentType = pPacket->cMaxUser;
m_cTournamentArea = 2;
}
CPvPTournamentMode::~CPvPTournamentMode()
{
}
void CPvPTournamentMode::ChangeState( eState State )
{
IPvPAllKillModeState* pPrevState = m_pState;
IPvPAllKillModeState* pNewState = NULL;
switch( State )
{
case eState::None:
{
pNewState = new CPvPAllKillModeNoneState( this );
break;
}
case eState::SelectPlayer:
{
pNewState = new CPvPAllKillModeSelectPlayerState( this );
SendIdleTick(PvPCommon::AllKillMode::Time::SelectPlayerTick);
break;
}
case eState::Starting:
{
if( CheckTournamentActiveActor() )
pNewState = new CPvPAllKillModeStartingState( this );
else
{
// 부전승이면 경기가 완전히 끝났는지 체크..
if ( CheckLastRound() )
{
_ProcessFinishRound(PvPCommon::Team::Max, PvPCommon::FinishReason::OpponentTeamAllGone );
return;
}
else
{
//Select 상태로 다시 돌아가기..
pNewState = new CPvPAllKillModeSelectPlayerState( this );
SendIdleTick(PvPCommon::AllKillMode::Time::SelectPlayerTick);
}
}
break;
}
case eState::Playing:
{
pNewState = new CPvPAllKillModePlayingState( this );
break;
}
case eState::FinishRound:
{
pNewState = new CPvPAllKillModeFinishRoundState( this );
break;
}
}
if( pPrevState )
pPrevState->EndState();
pNewState->BeginState();
SAFE_DELETE( pPrevState );
m_pState = pNewState;
}
void CPvPTournamentMode::_BeforeProcess( LOCAL_TIME LocalTime, float fDelta )
{
m_pState->BeforeProcess( fDelta );
if( m_pState->GetState() == eState::None )
{
SendTournamentMatchList();
#if defined( PRE_PVP_GAMBLEROOM )
if(GetGameRoom() && GetGameRoom()->GetGambleRoomDBID() > 0 )
{
AddGambleMemberDB();
}
#endif
ChangeState( SelectPlayer );
}
}
void CPvPTournamentMode::_AfterProcess( LOCAL_TIME LocalTime, float fDelta )
{
m_pState->AfterProcess( fDelta );
switch( m_pState->GetState() )
{
case SelectPlayer:
{
if( m_pState->GetElapsedTick() >= PvPCommon::AllKillMode::Time::SelectPlayerTick )
ChangeState( Starting );
break;
}
case Starting:
{
if( m_fStartDelta <= 0.f )
ChangeState( Playing );
break;
}
case Playing:
{
if( m_bFinishRoundFlag == true )
ChangeState( FinishRound );
break;
}
case FinishRound:
{
if( m_fFinishRoundDelta <= 0.f )
ChangeState( SelectPlayer );
break;
}
}
}
BYTE CPvPTournamentMode::GetTournamentRanking(UINT uiSessionID)
{
BYTE cRank = 0;
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID == uiSessionID )
{
if( (m_sTournamentMatchInfo[i].cTournamentStep == PvPCommon::Tournament::TOURNAMENT_4) && !m_sTournamentMatchInfo[i].bAbuse )
cRank = 3;
else if( m_sTournamentMatchInfo[i].cTournamentStep == PvPCommon::Tournament::TOURNAMENT_FINAL && !m_sTournamentMatchInfo[i].bAbuse )
cRank = m_sTournamentMatchInfo[i].bWin ? 1 : 2;
break;
}
}
return cRank;
}
bool CPvPTournamentMode::_CheckFinishGameMode( UINT& uiWinTeam )
{
if( uiWinTeam == PvPCommon::Team::Max )
{
if( m_FinishDetailReason == PvPCommon::FinishDetailReason::HPnContinuousWinDraw )
{
// 여기서 어뷰징으로 둘다 진넘들 셋팅.
char cATeamIndex = GetTournamentActorIndex(PvPCommon::TeamIndex::A);
if( cATeamIndex >= 0 && cATeamIndex < PvPCommon::Common::PvPTournamentUserMax )
{
m_sTournamentMatchInfo[cATeamIndex].bWin = false;
m_sTournamentMatchInfo[cATeamIndex].bAbuse = true;
}
char cBTeamIndex = GetTournamentActorIndex(PvPCommon::TeamIndex::B);
if( cBTeamIndex >= 0 && cBTeamIndex < PvPCommon::Common::PvPTournamentUserMax )
{
m_sTournamentMatchInfo[cBTeamIndex].bWin = false;
m_sTournamentMatchInfo[cBTeamIndex].bAbuse = true;
}
m_uiWinSessionID = 0;
SendTournamentMatchList();
return false;
}
else if( CheckLastRound() )
{
SendLastResult();
return true;
}
return false;
}
PvPCommon::TeamIndex::eCode WinIndex = PvPCommon::Team2Index( static_cast<PvPCommon::Team::eTeam>(uiWinTeam) );
PvPCommon::TeamIndex::eCode LoseIndex = (WinIndex == PvPCommon::TeamIndex::A) ? PvPCommon::TeamIndex::B : PvPCommon::TeamIndex::A ;
// 여기서 이긴넘, 진넘 셋팅
DnActorHandle hWinActor = GetActiveActor( WinIndex );
if( hWinActor )
{
CDNUserSession * pSession = GetGameRoom()->GetUserSession(hWinActor->GetSessionID());
if( pSession )
{
char cIndex = GetTournamentActorIndex(WinIndex);
if( cIndex != -1)
{
m_sTournamentMatchInfo[cIndex].bWin = true;
m_cCurrentTournamentStep = m_sTournamentMatchInfo[cIndex].cTournamentStep;
}
m_uiWinSessionID = pSession->GetSessionID();
}
}
// 진넘은 나가버려서 액터랑 세션이 없을수도 있다.
if( LoseIndex != PvPCommon::Team::Max )
{
char cLoseIndex = GetTournamentActorIndex(LoseIndex);
if( cLoseIndex >= 0 && cLoseIndex < PvPCommon::Common::PvPTournamentUserMax )
m_sTournamentMatchInfo[cLoseIndex].bWin = false;
}
SendTournamentMatchList();
// 마지막 경기인지 확인.
if( CheckLastRound() )
{
uiWinTeam = PvPCommon::Team::Max;
SendLastResult();
return true; // 끝내버리기..
}
return false;
}
void CPvPTournamentMode::SetTournamentUserInfo(MAGAPVP_TOURNAMENT_INFO* pPacket)
{
for( int i=0; i<pPacket->nCount; ++i)
{
memcpy(&m_sTournamentMatchInfo[i].sTournamentUserInfo, &pPacket->sTournamentUserInfo[i], sizeof(STournamentUserInfo));
}
}
#if defined( PRE_WORLDCOMBINE_PVP )
void CPvPTournamentMode::SetTournamentUserInfo( int nIndex, CDNUserSession* pGameSession, bool bIgnorePrevData/*= true*/ )
{
if(!bIgnorePrevData)
{
if( m_sTournamentMatchInfo[nIndex].sTournamentUserInfo.uiAccountDBID > 0 )
return;
}
if( pGameSession )
{
STournamentUserInfo UserInfo;
memset(&UserInfo,0,sizeof(UserInfo));
UserInfo.uiAccountDBID = pGameSession->GetAccountDBID();
UserInfo.biCharacterDBID = pGameSession->GetCharacterDBID();
UserInfo.cJob = pGameSession->GetUserJob();
UserInfo.uiSessionID = pGameSession->GetSessionID();
_wcscpy( UserInfo.wszCharName, _countof(UserInfo.wszCharName), pGameSession->GetCharacterName(), (int)wcslen(pGameSession->GetCharacterName()) );
memcpy(&m_sTournamentMatchInfo[nIndex].sTournamentUserInfo, &UserInfo, sizeof(STournamentUserInfo));
}
}
void CPvPTournamentMode::SetTournamentUserInfo()
{
int nUserCount = GetGameRoom()->GetLiveUserCount();
DWORD dwCount = 0;
DnActorHandle hActor;
for( DWORD i=0; i<GetGameRoom()->GetUserCount(); i++ )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
hActor = GetGameRoom()->GetUserData(i)->GetActorHandle();
if( pSession && pSession->GetActorHandle() && !pSession->GetActorHandle()->IsDie() )
{
STournamentUserInfo UserInfo;
memset(&UserInfo,0,sizeof(UserInfo));
UserInfo.uiAccountDBID = pSession->GetAccountDBID();
UserInfo.biCharacterDBID = pSession->GetCharacterDBID();
UserInfo.cJob = pSession->GetUserJob();
UserInfo.uiSessionID = pSession->GetSessionID();
_wcscpy( UserInfo.wszCharName, _countof(UserInfo.wszCharName), pSession->GetCharacterName(), (int)wcslen(pSession->GetCharacterName()) );
memcpy(&m_sTournamentMatchInfo[dwCount].sTournamentUserInfo, &UserInfo, sizeof(STournamentUserInfo));
dwCount++;
}
}
}
void CPvPTournamentMode::SetWorldPvPRoomStart()
{
if( GetGameRoom()->GetBreakIntoUserCount() == 0)
{
if( !CheckTournamentTeam() )
SetTournamentUserInfo();
SendTournamentUserInfo();
SetStartSetting(true);
}
}
bool CPvPTournamentMode::CheckTournamentTeam()
{
for( DWORD i=0; i<GetGameRoom()->GetUserCount(); i++ )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession && pSession->GetActorHandle() && !pSession->GetActorHandle()->IsDie() )
{
bool bExitUser = false;
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax;i++ )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID == pSession->GetAccountDBID() )
{
bExitUser = true;
break;
}
}
if( !bExitUser )
return false;
}
}
return true;
}
void CPvPTournamentMode::SendTournamentUserInfo()
{
PvPCommon::UserInfoList UserInfoList;
memset(&UserInfoList,0,sizeof(UserInfoList));
WCHAR* pwOffset = UserInfoList.wszBuffer;
BYTE cUserCount = 0;
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax;i++ )
{
CDNUserSession* pSession = GetGameRoom()->GetUserSession(m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID);
if( pSession && pSession->GetActorHandle() && !pSession->GetActorHandle()->IsDie() )
{
UserInfoList.uiSessionID[cUserCount] = pSession->GetSessionID();
UserInfoList.iJobID[cUserCount] = pSession->GetUserJob();
UserInfoList.cLevel[cUserCount] = pSession->GetLevel();
UserInfoList.cPvPLevel[cUserCount] = pSession->GetPvPData()->cLevel;
UserInfoList.usTeam[cUserCount] = pSession->GetTeam();
UserInfoList.cTeamIndex[cUserCount] = i;
UserInfoList.uiUserState[cUserCount] = pSession->GetPvPUserState();
UserInfoList.cCharacterNameLen[cUserCount] = static_cast<BYTE>(wcslen(pSession->GetCharacterName()));
memcpy( pwOffset, pSession->GetCharacterName(), sizeof(WCHAR)*UserInfoList.cCharacterNameLen[cUserCount] );
pwOffset += UserInfoList.cCharacterNameLen[cUserCount];
++cUserCount;
}
}
int nSize = static_cast<int>(sizeof(PvPCommon::UserInfoList)-sizeof(UserInfoList.wszBuffer)+(sizeof(WCHAR)*(pwOffset-UserInfoList.wszBuffer)));
if( cUserCount > 0 )
{
for( DWORD i=0; i<GetGameRoom()->GetUserCount(); i++ )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession )
{
pSession->SendWorldPvPRoomTournamentUserInfo( cUserCount, &UserInfoList, nSize);
}
}
}
return;
}
#endif
bool CPvPTournamentMode::CheckLastRound()
{
if( m_cTournamentStep == PvPCommon::Tournament::TOURNAMENT_FINAL && m_cTournamentStepCount == 1) // 결승전 이면.
return true;
else
{
// 두넘이 true이면 마지막이 아님..
int nWinUserCount = 0;
char cLastIndex = -1;
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID > 0 )
{
if( !m_sTournamentMatchInfo[i].bLeave && (m_sTournamentMatchInfo[i].bWin == true || m_sTournamentMatchInfo[i].bStartMatch == false) ) // 경기를 한넘도 안뛰거나 이긴넘
{
++nWinUserCount;
cLastIndex = i;
}
if( nWinUserCount >= 2)
return false;
}
}
// 요때는 마지막넘을 강제로 1위로 셋팅합니다.
if( cLastIndex != -1 )
{
m_sTournamentMatchInfo[cLastIndex].cTournamentStep = PvPCommon::Tournament::TOURNAMENT_FINAL;
m_sTournamentMatchInfo[cLastIndex].bWin = true;
m_uiWinSessionID = m_sTournamentMatchInfo[cLastIndex].sTournamentUserInfo.uiSessionID;
}
return true;
}
return false;
}
void CPvPTournamentMode::OnLeaveUser( DnActorHandle hActor )
{
if( hActor )
{
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if(m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID == hActor->GetSessionID())
{
m_sTournamentMatchInfo[i].bLeave = true;
}
}
}
CPvPAllKillMode::OnLeaveUser( hActor );
}
void CPvPTournamentMode::OnCheckFinishRound( PvPCommon::FinishReason::eCode Reason )
{
UINT uiWinTeam = PvPCommon::Team::Max;
m_FinishDetailReason = PvPCommon::FinishDetailReason::None;
switch( Reason )
{
case PvPCommon::FinishReason::OpponentTeamAllDead:
{
DnActorHandle hATeamActor = GetActiveActor( PvPCommon::TeamIndex::A );
DnActorHandle hBTeamActor = GetActiveActor( PvPCommon::TeamIndex::B );
if( !hATeamActor || !hBTeamActor )
return;
if( hATeamActor->IsDie() && hBTeamActor->IsDie() )
return;
if( !(hATeamActor->IsDie()) && !(hBTeamActor->IsDie()) )
return;
uiWinTeam = hATeamActor->IsDie() ? PvPCommon::Team::B : PvPCommon::Team::A;
break;
}
case PvPCommon::FinishReason::OpponentTeamAllGone:
{
DnActorHandle hATeamActor = GetActiveActor( PvPCommon::TeamIndex::A );
DnActorHandle hBTeamActor = GetActiveActor( PvPCommon::TeamIndex::B );
if( hATeamActor && hBTeamActor )
return;
if( hATeamActor && !hBTeamActor )
uiWinTeam = PvPCommon::Team::A;
else if( !hATeamActor && hBTeamActor )
uiWinTeam = PvPCommon::Team::B;
break;
}
case PvPCommon::FinishReason::TimeOver:
{
DnActorHandle hATeamActor = GetActiveActor( PvPCommon::TeamIndex::A );
DnActorHandle hBTeamActor = GetActiveActor( PvPCommon::TeamIndex::B );
if( hATeamActor && hBTeamActor )
{
m_FinishDetailReason = PvPCommon::FinishDetailReason::SuperiorHPWin;
int iAHPPercent = hATeamActor->GetHPPercent();
int iBHPPercent = hBTeamActor->GetHPPercent();
if( iAHPPercent > iBHPPercent )
uiWinTeam = PvPCommon::Team::A;
else if( iAHPPercent < iBHPPercent )
uiWinTeam = PvPCommon::Team::B;
else
{
// 어그로로 실제 싸운넘인지 확인
CDNAggroSystem::AggroStruct* pATargetStruct = hATeamActor->GetAggroSystem()->GetAggroStruct(hBTeamActor);
CDNAggroSystem::AggroStruct* pBTargetStruct = hBTeamActor->GetAggroSystem()->GetAggroStruct(hATeamActor);
if( pATargetStruct && pBTargetStruct )
{
if( pATargetStruct->iAggro > pBTargetStruct->iAggro )
{
m_FinishDetailReason = PvPCommon::FinishDetailReason::SuperiorContinuousWin;
uiWinTeam = PvPCommon::Team::B;
}
else if ( pATargetStruct->iAggro < pBTargetStruct->iAggro )
{
m_FinishDetailReason = PvPCommon::FinishDetailReason::SuperiorContinuousWin;
uiWinTeam = PvPCommon::Team::A;
}
else
{
uiWinTeam = PvPCommon::Team::Max;
m_FinishDetailReason = PvPCommon::FinishDetailReason::HPnContinuousWinDraw;
}
}
else
{
uiWinTeam = PvPCommon::Team::Max;
m_FinishDetailReason = PvPCommon::FinishDetailReason::HPnContinuousWinDraw;
}
}
}
else if( !hATeamActor && !hBTeamActor )
{
uiWinTeam = PvPCommon::Team::Max;
}
else
{
uiWinTeam = hATeamActor ? PvPCommon::Team::A : PvPCommon::Team::B;
}
break;
}
default:
{
return;
}
}
_ProcessFinishRound( uiWinTeam, Reason );
}
void CPvPTournamentMode::_ProcessFinishRoundMode( CDNUserSession* pSession, bool bIsWin, UINT uiWinTeam, PvPCommon::FinishReason::eCode Reason )
{
DnActorHandle hActor = pSession->GetActorHandle();
if( !hActor )
return;
if( bIsActiveActor( hActor) == false )
return;
if( bIsWin == true )
hActor->CmdRefreshHPSP( hActor->GetMaxHP(), hActor->GetMaxSP() );
else
hActor->CmdRefreshHPSP( 0,0 );
PvPCommon::TeamIndex::eCode TeamIndex = PvPCommon::Team2Index( static_cast<PvPCommon::Team::eTeam>(hActor->GetTeam()) );
if( TeamIndex == PvPCommon::TeamIndex::Max )
return;
char cIndex = GetTournamentActorIndex(TeamIndex);
if( cIndex != -1)
{
pSession->GetEventSystem()->OnEvent( EventSystem::OnRoundFinished, 4, EventSystem::PvPGameMode, PvPCommon::GameMode::PvP_Tournament,
EventSystem::PvPTournamentType, m_cTournamentType, EventSystem::PvPTournamentAdvance, m_sTournamentMatchInfo[cIndex].cTournamentStep,
EventSystem::PvPTournamentWin, bIsWin == true ? 1 : 0);
}
}
bool CPvPTournamentMode::CheckTournamentActiveActor()
{
while(true) // 나가는 조건은 1:1이 성립하거나 결승전이 셋팅될때.
{
if( m_cTournamentStep == PvPCommon::Tournament::TOURNAMENT_FINAL && m_cTournamentStepCount == 1) // 결승전 이면.
return false;
char cATeamIndex = -1;
char cBTeamIndex = -1;
CDNUserSession* pATeamUser = NULL;
CDNUserSession* pBTeamUser = NULL;
GetTournamentActiveActorIndex(m_cTournamentStep*2, cATeamIndex, cBTeamIndex);
if( cATeamIndex >= 0 && cATeamIndex < PvPCommon::Common::PvPTournamentUserMax)
{
pATeamUser = GetGameRoom()->GetUserSession(m_sTournamentMatchInfo[cATeamIndex].sTournamentUserInfo.uiSessionID);
m_sTournamentMatchInfo[cATeamIndex].cTournamentStep = m_cTournamentStep;
m_sTournamentMatchInfo[cATeamIndex].bStartMatch = true;
}
if( cBTeamIndex >= 0 && cBTeamIndex < PvPCommon::Common::PvPTournamentUserMax)
{
pBTeamUser = GetGameRoom()->GetUserSession(m_sTournamentMatchInfo[cBTeamIndex].sTournamentUserInfo.uiSessionID);
m_sTournamentMatchInfo[cBTeamIndex].cTournamentStep = m_cTournamentStep;
m_sTournamentMatchInfo[cBTeamIndex].bStartMatch = true;
}
++ m_cTournamentStepCount;
if( m_cTournamentStep/2 == m_cTournamentStepCount && m_cTournamentStep > PvPCommon::Tournament::TOURNAMENT_FINAL )
{
//다음으로
m_cTournamentStepCount = 0;
m_cTournamentStep = m_cTournamentStep/2;
m_cTournamentArea = m_cTournamentArea*2;
}
if( (pATeamUser && pATeamUser->GetActorHandle()) && (pBTeamUser == NULL || !pBTeamUser->GetActorHandle()) ) // 부전승
{
m_sTournamentMatchInfo[cATeamIndex].bWin = true;
if( cBTeamIndex >= 0)
m_sTournamentMatchInfo[cBTeamIndex].bWin = false;
m_uiWinSessionID = pATeamUser->GetSessionID();
SendTournamentDefaultWin(m_sTournamentMatchInfo[cATeamIndex].cTournamentStep, pATeamUser->GetSessionID());
SendTournamentMatchList();
return false;
}
else if( (pATeamUser == NULL || !pATeamUser->GetActorHandle()) && (pBTeamUser && pBTeamUser->GetActorHandle()) )
{
if( cATeamIndex >= 0 )
m_sTournamentMatchInfo[cATeamIndex].bWin = false;
m_sTournamentMatchInfo[cBTeamIndex].bWin = true;
m_uiWinSessionID = pBTeamUser->GetSessionID();
SendTournamentDefaultWin(m_sTournamentMatchInfo[cBTeamIndex].cTournamentStep, pBTeamUser->GetSessionID());
SendTournamentMatchList();
return false;
}
else if( (pATeamUser == NULL || !pATeamUser->GetActorHandle()) && (pBTeamUser == NULL || !pBTeamUser->GetActorHandle()) )
{
if( cATeamIndex >= 0 )
m_sTournamentMatchInfo[cATeamIndex].bWin = false;
if( cBTeamIndex >= 0)
m_sTournamentMatchInfo[cBTeamIndex].bWin = false;
}
else if( (pATeamUser && pATeamUser->GetActorHandle()) && (pBTeamUser && pBTeamUser->GetActorHandle()) )
{
pATeamUser->GetActorHandle()->CmdChangeTeam(PvPCommon::Team::A);
pBTeamUser->GetActorHandle()->CmdChangeTeam(PvPCommon::Team::B);
SetActiveActor( PvPCommon::TeamIndex::A, pATeamUser->GetActorHandle(), false );
SetActiveActor( PvPCommon::TeamIndex::B, pBTeamUser->GetActorHandle(), false );
SetTournamentActorIndex(PvPCommon::TeamIndex::A, cATeamIndex);
SetTournamentActorIndex(PvPCommon::TeamIndex::B, cBTeamIndex);
return true;
}
}
return false;
}
void CPvPTournamentMode::GetTournamentActiveActorIndex(char cStep, char& cATeamIndex, char& cBTeamIndex)
{
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID > 0 )
{
if( m_sTournamentMatchInfo[i].cTournamentStep == PvPCommon::Tournament::TOURNAMENT_NONE ||
(m_sTournamentMatchInfo[i].cTournamentStep == cStep && m_sTournamentMatchInfo[i].bWin == true) )
{
if(cATeamIndex == -1)
cATeamIndex = i;
else if(cBTeamIndex == -1)
{
// A랑 현재 같은 Group에 있는지 검사한다.
if( cATeamIndex/m_cTournamentArea == i/m_cTournamentArea )
{
cBTeamIndex = i;
break;
}
}
}
}
}
}
void CPvPTournamentMode::OnSuccessBreakInto( CDNUserSession* pGameSession )
{
CPvPAllKillMode::OnSuccessBreakInto(pGameSession);
SendTournamentMatchList(pGameSession);
}
char CPvPTournamentMode::GetTournamentActorIndex(PvPCommon::TeamIndex::eCode Team)
{
return m_cTournamentActorIndex[Team];
}
void CPvPTournamentMode::SetTournamentActorIndex( PvPCommon::TeamIndex::eCode Team, BYTE cActorIndex )
{
if( cActorIndex >= PvPCommon::Common::PvPTournamentUserMax )
return;
m_cTournamentActorIndex[Team] = cActorIndex;
}
void CPvPTournamentMode::SendTournamentMatchList(CDNUserSession* pBreakIntoUserSession)
{
SCPvPTournamentMatchList TxPacket;
memset( &TxPacket, 0, sizeof(TxPacket) );
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID > 0 )
{
TxPacket.sTournamentUserInfo[i].cTournamentStep = m_sTournamentMatchInfo[i].cTournamentStep;
TxPacket.sTournamentUserInfo[i].bWin = m_sTournamentMatchInfo[i].bWin;
TxPacket.sTournamentUserInfo[i].cJob = m_sTournamentMatchInfo[i].sTournamentUserInfo.cJob;
TxPacket.sTournamentUserInfo[i].uiSessionID = m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID;
memcpy(TxPacket.sTournamentUserInfo[i].wszCharName, m_sTournamentMatchInfo[i].sTournamentUserInfo.wszCharName, sizeof(TxPacket.sTournamentUserInfo[i].wszCharName));
++TxPacket.nCount;
}
}
#if defined( PRE_PVP_GAMBLEROOM )
CDNPvPGameRoom * pPvPRoom = static_cast<CDNPvPGameRoom*>(GetGameRoom());
if(pPvPRoom)
{
pPvPRoom->SetGamblePlayerCount(TxPacket.nCount);
TxPacket.cGambleType = pPvPRoom->GetGambleType();
TxPacket.nGamblePrice = pPvPRoom->GetGamblePrice();
}
#endif
int nLen = sizeof(SCPvPTournamentMatchList) - sizeof(TxPacket.sTournamentUserInfo) + (sizeof(TPvPTournamentUserInfo)*TxPacket.nCount);
if( pBreakIntoUserSession )
{
pBreakIntoUserSession->AddSendData( SC_PVP, ePvP::SC_PVP_TOURNAMENT_MATCHLIST, reinterpret_cast<char*>(&TxPacket), nLen );
return;
}
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession == NULL )
continue;
pSession->AddSendData( SC_PVP, ePvP::SC_PVP_TOURNAMENT_MATCHLIST, reinterpret_cast<char*>(&TxPacket), nLen );
}
}
void CPvPTournamentMode::SendTournamentDefaultWin(char cTournamentStep, UINT uiWinSessionID)
{
SCPvPTournamentDefaultWin TxPacket;
memset( &TxPacket, 0, sizeof(TxPacket) );
TxPacket.cTournamentStep = cTournamentStep;
TxPacket.uiWinSessionID = uiWinSessionID;
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession == NULL )
continue;
pSession->AddSendData( SC_PVP, ePvP::SC_PVP_TOURNAMENT_DEFAULTWIN, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
}
}
void CPvPTournamentMode::SendIdleTick(UINT uiIdleTick)
{
SCPvPTournamentIdleTick TxPacket;
memset( &TxPacket, 0, sizeof(TxPacket) );
TxPacket.uiCurTick = timeGetTime();
TxPacket.uiIdleTick = uiIdleTick;
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession == NULL )
continue;
pSession->AddSendData( SC_PVP, ePvP::SC_PVP_TOURNAMENT_IDLE_TICK, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
}
}
void CPvPTournamentMode::SendLastResult()
{
// 4위까지 참가자들한테 보내주고.
SendTournamentTop4();
// DB에 로그 심기
CDNDBConnection* pDBCon = GetGameRoom()->GetDBConnection();
if( pDBCon )
{
#if defined( PRE_PVP_GAMBLEROOM )
pDBCon->QueryAddTournamentResult(GetGameRoom()->GetDBThreadID(), GetGameRoom()->GetWorldSetID(), &m_sTournamentMatchInfo[0], GetGameRoom()->GetGambleRoomDBID());
#else
pDBCon->QueryAddTournamentResult(GetGameRoom()->GetDBThreadID(), GetGameRoom()->GetWorldSetID(), &m_sTournamentMatchInfo[0]);
#endif
}
}
void CPvPTournamentMode::SendTournamentTop4()
{
SCPvPTournamentTop4 TxPacket;
memset(&TxPacket, 0, sizeof(TxPacket));
#if defined( PRE_PVP_GAMBLEROOM )
CDNPvPGameRoom * pPvPRoom = static_cast<CDNPvPGameRoom*>(GetGameRoom());
BYTE cGambleRoomType = 0;
INT64 nGambleRoomDBID = 0;
TPvPGambleRoomWinData Member[PvPGambleRoom::Max];
memset(Member, 0, sizeof(Member));
if(pPvPRoom)
{
if( pPvPRoom->GetGambleType() > 0 )
{
cGambleRoomType = pPvPRoom->GetGambleType();
nGambleRoomDBID = pPvPRoom->GetGambleRoomDBID();
int nTotalPrice = pPvPRoom->GetGamblePrice() * pPvPRoom->GetGamblePlayerCount();
float fRate = CGlobalWeightTable::GetInstance().GetValue(CGlobalWeightTable::PvPGambleFirstWinnerRate);
int nGold = 1;
if( pPvPRoom->GetGambleType() == PvPGambleRoom::Gold )
nGold = 10000;
Member[PvPGambleRoom::firstWinner].nPrice = ((int)(nTotalPrice * fRate) * nGold);
fRate = CGlobalWeightTable::GetInstance().GetValue(CGlobalWeightTable::PvPGambleSecondWinnerRate);
Member[PvPGambleRoom::SecondWinner].nPrice = ((int)(nTotalPrice * fRate) * nGold);
}
}
#endif
BYTE cRank = 0;
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID > 0 )
{
cRank = 0;
if( (m_sTournamentMatchInfo[i].cTournamentStep == PvPCommon::Tournament::TOURNAMENT_4) && !m_sTournamentMatchInfo[i].bAbuse )
cRank = 3;
else if( (m_sTournamentMatchInfo[i].cTournamentStep == PvPCommon::Tournament::TOURNAMENT_FINAL) && !m_sTournamentMatchInfo[i].bAbuse )
cRank = m_sTournamentMatchInfo[i].bWin ? 1 : 2;
if( cRank > 0)
{
CDNUserSession* pUser = GetGameRoom()->GetUserSession(m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID);
if( pUser ) // 접속 중인 아이만..
{
if( cRank == 3 && TxPacket.uiSessionID[2] > 0) // 3위는 2명
TxPacket.uiSessionID[3] = m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID;
else
{
TxPacket.uiSessionID[cRank-1] = m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID;
#if defined( PRE_PVP_GAMBLEROOM )
if( cGambleRoomType > 0 && cRank <= PvPGambleRoom::Max)
{
if( cGambleRoomType == PvPGambleRoom::Gold )
{
int nLogCode = 0;
if(cRank == 1 )
nLogCode = DBDNWorldDef::CoinChangeCode::GambleFirstWinner;
else
nLogCode = DBDNWorldDef::CoinChangeCode::GambleSecondWinner;
pUser->AddCoin( Member[cRank-1].nPrice, nLogCode, nGambleRoomDBID, true );
}
else if( cGambleRoomType == PvPGambleRoom::Petal && pUser->GetDBConnection() )
{
int nLogCode = 0;
if(cRank == 1 )
nLogCode = DBDNWorldDef::CoinChangeCode::GambleFirstWinPetal;
else
nLogCode = DBDNWorldDef::CoinChangeCode::GambleSecondWinPetal;
pUser->GetDBConnection()->QueryPetalLog(pUser, Member[cRank-1].nPrice, 0, DBDNWorldDef::CoinChangeCode::GambleFirstWinPetal, nGambleRoomDBID);
}
TxPacket.nGamblePrice[cRank-1] = Member[cRank-1].nPrice;
Member[cRank-1].biCharacterDBID = pUser->GetCharacterDBID();
}
#endif
}
}
}
}
}
for( UINT i=0 ; i<GetGameRoom()->GetUserCount() ; ++i )
{
CDNUserSession* pSession = GetGameRoom()->GetUserData(i);
if( pSession == NULL )
continue;
pSession->AddSendData( SC_PVP, ePvP::SC_PVP_TOURNAMENT_TOP4, reinterpret_cast<char*>(&TxPacket), sizeof(TxPacket) );
}
#if defined( PRE_PVP_GAMBLEROOM )
if( GetGameRoom()->GetDBConnection() && cGambleRoomType > 0 )
{
GetGameRoom()->GetDBConnection()->QueryEndGambleRoom(GetGameRoom()->GetDBThreadID(), GetGameRoom()->GetWorldSetID(), GetGameRoom()->GetGambleRoomDBID(), Member);
}
#endif
}
#endif // #if defined(PRE_ADD_PVP_TOURNAMENT)
#if defined( PRE_PVP_GAMBLEROOM )
void CPvPTournamentMode::AddGambleMemberDB()
{
if( !GetGameRoom()->bIsPvPRoom() )
return;
CDNPvPGameRoom * pPvPRoom = static_cast<CDNPvPGameRoom*>(GetGameRoom());
int nGamblePrice = pPvPRoom->GetGamblePrice();
if( pPvPRoom->GetGambleType() == PvPGambleRoom::Gold )
nGamblePrice *= 10000 ;
INT64 nGambleRoomDBID = pPvPRoom->GetGambleRoomDBID();
for( int i=0; i<PvPCommon::Common::PvPTournamentUserMax; ++i )
{
if( m_sTournamentMatchInfo[i].sTournamentUserInfo.uiAccountDBID > 0 )
{
CDNUserSession* pUser = GetGameRoom()->GetUserSession(m_sTournamentMatchInfo[i].sTournamentUserInfo.uiSessionID);
if( pUser && pUser->GetDBConnection() ) // 접속 중인 아이만
{
// 참가 유저
pUser->GetDBConnection()->QueryAddGambleRoomMember( pUser->GetDBThreadID(), pUser->GetWorldSetID(), nGambleRoomDBID, pUser->GetCharacterDBID());
// 참가비 삭제
if( pPvPRoom->GetGambleType() == PvPGambleRoom::Gold )
pUser->DelCoin( nGamblePrice, DBDNWorldDef::CoinChangeCode::GamblePrice, nGambleRoomDBID, true );
else if( pPvPRoom->GetGambleType() == PvPGambleRoom::Petal )
pUser->GetDBConnection()->QueryUsePetal(pUser->GetDBThreadID(), pUser->GetWorldSetID(), pUser->GetAccountDBID(), pUser->GetCharacterDBID(), nGamblePrice, DBDNWorldDef::CoinChangeCode::GambleEnterPetal, nGambleRoomDBID);
}
}
}
}
#endif