Reworking teams to allow pausing in team

* Adding wrappers functions to modify character or pause data if player are in game or paused.
* Moved OnFinish() function to teams.cpp so it can also be called on paused players.
* Pause is now enabled for team players.
* Adding bool CPlayer::IsPlaying() function that return true if the player is either in game or in pause. (false if spectator/dead).
This commit is contained in:
Romain Labolle 2011-06-06 21:24:27 +02:00 committed by GreYFoX
parent 413bf4a39e
commit c17d3cdeda
12 changed files with 261 additions and 144 deletions

View file

@ -466,7 +466,7 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, i
if(g_Config.m_SvPauseable) if(g_Config.m_SvPauseable)
{ {
CCharacter* pChr = pPlayer->GetCharacter(); CCharacter* pChr = pPlayer->GetCharacter();
if(!pPlayer->GetTeam() && pChr && (!pChr->GetWeaponGot(WEAPON_NINJA) || pChr->m_FreezeTime) && pChr->IsGrounded() && pChr->m_Pos==pChr->m_PrevPos && !pChr->Team() && !pPlayer->m_InfoSaved) if(!pPlayer->GetTeam() && pChr && (!pChr->GetWeaponGot(WEAPON_NINJA) || pChr->m_FreezeTime) && pChr->IsGrounded() && pChr->m_Pos==pChr->m_PrevPos && !pPlayer->m_InfoSaved)
{ {
if(pPlayer->m_LastSetTeam + pSelf->Server()->TickSpeed() * g_Config.m_SvPauseFrequency <= pSelf->Server()->Tick()) if(pPlayer->m_LastSetTeam + pSelf->Server()->TickSpeed() * g_Config.m_SvPauseFrequency <= pSelf->Server()->Tick())
{ {
@ -485,7 +485,7 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData, i
//pPlayer->LoadCharacter();//TODO:Check if this system Works //pPlayer->LoadCharacter();//TODO:Check if this system Works
} }
else if(pChr) else if(pChr)
pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", (pChr->Team())?"You can't pause while you are in a team":pChr->GetWeaponGot(WEAPON_NINJA)?"You can't use /pause while you are a ninja":(!pChr->IsGrounded())?"You can't use /pause while you are a in air":"You can't use /pause while you are moving"); pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", pChr->GetWeaponGot(WEAPON_NINJA)?"You can't use /pause while you are a ninja":(!pChr->IsGrounded())?"You can't use /pause while you are a in air":"You can't use /pause while you are moving");
else else
pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "No pause data saved."); pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "No pause data saved.");
} }
@ -620,13 +620,13 @@ void CGameContext::ConJoinTeam(IConsole::IResult *pResult, void *pUserData, int
else else
{ {
char aBuf[512]; char aBuf[512];
if(pPlayer->GetCharacter() == 0) if(!pPlayer->IsPlaying())
{ {
pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can't check your team while you are dead/a spectator."); pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", "You can't check your team while you are dead/a spectator.");
} }
else else
{ {
str_format(aBuf, sizeof(aBuf), "You are in team %d", pPlayer->GetCharacter()->Team()); str_format(aBuf, sizeof(aBuf), "You are in team %d", ((CGameControllerDDRace*)pSelf->m_pController)->m_Teams.m_Core.Team(ClientID));
pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf); pResult->Print(IConsole::OUTPUT_LEVEL_STANDARD, "info", aBuf);
} }
} }

View file

