478 lines
11 KiB
C++
478 lines
11 KiB
C++
#include "stdafx.h"
|
|
#include "stdafx.h"
|
|
#include "SBattleArenaBeginAreaDB.h"
|
|
#include "Arena\\ArenaUtility.h"
|
|
#include "SPlayerInfoMgr.h"
|
|
#include "SGameAvatarEx.h"
|
|
#include "SGameSystem.h"
|
|
#include "ArenaSystem.h"
|
|
|
|
extern SGameSystem* g_pCurrentGameSystem;
|
|
|
|
sArenaSystem::sArenaSystem()
|
|
{
|
|
/// 페널티 정보는 clear에 들어가면 안된다. 왜냐면 clear는 여러곳에서 호출 될 수가 있어서,
|
|
/// 이미 들어 있는 페널티 정보가 삭제 될 수 있다.
|
|
m_blockTime = 0.0f;
|
|
m_penaltyCount = -1;
|
|
m_penaltyCountTime = 0.0f;
|
|
|
|
clear();
|
|
}
|
|
|
|
sArenaSystem::~sArenaSystem()
|
|
{
|
|
m_blockList.clear();
|
|
}
|
|
|
|
void sArenaSystem::clear()
|
|
{
|
|
m_arenaId = -1;
|
|
m_myTeam = sArenaUtility::TEAM_NONE;
|
|
m_opponentTeam = sArenaUtility::TEAM_NONE;
|
|
m_forceEnterTime = 0;
|
|
m_endTime = 0;
|
|
m_startTime = 0;
|
|
m_status = 0;
|
|
ZeroMemory(m_playerCount, sizeof (m_playerCount));
|
|
ZeroMemory(m_playerInfo, sizeof (m_playerInfo));
|
|
ZeroMemory(m_playerScore, sizeof (m_playerScore));
|
|
ZeroMemory(m_teamScore, sizeof (m_teamScore));
|
|
m_blockList.clear();
|
|
}
|
|
|
|
void sArenaSystem::process(float elapsedTime)
|
|
{
|
|
m_blockTime -= elapsedTime;
|
|
if (0.0f > m_blockTime)
|
|
m_blockTime = 0.0f;
|
|
|
|
m_penaltyCountTime -= elapsedTime;
|
|
if (0.0f > m_penaltyCountTime)
|
|
m_penaltyCountTime = 0.0f;
|
|
|
|
procBlockList();
|
|
}
|
|
|
|
void sArenaSystem::procBlockList()
|
|
{
|
|
/// test
|
|
int arenaId = 0;
|
|
if (arenaId)
|
|
{
|
|
int teamNum = 1;
|
|
GetBattleArenaBeginAreaDB().getPointList(arenaId, teamNum, m_blockList);
|
|
if (2 < m_blockList.size())
|
|
m_blockList.push_back(K3DVector2(m_blockList[0].x, m_blockList[0].y));
|
|
return ;
|
|
}
|
|
|
|
if (!isRecvBattleInfo())
|
|
return ;
|
|
|
|
if (isPlaying())
|
|
{
|
|
if (!m_blockList.empty())
|
|
m_blockList.clear();
|
|
}
|
|
}
|
|
|
|
sArenaSystem::sPlayerInfo* sArenaSystem::findPlayerInfo(char const* playerName, int& team)
|
|
{
|
|
int player;
|
|
return findPlayerInfo(playerName, team, player);
|
|
}
|
|
|
|
sArenaSystem::sPlayerInfo* sArenaSystem::findPlayerInfo(char const* playerName, int& team, int& player)
|
|
{
|
|
int playerCount = sArenaUtility::MAX_MEMBER_ONE_TEAM;
|
|
for (int tn = 0; tn < sArenaUtility::MAX_TEAM_NUM; ++tn)
|
|
{
|
|
for (int pn = 0; pn < playerCount; ++pn)
|
|
{
|
|
if (strcmp(m_playerInfo[tn][pn].name, playerName) == 0)
|
|
{
|
|
team = tn;
|
|
player = pn;
|
|
return &m_playerInfo[tn][pn];
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int sArenaSystem::getMyTeam()
|
|
{
|
|
/// 경기 중간에 들어 갔을 때, localPlayer를 받기 전에 battle info를 받으면 local player데이타가 없기 때문에
|
|
/// 나의 팀 인덱스가 설정되지 않는다. 그래서 getMyTeam()을 호출 할 때 항상 체크하도록 한다
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(m_myTeam))
|
|
{
|
|
findMyTeam();
|
|
return m_myTeam;
|
|
}
|
|
|
|
return m_myTeam;
|
|
}
|
|
|
|
int sArenaSystem::findTeam(char const* playerName) const
|
|
{
|
|
int playerCount = sArenaUtility::MAX_MEMBER_ONE_TEAM;
|
|
for (int tn = 0; tn < sArenaUtility::MAX_TEAM_NUM; ++tn)
|
|
{
|
|
for (int pn = 0; pn < playerCount; ++pn)
|
|
{
|
|
if (strcmp(m_playerInfo[tn][pn].name, playerName) == 0)
|
|
{
|
|
return tn;
|
|
}
|
|
}
|
|
}
|
|
return sArenaUtility::TEAM_NONE;
|
|
}
|
|
|
|
sArenaSystem::sPlayerInfo* sArenaSystem::getPlayerInfo(int team, int player)
|
|
{
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(team))
|
|
return NULL;
|
|
if (0 > player)
|
|
return NULL;
|
|
|
|
return &m_playerInfo[team][player];
|
|
}
|
|
|
|
sArenaSystem::sPlayerInfo* sArenaSystem::findEmptyPlayerInfo(int team)
|
|
{
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(team))
|
|
return NULL;
|
|
|
|
for (int pn = 0; pn < sArenaUtility::MAX_MEMBER_ONE_TEAM; ++pn)
|
|
{
|
|
if (m_playerInfo[team][pn].name[0] == 0x00)
|
|
{
|
|
return &m_playerInfo[team][pn];
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void sArenaSystem::findMyTeam()
|
|
{
|
|
SGameAvatarEx* localPlayer = g_pCurrentGameSystem->GetLocalPlayer();
|
|
if (!localPlayer)
|
|
{
|
|
m_myTeam = sArenaUtility::TEAM_NONE;
|
|
m_opponentTeam = sArenaUtility::TEAM_NONE;
|
|
return ;
|
|
}
|
|
|
|
AR_HANDLE localHandle = localPlayer->GetArID();
|
|
int playerCount = sArenaUtility::MAX_MEMBER_ONE_TEAM;
|
|
for (int tn = 0; tn < sArenaUtility::MAX_TEAM_NUM; ++tn)
|
|
{
|
|
for (int pn = 0; pn < playerCount; ++pn)
|
|
{
|
|
if (m_playerInfo[tn][pn].handle == localHandle)
|
|
{
|
|
m_myTeam = tn;
|
|
sArenaUtility utility;
|
|
m_opponentTeam = utility.convertOpponentTeam(m_myTeam);
|
|
return ;
|
|
}
|
|
}
|
|
}
|
|
|
|
m_myTeam = sArenaUtility::TEAM_NONE;
|
|
m_opponentTeam = sArenaUtility::TEAM_NONE;
|
|
}
|
|
|
|
sArenaSystem::sPlayerScore* sArenaSystem::findPlayerScore(char const* playerName)
|
|
{
|
|
int playerCount = sArenaUtility::MAX_MEMBER_ONE_TEAM;
|
|
for (int tn = 0; tn < sArenaUtility::MAX_TEAM_NUM; ++tn)
|
|
{
|
|
for (int pn = 0; pn < playerCount; ++pn)
|
|
{
|
|
if (strcmp(m_playerScore[tn][pn].name, playerName) == 0)
|
|
{
|
|
return &m_playerScore[tn][pn];
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void sArenaSystem::erasePlayerScore(char const* playerName)
|
|
{
|
|
sPlayerScore* player = findPlayerScore(playerName);
|
|
if (player)
|
|
{
|
|
player->name[0] = 0x00;
|
|
}
|
|
}
|
|
|
|
sArenaSystem::sPlayerScore* sArenaSystem::getMyPlayerScore()
|
|
{
|
|
SGameAvatarEx* localPlayer = g_pCurrentGameSystem->GetLocalPlayer();
|
|
if (!localPlayer)
|
|
return NULL;
|
|
return findPlayerScore(localPlayer->GetName());
|
|
}
|
|
|
|
sArenaSystem::sTeamScore* sArenaSystem::getTeamScore(int team)
|
|
{
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(team))
|
|
return NULL;
|
|
|
|
return m_teamScore + team;
|
|
}
|
|
|
|
int sArenaSystem::getPlayerCount(int team)
|
|
{
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(team))
|
|
return 0;
|
|
|
|
return m_playerCount[team];
|
|
}
|
|
|
|
bool sArenaSystem::isWaiting()
|
|
{
|
|
AR_TIME cur = GetArTime();
|
|
if (m_startTime > cur)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool sArenaSystem::isPlaying()
|
|
{
|
|
AR_TIME cur = GetArTime();
|
|
if (m_forceEnterTime <= cur && m_endTime > cur)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool sArenaSystem::isReady(int team)
|
|
{
|
|
return m_readyState & (1<<team);
|
|
}
|
|
|
|
bool sArenaSystem::isRecvBattleInfo()
|
|
{
|
|
return m_startTime != 0;
|
|
}
|
|
|
|
bool sArenaSystem::isEnoughHalfPlayerCount(int maxMember) const
|
|
{
|
|
int halfMember = maxMember >> 1;
|
|
for (int i = 0; i < sArenaUtility::MAX_TEAM_NUM; ++i)
|
|
{
|
|
if (m_playerCount[i] < halfMember)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
char const* sArenaSystem::getPlayerName(SPlayerInfoMgr const* playerInfo)
|
|
{
|
|
if (isExercise())
|
|
{
|
|
return playerInfo->GetName();
|
|
}
|
|
else
|
|
{
|
|
if (isRecvBattleInfo() && playerInfo->IsAlias())
|
|
return playerInfo->GetAlias();
|
|
else
|
|
return playerInfo->GetName();
|
|
}
|
|
return "";
|
|
}
|
|
|
|
bool sArenaSystem::isEqualScore() const
|
|
{
|
|
return m_teamScore[sArenaUtility::TEAM_ALLIANCE].score == m_teamScore[sArenaUtility::TEAM_WITCH].score;
|
|
}
|
|
|
|
bool sArenaSystem::isExercise() const
|
|
{
|
|
return m_arenaId == sArenaUtility::EXERCISE_ARENA_ID;
|
|
}
|
|
|
|
bool sArenaSystem::isJoin() const
|
|
{
|
|
return m_arenaId != -1;
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaJoinQueue(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_JOIN_QUEUE* _msg = dynamicCast<SMSG_BATTLE_ARENA_JOIN_QUEUE*>(msg);
|
|
|
|
m_arenaId = _msg->arenaId;
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaLeave(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_LEAVE* _msg = dynamicCast<SMSG_BATTLE_ARENA_LEAVE*>(msg);
|
|
|
|
int team;
|
|
sPlayerInfo* info = findPlayerInfo(_msg->name, team);
|
|
if (info)
|
|
{
|
|
erasePlayerScore(_msg->name);
|
|
|
|
info->name[0] = 0x00;
|
|
info->handle = 0;
|
|
info->jobID = 0;
|
|
|
|
/// 플레이어 카운트가 새로 받지 않기 때문에 알아서 빼준다
|
|
m_playerCount[team] -= 1;
|
|
if (0 > m_playerCount[team])
|
|
m_playerCount[team] = 0;
|
|
}
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaBattleInfo(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_BATTLE_INFO* _msg = dynamicCast<SMSG_BATTLE_ARENA_BATTLE_INFO*>(msg);
|
|
|
|
/// 다른 데이타들도 초기화를 해준다
|
|
ZeroMemory(m_playerInfo, sizeof (m_playerInfo));
|
|
ZeroMemory(m_teamScore, sizeof (m_teamScore));
|
|
ZeroMemory(m_playerScore, sizeof (m_playerScore));
|
|
|
|
m_arenaId = _msg->arenaId;
|
|
for (int i = 0; i < sArenaUtility::MAX_TEAM_NUM; ++i)
|
|
{
|
|
m_playerCount[i] = _msg->playerCountPerTeam[i];
|
|
if (0 < m_playerCount[i])
|
|
memcpy(m_playerInfo[i], _msg->playerInfo[i], m_playerCount[i] * sizeof (sPlayerInfo));
|
|
}
|
|
|
|
m_forceEnterTime = _msg->forceEnterTime;
|
|
m_endTime = _msg->endTime;
|
|
m_startTime = _msg->startTime;
|
|
|
|
m_readyState = 0;
|
|
|
|
findMyTeam();
|
|
|
|
extractBlockList();
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaBattleStatus(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_BATTLE_STATUS* _msg = dynamicCast<SMSG_BATTLE_ARENA_BATTLE_STATUS*>(msg);
|
|
m_status = _msg->status;
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaBattleScore(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_BATTLE_SCORE* _msg = dynamicCast<SMSG_BATTLE_ARENA_BATTLE_SCORE*>(msg);
|
|
|
|
for (int i = 0; i < _msg->playerScoreCount; ++i)
|
|
{
|
|
sPlayerScore* _score = _msg->playerScore + i;
|
|
sPlayerScore* score = findPlayerScore(_score->name);
|
|
/// 스코어 정보가 없을 때
|
|
if (!score)
|
|
{
|
|
int team, player;
|
|
if (!findPlayerInfo(_score->name, team, player))
|
|
{
|
|
continue;
|
|
}
|
|
score = &m_playerScore[team][player];
|
|
}
|
|
|
|
memcpy(score, _score, sizeof (sPlayerScore));
|
|
}
|
|
|
|
memcpy(m_teamScore, _msg->teamScore, sizeof (m_teamScore));
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaJoinBattle(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_JOIN_BATTLE* _msg = dynamicCast<SMSG_BATTLE_ARENA_JOIN_BATTLE*>(msg);
|
|
|
|
int team;
|
|
if (findPlayerInfo(_msg->name, team))
|
|
return ;
|
|
|
|
sPlayerInfo* info = findEmptyPlayerInfo(_msg->teamNo);
|
|
if (info)
|
|
{
|
|
/// playerinfo를 새로 받지 않기 때문에 빈곳을 찾아서 추가해 준다
|
|
info->handle = _msg->handle;
|
|
info->jobID = _msg->jobID;
|
|
strcpy(info->name, _msg->name);
|
|
|
|
m_playerCount[_msg->teamNo] += 1;
|
|
}
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaDisconnectBattle(SGameMessage* /*msg*/)
|
|
{
|
|
/// 따로 저장할 데이타가 없다
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaReconnectBattle(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_RECONNECT_BATTLE* _msg = dynamicCast<SMSG_BATTLE_ARENA_RECONNECT_BATTLE*>(msg);
|
|
|
|
int team;
|
|
sPlayerInfo* info = findPlayerInfo(_msg->name, team);
|
|
if (info)
|
|
{
|
|
info->handle = _msg->newHandle;
|
|
}
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaResult(SGameMessage* /*msg*/)
|
|
{
|
|
/// 따로 저장할 데이타가 없다
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaAbsenceCheck(SGameMessage *msg)
|
|
{
|
|
/// 따로 저장할 데이타가 없다
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaPenaltyInfo(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_PENALTY_INFO* _msg = dynamicCast<SMSG_BATTLE_ARENA_PENALTY_INFO*>(msg);
|
|
|
|
m_blockTime = (float)_msg->blockTime/100.0f;
|
|
m_penaltyCount = _msg->penaltyCount;
|
|
m_penaltyCountTime = (float)_msg->penaltyCountTime/100.0f;
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaUpdateWaitUserCount(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT* _msg = dynamicCast<SMSG_BATTLE_ARENA_UPDATE_WAIT_USER_COUNT*>(msg);
|
|
m_waitingUserCount = _msg->waitUserCount;
|
|
}
|
|
|
|
void sArenaSystem::recvMsgBattleArenaExerciseReadyStatus(SGameMessage* msg)
|
|
{
|
|
SMSG_BATTLE_ARENA_EXERCISE_READY_STATUS* _msg = dynamicCast<SMSG_BATTLE_ARENA_EXERCISE_READY_STATUS*>(msg);
|
|
m_readyState = _msg->readyState;
|
|
}
|
|
|
|
void sArenaSystem::extractBlockList()
|
|
{
|
|
sArenaUtility utility;
|
|
if (!utility.isValidTeam(m_myTeam))
|
|
return ;
|
|
|
|
int teamNum = sArenaUtility::TEAM_ALLIANCE == m_myTeam ? 1 : 2;
|
|
GetBattleArenaBeginAreaDB().getPointList(m_arenaId, teamNum, m_blockList);
|
|
if (2 < m_blockList.size())
|
|
m_blockList.push_back(K3DVector2(m_blockList[0].x, m_blockList[0].y));
|
|
}
|