Enhance pausing system (by @heinrich5991):

* enhance /pause (@heinrich5991)
 * add /spec command to pause without leaving the game (@heinrich5991)
 * if sv_pauseable is set to 0, /pause behave as /spec (@heinrich5991)
 * should fix #124 and #127 (@ravomavain)
This commit is contained in:
Ravomavain 2011-12-29 14:58:39 +01:00 committed by GreYFoX
parent 21be03f3c6
commit 88be9657d2
11 changed files with 148 additions and 236 deletions

View file

@ -121,7 +121,7 @@ MACRO_CONFIG_INT(SvEndlessSuperHook, sv_endless_super_hook, 0, 0, 1, CFGFLAG_SER
MACRO_CONFIG_INT(SvHideScore, sv_hide_score, 0, 0, 1, CFGFLAG_SERVER, "Whether players scores will be announced or not")
MACRO_CONFIG_INT(SvPauseable, sv_pauseable, 1, 0, 1, CFGFLAG_SERVER, "Whether players can pause their char or not")
MACRO_CONFIG_INT(SvPauseTime, sv_pause_time, 0, 0, 1, CFGFLAG_SERVER, "Whether '/pause' and 'sv_max_dc_restore' pauses the time of player or not")
MACRO_CONFIG_INT(SvPauseFrequency, sv_pause_frequency, 5, 0, 9999, CFGFLAG_SERVER, "The minimum allowed delay between pauses")
MACRO_CONFIG_INT(SvPauseFrequency, sv_pause_frequency, 1, 0, 9999, CFGFLAG_SERVER, "The minimum allowed delay between pauses")
MACRO_CONFIG_INT(SvEmotionalTees, sv_emotional_tees, 1, -1, 1, CFGFLAG_SERVER, "Whether eye change of tees is enabled with emoticons = 1, not = 0, -1 not at all")
MACRO_CONFIG_INT(SvEmoticonDelay, sv_emoticon_delay, 3, 0, 9999, CFGFLAG_SERVER, "The time in seconds between over-head emoticons")

View file

@ -317,67 +317,44 @@ void CGameContext::ConTogglePause(IConsole::IResult *pResult, void *pUserData)
return;
char aBuf[128];
if(!g_Config.m_SvPauseable)
{
ConToggleSpec(pResult, pUserData);
return;
}
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
if (!pPlayer)
return;
if (g_Config.m_SvPauseable)
if (pPlayer->m_Paused == CPlayer::PAUSED_FORCE)
{
CCharacter* pChr = pPlayer->GetCharacter();
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())
{
pPlayer->SaveCharacter();
pPlayer->m_InfoSaved = true;
pPlayer->SetTeam(TEAM_SPECTATORS);
}
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD,
"pause", "You can\'t pause that often.");
}
else if (pPlayer->GetTeam() == TEAM_SPECTATORS && pPlayer->m_InfoSaved
&& pPlayer->m_ForcePauseTime == 0)
{
pPlayer->m_PauseInfo.m_Respawn = true;
pPlayer->SetTeam(TEAM_RED);
pPlayer->m_InfoSaved = false;
//pPlayer->LoadCharacter();//TODO:Check if this system Works
}
else if (pChr)
pSelf->Console()->Print(
IConsole::OUTPUT_LEVEL_STANDARD,
"pause",
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 if (pPlayer->m_ForcePauseTime > 0)
{
str_format(aBuf, sizeof(aBuf),
"You have been force-paused. %ds left.",
pPlayer->m_ForcePauseTime / pSelf->Server()->TickSpeed());
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause",
aBuf);
}
else if (pPlayer->m_ForcePauseTime < 0)
{
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause",
"You have been force-paused.");
}
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause",
"No pause data saved.");
str_format(aBuf, sizeof(aBuf), "You are force-paused. %ds left.", pPlayer->m_ForcePauseTime/pSelf->Server()->TickSpeed());
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause", aBuf);
return;
}
else
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "pause",
"Pause isn't allowed on this server.");
pPlayer->m_Paused = (pPlayer->m_Paused == CPlayer::PAUSED_PAUSED) ? CPlayer::PAUSED_NONE : CPlayer::PAUSED_PAUSED;
}
void CGameContext::ConToggleSpec(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *)pUserData;
if(!CheckClientID(pResult->m_ClientID)) return;
char aBuf[128];
CPlayer *pPlayer = pSelf->m_apPlayers[pResult->m_ClientID];
if(!pPlayer)
return;
if(pPlayer->m_Paused == CPlayer::PAUSED_FORCE)
{
str_format(aBuf, sizeof(aBuf), "You are force-paused. %ds left.", pPlayer->m_ForcePauseTime/pSelf->Server()->TickSpeed());
pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "spec", aBuf);
return;
}
pPlayer->m_Paused = (pPlayer->m_Paused == CPlayer::PAUSED_SPEC) ? CPlayer::PAUSED_NONE : CPlayer::PAUSED_SPEC;
}
void CGameContext::ConTop5(IConsole::IResult *pResult, void *pUserData)

