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

1222 lines
42 KiB
C++

#include "StdAfx.h"
#include "Util.h"
#include "DNGuildWarManager.h"
#include "DNDivisionManager.h"
#include "DNVillageConnection.h"
#include "MtRandom.h"
#include "TimeSet.h"
#include "DNExtManager.h"
#include "DNPvP.h"
CDNGuildWarManager * g_pGuildWarManager = NULL;
extern TMasterConfig g_Config;
CDNGuildWarManager::CDNGuildWarManager()
{
memset (m_pWarEventStep, 0x00, sizeof(m_pWarEventStep));
m_pWarEventStep[GUILDWAR_STEP_PREPARATION] = new CDNGuildWarPreparation;
m_pWarEventStep[GUILDWAR_STEP_TRIAL] = new CDNGuildWarTrial;
m_pWarEventStep[GUILDWAR_STEP_REWARD] = new CDNGuildWarReward;
Clear();
}
void CDNGuildWarManager::Clear()
{
// 스텝 초기화
ResetStep();
m_bSendGuildWarInfo = false;
m_eSettingStep = REQ_NONE;
m_wWinersWeightRate = 0;
m_wScheduleID = GUILDWARSCHEDULE_DEF;
m_TickCheckGuildWar = 0;
memset(&m_GuildWarFinalInfo, 0, sizeof(m_GuildWarFinalInfo));
memset(&m_sGuildWarSchedule, 0, sizeof(m_sGuildWarSchedule));
memset(&m_sGuildWarFinalSchedule, 0, sizeof(m_sGuildWarFinalSchedule));
memset(&m_bTournamentGroup, 0, sizeof(m_bTournamentGroup));
memset(&m_GuildWarOpeningPoints, 0, sizeof(m_GuildWarOpeningPoints));
m_nFinalTeamCount = 0;
m_bFinalTeamSetting = false;
m_cSecretTeam = 0;
m_nSecretRandomSeed = 0;
m_bCheatFlag = false;
m_nBlueTeamPoint = 0;
m_nRedTeamPoint = 0;
m_dwPreWinSkillCoolTime = 0;
m_bFinalWinGuild = false;
m_bResetSchedule = false;
m_bFinalStart = false;
memset(&m_sGuildWarPointTrialRanking, 0, sizeof(m_sGuildWarPointTrialRanking));
m_wPreWinScheduleID = 0;
m_bFrinalProgress = false;
m_tRewardExpireDate = 0;
m_PreWinGuildUID.Reset();
#if defined(PRE_FIX_75807)
m_bFarmForceHarbest = false;
#endif //#if defined(PRE_FIX_75807)
}
CDNGuildWarManager::~CDNGuildWarManager()
{
CDNGuildWar** pWarEventStep = m_pWarEventStep;
for (int j=GUILDWAR_STEP_NONE; j<GUILDWAR_STEP_END; j++)
if (pWarEventStep[j]) SAFE_DELETE(pWarEventStep[j])
}
bool CDNGuildWarManager::LoadScheduleInfo(const VIMASetGuildWarSchedule* pData)
{
// 이미 종료된 이벤트 정보인지 확인한다
time_t tCurrentTime;
time(&tCurrentTime);
if (pData->bForce)
{
m_bWarEvent = false;
m_bCheatFlag = true;
}
if (!pData->bForce && tCurrentTime > pData->EventInfo[GUILDWAR_STEP_REWARD].tEndTime)
{
// 이미 지난 이벤트이거나 셋팅이 안된거임
//g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadScheduleInfo Failed !!! TimeOut or Schedule empty\n");
#if defined(PRE_FIX_75807)
// 여기서 혹시 지난 길드전 우승자의 값이 현재를 안넘었는지 본다.
if( pData->tRewardExpireDate > 0 && !GetPreWinGuild().IsSet() )
{
__time64_t tCurrentTime;
time(&tCurrentTime);
if( tCurrentTime < pData->tRewardExpireDate )
{
m_tRewardExpireDate = pData->tRewardExpireDate;
// 아직 보상 기간이 남아 있으면 우승길드 뽑아오기
m_eSettingStep = REQ_PRE_WIN;
SendGuildWarInfoReq(); // 본선 스케쥴 정보 가져오기 요청
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Send GetPrewinGuild Schedule Empty!!!\n");
return true;
}
}
else if( pData->tRewardExpireDate == 0 && !m_bFarmForceHarbest )
{
// 여기서 게임서버 우승농장 초기화 진행
MAGuildWarPreWinGuild GuildWarPreWinGuild;
GuildWarPreWinGuild.GuildUID.Reset();
GuildWarPreWinGuild.bPreWin = false;
m_bFarmForceHarbest = true;
g_pDivisionManager->SendSetGuildWarPreWinGuildGameServer(&GuildWarPreWinGuild);
}
m_bSendGuildWarInfo = false;
#endif //#if defined(PRE_FIX_75807)
return true;
}
if( pData->tRewardExpireDate > 0)
m_tRewardExpireDate = pData->tRewardExpireDate;
//////////////////////////////////////////////////////////////////////////////////////////////////
bool bResult = false;
m_wWinersWeightRate = pData->wWinersWeightRate;
memcpy(m_sGuildWarSchedule, pData->EventInfo, sizeof(m_sGuildWarSchedule));
// 이벤트 진행중이면
if (m_bWarEvent)
{
// 동일차수에 한해 기간 업데이트 가능
if (m_wScheduleID != pData->wScheduleID)
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadScheduleInfo Failed !!! Wrong ScheduleID Old(%d)<->New(%d) \n", m_wScheduleID, pData->wScheduleID);
return false;
}
else
{
bResult = UpdateScheduleGroup(pData->wScheduleID, pData->EventInfo);
}
}
else // 이벤트 진행중이 아니라면 신규 등록
{
bResult = RegisterScheduleGroup(pData->wScheduleID, pData->EventInfo);
}
if (bResult)
{
// 등록을 하든 업데이트를 하든 여기서 정보를 새로 업데이트한다.
m_wScheduleID = pData->wScheduleID;
m_eSettingStep = REQ_FINAL_SCHEDULE;
SendGuildWarInfoReq(); // 본선 스케쥴 정보 가져오기 요청
SetFinalProgress(pData->bFinalProgress);
return true;
}
return false;
}
bool CDNGuildWarManager::LoadFinalScheduleInfo(MASetGuildWarFinalSchedule* pData)
{
__time64_t tCurrentTime;
time(&tCurrentTime);
//////////////////////////////////////////////////////////////////////////////////////////////////
__time64_t tCheckPeriod = 0;
// 이미 본선이 진행중이며 스케쥴이 셋팅되어 있는지 체크..
// 각 시간체크
for( int i=GUILDWAR_FINALPART_MAX-1; i>GUILDWAR_FINALPART_NONE; --i)
{
if( tCheckPeriod > pData->GuildWarFinalSchedule[i].tBeginTime || pData->GuildWarFinalSchedule[i].tBeginTime > pData->GuildWarFinalSchedule[i].tEndTime )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n"
, pData->GuildWarFinalSchedule[i].tBeginTime, pData->GuildWarFinalSchedule[i].tEndTime, tCheckPeriod);
return false;
}
tCheckPeriod = pData->GuildWarFinalSchedule[i].tBeginTime;
}
CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD];
if( !pGuildWarReward )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo Failed !!! CDNGuildWarReward Null\n");
return false;
}
memcpy(m_sGuildWarFinalSchedule, pData->GuildWarFinalSchedule, sizeof(m_sGuildWarFinalSchedule));
pGuildWarReward->SetFinalScheduleInfo(pData);
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo ScheduleID:%d\n", m_wScheduleID);
// 본선 스케쥴 돌아라..
StartStep();
// 전체 스케쥴 보내주기
MASetGuildWarEventTime SetGuildWarEventTime;
memset(&SetGuildWarEventTime, 0, sizeof(SetGuildWarEventTime));
memcpy(SetGuildWarEventTime.sGuildWarTime, m_sGuildWarSchedule, sizeof(SetGuildWarEventTime.sGuildWarTime));
memcpy(SetGuildWarEventTime.sFinalPartTime, m_sGuildWarFinalSchedule, sizeof(SetGuildWarEventTime.sFinalPartTime));
SetGuildWarEventTime.bFinalProgress = GetFinalProgress();
g_pDivisionManager->SendSetGuildWarSchedule(&SetGuildWarEventTime);
if( (m_cStepIndex != GUILDWAR_STEP_REWARD || !GetFinalStart() ) && m_wScheduleID != 1) // 맨 처음 차수가 아니면.
{
// 본선이 아니거나 아직 시작을 안했으면 지난 차수 우승팀 가져오기..
m_eSettingStep = REQ_PRE_WIN;
SendGuildWarInfoReq();
return true;
}
else if( m_cStepIndex == GUILDWAR_STEP_TRIAL || m_cStepIndex == GUILDWAR_STEP_REWARD )
{
// 예선이거나 본선이면 청팀, 홍팀 포인트 가져오기
m_eSettingStep = REQ_TEAM_POINT;
SendGuildWarInfoReq();
return true;
}
m_bSendGuildWarInfo = false;
m_eSettingStep = REQ_ALL_COMPLETE;
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] LoadFinalScheduleInfo REQ_ALL_COMPLETE !!!\n");
return true;
}
void CDNGuildWarManager::SendGuildWarInfoReq()
{
// 콜로세움 빌리지한테 요청
CDNVillageConnection* pVillageConnection = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() );
if( pVillageConnection == NULL || pVillageConnection->GetActive() == false )
return;
if( pVillageConnection )
{
switch(m_eSettingStep)
{
case REQ_NONE :
case REQ_SCHEDULE :
{
pVillageConnection->SendGetGuildWarSchedule(); // 스케쥴 정보 가져오기 요청
m_eSettingStep = REQ_SCHEDULE;
}
break;
case REQ_FINAL_SCHEDULE :
{
pVillageConnection->SendGetGuildWarFinalSchedule(m_wScheduleID); // 본선 스케쥴 정보 가져오기 요청
}
break;
case REQ_PRE_WIN :
{
pVillageConnection->SendGetGuildWarPreWinGuild(); // 우승팀 가져오기
}
break;
case REQ_TEAM_POINT :
{
pVillageConnection->SendGetGuildWarPoint(); // 청팀, 홍팀 포인트 가져오기
}
break;
}
m_bSendGuildWarInfo = true;
m_TickCheckGuildWar = timeGetTime();
}
}
void CDNGuildWarManager::SetGuildWarPoint(int nBlueTeam, int nRedTeam)
{
InterlockedExchange(&m_nBlueTeamPoint, nBlueTeam);
InterlockedExchange(&m_nRedTeamPoint, nRedTeam);
CalcTeamSecret();
m_bSendGuildWarInfo = false;
m_eSettingStep = REQ_ALL_COMPLETE;
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarPoint REQ_ALL_COMPLETE !!!\n");
}
void CDNGuildWarManager::AddGuildWarPoint(char cTeamType, int nAddPoint)
{
if( cTeamType == GUILDWAR_TEAM_BLUE)
InterlockedExchangeAdd(&m_nBlueTeamPoint, nAddPoint);
else if( cTeamType == GUILDWAR_TEAM_RED )
InterlockedExchangeAdd(&m_nRedTeamPoint, nAddPoint);
CalcTeamSecret();
}
void CDNGuildWarManager::SetGuildWarPreWinGuild(TGuildUID GuildUID)
{
m_PreWinGuildUID = GuildUID;
if( m_cStepIndex == GUILDWAR_STEP_TRIAL || m_cStepIndex == GUILDWAR_STEP_REWARD )
{
// 예선이거나 본선이면 전이면 청팀, 홍팀 포인트 가져오기
m_eSettingStep = REQ_TEAM_POINT;
SendGuildWarInfoReq();
return;
}
m_bSendGuildWarInfo = false;
m_eSettingStep = REQ_ALL_COMPLETE;
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarPreWinGuild REQ_ALL_COMPLETE !!!\n");
}
UINT CDNGuildWarManager::GetGuildDBIDWithFinal(const UINT uiPvPIndex, const WCHAR * pGuildName)
{
if (pGuildName == NULL)
return 0;
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i)
{
if( m_bTournamentGroup[i].ATeam.nTeamNum > 0 && m_bTournamentGroup[i].BTeam.nTeamNum > 0)
{
if (wcscmp(m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].wszGuildName, pGuildName) == 0 && m_bTournamentGroup[i].unPvPIndex == uiPvPIndex)
return m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID;
if (wcscmp(m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].wszGuildName, pGuildName) == 0 && m_bTournamentGroup[i].unPvPIndex == uiPvPIndex)
return m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID;
}
}
return 0;
}
bool CDNGuildWarManager::IsTrialStats()
{
if( m_cStepIndex == GUILDWAR_STEP_REWARD)
{
CDNGuildWarReward* pReward = (CDNGuildWarReward*)m_pWarEventStep[m_cStepIndex];
return pReward->m_bTrialStatsRequest;
}
return false;
}
void CDNGuildWarManager::SetTrialStats()
{
CDNGuildWarReward* pReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD];
pReward->m_bTrialStatsRequest = true;
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetTrialStats!!!\n");
}
void CDNGuildWarManager::CalcGuildWarTournament(VIMASetGuildWarFinalTeam* pData)
{
// 자리는 고정입니다요...자세한건 [DN]길드전_본선대진표배치_1_.pptx 참조
int MatchSequence[]={0,8,14,6,4,12,10,2,3,11,13,5,7,15,9,1};
sTournamentGroup Groups[GUILDWAR_TOURNAMENT_GROUP_MAX];
memset(Groups, 0, sizeof(Groups));
for( int i=0; i<pData->nCount; ++i )
{
int nGroupIndex = MatchSequence[i]/2;
if( MatchSequence[i]%2 )
Groups[nGroupIndex].BTeam.nTeamNum = i+1;
else
Groups[nGroupIndex].ATeam.nTeamNum = i+1;
}
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i )
{
if( Groups[i].ATeam.nTeamNum )
{
//m_bTournamentGroup[i].ATeam.nTeamNum = (i*2)+1;
//m_bTournamentGroup[i].ATeam.nOpeningPoint = pData->nTotalPoint[Groups[i].ATeam.nTeamNum-1];
m_GuildWarFinalInfo[i*2].GuildUID = pData->GuidUID[Groups[i].ATeam.nTeamNum-1];
m_GuildWarOpeningPoints[i*2] = pData->nTotalPoint[Groups[i].ATeam.nTeamNum-1];
memcpy(m_GuildWarFinalInfo[i*2].wszGuildName, pData->wszGuildName[Groups[i].ATeam.nTeamNum-1], sizeof(m_GuildWarFinalInfo[Groups[i].ATeam.nTeamNum-1].wszGuildName));
}
if( Groups[i].BTeam.nTeamNum )
{
//m_bTournamentGroup[i].BTeam.nTeamNum = (i*2)+2;
//m_bTournamentGroup[i].BTeam.nOpeningPoint = pData->nTotalPoint[Groups[i].BTeam.nTeamNum-1];
m_GuildWarFinalInfo[(i*2)+1].GuildUID = pData->GuidUID[Groups[i].BTeam.nTeamNum-1];
m_GuildWarOpeningPoints[(i*2)+1] = pData->nTotalPoint[Groups[i].BTeam.nTeamNum-1];
memcpy(m_GuildWarFinalInfo[(i*2)+1].wszGuildName, pData->wszGuildName[Groups[i].BTeam.nTeamNum-1], sizeof(m_GuildWarFinalInfo[Groups[i].BTeam.nTeamNum-1].wszGuildName));
}
}
m_nFinalTeamCount = pData->nCount;
SetGuildWarTournamentGroup();
m_bFinalTeamSetting = true;
// 여기서 길드 정보 업데이트
MAChangeGuildInfo ChangeGuildInfo;
memset(&ChangeGuildInfo, 0, sizeof(ChangeGuildInfo));
// 본선 진출 횟수 1회 추가~~
ChangeGuildInfo.btGuildUpdate = GUILDUPDATE_TYPE_GUILDWAR;
ChangeGuildInfo.Int1 = 1;
for(int i=0; i<GUILDWAR_FINALS_TEAM_MAX; ++i)
{
if( !m_GuildWarFinalInfo[i].GuildUID.IsSet() )
continue;
ChangeGuildInfo.GuildUID = m_GuildWarFinalInfo[i].GuildUID;
g_pDivisionManager->SendChangeGuildInfo(&ChangeGuildInfo);
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] CalcGuildWarTournament Success TeamCount:%d !!!\n", m_nFinalTeamCount);
}
void CDNGuildWarManager::DoUpdate(DWORD CurTick)
{
// Reset 확인
if ( m_bResetSchedule )
{
if( g_pGuildWarManager->GetFinalProgress() && g_pGuildWarManager->GetFinalStart() )
{
// 본선 진행중이면..이때는 강제 중단으로 여기고 모든 길드전 강제 종료..
g_pDivisionManager->SendGuildWarAllStop();
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Emergence GuilWar Stop Process!!!\n");
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] Reset Schedule GuilWar Progress:%d, Start:%d\n",g_pGuildWarManager->GetFinalProgress(),g_pGuildWarManager->GetFinalStart() );
Clear(); // 전부 초기화하고
SendGuildWarInfoReq(); // 다시 첨부터 로딩 ㄱㄱ
return;
}
//우승 길드가 셋팅되어 있으면 보상이 지급됐는지 가져오자..대략 1분 마다 한번씩..
DWORD dwTick = timeGetTime();
static DWORD SendTick = 60*1000;
if( GetPreWinGuild().IsSet() && !GetFinalWinGuildReward() && SendTick+(60*1000) < dwTick)
{
//CDNVillageConnection *pVillageConnection = g_pDivisionManager->GetFirstEnableVillageServer();
CDNVillageConnection* pVillageConnection = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() );
if( pVillageConnection )
{
pVillageConnection->SendGetGuildWarPreWindGuildReward(GetPreWinScheduleID(), GetPreWinGuild().nDBID);
}
SendTick = dwTick;
}
if ( m_eSettingStep != REQ_ALL_COMPLETE && (!m_bSendGuildWarInfo
|| (m_bSendGuildWarInfo && CurTick > m_TickCheckGuildWar+REQ_GUILDWARINFO_TICK_MAX)) ) // 활성화 되어 있지 않고 빌리지에게 정보 요청하지 않은 상태거나 타임오바이면
{
SendGuildWarInfoReq();
return;
}
// 우승길드 해제..제스쳐, 농장
if( m_PreWinGuildUID.IsSet() && m_bFinalWinGuild && m_tRewardExpireDate > 0 )
{
__time64_t tCurrentTime;
time(&tCurrentTime);
if( tCurrentTime > m_tRewardExpireDate )
{
// 우승길드 해제
MAGuildWarPreWinGuild pPacket;
memset(&pPacket, 0, sizeof(MAGuildWarPreWinGuild));
pPacket.GuildUID = GetPreWinGuild();
pPacket.bPreWin = false;
g_pDivisionManager->SendSetGuildWarPreWinGuild(&pPacket); // 전체 게임 및 빌리지에 통보.
m_PreWinGuildUID.Reset();
m_tRewardExpireDate = 0;
g_pGuildWarManager->SetFinalWinGuild(false);
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] PreWinGuild ExpireDate!!!\n");
}
}
if (m_bWarEvent && CheckStep(m_cStepIndex) && m_eSettingStep == REQ_ALL_COMPLETE)
{
CDNGuildWar** pWarEventStep = m_pWarEventStep;
CDNGuildWar* pCurrentEvent = pWarEventStep[m_cStepIndex];
if (pCurrentEvent)
{
// 해당 이벤트객체를 호출하여 처리!
pCurrentEvent->Process();
// 모든 이벤트가 끝났을때 다음스텝으로 진행
if (pCurrentEvent->IsFinishPeriod())
NextStep();
}
}
// 본선 진행일때만..
if( GetFinalProgress() )
{
CDNVillageConnection* pVillageCon = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() );
if( pVillageCon == NULL || pVillageCon->GetActive() == false )
return; //이거 어케해야함?
// 본선이고 방이 만들어진 애들은 시간이 되면 스타트 날려주자..
CDNPvP* pPvP = NULL;
VIMAPVP_START Packet;
memset(&Packet, 0, sizeof(Packet));
Packet.sCSPVP_START.unCheck = PvPCommon::Check::AllCheck;
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i )
{
if( m_bTournamentGroup[i].ATeam.nTeamNum && m_bTournamentGroup[i].BTeam.nTeamNum
&& m_bTournamentGroup[i].unPvPIndex && m_bTournamentGroup[i].dwStartTick > 0)
{
if( CurTick > m_bTournamentGroup[i].dwStartTick+GUILDWAR_FINAL_ROOMSTRAT_TICK_MAX )
{
if( g_pDivisionManager->GetGameConnectionCount() <= 0 )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Failed !!! Not GameConnection \n");
return;
}
pPvP = g_pDivisionManager->GetPvPRoomByIdx(m_bTournamentGroup[i].unPvPIndex);
if( pPvP )
{
short wRet = pPvP->StartPvP(pVillageCon, &Packet);
if( wRet != ERROR_NONE )
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Failed !!! %d \n", wRet);
else
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] StartPvP Success PvPIndex:%u !!! \n", m_bTournamentGroup[i].unPvPIndex);
m_bTournamentGroup[i].dwStartTick = 0;
}
}
}
}
}
}
}
CDNGuildWar* CDNGuildWarManager::GetWarEvent(char cStep)
{
if (!CheckStep(cStep))
return NULL;
return m_pWarEventStep[cStep];
}
int CDNGuildWarManager::SetGuildTournamentInfo(SGuildTournamentInfo* pGuildTournamentInfo)
{
// 카운트 셀려고 루프돔.ㅠㅠ
int nCount = 0;
for( int i=0; i<GUILDWAR_FINALS_TEAM_MAX; ++i)
{
if( pGuildTournamentInfo[i].GuildUID.IsSet() )
++nCount;
}
if( nCount > 0)
{
memcpy(m_GuildWarFinalInfo, pGuildTournamentInfo, sizeof(m_GuildWarFinalInfo));
m_nFinalTeamCount = nCount;
SetGuildWarTournamentGroup();
m_bFinalTeamSetting = true;
}
return nCount;
}
void CDNGuildWarManager::SetGuildWarPointTrialRanking(const MASetGuildWarPointRunningTotal* pData)
{
memcpy(m_sGuildWarPointTrialRanking, pData, sizeof(m_sGuildWarPointTrialRanking));
}
void CDNGuildWarManager::CalcGuildWarTournamentResult()
{
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i)
{
if( m_bTournamentGroup[i].ATeam.nTeamNum > 0 && m_bTournamentGroup[i].BTeam.nTeamNum > 0)
{
BYTE ATeamIndex = m_bTournamentGroup[i].ATeam.nTeamNum-1;
BYTE BTeamIndex = m_bTournamentGroup[i].BTeam.nTeamNum-1;
// 둘다 진 상태로 되어 있으면..
if( ATeamIndex < GUILDWAR_FINALS_TEAM_MAX && BTeamIndex < GUILDWAR_FINALS_TEAM_MAX
&& !m_GuildWarFinalInfo[ATeamIndex].bWin && !m_GuildWarFinalInfo[BTeamIndex].bWin )
{
// 그냥 결판 내버리자..
CalcGuildWarTournamentWin(i);
}
}
}
}
void CDNGuildWarManager::SetGuildWarTournamentGroup()
{
memset(m_bTournamentGroup, 0, sizeof(m_bTournamentGroup));
char cCurFinalPart = GetCurFinalPart();
int nCount = 0;
int nDefaultWinMax = 0;
//부전승 건너띄기
switch(cCurFinalPart)
{
case GUILDWAR_FINALPART_NONE :
case GUILDWAR_FINALPART_16 :
nDefaultWinMax = 1;
break;
case GUILDWAR_FINALPART_8 : nDefaultWinMax = 3; break;
case GUILDWAR_FINALPART_4 : nDefaultWinMax = 7; break;
case GUILDWAR_FINALPART_FINAL : nDefaultWinMax = 15; break;
}
for( int i=0; i<GUILDWAR_FINALS_TEAM_MAX; ++i )
{
if( !m_GuildWarFinalInfo[i].GuildUID.IsSet() )
continue;
if( m_GuildWarFinalInfo[i].cMatchTypeCode != GUILDWAR_FINALPART_NONE && m_GuildWarFinalInfo[i].bWin == false )
continue;
// 최종 우승자 스킵..
if( m_GuildWarFinalInfo[i].cMatchTypeCode == GUILDWAR_FINALPART_FINAL && m_GuildWarFinalInfo[i].bWin == true)
continue;
// 현재 진행중인 차수와 대조
if( m_GuildWarFinalInfo[i].cMatchTypeCode != GUILDWAR_FINALPART_NONE && m_GuildWarFinalInfo[i].cMatchTypeCode != cCurFinalPart+1)
continue;
if( m_bTournamentGroup[nCount].ATeam.nTeamNum == 0)
{
m_bTournamentGroup[nCount].ATeam.nTeamNum = i+1;
m_bTournamentGroup[nCount].ATeam.nOpeningPoint = m_GuildWarOpeningPoints[i];
// 부전승 체크..이 방법밖에 없을라나..ㅠㅠ
bool bDefaltWin = true;
for( int j=1; j<= nDefaultWinMax; ++j )
{
if( i+j >= GUILDWAR_FINALS_TEAM_MAX )
break;
if( !m_GuildWarFinalInfo[i+j].GuildUID.IsSet() )
continue;
if( m_GuildWarFinalInfo[i+j].cMatchTypeCode != GUILDWAR_FINALPART_NONE && m_GuildWarFinalInfo[i+j].bWin == false )
continue;
// 결승전을 제외하고 왼쪽 팀이 오른쪽 팀과 붙을 일은 없다.
if( cCurFinalPart != GUILDWAR_FINALPART_FINAL && i < GUILDWAR_TOURNAMENT_GROUP_MAX && i+j >= GUILDWAR_TOURNAMENT_GROUP_MAX )
break;
bDefaltWin = false;
break;
}
if( bDefaltWin )
++nCount;
m_GuildWarFinalInfo[i].cMatchTypeCode = cCurFinalPart;
m_GuildWarFinalInfo[i].bWin = false;
}
else if( m_bTournamentGroup[nCount].BTeam.nTeamNum == 0)
{
m_bTournamentGroup[nCount].BTeam.nTeamNum = i+1;
m_bTournamentGroup[nCount].BTeam.nOpeningPoint = m_GuildWarOpeningPoints[i];
++nCount;
m_GuildWarFinalInfo[i].cMatchTypeCode = cCurFinalPart;
m_GuildWarFinalInfo[i].bWin = false;
}
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetGuildWarTournamentGroup FinalPart:%d !!!\n", cCurFinalPart);
}
// 길드전 방 생성
void CDNGuildWarManager::GuildWarCreateRoom()
{
CDNVillageConnection* pVillageCon = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() );
if( pVillageCon == NULL || pVillageCon->GetActive() == false )
return; //이거 어케해야함?
CTimeSet CurTime;
CurTime.GetMonth();
// MapID 얻어오기
UINT uiMapIndex = g_pExtManager->GetGuildWarMapInfoID((char)CurTime.GetMonth());
if( uiMapIndex == 0 )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! GuildWarMapID is Zero\n");
return;
}
// MapID로 PvPMapTable 얻어오기
const TPvPMapTable* pMapTable = g_pExtManager->GetPvPMapTable(uiMapIndex);
if( pMapTable == NULL )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! pMapTable is NULL\n");
return;
}
// PvPMapTable에서 GameMode 정보 가져오기
const TPvPGameModeTable* pPvPGameModeTable = g_pExtManager->GetPvPGameModeTable( pMapTable->vGameModeTableID[0] );
if( pPvPGameModeTable == NULL )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! pPvPGameModeTable is NULL\n");
return;
}
for( int i=0; i<GUILDWAR_FINALS_TEAM_MAX/2; ++i)
{
if( m_bTournamentGroup[i].ATeam.nTeamNum )
{
if( m_bTournamentGroup[i].BTeam.nTeamNum == 0)
{
// 요건 부전승이다..DB저장 해야함..
SetGuildTournamentInfoWin(m_bTournamentGroup[i].ATeam.nTeamNum-1, true); //이긴걸로 표시
SendSetGuildWarFinalResult(m_bTournamentGroup[i].ATeam.nTeamNum-1);
pVillageCon->SendSetGuildWarFinalResultDB(m_wScheduleID, m_bTournamentGroup[i].ATeam.nTeamNum, m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID, GetCurFinalPart(), true);
}
else
{
// 여기서 방만들기..
VIMAPVP_CREATEROOM sCreateRoom;
memset(&sCreateRoom, 0, sizeof(sCreateRoom));
sCreateRoom.unVillageChannelID = g_pDivisionManager->GetPvPLobbyChannelID();
sCreateRoom.uiVillageMapIndex = g_pDivisionManager->GetPvPLobbyMapIndex();
sCreateRoom.cGameMode = PvPCommon::GameMode::PvP_GuildWar;
sCreateRoom.nGuildDBID[0] = m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID;
sCreateRoom.nGuildQualifyingScore[0] = m_GuildWarOpeningPoints[m_bTournamentGroup[i].ATeam.nTeamNum-1];
sCreateRoom.nGuildDBID[1] = m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID;
sCreateRoom.nGuildQualifyingScore[1] = m_GuildWarOpeningPoints[m_bTournamentGroup[i].BTeam.nTeamNum-1];
sCreateRoom.sCSPVP_CREATEROOM.uiMapIndex = uiMapIndex;
sCreateRoom.sCSPVP_CREATEROOM.uiGameModeTableID = pMapTable->vGameModeTableID[0];
sCreateRoom.sCSPVP_CREATEROOM.uiSelectWinCondition = pPvPGameModeTable->vWinCondition[0]; // 요거 점수인데 에라 모르겠다.
sCreateRoom.sCSPVP_CREATEROOM.uiSelectPlayTimeSec = pPvPGameModeTable->vPlayTimeSec[0];
sCreateRoom.sCSPVP_CREATEROOM.cMaxUser = pPvPGameModeTable->uiNumOfPlayersMax;
sCreateRoom.sCSPVP_CREATEROOM.cMinUser = 0;
sCreateRoom.sCSPVP_CREATEROOM.cRoomPWLen = 0;
sCreateRoom.sCSPVP_CREATEROOM.cMinLevel = 1;
sCreateRoom.sCSPVP_CREATEROOM.cMaxLevel = 100;
sCreateRoom.sCSPVP_CREATEROOM.unRoomOptionBit |= (PvPCommon::RoomOption::BreakInto|PvPCommon::RoomOption::NoRegulation); // 난입,무조정 허용
sCreateRoom.sCSPVP_CREATEROOM.uiEventItemID = 0;
#ifdef PRE_ADD_COLOSSEUM_BEGINNER
sCreateRoom.sCSPVP_CREATEROOM.cRoomType = PvPCommon::RoomType::regular;
#endif //#ifdef PRE_ADD_COLOSSEUM_BEGINNER
wsprintf(sCreateRoom.sCSPVP_CREATEROOM.wszBuf, L"%s vs %s", m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].wszGuildName,
m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].wszGuildName);
sCreateRoom.sCSPVP_CREATEROOM.cRoomNameLen = (BYTE)wcslen(sCreateRoom.sCSPVP_CREATEROOM.wszBuf);
short nRetCode = g_pDivisionManager->CreatePvPRoom( pVillageCon, &sCreateRoom, &m_bTournamentGroup[i].unPvPIndex );
if( nRetCode != ERROR_NONE )
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom Failed !!! CreatePvPRoom %s \n", sCreateRoom.sCSPVP_CREATEROOM.wszBuf);
else
{
m_bTournamentGroup[i].dwStartTick = timeGetTime();
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] GuildWarCreateRoom !!! CreatePvPRoom PvPIndex:%u %s \n", m_bTournamentGroup[i].unPvPIndex, sCreateRoom.sCSPVP_CREATEROOM.wszBuf);
}
}
}
}
}
void CDNGuildWarManager::SetGuildWarTournamentResult(GAMAPvPGuildWarResult* pGuildWarResult)
{
char cWinGuildIndex =-1, cLoseGuildIndex = -1;
for(char i=0; i<GUILDWAR_FINALS_TEAM_MAX; ++i)
{
if( !m_GuildWarFinalInfo[i].GuildUID.IsSet() )
continue;
if( m_GuildWarFinalInfo[i].GuildUID.nDBID == pGuildWarResult->nWinGuildDBID )
{
SetGuildTournamentInfoWin(i, true);
cWinGuildIndex = i;
continue;
}
if( m_GuildWarFinalInfo[i].GuildUID.nDBID == pGuildWarResult->nLoseGuildDBID )
{
SetGuildTournamentInfoWin(i, false);
cLoseGuildIndex = i;
continue;
}
}
SendSetGuildWarFinalResult(cWinGuildIndex, cLoseGuildIndex);
SendSetGuildWarTournamentWin(cWinGuildIndex, m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode);
//결승이면 우승길드로 셋팅해 주자~
if( m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode == GUILDWAR_FINALPART_FINAL )
{
SetPreWinGuild( m_GuildWarFinalInfo[cWinGuildIndex].GuildUID);
SetPreWinScheduleID(m_wScheduleID);
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] TournamentResult !!! FinalPart:%d, WinGuildDBID:%d, LosGuildDBID:%d \n", GetCurFinalPart(),
pGuildWarResult->nWinGuildDBID, pGuildWarResult->nLoseGuildDBID);
}
void CDNGuildWarManager::SendSetGuildWarFinalResult(char cWinGuildIndex, char cLoseGuildIndex )
{
MAVISetGuildWarFinalResult FinalResult;
memset(&FinalResult, 0, sizeof(FinalResult));
FinalResult.cMatchTypeCode = GetCurFinalPart();
FinalResult.cWinGuildIndex = cWinGuildIndex;
FinalResult.cLoseGuildIndex = cLoseGuildIndex;
g_pDivisionManager->SendSetGuildWarFinalResult(&FinalResult);
}
void CDNGuildWarManager::SetGuildTournamentInfoWin(char cIndex, bool bWin)
{
if( cIndex < 0 || cIndex >= GUILDWAR_FINALS_TEAM_MAX )
return;
m_GuildWarFinalInfo[cIndex].bWin = bWin;
// 만약 결승전 승자 이면..
if( m_GuildWarFinalInfo[cIndex].cMatchTypeCode == GUILDWAR_FINALPART_FINAL && bWin )
{
// 여기서 길드 정보 업데이트
MAChangeGuildInfo ChangeGuildInfo;
memset(&ChangeGuildInfo, 0, sizeof(ChangeGuildInfo));
// 본선 우승 횟수 1회 추가~~
ChangeGuildInfo.btGuildUpdate = GUILDUPDATE_TYPE_GUILDWAR;
ChangeGuildInfo.Int2 = 1;
ChangeGuildInfo.GuildUID = m_GuildWarFinalInfo[cIndex].GuildUID;
g_pDivisionManager->SendChangeGuildInfo(&ChangeGuildInfo);
}
}
void CDNGuildWarManager::SetGuildWarOpenningPoint(VIMASetGuildWarFinalTeam* pData )
{
for( int i=0; i<pData->nCount; ++i)
{
for( int j=0; j<GUILDWAR_FINALS_TEAM_MAX; ++j)
{
if( pData->GuidUID[i] == m_GuildWarFinalInfo[j].GuildUID )
{
m_GuildWarOpeningPoints[j] = pData->nTotalPoint[i];
break;
}
}
}
}
void CDNGuildWarManager::SetGuildWarTournamentPoint(GAMAPvPGuildWarScore* pGuildWarPoint)
{
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i )
{
if( m_bTournamentGroup[i].ATeam.nTeamNum
&& m_GuildWarFinalInfo[m_bTournamentGroup[i].ATeam.nTeamNum-1].GuildUID.nDBID == pGuildWarPoint->nGuildDBID)
{
m_bTournamentGroup[i].ATeam.nTournamentPoint = pGuildWarPoint->nScore;
break;
}
if( m_bTournamentGroup[i].BTeam.nTeamNum
&& m_GuildWarFinalInfo[m_bTournamentGroup[i].BTeam.nTeamNum-1].GuildUID.nDBID == pGuildWarPoint->nGuildDBID)
{
m_bTournamentGroup[i].BTeam.nTournamentPoint = pGuildWarPoint->nScore;
break;
}
}
}
void CDNGuildWarManager::SendSetGuildWarTournamentWin(char cWinGuildIndex, char cFinalPart)
{
if( cWinGuildIndex < 0 || cWinGuildIndex >= GUILDWAR_FINALS_TEAM_MAX )
return;
MASetGuildWarTournamentWin SetGuildWarTournamentWin;
memset(&SetGuildWarTournamentWin, 0, sizeof(SetGuildWarTournamentWin));
SetGuildWarTournamentWin.cMatchTypeCode = cFinalPart;
memcpy(SetGuildWarTournamentWin.wszGuildName, m_GuildWarFinalInfo[cWinGuildIndex].wszGuildName, sizeof(SetGuildWarTournamentWin.wszGuildName) );
g_pDivisionManager->SendSetGuildWarTournamentWin(&SetGuildWarTournamentWin);
}
char CDNGuildWarManager::GetCurFinalPart()
{
CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD];
if( pGuildWarReward )
return pGuildWarReward->GetCurFinalPart();
return 0;
}
time_t CDNGuildWarManager::GetCurFinalPartBeginTime()
{
CDNGuildWarReward* pGuildWarReward = (CDNGuildWarReward*)m_pWarEventStep[GUILDWAR_STEP_REWARD];
if( pGuildWarReward )
return pGuildWarReward->GetCurFinalPartBeginTime();
return 0;
}
void CDNGuildWarManager::SetDBJobSend(bool bSend)
{
CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex];
if( pGuildWar )
pGuildWar->SetDBJobSend(bSend);
}
void CDNGuildWarManager::SetDBJobSeq(int nJobSeq)
{
CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex];
if( pGuildWar )
pGuildWar->SetDBJobSeq(nJobSeq);
}
void CDNGuildWarManager::SetDBJobSuccess(bool bSuccess)
{
CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex];
if( pGuildWar )
pGuildWar->SetDBJobSuccess(bSuccess);
}
bool CDNGuildWarManager::GetDBJobSuccess()
{
CDNGuildWar* pGuildWar = m_pWarEventStep[m_cStepIndex];
if( pGuildWar )
return pGuildWar->GetDBJobSuccess();
return false;
}
// 방이 뽀사지거나 게임서버가 튕겼을때 호출바람..
void CDNGuildWarManager::SetDropTournament(UINT unPvPIndex)
{
for( int i=0; i<GUILDWAR_TOURNAMENT_GROUP_MAX; ++i )
{
if( m_bTournamentGroup[i].unPvPIndex == unPvPIndex )
{
CalcGuildWarTournamentWin(i);
break;
}
}
}
void CDNGuildWarManager::CalcGuildWarTournamentWin(BYTE cGroupIndex)
{
if( cGroupIndex >= GUILDWAR_TOURNAMENT_GROUP_MAX)
return;
char cWinGuildIndex = -1, cLoseGuildIndex = -1;
// 먼저 중간 점수 보고
if( m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint != m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint )
{
cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint > m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint ? m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1;
cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTournamentPoint > m_bTournamentGroup[cGroupIndex].BTeam.nTournamentPoint ? m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1;
}
// 안되면 예선점수 보고
else if( m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint != m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint )
{
cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint > m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint ? m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1;
cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nOpeningPoint > m_bTournamentGroup[cGroupIndex].BTeam.nOpeningPoint ? m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1 : m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1;
}
else
{
//이건 운이다..된장..
cWinGuildIndex = m_bTournamentGroup[cGroupIndex].ATeam.nTeamNum-1;
cLoseGuildIndex = m_bTournamentGroup[cGroupIndex].BTeam.nTeamNum-1;
}
char cMatchTypeCode = m_GuildWarFinalInfo[cWinGuildIndex].cMatchTypeCode;
SetGuildTournamentInfoWin(cWinGuildIndex, true); //이긴걸로 표시
SetGuildTournamentInfoWin(cLoseGuildIndex, false); //진걸로 표시
SendSetGuildWarFinalResult(cWinGuildIndex, cLoseGuildIndex); // 결과 보내주고..
SendSetGuildWarTournamentWin(cWinGuildIndex, cMatchTypeCode); // 승리 길드 알림.
//보상지급해줘야함..
//CDNVillageConnection* pVillage = g_pDivisionManager->GetFirstEnableVillageServer();
CDNVillageConnection* pVillage = g_pDivisionManager->GetVillageConnectionByVillageID( g_pDivisionManager->GetPvPLobbyVillageID() );
if( pVillage )
{
//이긴넘 진넘 둘다 DB에 결과 저장
pVillage->SendSetGuildWarFinalResultDB(m_wScheduleID, cWinGuildIndex+1, m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID, cMatchTypeCode, true);
pVillage->SendSetGuildWarFinalResultDB(m_wScheduleID, cLoseGuildIndex+1, m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID, cMatchTypeCode, false);
}
else
{
// 요건 보상도 못주고 결과 기록도 못함.ㅠㅠ
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetDropTournament Failed !!! WinGuildDBID:%d, LosGuildDBID:%d \n", m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID,
m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID);
}
//결승이면 우승길드로 셋팅해 주자~
if( cMatchTypeCode == GUILDWAR_FINALPART_FINAL )
{
g_pGuildWarManager->SetPreWinGuild( m_GuildWarFinalInfo[cWinGuildIndex].GuildUID);
g_pGuildWarManager->SetPreWinScheduleID(m_wScheduleID);
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SetDropTournament !!! WinGuildDBID:%d, LosGuildDBID:%d \n", m_GuildWarFinalInfo[cWinGuildIndex].GuildUID.nDBID,
m_GuildWarFinalInfo[cLoseGuildIndex].GuildUID.nDBID);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Private Function
bool CDNGuildWarManager::CheckStep(char cStep)
{
if (GUILDWAR_STEP_NONE < cStep && cStep < GUILDWAR_STEP_END)
return true;
return false;
}
void CDNGuildWarManager::ResetStep()
{
// 스케쥴 ID리셋
m_wScheduleID = GUILDWARSCHEDULE_DEF;
// 스텝 초기화
m_cStepIndex = GUILDWAR_STEP_NONE;
m_bWarEvent = false;
for (int i=GUILDWAR_STEP_NONE; i<GUILDWAR_STEP_END; i++)
{
if (m_pWarEventStep[i])
m_pWarEventStep[i]->Reset();
}
}
void CDNGuildWarManager::StartStep()
{
m_bWarEvent = true;
m_cStepIndex = GUILDWAR_STEP_PREPARATION;
// 현재 어떤 이벤트가 진행되는지 여기서 맞춰버리자.
for( int i=GUILDWAR_STEP_PREPARATION; i<GUILDWAR_STEP_END; ++i)
{
CDNGuildWar** pWarEventStep = m_pWarEventStep;
if (!pWarEventStep[i])
return;
// 해당 이벤트객체를 호출하여 처리!
pWarEventStep[i]->Process();
// 모든 이벤트가 끝났을때 다음스텝으로 진행
if (pWarEventStep[i]->IsFinishPeriod())
NextStep();
}
}
void CDNGuildWarManager::NextStep()
{
// 혹시 모르니 타입체크 한번더!
if (!CheckStep(m_cStepIndex))
return;
char cNextStepIndex = m_cStepIndex + 1;
if (cNextStepIndex >= GUILDWAR_STEP_END)
{
// 다음스텝이 마지막이면 종료한다.
FinalStep();
// 다음 차수 가져오기~
m_eSettingStep = REQ_SCHEDULE;
SendGuildWarInfoReq();
return;
}
time_t tNextEvent = m_pWarEventStep[cNextStepIndex]->GetEventTime (GUILDWAR_EVENT_START);
time_t tCurrentTime;
time(&tCurrentTime);
// 다음 이벤트 시간이 현재시각보다 많으면 다음 스텝으로 진행한다.
if (tCurrentTime > tNextEvent)
m_cStepIndex++;
}
void CDNGuildWarManager::FinalStep()
{
Clear();
//ResetStep();
}
bool CDNGuildWarManager::RegisterScheduleGroup(short wScheduleID, const TGuildWarEventInfo vEventInfo[])
{
ResetStep();
time_t tCheckPeriod = 0;
time_t tBeginTime = 0;
time_t tEndTime = 0;
for (char i=GUILDWAR_STEP_PREPARATION; i<GUILDWAR_STEP_END; i++)
{
char cStep = i;
// 타입체크
if (!CheckStep(cStep))
{
g_Log.Log(LogType::_FILELOG, L"CDNGuildWarManager::RegisterScheduleGroup Failed !!! Wrong Step Type (%d)\n", cStep);
return false;
}
tBeginTime = vEventInfo[i].tBeginTime;
tEndTime = vEventInfo[i].tEndTime;
// 시간체크
if (tBeginTime < tCheckPeriod || tEndTime < tCheckPeriod || tBeginTime >= tEndTime)
{
ResetStep(); // 연속된 기간이 아니라면 에러처리하고 리셋!
g_Log.Log(LogType::_FILELOG, L"CDNGuildWarManager::RegisterScheduleGroup Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n", tBeginTime, tEndTime, tCheckPeriod);
return false;
}
m_pWarEventStep[cStep]->UpdateTime(wScheduleID, tBeginTime, tEndTime, m_wWinersWeightRate);
// 마지막 시간을 저장해서 다음 기간에 대한 검사조건으로 사용한다.
tCheckPeriod = tEndTime;
}
m_wScheduleID = wScheduleID;
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] RegisterScheduleGroup Success ScheduleID:%d!!!\n", wScheduleID);
return true;
}
bool CDNGuildWarManager::UpdateScheduleGroup(short wScheduleID, const TGuildWarEventInfo vEventInfo[])
{
time_t tCurrentTime;
time(&tCurrentTime); // 현재시간
// 데이터상의 현재 스텝
char cStepIndex = GUILDWAR_STEP_NONE;
time_t tCheckPeriod = 0;
time_t tBeginTime = 0;
time_t tEndTime = 0;
// 본선 진행중일때는 스케쥴 업데이트 하지말자..이럼 Hell 될것 같음.
if( m_cStepIndex == GUILDWAR_STEP_REWARD )
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Already Reward Step On\n");
return false;
}
// 데이터 체크
for (char i=GUILDWAR_STEP_PREPARATION; i<GUILDWAR_STEP_END; i++)
{
char cStep = i;
// 타입체크
if (!CheckStep(cStep))
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Wrong Step Type (%d)\n", cStep);
return false;
}
tBeginTime = vEventInfo[i].tBeginTime;
tEndTime = vEventInfo[i].tEndTime;
// 시간체크
if (tBeginTime < tCheckPeriod || tEndTime < tCheckPeriod || tBeginTime >= tEndTime)
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Wrong Time Schedule Begin(%d) End(%d) Check(%d)\n", tBeginTime, tEndTime, tCheckPeriod);
return false;
}
// 데이터상 현재 스텝을 구한다.
if (tCurrentTime > tBeginTime && tCurrentTime < tEndTime)
cStepIndex = i;
// 마지막 시간을 저장해서 다음 기간에 대한 검사조건으로 사용한다.
tCheckPeriod = tEndTime;
}
// 현재 스텝과 맞지 않으면 에러처리
if (m_cStepIndex != cStepIndex)
{
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Failed !!! Wrong Step Index[%d]<->[%d]\n", m_cStepIndex, cStepIndex);
return false;
}
// 데이터 입력
for (char i=GUILDWAR_STEP_PREPARATION; i<GUILDWAR_STEP_END; i++)
{
char cStep = i;
tBeginTime = vEventInfo[i].tBeginTime;
tEndTime = vEventInfo[i].tEndTime;
if (CheckStep(cStep))
m_pWarEventStep[cStep]->UpdateTime(wScheduleID, tBeginTime, tEndTime, m_wWinersWeightRate);
else
{
_DANGER_POINT(); // 위에서 한번 체크했는데 타입체크 실패하면 말이 안됨!
return false;
}
}
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] UpdateScheduleGroup Success ScheduleID:%d!!!\n", wScheduleID);
return true;
}
void CDNGuildWarManager::CalcTeamSecret()
{
// 블루 : 1
// 레드 : 2
if (m_nBlueTeamPoint == m_nRedTeamPoint)
{
m_cSecretTeam = 0;
return;
}
BYTE cTeamCode = 0;
float fSecretRate = 0.0f;
if (m_nBlueTeamPoint > m_nRedTeamPoint)
{
fSecretRate = (float)m_nRedTeamPoint / (float)m_nBlueTeamPoint;
cTeamCode = 2; // 레드팀 혜택
}
else
{
fSecretRate = (float)m_nBlueTeamPoint / (float)m_nRedTeamPoint;
cTeamCode = 1; // 블루팀 혜택
}
if (fSecretRate < 0)
{
DN_ASSERT( false, "fSecretRate < 0" );
return;
}
fSecretRate = 1.0f - fSecretRate;
float nSecretStartRate = GUILDWAR_SECRET_SATRT_RATE;
float nSecretEndRate = GUILDWAR_SECRET_END_RATE;
time_t tCurrentTime;
time(&tCurrentTime);
time_t tStartTime = m_pWarEventStep[GUILDWAR_STEP_TRIAL]->GetEventTime(GUILDWAR_EVENT_START);
time_t tEndTime = m_pWarEventStep[GUILDWAR_STEP_TRIAL]->GetEventTime(GUILDWAR_EVENT_END);
//예선 종료 시간 먼저 체크
if( tEndTime - tCurrentTime <= GUILDWAR_SECRET_TERM_SECOND ) // 24시간 이하로 남았으면 비율을 반으로 줄임
{
nSecretStartRate = nSecretStartRate*0.5f;
nSecretEndRate = nSecretEndRate*0.5f;
}
else if( tCurrentTime - tStartTime < GUILDWAR_SECRET_TERM_SECOND ) // 시작된지 24시간 안 지났으면 시크릿 발동 안됨.
return;
if (fSecretRate >= nSecretStartRate)
{
if (m_cSecretTeam != cTeamCode)
{
m_cSecretTeam = cTeamCode; // 적용
CMtRandom rand;
rand.srand( timeGetTime() );
m_nSecretRandomSeed = rand.rand();
MASetGuildWarSecretMission packet = {0,};
packet.cTeamCode = m_cSecretTeam;
packet.nRandomSeed = m_nSecretRandomSeed;
g_pDivisionManager->SendSetGuildWarSecretMission(&packet);
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SecretStart Seed:%d, Team:%d, Rate:%f!!!\n", packet.nRandomSeed, packet.cTeamCode, fSecretRate );
}
}
else if (fSecretRate <= nSecretEndRate && m_cSecretTeam != 0)
{
m_cSecretTeam = 0; // 해제
MASetGuildWarSecretMission packet = {0,};
packet.cTeamCode = m_cSecretTeam;
packet.nRandomSeed = -1;
g_pDivisionManager->SendSetGuildWarSecretMission(&packet);
g_Log.Log(LogType::_GUILDWAR, g_Config.nWorldSetID, 0, 0, 0, L"[GUILDWAR] SecretEnd Rate:%f!!!\n", fSecretRate );
}
}