@ -756,6 +756,7 @@ void CCharacter::Die(int Killer, int Weapon)
GameServer()->m_World.RemoveEntity(this); GameServer()->m_World.RemoveEntity(this);
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0; GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID(), Teams()->TeamMask(Team())); GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID(), Teams()->TeamMask(Team()));
if(!m_pPlayer->m_InfoSaved)
((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.SetForceCharacterTeam(m_pPlayer->GetCID(), 0); ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.SetForceCharacterTeam(m_pPlayer->GetCID(), 0);
} }
@ -951,122 +952,6 @@ bool CCharacter::SameTeam(int ClientID)
return Teams()->m_Core.SameTeam(GetPlayer()->GetCID(), ClientID); return Teams()->m_Core.SameTeam(GetPlayer()->GetCID(), ClientID);
} }
void CCharacter::OnFinish()
{
//TODO:DDRace:btd: this ugly
float time = (float)(Server()->Tick() - m_StartTime) / ((float)Server()->TickSpeed());
if(time < 0.000001f) return;
CPlayerData *pData = GameServer()->Score()->PlayerData(m_pPlayer->GetCID());
char aBuf[128];
m_CpActive=-2;
str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.2f second(s)", Server()->ClientName(m_pPlayer->GetCID()), (int)time/60, time-((int)time/60*60));
if(g_Config.m_SvHideScore)
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
else
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
if(time - pData->m_BestTime < 0)
{
// new record \o/
str_format(aBuf, sizeof(aBuf), "New record: %5.2f second(s) better.", fabs(time - pData->m_BestTime));
if(g_Config.m_SvHideScore)
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);
else
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}
else if(pData->m_BestTime != 0) // tee has already finished?
{
if(fabs(time - pData->m_BestTime) <= 0.005)
{
GameServer()->SendChatTarget(m_pPlayer->GetCID(), "You finished with your best time.");
}
else
{
str_format(aBuf, sizeof(aBuf), "%5.2f second(s) worse, better luck next time.", fabs(pData->m_BestTime - time));
GameServer()->SendChatTarget(m_pPlayer->GetCID(), aBuf);//this is private, sent only to the tee
}
}
bool pCallSaveScore = false;
#if defined(CONF_SQL)
pCallSaveScore = g_Config.m_SvUseSQL;
#endif
if(!pData->m_BestTime || time < pData->m_BestTime)
{
// update the score
pData->Set(time, m_CpCurrent);
pCallSaveScore = true;
}
if(pCallSaveScore)
if(str_comp_num(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0)
GameServer()->Score()->SaveScore(m_pPlayer->GetCID(), time, this);
bool NeedToSendNewRecord = false;
// update server best time
if(GameServer()->m_pController->m_CurrentRecord == 0 || time < GameServer()->m_pController->m_CurrentRecord)
{
// check for nameless
if(str_comp_num(Server()->ClientName(m_pPlayer->GetCID()), "nameless tee", 12) != 0) {
GameServer()->m_pController->m_CurrentRecord = time;
//dbg_msg("character", "Finish");
NeedToSendNewRecord = true;
}
}
m_DDRaceState = DDRACE_FINISHED;
// set player score
if(!pData->m_CurrentTime || pData->m_CurrentTime > time)
{
pData->m_CurrentTime = time;
NeedToSendNewRecord = true;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_IsUsingDDRaceClient)
{
if(!g_Config.m_SvHideScore || i == m_pPlayer->GetCID())
{
CNetMsg_Sv_PlayerTime Msg;
Msg.m_Time = time * 100.0;
Msg.m_ClientID = m_pPlayer->GetCID();
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, i);
}
}
}
}
if(NeedToSendNewRecord && GetPlayer()->m_IsUsingDDRaceClient) {
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_IsUsingDDRaceClient)
{
GameServer()->SendRecord(i);
}
}
}
if(GetPlayer()->m_IsUsingDDRaceClient) {
CNetMsg_Sv_DDRaceTime Msg;
Msg.m_Time = (int)(time * 100.0f);
Msg.m_Check = 0;
Msg.m_Finish = 1;
if(pData->m_BestTime)
{
float Diff = (time - pData->m_BestTime)*100;
Msg.m_Check = (int)Diff;
}
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, m_pPlayer->GetCID());
}
int TTime = 0-(int)time;
if(m_pPlayer->m_Score < TTime)
m_pPlayer->m_Score = TTime;
}
int CCharacter::Team() int CCharacter::Team()
{ {
return ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(m_pPlayer->GetCID()); return ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(m_pPlayer->GetCID());

View file

@ -148,7 +148,6 @@ public:
bool UnFreeze(); bool UnFreeze();
void GiveAllWeapons(); void GiveAllWeapons();
int m_DDRaceState; int m_DDRaceState;
void OnFinish();
int Team(); int Team();
bool CanCollide(int ClientID); bool CanCollide(int ClientID);
bool SameTeam(int ClientID); bool SameTeam(int ClientID);

View file

@ -346,6 +346,9 @@ void CPlayer::LoadCharacter()
m_pCharacter->m_DeepFreeze = m_PauseInfo.m_DeepFreeze; m_pCharacter->m_DeepFreeze = m_PauseInfo.m_DeepFreeze;
m_pCharacter->m_EndlessHook = m_PauseInfo.m_EndlessHook; m_pCharacter->m_EndlessHook = m_PauseInfo.m_EndlessHook;
m_pCharacter->m_TeleCheckpoint = m_PauseInfo.m_TeleCheckpoint; m_pCharacter->m_TeleCheckpoint = m_PauseInfo.m_TeleCheckpoint;
m_pCharacter->m_CpActive = m_PauseInfo.m_CpActive;
for(int i = 0; i < NUM_CHECKPOINTS; i++)
m_pCharacter->m_CpCurrent[i] = m_PauseInfo.m_CpCurrent[i];
((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID(), m_PauseInfo.m_Team); ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID(), m_PauseInfo.m_Team);
m_PauseInfo.m_Respawn = false; m_PauseInfo.m_Respawn = false;
m_InfoSaved = false; m_InfoSaved = false;
@ -370,6 +373,9 @@ void CPlayer::SaveCharacter()
m_PauseInfo.m_Team = ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID()); m_PauseInfo.m_Team = ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID());
m_PauseInfo.m_PauseTime = Server()->Tick(); m_PauseInfo.m_PauseTime = Server()->Tick();
m_PauseInfo.m_TeleCheckpoint = m_pCharacter->m_TeleCheckpoint; m_PauseInfo.m_TeleCheckpoint = m_pCharacter->m_TeleCheckpoint;
m_PauseInfo.m_CpActive = m_pCharacter->m_CpActive;
for(int i = 0; i < NUM_CHECKPOINTS; i++)
m_PauseInfo.m_CpCurrent[i] = m_pCharacter->m_CpCurrent[i];
//m_PauseInfo.m_RefreshTime = m_pCharacter->m_RefreshTime; //m_PauseInfo.m_RefreshTime = m_pCharacter->m_RefreshTime;
} }
@ -432,3 +438,10 @@ bool CPlayer::AfkTimer(int NewTargetX, int NewTargetY)
} }
return false; return false;
} }
bool CPlayer::IsPlaying()
{
if(m_InfoSaved || (m_pCharacter && m_pCharacter->IsAlive()))
return true;
return false;
}