View file

@ -13,7 +13,8 @@ CHAT_COMMAND("settings", "?s", CFGFLAG_CHAT|CFGFLAG_SERVER, ConSettings, this, "
CHAT_COMMAND("help", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConHelp, this, "Shows help to command r, general help if left blank")
CHAT_COMMAND("info", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConInfo, this, "Shows info about this server")
CHAT_COMMAND("me", "r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConMe, this, "Like the famous irc command '/me says hi' will display '<yourname> says hi'")
CHAT_COMMAND("pause", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTogglePause, this, "Toggles pause on/off (if activated on server)")
CHAT_COMMAND("pause", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConTogglePause, this, "Toggles pause (if not activated on the server, it toggles spec)")
CHAT_COMMAND("spec", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConToggleSpec, this, "Toggles spec")
CHAT_COMMAND("rank", "?r", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRank, this, "Shows the rank of player with name r (your rank by default)")
CHAT_COMMAND("rules", "", CFGFLAG_CHAT|CFGFLAG_SERVER, ConRules, this, "Shows the server rules")
CHAT_COMMAND("team", "?i", CFGFLAG_CHAT|CFGFLAG_SERVER, ConJoinTeam, this, "Lets you join team i (shows your team if left blank)")

View file

@ -287,45 +287,19 @@ void CGameContext::ConKill(IConsole::IResult *pResult, void *pUserData)
void CGameContext::ConForcePause(IConsole::IResult *pResult, void *pUserData)
{
CGameContext *pSelf = (CGameContext *) pUserData;
// if(!CheckClientID(pResult->m_ClientID)) return;
CServer* pServ = (CServer*) pSelf->Server();
CGameContext *pSelf = (CGameContext *)pUserData;
CServer* pServ = (CServer*)pSelf->Server();
int Victim = pResult->GetVictim();
int Seconds = 0;
char aBuf[128];
if (pResult->NumArguments() > 0 && pResult->m_ClientID < 0)
Seconds = clamp(pResult->GetInteger(0), 0, 15);
//else if(pResult->NumArguments() > 0 && CheckClientID(pResult->m_ClientID))
//Seconds = clamp(pResult->GetInteger(1), 0, 360);
if (pResult->NumArguments() > 0)
Seconds = clamp(pResult->GetInteger(0), 0, 360);
CPlayer *pPlayer = pSelf->m_apPlayers[Victim];
if (!pPlayer || (!Seconds && pResult->m_ClientID >= 0))
if (!pPlayer)
return;
CCharacter* pChr = pPlayer->GetCharacter();
if (!pPlayer->GetTeam() && pChr && !pPlayer->m_InfoSaved
&& pResult->m_ClientID < 0)
{
pPlayer->SaveCharacter();
pPlayer->m_InfoSaved = true;
pPlayer->SetTeam(TEAM_SPECTATORS);
pPlayer->m_ForcePauseTime = Seconds * pServ->TickSpeed();
}
else
{
pPlayer->m_ForcePauseTime = Seconds * pServ->TickSpeed();
}
if (pResult->m_ClientID < 0)
str_format(aBuf, sizeof(aBuf),
"'%s' has been force-paused for %d seconds",
pServ->ClientName(Victim), Seconds);
else
str_format(aBuf, sizeof(aBuf),
"Force-pause of '%s' have been removed by '%s'",
pServ->ClientName(Victim),
pServ->ClientName(pResult->m_ClientID));
pSelf->SendChat(-1, CHAT_ALL, aBuf);
pPlayer->m_ForcePauseTime = Seconds*pServ->TickSpeed();
pPlayer->m_Paused = CPlayer::PAUSED_FORCE;
}
void CGameContext::Mute(IConsole::IResult *pResult, NETADDR *Addr, int Secs,

View file

@ -614,6 +614,9 @@ void CCharacter::Tick()
m_pPlayer->m_ForceBalanced = false;
}*/
if (m_Paused)
return;
DDRaceTick();
m_Core.m_Input = m_Input;
@ -773,8 +776,7 @@ void CCharacter::Die(int Killer, int Weapon)
GameServer()->m_World.RemoveEntity(this);
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
GameServer()->CreateDeath(m_Pos, m_pPlayer->GetCID(), Teams()->TeamMask(Team(), -1, m_pPlayer->GetCID()));
if(!m_pPlayer->m_InfoSaved)
((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.SetForceCharacterTeam(m_pPlayer->GetCID(), 0);
Teams()->SetForceCharacterTeam(m_pPlayer->GetCID(), 0);
}
bool CCharacter::TakeDamage(vec2 Force, int Dmg, int From, int Weapon)
@ -888,7 +890,7 @@ void CCharacter::Snap(int SnappingClient)
return;
CCharacter* SnapChar = GameServer()->GetPlayerChar(SnappingClient);
if(SnapChar && !SnapChar->m_Super &&
if(SnapChar && !SnapChar->m_Super && !SnapChar->IsPaused() &&
GameServer()->m_apPlayers[SnappingClient]->GetTeam() != -1 &&
!CanCollide(SnappingClient) &&
(!GameServer()->m_apPlayers[SnappingClient]->m_IsUsingDDRaceClient ||
@ -899,6 +901,9 @@ void CCharacter::Snap(int SnappingClient)
)
return;
if (m_Paused)
return;
CNetObj_Character *pCharacter = static_cast<CNetObj_Character *>(Server()->SnapNewItem(NETOBJTYPE_CHARACTER, m_pPlayer->GetCID(), sizeof(CNetObj_Character)));
if(!pCharacter)
return;
@ -1573,8 +1578,24 @@ void CCharacter::GiveAllWeapons()
return;
}
void CCharacter::Pause(bool Pause)
{
m_Paused = Pause;
if(Pause)
{
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = 0;
GameServer()->m_World.RemoveEntity(this);
}
else
{
GameServer()->m_World.m_Core.m_apCharacters[m_pPlayer->GetCID()] = &m_Core;
GameServer()->m_World.InsertEntity(this);
}
}
void CCharacter::DDRaceInit()
{
m_Paused = false;
m_DDRaceState = DDRACE_NONE;
m_PrevPos = m_Pos;
m_LastBroadcast = 0;

View file

@ -63,6 +63,7 @@ public:
void SetEmote(int Emote, int Tick);
bool IsAlive() const { return m_Alive; }
bool IsPaused() const { return m_Paused; }
class CPlayer *GetPlayer() { return m_pPlayer; }
private:
@ -70,6 +71,7 @@ private:
class CPlayer *m_pPlayer;
bool m_Alive;
bool m_Paused;
// weapon info
CEntity *m_apHitObjects[10];
@ -144,6 +146,7 @@ private:
void HandleBroadcast();
public:
CGameTeams* Teams();
void Pause(bool Pause);
bool Freeze(int Time);
bool Freeze();
bool UnFreeze();

View file

@ -1019,7 +1019,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
{
//if(m_pController->CanChangeTeam(pPlayer, pMsg->m_Team))
if(pPlayer->GetTeam()==-1 && pPlayer->m_InfoSaved)
if(pPlayer->m_Paused)
SendChatTarget(ClientID,"Use /pause first then you can kill");
else
{
@ -1082,7 +1082,7 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID)
{
CNetMsg_Cl_SetSpectatorMode *pMsg = (CNetMsg_Cl_SetSpectatorMode *)pRawMsg;
if(pPlayer->GetTeam() != TEAM_SPECTATORS || pPlayer->m_SpectatorID == pMsg->m_SpectatorID || ClientID == pMsg->m_SpectatorID ||
if((pPlayer->GetTeam() != TEAM_SPECTATORS && !pPlayer->m_Paused) || pPlayer->m_SpectatorID == pMsg->m_SpectatorID || ClientID == pMsg->m_SpectatorID ||
(g_Config.m_SvSpamprotection && pPlayer->m_LastSetSpectatorMode && pPlayer->m_LastSetSpectatorMode+Server()->TickSpeed()*3 > Server()->Tick()))
return;

View file

@ -215,6 +215,7 @@ private:
static void ConRules(IConsole::IResult *pResult, void *pUserData);
static void ConKill(IConsole::IResult *pResult, void *pUserData);
static void ConTogglePause(IConsole::IResult *pResult, void *pUserData);
static void ConToggleSpec(IConsole::IResult *pResult, void *pUserData);
static void ConForcePause(IConsole::IResult *pResult, void *pUserData);
static void ConTop5(IConsole::IResult *pResult, void *pUserData);
#if defined(CONF_SQL)

View file

@ -37,7 +37,6 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team)
m_Sent1stAfkWarning = 0;
m_Sent2ndAfkWarning = 0;
m_ChatScore = 0;
m_PauseInfo.m_Respawn = false;
m_EyeEmote = true;
m_BroadcastTime = g_Config.m_SvTimeInBroadcast;
m_GameTimerTime = g_Config.m_SvTimeInGameTimer;
@ -49,6 +48,10 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, int Team)
m_IsUsingDDRaceClient = false;
m_ShowOthers = false;
m_Paused = PAUSED_NONE;
m_NextPauseTick = 0;
// Variable initialized:
m_Last_Team = 0;
#if defined(CONF_SQL)
@ -99,9 +102,6 @@ void CPlayer::Tick()
}
}
if(!m_pCharacter && m_Team == TEAM_SPECTATORS && m_SpectatorID == SPEC_FREEVIEW)
m_ViewPos -= vec2(clamp(m_ViewPos.x-m_LatestActivity.m_TargetX, -500.0f, 500.0f), clamp(m_ViewPos.y-m_LatestActivity.m_TargetY, -400.0f, 400.0f));
if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick())
m_Spawning = true;
@ -109,9 +109,25 @@ void CPlayer::Tick()
{
if(m_pCharacter->IsAlive())
{
m_ViewPos = m_pCharacter->m_Pos;
if(m_Paused >= PAUSED_FORCE)
{
if(m_ForcePauseTime == 0)
m_Paused = PAUSED_NONE;
ProcessPause();
}
else if(m_Paused == PAUSED_PAUSED && m_NextPauseTick < Server()->Tick())
{
if((!m_pCharacter->GetWeaponGot(WEAPON_NINJA) || m_pCharacter->m_FreezeTime) && m_pCharacter->IsGrounded() && m_pCharacter->m_Pos == m_pCharacter->m_PrevPos)
ProcessPause();
}
else if(m_NextPauseTick < Server()->Tick())
{
ProcessPause();
}
if(!m_Paused)
m_ViewPos = m_pCharacter->m_Pos;
}
else
else if(!m_pCharacter->IsPaused())
{
delete m_pCharacter;
m_pCharacter = 0;
@ -134,7 +150,7 @@ void CPlayer::PostTick()
}
// update view pos for spectators
if(m_Team == TEAM_SPECTATORS && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
if((m_Team == TEAM_SPECTATORS || m_Paused) && m_SpectatorID != SPEC_FREEVIEW && GameServer()->m_apPlayers[m_SpectatorID])
m_ViewPos = GameServer()->m_apPlayers[m_SpectatorID]->m_ViewPos;
}
@ -166,12 +182,12 @@ void CPlayer::Snap(int SnappingClient)
pPlayerInfo->m_Local = 0;
pPlayerInfo->m_ClientID = m_ClientID;
pPlayerInfo->m_Score = abs(m_Score) * -1;
pPlayerInfo->m_Team = m_Team;
pPlayerInfo->m_Team = (m_Paused != PAUSED_SPEC || m_ClientID != SnappingClient) && m_Paused < PAUSED_PAUSED ? m_Team : TEAM_SPECTATORS;
if(m_ClientID == SnappingClient)
pPlayerInfo->m_Local = 1;
if(m_ClientID == SnappingClient && m_Team == TEAM_SPECTATORS)
if(m_ClientID == SnappingClient && (m_Team == TEAM_SPECTATORS || m_Paused))
{
CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo)));
if(!pSpectatorInfo)
@ -187,8 +203,6 @@ void CPlayer::Snap(int SnappingClient)
pPlayerInfo->m_Score = -9999;
else
pPlayerInfo->m_Score = abs(m_Score) * -1;
pPlayerInfo->m_Team = m_Team;
}
void CPlayer::OnDisconnect(const char *pReason)
@ -218,7 +232,7 @@ void CPlayer::OnPredictedInput(CNetObj_PlayerInput *NewInput)
if((m_PlayerFlags&PLAYERFLAG_CHATTING) && (NewInput->m_PlayerFlags&PLAYERFLAG_CHATTING))
return;
if(m_pCharacter)
if(m_pCharacter && !m_Paused)
m_pCharacter->OnPredictedInput(NewInput);
}
@ -243,11 +257,19 @@ void CPlayer::OnDirectInput(CNetObj_PlayerInput *NewInput)
m_PlayerFlags = NewInput->m_PlayerFlags;
if(m_pCharacter)
m_pCharacter->OnDirectInput(NewInput);
{
if(!m_Paused)
m_pCharacter->OnDirectInput(NewInput);
else
m_pCharacter->ResetInput();
}
if(!m_pCharacter && m_Team != TEAM_SPECTATORS && (NewInput->m_Fire&1))
m_Spawning = true;
if(((!m_pCharacter && m_Team == TEAM_SPECTATORS) || m_Paused) && m_SpectatorID == SPEC_FREEVIEW)
m_ViewPos = vec2(NewInput->m_TargetX, NewInput->m_TargetY);
// check for activity
if(NewInput->m_Direction || m_LatestActivity.m_TargetX != NewInput->m_TargetX ||
m_LatestActivity.m_TargetY != NewInput->m_TargetY || NewInput->m_Jump ||
@ -290,15 +312,7 @@ void CPlayer::SetTeam(int Team)
return;
char aBuf[512];
if(m_InfoSaved)
{
if(Team == TEAM_SPECTATORS)
str_format(aBuf, sizeof(aBuf), "'%s' paused", Server()->ClientName(m_ClientID));
else
str_format(aBuf, sizeof(aBuf), "'%s' resumed", Server()->ClientName(m_ClientID));
}
else
str_format(aBuf, sizeof(aBuf), "'%s' joined the %s", Server()->ClientName(m_ClientID), GameServer()->m_pController->GetTeamName(Team));
str_format(aBuf, sizeof(aBuf), "'%s' joined the %s", Server()->ClientName(m_ClientID), GameServer()->m_pController->GetTeamName(Team));
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
KillCharacter();
@ -326,15 +340,6 @@ void CPlayer::SetTeam(int Team)
void CPlayer::TryRespawn()
{
if(m_PauseInfo.m_Respawn)
{
m_pCharacter = new(m_ClientID) CCharacter(&GameServer()->m_World);
m_pCharacter->Spawn(this, m_PauseInfo.m_Core.m_Pos);
GameServer()->CreatePlayerSpawn(m_PauseInfo.m_Core.m_Pos, ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.TeamMask((m_PauseInfo.m_Team > 0 && m_PauseInfo.m_Team < TEAM_SUPER) ? m_PauseInfo.m_Team : 0, -1, m_ClientID));
LoadCharacter();
}
else
{
vec2 SpawnPos;
if(!GameServer()->m_pController->CanSpawn(m_Team, &SpawnPos))
@ -344,74 +349,6 @@ void CPlayer::TryRespawn()
m_pCharacter = new(m_ClientID) CCharacter(&GameServer()->m_World);
m_pCharacter->Spawn(this, SpawnPos);
GameServer()->CreatePlayerSpawn(SpawnPos);
}
}
void CPlayer::LoadCharacter()
{
m_pCharacter->SetCore(m_PauseInfo.m_Core);
if(g_Config.m_SvPauseTime)
m_pCharacter->m_StartTime = Server()->Tick() - (m_PauseInfo.m_PauseTime - m_PauseInfo.m_StartTime);
else
m_pCharacter->m_StartTime = m_PauseInfo.m_StartTime;
m_pCharacter->m_DDRaceState = m_PauseInfo.m_DDRaceState;
m_pCharacter->m_RefreshTime = Server()->Tick();
for(int i = 0; i < NUM_WEAPONS; ++i)
{
if(m_PauseInfo.m_aHasWeapon[i])
{
if(!m_PauseInfo.m_FreezeTime)
m_pCharacter->GiveWeapon(i, -1);
else
m_pCharacter->GiveWeapon(i, 0);
}
}
m_pCharacter->m_FreezeTime = m_PauseInfo.m_FreezeTime;
m_pCharacter->SetLastAction(Server()->Tick());
m_pCharacter->SetArmor(m_PauseInfo.m_Armor);
m_pCharacter->m_LastMove = m_PauseInfo.m_LastMove;
m_pCharacter->m_PrevPos = m_PauseInfo.m_PrevPos;
m_pCharacter->SetActiveWeapon(m_PauseInfo.m_ActiveWeapon);
m_pCharacter->SetLastWeapon(m_PauseInfo.m_LastWeapon);
m_pCharacter->m_Super = m_PauseInfo.m_Super;
m_pCharacter->m_DeepFreeze = m_PauseInfo.m_DeepFreeze;
m_pCharacter->m_EndlessHook = m_PauseInfo.m_EndlessHook;
m_pCharacter->m_TeleCheckpoint = m_PauseInfo.m_TeleCheckpoint;
m_pCharacter->m_CpActive = m_PauseInfo.m_CpActive;
m_pCharacter->m_Hit = m_PauseInfo.m_Hit;
m_pCharacter->Teams()->m_Core.SetSolo(m_ClientID, m_PauseInfo.m_Solo);
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);
m_PauseInfo.m_Respawn = false;
m_InfoSaved = false;
}
void CPlayer::SaveCharacter()
{
m_PauseInfo.m_Core = m_pCharacter->GetCore();
m_PauseInfo.m_StartTime = m_pCharacter->m_StartTime;
m_PauseInfo.m_DDRaceState = m_pCharacter->m_DDRaceState;
for(int i = 0; i < WEAPON_NINJA; ++i)
m_PauseInfo.m_aHasWeapon[i] = m_pCharacter->GetWeaponGot(i);
m_PauseInfo.m_FreezeTime=m_pCharacter->m_FreezeTime;
m_PauseInfo.m_Armor = m_pCharacter->GetArmor();
m_PauseInfo.m_LastMove = m_pCharacter->m_LastMove;
m_PauseInfo.m_PrevPos = m_pCharacter->m_PrevPos;
m_PauseInfo.m_ActiveWeapon = m_pCharacter->GetActiveWeapon();
m_PauseInfo.m_LastWeapon = m_pCharacter->GetLastWeapon();
m_PauseInfo.m_Super = m_pCharacter->m_Super;
m_PauseInfo.m_DeepFreeze = m_pCharacter->m_DeepFreeze;
m_PauseInfo.m_EndlessHook = m_pCharacter->m_EndlessHook;
m_PauseInfo.m_Team = ((CGameControllerDDRace*)GameServer()->m_pController)->m_Teams.m_Core.Team(GetCID());
m_PauseInfo.m_PauseTime = Server()->Tick();
m_PauseInfo.m_TeleCheckpoint = m_pCharacter->m_TeleCheckpoint;
m_PauseInfo.m_CpActive = m_pCharacter->m_CpActive;
m_PauseInfo.m_Hit = m_pCharacter->m_Hit;
m_PauseInfo.m_Solo = m_pCharacter->Teams()->m_Core.GetSolo(m_ClientID);
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;
}
bool CPlayer::AfkTimer(int NewTargetX, int NewTargetY)
@ -474,9 +411,37 @@ bool CPlayer::AfkTimer(int NewTargetX, int NewTargetY)
return false;
}
void CPlayer::ProcessPause()
{
char aBuf[128];
if(m_Paused >= PAUSED_PAUSED)
{
if(!m_pCharacter->IsPaused())
{
m_pCharacter->Pause(true);
str_format(aBuf, sizeof(aBuf), (m_Paused == PAUSED_PAUSED) ? "'%s' paused" : "'%s' was force-paused for %ds", Server()->ClientName(m_ClientID), m_ForcePauseTime/Server()->TickSpeed());
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
GameServer()->CreateDeath(m_pCharacter->m_Pos, m_ClientID, m_pCharacter->Teams()->TeamMask(m_pCharacter->Team(), -1, m_ClientID));
GameServer()->CreateSound(m_pCharacter->m_Pos, SOUND_PLAYER_DIE, m_pCharacter->Teams()->TeamMask(m_pCharacter->Team(), -1, m_ClientID));
m_NextPauseTick = Server()->Tick() + g_Config.m_SvPauseFrequency * Server()->TickSpeed();
}
}
else
{
if(m_pCharacter->IsPaused())
{
m_pCharacter->Pause(false);
str_format(aBuf, sizeof(aBuf), "'%s' resumed", Server()->ClientName(m_ClientID));
GameServer()->SendChat(-1, CGameContext::CHAT_ALL, aBuf);
GameServer()->CreatePlayerSpawn(m_pCharacter->m_Pos, m_pCharacter->Teams()->TeamMask(m_pCharacter->Team(), -1, m_ClientID));
m_NextPauseTick = Server()->Tick() + g_Config.m_SvPauseFrequency * Server()->TickSpeed();
}
}
}
bool CPlayer::IsPlaying()
{
if(m_InfoSaved || (m_pCharacter && m_pCharacter->IsAlive()))
if(m_pCharacter && m_pCharacter->IsAlive())
return true;
return false;
}

