diff --git a/src/engine/shared/config_variables.h b/src/engine/shared/config_variables.h index c1502912e..047d42f49 100644 --- a/src/engine/shared/config_variables.h +++ b/src/engine/shared/config_variables.h @@ -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") diff --git a/src/game/server/ddracechat.cpp b/src/game/server/ddracechat.cpp index 99dc46f4d..6f95be86c 100644 --- a/src/game/server/ddracechat.cpp +++ b/src/game/server/ddracechat.cpp @@ -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) diff --git a/src/game/server/ddracechat.h b/src/game/server/ddracechat.h index 9bf8bb9c9..73daf43f6 100644 --- a/src/game/server/ddracechat.h +++ b/src/game/server/ddracechat.h @@ -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 ' 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)") diff --git a/src/game/server/ddracecommands.cpp b/src/game/server/ddracecommands.cpp index 740ee4f0e..48f001031 100644 --- a/src/game/server/ddracecommands.cpp +++ b/src/game/server/ddracecommands.cpp @@ -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, diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index fc90c7498..4c212c2f2 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -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(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; diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h index 0d8a80701..029ebc183 100644 --- a/src/game/server/entities/character.h +++ b/src/game/server/entities/character.h @@ -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(); diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 9f7264c9f..ff92c2109 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -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; diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 8eca9114a..27a3a5c12 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -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) diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index 189b30c04..e0f89065a 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -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(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; } diff --git a/src/game/server/player.h b/src/game/server/player.h index 1a9f9be08..27fb4e65e 100644 --- a/src/game/server/player.h +++ b/src/game/server/player.h @@ -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; diff --git a/src/game/server/teams.cpp b/src/game/server/teams.cpp index 2ea9bf084..dbd29cc08 100644 --- a/src/game/server/teams.cpp +++ b/src/game/server/teams.cpp @@ -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; }