View file

@ -131,8 +131,11 @@ public:
int m_PauseTime; int m_PauseTime;
int m_Team; int m_Team;
int m_TeleCheckpoint; int m_TeleCheckpoint;
int m_CpActive;
float m_CpCurrent[25];
} m_PauseInfo; } m_PauseInfo;
bool m_InfoSaved; bool m_InfoSaved;
bool IsPlaying();
void LoadCharacter(); void LoadCharacter();
void SaveCharacter(); void SaveCharacter();
int64 m_Last_KickVote; int64 m_Last_KickVote;

View file

@ -44,7 +44,7 @@ public:
CPlayerData *PlayerData(int ID) { return &m_aPlayerData[ID]; } CPlayerData *PlayerData(int ID) { return &m_aPlayerData[ID]; }
virtual void LoadScore(int ClientID) = 0; virtual void LoadScore(int ClientID) = 0;
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar) = 0; virtual void SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS]) = 0;
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut=1) = 0; virtual void ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut=1) = 0;
virtual void ShowRank(int ClientID, const char* pName, bool Search=false) = 0; virtual void ShowRank(int ClientID, const char* pName, bool Search=false) = 0;

View file

@ -194,11 +194,11 @@ void CFileScore::LoadScore(int ClientID)
PlayerData(ClientID)->Set(pPlayer->m_Score, pPlayer->m_aCpTime); PlayerData(ClientID)->Set(pPlayer->m_Score, pPlayer->m_aCpTime);
} }
void CFileScore::SaveScore(int ClientID, float Time, CCharacter *pChar) void CFileScore::SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS])
{ {
CConsole* pCon = (CConsole*)GameServer()->Console(); CConsole* pCon = (CConsole*)GameServer()->Console();
if(!pCon->m_Cheated) if(!pCon->m_Cheated)
UpdatePlayer(ClientID, Time, pChar->m_CpCurrent); UpdatePlayer(ClientID, Time, CpTime);
} }
void CFileScore::ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut) void CFileScore::ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut)