View file

@ -112,36 +112,20 @@ private:
// DDRace
public:
struct PauseInfo
enum
{
CCharacterCore m_Core;
int m_StartTime;
int m_DDRaceState;
int m_FreezeTime;
int m_Armor;
int m_LastMove;
vec2 m_PrevPos;
int m_ActiveWeapon;
int m_LastWeapon;
bool m_Respawn;
bool m_aHasWeapon[NUM_WEAPONS];
bool m_Super;
bool m_DeepFreeze;
bool m_EndlessHook;
int m_PauseTime;
int m_Team;
int m_TeleCheckpoint;
int m_CpActive;
float m_CpCurrent[25];
int m_Hit;
bool m_Solo;
} m_PauseInfo;
PAUSED_NONE=0,
PAUSED_SPEC,
PAUSED_PAUSED,
PAUSED_FORCE
};
int m_Paused;
int64 m_NextPauseTick;
void ProcessPause();
int m_ForcePauseTime;
bool m_InfoSaved;
bool IsPlaying();
void LoadCharacter();
void SaveCharacter();
int64 m_Last_KickVote;
int64 m_Last_Team;
int m_Authed;

View file

@ -278,8 +278,6 @@ int CGameTeams::GetDDRaceState(CPlayer* Player)
CCharacter* pChar = Player->GetCharacter();
if (pChar)
return pChar->m_DDRaceState;
else if (Player->m_InfoSaved)
return Player->m_PauseInfo.m_DDRaceState;
return DDRACE_NONE;
}
@ -291,8 +289,6 @@ void CGameTeams::SetDDRaceState(CPlayer* Player, int DDRaceState)
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)
@ -303,8 +299,6 @@ int CGameTeams::GetStartTime(CPlayer* Player)
CCharacter* pChar = Player->GetCharacter();
if (pChar)
return pChar->m_StartTime;
else if (Player->m_InfoSaved)
return Player->m_PauseInfo.m_StartTime;
return 0;
}
@ -316,8 +310,6 @@ void CGameTeams::SetStartTime(CPlayer* Player, int StartTime)
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)
@ -328,8 +320,6 @@ void CGameTeams::SetRefreshTime(CPlayer* Player, int RefreshTime)
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)
@ -340,8 +330,6 @@ void CGameTeams::SetCpActive(CPlayer* Player, int CpActive)
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)
@ -352,8 +340,6 @@ float *CGameTeams::GetCpCurrent(CPlayer* Player)
CCharacter* pChar = Player->GetCharacter();
if (pChar)
return pChar->m_CpCurrent;
else if (Player->m_InfoSaved)
return Player->m_PauseInfo.m_CpCurrent;
return NULL;
}