View file

@ -45,7 +45,7 @@ public:
~CFileScore(); ~CFileScore();
virtual void LoadScore(int ClientID); virtual void LoadScore(int ClientID);
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar); virtual void SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS]);
virtual void ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut=1); virtual void ShowTop5(IConsole::IResult *pResult, int ClientID, int Debut=1);
virtual void ShowRank(int ClientID, const char* pName, bool Search=false); virtual void ShowRank(int ClientID, const char* pName, bool Search=false);

View file

@ -283,7 +283,7 @@ void CSqlScore::SaveScoreThread(void *pUser)
lock_release(gs_SqlLock); lock_release(gs_SqlLock);
} }
void CSqlScore::SaveScore(int ClientID, float Time, CCharacter *pChar) void CSqlScore::SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS])
{ {
CConsole* pCon = (CConsole*)GameServer()->Console(); CConsole* pCon = (CConsole*)GameServer()->Console();
if(pCon->m_Cheated) if(pCon->m_Cheated)
@ -293,7 +293,7 @@ void CSqlScore::SaveScore(int ClientID, float Time, CCharacter *pChar)
str_copy(Tmp->m_aName, Server()->ClientName(ClientID), sizeof(Tmp->m_aName)); str_copy(Tmp->m_aName, Server()->ClientName(ClientID), sizeof(Tmp->m_aName));
Tmp->m_Time = Time; Tmp->m_Time = Time;
for(int i = 0; i < NUM_CHECKPOINTS; i++) for(int i = 0; i < NUM_CHECKPOINTS; i++)
Tmp->m_aCpCurrent[i] = pChar->m_CpCurrent[i]; Tmp->m_aCpCurrent[i] = CpTime[i];
Tmp->m_pSqlData = this; Tmp->m_pSqlData = this;
void *SaveThread = thread_create(SaveScoreThread, Tmp); void *SaveThread = thread_create(SaveScoreThread, Tmp);

View file

@ -55,7 +55,7 @@ public:
~CSqlScore(); ~CSqlScore();
virtual void LoadScore(int ClientID); virtual void LoadScore(int ClientID);
virtual void SaveScore(int ClientID, float Time, CCharacter *pChar); virtual void SaveScore(int ClientID, float Time, float CpTime[NUM_CHECKPOINTS]);
virtual void ShowRank(int ClientID, const char* pName, bool Search=false); virtual void ShowRank(int ClientID, const char* pName, bool Search=false);
virtual void ShowTimes(int ClientID, const char* pName, int Debut=1); virtual void ShowTimes(int ClientID, const char* pName, int Debut=1);
virtual void ShowTimes(int ClientID, int Debut=1); virtual void ShowTimes(int ClientID, int Debut=1);

View file

@ -39,8 +39,8 @@ void CGameTeams::OnCharacterStart(int ClientID)
{ {
if(m_Core.Team(ClientID) == m_Core.Team(i)) if(m_Core.Team(ClientID) == m_Core.Team(i))
{ {
CCharacter* pChar = Character(i); CPlayer* pPlayer = GetPlayer(i);
if(pChar->m_DDRaceState == DDRACE_FINISHED) if(pPlayer && pPlayer->IsPlaying() && GetDDRaceState(pPlayer) == DDRACE_FINISHED)
{ {
Waiting = true; Waiting = true;
if(m_LastChat[ClientID] + Server()->TickSpeed() + g_Config.m_SvChatDelay < Tick) if(m_LastChat[ClientID] + Server()->TickSpeed() + g_Config.m_SvChatDelay < Tick)
@ -68,12 +68,12 @@ void CGameTeams::OnCharacterStart(int ClientID)
{ {
if(m_Core.Team(ClientID) == m_Core.Team(i)) if(m_Core.Team(ClientID) == m_Core.Team(i))
{ {
CCharacter* pChar = Character(i); CPlayer* pPlayer = GetPlayer(i);
if(pChar) if(pPlayer && pPlayer->IsPlaying())
{ {
pChar->m_DDRaceState = DDRACE_STARTED; SetDDRaceState(pPlayer, DDRACE_STARTED);
pChar->m_StartTime = Tick; SetStartTime(pPlayer, Tick);
pChar->m_RefreshTime = Tick; SetRefreshTime(pPlayer, Tick);
} }
} }
} }
@ -85,7 +85,9 @@ void CGameTeams::OnCharacterFinish(int ClientID)
{ {
if(m_Core.Team(ClientID) == TEAM_FLOCK || m_Core.Team(ClientID) == TEAM_SUPER) if(m_Core.Team(ClientID) == TEAM_FLOCK || m_Core.Team(ClientID) == TEAM_SUPER)
{ {
Character(ClientID)->OnFinish(); CPlayer* pPlayer = GetPlayer(ClientID);
if(pPlayer && pPlayer->IsPlaying())
OnFinish(pPlayer);
} }
else else
{ {
@ -98,10 +100,10 @@ void CGameTeams::OnCharacterFinish(int ClientID)
{ {
if(m_Core.Team(ClientID) == m_Core.Team(i)) if(m_Core.Team(ClientID) == m_Core.Team(i))
{ {
CCharacter * pChar = Character(i); CPlayer* pPlayer = GetPlayer(i);
if(pChar != 0) if(pPlayer && pPlayer->IsPlaying())
{ {
pChar->OnFinish(); OnFinish(pPlayer);
m_TeeFinished[i] = false; m_TeeFinished[i] = false;
} }
} }
@ -129,7 +131,7 @@ bool CGameTeams::SetCharacterTeam(int ClientID, int Team)
{ {
//you will be killed if you try to join FLOCK //you will be killed if you try to join FLOCK
if(Team == TEAM_FLOCK && m_Core.Team(ClientID) != TEAM_FLOCK) if(Team == TEAM_FLOCK && m_Core.Team(ClientID) != TEAM_FLOCK)
Character(ClientID)->GetPlayer()->KillCharacter(WEAPON_GAME); GetPlayer(ClientID)->KillCharacter(WEAPON_GAME);
else if(Team != TEAM_SUPER) else if(Team != TEAM_SUPER)
return false; return false;
} }
@ -165,7 +167,7 @@ void CGameTeams::SetForceCharacterTeam(int ClientID, int Team)
for (int LoopClientID = 0; LoopClientID < MAX_CLIENTS; ++LoopClientID) for (int LoopClientID = 0; LoopClientID < MAX_CLIENTS; ++LoopClientID)
{ {
if(Character(LoopClientID) && Character(LoopClientID)->GetPlayer()->m_IsUsingDDRaceClient) if(GetPlayer(LoopClientID) && GetPlayer(LoopClientID)->m_IsUsingDDRaceClient)
SendTeamsState(LoopClientID); SendTeamsState(LoopClientID);
} }
} }
@ -197,7 +199,7 @@ int CGameTeams::TeamMask(int Team, int ExceptID)
for(int i = 0; i < MAX_CLIENTS; ++i) for(int i = 0; i < MAX_CLIENTS; ++i)
if(i != ExceptID) if(i != ExceptID)
if((Character(i) && (m_Core.Team(i) == Team || m_Core.Team(i) == TEAM_SUPER)) if((Character(i) && (m_Core.Team(i) == Team || m_Core.Team(i) == TEAM_SUPER))
|| (GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->GetTeam() == -1)) || (GetPlayer(i) && GetPlayer(i)->GetTeam() == -1))
Mask |= 1 << i; Mask |= 1 << i;
return Mask; return Mask;
} }
@ -225,3 +227,208 @@ void CGameTeams::SendTeamsState(int ClientID)
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID); Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, ClientID);
} }
int CGameTeams::GetDDRaceState(CPlayer* Player)
{
if(!Player)
return DDRACE_NONE;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
return pChar->m_DDRaceState;
else if(Player->m_InfoSaved)
return Player->m_PauseInfo.m_DDRaceState;
return DDRACE_NONE;
}
void CGameTeams::SetDDRaceState(CPlayer* Player, int DDRaceState)
{
if(!Player)
return;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
pChar->m_DDRaceState = DDRaceState;
else if(Player->m_InfoSaved)
Player->m_PauseInfo.m_DDRaceState = DDRaceState;
}
int CGameTeams::GetStartTime(CPlayer* Player)
{
if(!Player)
return 0;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
return pChar->m_StartTime;
else if(Player->m_InfoSaved)
return Player->m_PauseInfo.m_StartTime;
return 0;
}
void CGameTeams::SetStartTime(CPlayer* Player, int StartTime)
{
if(!Player)
return;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
pChar->m_StartTime = StartTime;
else if(Player->m_InfoSaved)
Player->m_PauseInfo.m_StartTime = StartTime;
}
void CGameTeams::SetRefreshTime(CPlayer* Player, int RefreshTime)
{
if(!Player)
return;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
pChar->m_RefreshTime = RefreshTime;
/*else if(Player->m_InfoSaved)
Player->m_PauseInfo.m_RefreshTime = RefreshTime;*/
}
void CGameTeams::SetCpActive(CPlayer* Player, int CpActive)
{
if(!Player)
return;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
pChar->m_CpActive = CpActive;
else if(Player->m_InfoSaved)
Player->m_PauseInfo.m_CpActive = CpActive;
}
float *CGameTeams::GetCpCurrent(CPlayer* Player)
{
if(!Player)
return NULL;
CCharacter* pChar = Player->GetCharacter();
if(pChar)
return pChar->m_CpCurrent;
else if(Player->m_InfoSaved)
return Player->m_PauseInfo.m_CpCurrent;
return NULL;
}
void CGameTeams::OnFinish(CPlayer* Player)
{
if(!Player || !Player->IsPlaying())
return;
//TODO:DDRace:btd: this ugly
float time = (float)(Server()->Tick() - GetStartTime(Player)) / ((float)Server()->TickSpeed());
if(time < 0.000001f) return;
CPlayerData *pData = GameServer()->Score()->PlayerData(Player->GetCID());
char aBuf[128];
SetCpActive(Player, -2);
str_format(aBuf, sizeof(aBuf), "%s finished in: %d minute(s) %5.2f second(s)", Server()->ClientName(Player->GetCID()), (int)time/60, time-((int)time/60*60));
if(g_Config.m_SvHideScore)
GameServer()->SendChatTarget(Player->GetCID(), aBuf);
else
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
if(time - pData->m_BestTime < 0)
{
// new record \o/
str_format(aBuf, sizeof(aBuf), "New record: %5.2f second(s) better.", fabs(time - pData->m_BestTime));
if(g_Config.m_SvHideScore)
GameServer()->SendChatTarget(Player->GetCID(), aBuf);
else
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
}
else if(pData->m_BestTime != 0) // tee has already finished?
{
if(fabs(time - pData->m_BestTime) <= 0.005)
{
GameServer()->SendChatTarget(Player->GetCID(), "You finished with your best time.");
}
else
{
str_format(aBuf, sizeof(aBuf), "%5.2f second(s) worse, better luck next time.", fabs(pData->m_BestTime - time));
GameServer()->SendChatTarget(Player->GetCID(), aBuf);//this is private, sent only to the tee
}
}
bool pCallSaveScore = false;
#if defined(CONF_SQL)
pCallSaveScore = g_Config.m_SvUseSQL;
#endif
if(!pData->m_BestTime || time < pData->m_BestTime)
{
// update the score
pData->Set(time, GetCpCurrent(Player));
pCallSaveScore = true;
}
if(pCallSaveScore)
if(str_comp_num(Server()->ClientName(Player->GetCID()), "nameless tee", 12) != 0)
GameServer()->Score()->SaveScore(Player->GetCID(), time, GetCpCurrent(Player));
bool NeedToSendNewRecord = false;
// update server best time
if(GameServer()->m_pController->m_CurrentRecord == 0 || time < GameServer()->m_pController->m_CurrentRecord)
{
// check for nameless
if(str_comp_num(Server()->ClientName(Player->GetCID()), "nameless tee", 12) != 0) {
GameServer()->m_pController->m_CurrentRecord = time;
//dbg_msg("character", "Finish");
NeedToSendNewRecord = true;
}
}
SetDDRaceState(Player, DDRACE_FINISHED);
// set player score
if(!pData->m_CurrentTime || pData->m_CurrentTime > time)
{
pData->m_CurrentTime = time;
NeedToSendNewRecord = true;
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(GetPlayer(i) && GetPlayer(i)->m_IsUsingDDRaceClient)
{
if(!g_Config.m_SvHideScore || i == Player->GetCID())
{
CNetMsg_Sv_PlayerTime Msg;
Msg.m_Time = time * 100.0;
Msg.m_ClientID = Player->GetCID();
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, i);
}
}
}
}
if(NeedToSendNewRecord && Player->m_IsUsingDDRaceClient) {
for(int i = 0; i < MAX_CLIENTS; i++)
{
if(GameServer()->m_apPlayers[i] && GameServer()->m_apPlayers[i]->m_IsUsingDDRaceClient)
{
GameServer()->SendRecord(i);
}
}
}
if(Player->m_IsUsingDDRaceClient) {
CNetMsg_Sv_DDRaceTime Msg;
Msg.m_Time = (int)(time * 100.0f);
Msg.m_Check = 0;
Msg.m_Finish = 1;
if(pData->m_BestTime)
{
float Diff = (time - pData->m_BestTime)*100;
Msg.m_Check = (int)Diff;
}
Server()->SendPackMsg(&Msg, MSGFLAG_VITAL, Player->GetCID());
}
int TTime = 0-(int)time;
if(Player->m_Score < TTime)
Player->m_Score = TTime;
}

View file

@ -29,6 +29,7 @@ public:
//helper methods //helper methods
CCharacter* Character(int ClientID) { return GameServer()->GetPlayerChar(ClientID); } CCharacter* Character(int ClientID) { return GameServer()->GetPlayerChar(ClientID); }
CPlayer* GetPlayer(int ClientID) { return GameServer()->m_apPlayers[ClientID]; }
class CGameContext *GameServer() { return m_pGameContext; } class CGameContext *GameServer() { return m_pGameContext; }
class IServer *Server() { return m_pGameContext->Server(); } class IServer *Server() { return m_pGameContext->Server(); }
@ -54,6 +55,15 @@ public:
void SendTeamsState(int Cid); void SendTeamsState(int Cid);
int m_LastChat[MAX_CLIENTS]; int m_LastChat[MAX_CLIENTS];
int GetDDRaceState(CPlayer* Player);
int GetStartTime(CPlayer* Player);
float *GetCpCurrent(CPlayer* Player);
void SetDDRaceState(CPlayer* Player, int DDRaceState);
void SetStartTime(CPlayer* Player, int StartTime);
void SetRefreshTime(CPlayer* Player, int RefreshTime);
void SetCpActive(CPlayer* Player, int CpActive);
void OnFinish(CPlayer* Player);
}; };
#endif #endif