From afb1d5e20158de57e7e6fcb49be5204b02a8fe12 Mon Sep 17 00:00:00 2001 From: BeaR Date: Sun, 4 Sep 2011 11:13:30 +0200 Subject: Swap and Shuffle Teams --- src/game/server/gamecontext.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/game/server/gamecontext.h') diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 6288850d..b899f2d8 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -54,6 +54,8 @@ class CGameContext : public IGameServer static void ConSay(IConsole::IResult *pResult, void *pUserData); static void ConSetTeam(IConsole::IResult *pResult, void *pUserData); static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData); + static void ConSwapTeams(IConsole::IResult *pResult, void *pUserData); + static void ConShuffleTeams(IConsole::IResult *pResult, void *pUserData); static void ConAddVote(IConsole::IResult *pResult, void *pUserData); static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData); static void ConForceVote(IConsole::IResult *pResult, void *pUserData); -- cgit 1.4.1 From ccaec795675b92c36da77e8d1e42e176f60b4e21 Mon Sep 17 00:00:00 2001 From: oy Date: Fri, 30 Dec 2011 22:47:26 +0100 Subject: made it possible to automatically swap teams between rounds --- src/game/server/gamecontext.cpp | 38 ++++++++++++++++++++------------------ src/game/server/gamecontext.h | 3 +++ src/game/server/gamecontroller.cpp | 4 ++++ src/game/variables.h | 1 + 4 files changed, 28 insertions(+), 18 deletions(-) (limited to 'src/game/server/gamecontext.h') diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 53b109b8..0cd8e801 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -387,6 +387,22 @@ void CGameContext::SendTuningParams(int ClientID) Server()->SendMsg(&Msg, MSGFLAG_VITAL, ClientID); } +void CGameContext::SwapTeams() +{ + if(!m_pController->IsTeamplay()) + return; + + SendChat(-1, CGameContext::CHAT_ALL, "Teams were swapped"); + + for(int i = 0; i < MAX_CLIENTS; ++i) + { + if(m_apPlayers[i] && m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) + m_apPlayers[i]->SetTeam(m_apPlayers[i]->GetTeam()^1, false); + } + + (void)m_pController->CheckTeamBalance(); +} + void CGameContext::OnTick() { // check tuning @@ -1044,17 +1060,14 @@ void CGameContext::ConSetTeam(IConsole::IResult *pResult, void *pUserData) CGameContext *pSelf = (CGameContext *)pUserData; int ClientID = clamp(pResult->GetInteger(0), 0, (int)MAX_CLIENTS-1); int Team = clamp(pResult->GetInteger(1), -1, 1); - int Delay = 0; - if(pResult->NumArguments() > 2) - Delay = pResult->GetInteger(2); + int Delay = pResult->NumArguments()>2 ? pResult->GetInteger(2) : 0; + if(!pSelf->m_apPlayers[ClientID]) + return; char aBuf[256]; str_format(aBuf, sizeof(aBuf), "moved client %d to team %d", ClientID, Team); pSelf->Console()->Print(IConsole::OUTPUT_LEVEL_STANDARD, "server", aBuf); - if(!pSelf->m_apPlayers[ClientID]) - return; - pSelf->m_apPlayers[ClientID]->m_TeamChangeTick = pSelf->Server()->Tick()+pSelf->Server()->TickSpeed()*Delay*60; pSelf->m_apPlayers[ClientID]->SetTeam(Team); (void)pSelf->m_pController->CheckTeamBalance(); @@ -1079,18 +1092,7 @@ void CGameContext::ConSetTeamAll(IConsole::IResult *pResult, void *pUserData) void CGameContext::ConSwapTeams(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; - if(!pSelf->m_pController->IsTeamplay()) - return; - - pSelf->SendChat(-1, CGameContext::CHAT_ALL, "Teams were swapped"); - - for(int i = 0; i < MAX_CLIENTS; ++i) - { - if(pSelf->m_apPlayers[i] && pSelf->m_apPlayers[i]->GetTeam() != TEAM_SPECTATORS) - pSelf->m_apPlayers[i]->SetTeam(pSelf->m_apPlayers[i]->GetTeam()^1, false); - } - - (void)pSelf->m_pController->CheckTeamBalance(); + pSelf->SwapTeams(); } void CGameContext::ConShuffleTeams(IConsole::IResult *pResult, void *pUserData) diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index b899f2d8..fe07637e 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -143,6 +143,9 @@ public: void CheckPureTuning(); void SendTuningParams(int ClientID); + // + void SwapTeams(); + // engine events virtual void OnInit(); virtual void OnConsoleInit(); diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 3d582991..5eb49c00 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -245,7 +245,11 @@ void IGameController::CycleMap() return; if(m_RoundCount < g_Config.m_SvRoundsPerMap-1) + { + if(g_Config.m_SvRoundSwap) + GameServer()->SwapTeams(); return; + } // handle maprotation const char *pMapRotation = g_Config.m_SvMaprotation; diff --git a/src/game/variables.h b/src/game/variables.h index 3a587ef3..4faa109d 100644 --- a/src/game/variables.h +++ b/src/game/variables.h @@ -60,6 +60,7 @@ MACRO_CONFIG_STR(SvMotd, sv_motd, 900, "", CFGFLAG_SERVER, "Message of the day t MACRO_CONFIG_INT(SvTeamdamage, sv_teamdamage, 0, 0, 1, CFGFLAG_SERVER, "Team damage") MACRO_CONFIG_STR(SvMaprotation, sv_maprotation, 768, "", CFGFLAG_SERVER, "Maps to rotate between") MACRO_CONFIG_INT(SvRoundsPerMap, sv_rounds_per_map, 1, 1, 100, CFGFLAG_SERVER, "Number of rounds on each map before rotating") +MACRO_CONFIG_INT(SvRoundSwap, sv_round_swap, 1, 0, 1, CFGFLAG_SERVER, "Swap teams between rounds") MACRO_CONFIG_INT(SvPowerups, sv_powerups, 1, 0, 1, CFGFLAG_SERVER, "Allow powerups like ninja") MACRO_CONFIG_INT(SvScorelimit, sv_scorelimit, 20, 0, 1000, CFGFLAG_SERVER, "Score limit (0 disables)") MACRO_CONFIG_INT(SvTimelimit, sv_timelimit, 0, 0, 1000, CFGFLAG_SERVER, "Time limit in minutes (0 disables)") -- cgit 1.4.1 From 57a975f38e2021fa5a0c7581249003038690a7a3 Mon Sep 17 00:00:00 2001 From: oy Date: Sun, 8 Jan 2012 13:55:20 +0100 Subject: added a server command to lock teams. Closes #831 --- src/game/server/gamecontext.cpp | 18 ++++++++++++++++++ src/game/server/gamecontext.h | 3 +++ 2 files changed, 21 insertions(+) (limited to 'src/game/server/gamecontext.h') diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index 1f163983..868ac593 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -799,6 +799,13 @@ void CGameContext::OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) if(pPlayer->GetTeam() == pMsg->m_Team || (g_Config.m_SvSpamprotection && pPlayer->m_LastSetTeam && pPlayer->m_LastSetTeam+Server()->TickSpeed()*3 > Server()->Tick())) return; + if(pMsg->m_Team != TEAM_SPECTATORS && m_LockTeams) + { + pPlayer->m_LastSetTeam = Server()->Tick(); + SendBroadcast("Teams are locked", ClientID); + return; + } + if(pPlayer->m_TeamChangeTick > Server()->Tick()) { pPlayer->m_LastSetTeam = Server()->Tick(); @@ -1139,6 +1146,16 @@ void CGameContext::ConShuffleTeams(IConsole::IResult *pResult, void *pUserData) (void)pSelf->m_pController->CheckTeamBalance(); } +void CGameContext::ConLockTeams(IConsole::IResult *pResult, void *pUserData) +{ + CGameContext *pSelf = (CGameContext *)pUserData; + pSelf->m_LockTeams ^= 1; + if(pSelf->m_LockTeams) + pSelf->SendChat(-1, CGameContext::CHAT_ALL, "Teams were locked"); + else + pSelf->SendChat(-1, CGameContext::CHAT_ALL, "Teams were unlocked"); +} + void CGameContext::ConAddVote(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; @@ -1400,6 +1417,7 @@ void CGameContext::OnConsoleInit() Console()->Register("set_team_all", "i", CFGFLAG_SERVER, ConSetTeamAll, this, "Set team of all players to team"); Console()->Register("swap_teams", "", CFGFLAG_SERVER, ConSwapTeams, this, "Swap the current teams"); Console()->Register("shuffle_teams", "", CFGFLAG_SERVER, ConShuffleTeams, this, "Shuffle the current teams"); + Console()->Register("lock_teams", "", CFGFLAG_SERVER, ConLockTeams, this, "Lock/unlock teams"); Console()->Register("add_vote", "sr", CFGFLAG_SERVER, ConAddVote, this, "Add a voting option"); Console()->Register("remove_vote", "s", CFGFLAG_SERVER, ConRemoveVote, this, "remove a voting option"); diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index fe07637e..559d1c0d 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -56,6 +56,7 @@ class CGameContext : public IGameServer static void ConSetTeamAll(IConsole::IResult *pResult, void *pUserData); static void ConSwapTeams(IConsole::IResult *pResult, void *pUserData); static void ConShuffleTeams(IConsole::IResult *pResult, void *pUserData); + static void ConLockTeams(IConsole::IResult *pResult, void *pUserData); static void ConAddVote(IConsole::IResult *pResult, void *pUserData); static void ConRemoveVote(IConsole::IResult *pResult, void *pUserData); static void ConForceVote(IConsole::IResult *pResult, void *pUserData); @@ -87,6 +88,8 @@ public: // helper functions class CCharacter *GetPlayerChar(int ClientID); + int m_LockTeams; + // voting void StartVote(const char *pDesc, const char *pCommand, const char *pReason); void EndVote(); -- cgit 1.4.1 From dfe91338f03534a6c8ed596f16742e7a1617d78e Mon Sep 17 00:00:00 2001 From: oy Date: Tue, 10 Jan 2012 00:49:31 +0100 Subject: added pause command. Closes #15 --- src/game/client/components/controls.cpp | 2 +- src/game/client/components/damageind.cpp | 5 ++++ src/game/client/components/items.cpp | 45 ++++++++++++++++---------------- src/game/client/components/maplayers.cpp | 22 +++++++++------- src/game/client/components/particles.cpp | 10 ++++++- src/game/client/components/players.cpp | 31 ++++++++++++++++++---- src/game/server/entities/character.cpp | 14 ++++++++++ src/game/server/entities/character.h | 1 + src/game/server/entities/flag.cpp | 7 +++++ src/game/server/entities/flag.h | 1 + src/game/server/entities/laser.cpp | 5 ++++ src/game/server/entities/laser.h | 1 + src/game/server/entities/pickup.cpp | 6 +++++ src/game/server/entities/pickup.h | 1 + src/game/server/entities/projectile.cpp | 5 ++++ src/game/server/entities/projectile.h | 1 + src/game/server/entity.h | 6 +++++ src/game/server/gamecontext.cpp | 11 ++++++++ src/game/server/gamecontext.h | 1 + src/game/server/gamecontroller.cpp | 6 ++++- src/game/server/gamecontroller.h | 1 + src/game/server/gameworld.cpp | 11 ++++++++ src/game/server/player.cpp | 41 ++++++++++++++++++----------- 23 files changed, 180 insertions(+), 54 deletions(-) (limited to 'src/game/server/gamecontext.h') diff --git a/src/game/client/components/controls.cpp b/src/game/client/components/controls.cpp index dd856413..c0790799 100644 --- a/src/game/client/components/controls.cpp +++ b/src/game/client/components/controls.cpp @@ -199,7 +199,7 @@ int CControls::SnapInput(int *pData) void CControls::OnRender() { // update target pos - if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED || m_pClient->m_Snap.m_SpecInfo.m_Active)) + if(m_pClient->m_Snap.m_pGameInfoObj && !m_pClient->m_Snap.m_SpecInfo.m_Active) m_TargetPos = m_pClient->m_LocalCharacterPos + m_MousePos; else if(m_pClient->m_Snap.m_SpecInfo.m_Active && m_pClient->m_Snap.m_SpecInfo.m_UsePosition) m_TargetPos = m_pClient->m_Snap.m_SpecInfo.m_Position + m_MousePos; diff --git a/src/game/client/components/damageind.cpp b/src/game/client/components/damageind.cpp index e2da21e1..0f521753 100644 --- a/src/game/client/components/damageind.cpp +++ b/src/game/client/components/damageind.cpp @@ -60,6 +60,11 @@ void CDamageInd::OnRender() else m_aItems[i].m_StartTime += (Client()->LocalTime()-s_LastLocalTime)*(1.0f-pInfo->m_Speed); } + else + { + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) + m_aItems[i].m_StartTime += Client()->LocalTime()-s_LastLocalTime; + } float Life = 0.75f - (Client()->LocalTime() - m_aItems[i].m_StartTime); if(Life < 0.0f) diff --git a/src/game/client/components/items.cpp b/src/game/client/components/items.cpp index 9f787a4b..e1032a51 100644 --- a/src/game/client/components/items.cpp +++ b/src/game/client/components/items.cpp @@ -41,7 +41,10 @@ void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID) Speed = m_pClient->m_Tuning.m_GunSpeed; } - float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + static float s_LastGameTickTime = Client()->GameTickTime(); + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + s_LastGameTickTime = Client()->GameTickTime(); + float Ct = (Client()->PrevGameTick()-pCurrent->m_StartTick)/(float)SERVER_TICK_SPEED + s_LastGameTickTime; if(Ct < 0) return; // projectile havn't been shot yet @@ -63,22 +66,23 @@ void CItems::RenderProjectile(const CNetObj_Projectile *pCurrent, int ItemID) if(pCurrent->m_Type == WEAPON_GRENADE) { m_pClient->m_pEffects->SmokeTrail(Pos, Vel*-1); + static float s_Time = 0.0f; + static float s_LastLocalTime = Client()->LocalTime(); if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); - static float Time = 0; - static float LastLocalTime = Client()->LocalTime(); - if(!pInfo->m_Paused) - Time += (Client()->LocalTime()-LastLocalTime)*pInfo->m_Speed; - - Graphics()->QuadsSetRotation(Time*pi*2*2 + ItemID); - - LastLocalTime = Client()->LocalTime(); + s_Time += (Client()->LocalTime()-s_LastLocalTime)*pInfo->m_Speed; } else - Graphics()->QuadsSetRotation(Client()->LocalTime()*pi*2*2 + ItemID); + { + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + s_Time += Client()->LocalTime()-s_LastLocalTime; + } + + Graphics()->QuadsSetRotation(s_Time*pi*2*2 + ItemID); + s_LastLocalTime = Client()->LocalTime(); } else { @@ -130,26 +134,23 @@ void CItems::RenderPickup(const CNetObj_Pickup *pPrev, const CNetObj_Pickup *pCu Graphics()->QuadsSetRotation(Angle); + static float s_Time = 0.0f; + static float s_LastLocalTime = Client()->LocalTime(); float Offset = Pos.y/32.0f + Pos.x/32.0f; if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); - static float Time = 0; - static float LastLocalTime = Client()->LocalTime(); - if(!pInfo->m_Paused) - Time += (Client()->LocalTime()-LastLocalTime)*pInfo->m_Speed; - - Pos.x += cosf(Time*2.0f+Offset)*2.5f; - Pos.y += sinf(Time*2.0f+Offset)*2.5f; - - LastLocalTime = Client()->LocalTime(); + s_Time += (Client()->LocalTime()-s_LastLocalTime)*pInfo->m_Speed; } else { - Pos.x += cosf(Client()->LocalTime()*2.0f+Offset)*2.5f; - Pos.y += sinf(Client()->LocalTime()*2.0f+Offset)*2.5f; - } + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + s_Time += Client()->LocalTime()-s_LastLocalTime; + } + Pos.x += cosf(s_Time*2.0f+Offset)*2.5f; + Pos.y += sinf(s_Time*2.0f+Offset)*2.5f; + s_LastLocalTime = Client()->LocalTime(); RenderTools()->DrawSprite(Pos.x, Pos.y, Size); Graphics()->QuadsEnd(); } diff --git a/src/game/client/components/maplayers.cpp b/src/game/client/components/maplayers.cpp index f0460d26..db74b165 100644 --- a/src/game/client/components/maplayers.cpp +++ b/src/game/client/components/maplayers.cpp @@ -77,7 +77,8 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void CMapItemEnvelope *pItem = (CMapItemEnvelope *)pThis->m_pLayers->Map()->GetItem(Start+Env, 0, 0); - static float Time = 0; + static float s_Time = 0.0f; + static float s_LastLocalTime = pThis->Client()->LocalTime(); if(pThis->Client()->State() == IClient::STATE_DEMOPLAYBACK) { const IDemoPlayer::CInfo *pInfo = pThis->DemoPlayer()->BaseInfo(); @@ -90,25 +91,28 @@ void CMapLayers::EnvelopeEval(float TimeOffset, int Env, float *pChannels, void pThis->m_CurrentLocalTick = pInfo->m_CurrentTick; } - Time = mix(pThis->m_LastLocalTick / (float)pThis->Client()->GameTickSpeed(), + s_Time = mix(pThis->m_LastLocalTick / (float)pThis->Client()->GameTickSpeed(), pThis->m_CurrentLocalTick / (float)pThis->Client()->GameTickSpeed(), pThis->Client()->IntraGameTick()); } - pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, Time+TimeOffset, pChannels); + pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time+TimeOffset, pChannels); } else { - if(pItem->m_Version < 2 || pItem->m_Synchronized) + if(pThis->m_pClient->m_Snap.m_pGameInfoObj && !(pThis->m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) { - if(pThis->m_pClient->m_Snap.m_pGameInfoObj) - Time = mix((pThis->Client()->PrevGameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), + if(pItem->m_Version < 2 || pItem->m_Synchronized) + { + s_Time = mix((pThis->Client()->PrevGameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), (pThis->Client()->GameTick()-pThis->m_pClient->m_Snap.m_pGameInfoObj->m_RoundStartTick) / (float)pThis->Client()->GameTickSpeed(), pThis->Client()->IntraGameTick()); + } + else + s_Time += pThis->Client()->LocalTime()-s_LastLocalTime; } - else - Time = pThis->Client()->LocalTime(); - pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, Time+TimeOffset, pChannels); + pThis->RenderTools()->RenderEvalEnvelope(pPoints+pItem->m_StartPoint, pItem->m_NumPoints, 4, s_Time+TimeOffset, pChannels); + s_LastLocalTime = pThis->Client()->LocalTime(); } } diff --git a/src/game/client/components/particles.cpp b/src/game/client/components/particles.cpp index c4583cb1..66a62f1c 100644 --- a/src/game/client/components/particles.cpp +++ b/src/game/client/components/particles.cpp @@ -43,6 +43,11 @@ void CParticles::Add(int Group, CParticle *pPart) if(pInfo->m_Paused) return; } + else + { + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) + return; + } if (m_FirstFree == -1) return; @@ -142,7 +147,10 @@ void CParticles::OnRender() Update((float)((t-LastTime)/(double)time_freq())*pInfo->m_Speed); } else - Update((float)((t-LastTime)/(double)time_freq())); + { + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + Update((float)((t-LastTime)/(double)time_freq())); + } LastTime = t; } diff --git a/src/game/client/components/players.cpp b/src/game/client/components/players.cpp index c53a1977..2eddd8a9 100644 --- a/src/game/client/components/players.cpp +++ b/src/game/client/components/players.cpp @@ -285,14 +285,17 @@ void CPlayers::RenderPlayer( else if(!WantOtherDir) State.Add(&g_pData->m_aAnimations[ANIM_WALK], WalkTime, 1.0f); + static float s_LastGameTickTime = Client()->GameTickTime(); + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + s_LastGameTickTime = Client()->GameTickTime(); if (Player.m_Weapon == WEAPON_HAMMER) { - float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + s_LastGameTickTime; State.Add(&g_pData->m_aAnimations[ANIM_HAMMER_SWING], clamp(ct*5.0f,0.0f,1.0f), 1.0f); } if (Player.m_Weapon == WEAPON_NINJA) { - float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + Client()->GameTickTime(); + float ct = (Client()->PrevGameTick()-Player.m_AttackTick)/(float)SERVER_TICK_SPEED + s_LastGameTickTime; State.Add(&g_pData->m_aAnimations[ANIM_NINJA_SWING], clamp(ct*2.0f,0.0f,1.0f), 1.0f); } @@ -364,15 +367,22 @@ void CPlayers::RenderPlayer( if ((Client()->GameTick()-Player.m_AttackTick) <= (SERVER_TICK_SPEED / 6) && g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles) { int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + static int s_LastIteX = IteX; if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { - static int s_LastIteX = IteX; const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); if(pInfo->m_Paused) IteX = s_LastIteX; else s_LastIteX = IteX; } + else + { + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) + IteX = s_LastIteX; + else + s_LastIteX = IteX; + } if(g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { vec2 Dir = vec2(pPlayerChar->m_X,pPlayerChar->m_Y) - vec2(pPrevChar->m_X, pPrevChar->m_Y); @@ -393,7 +403,11 @@ void CPlayers::RenderPlayer( { // TODO: should be an animation Recoil = 0; - float a = (Client()->GameTick()-Player.m_AttackTick+IntraTick)/5.0f; + static float s_LastIntraTick = IntraTick; + if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED)) + s_LastIntraTick = IntraTick; + + float a = (Client()->GameTick()-Player.m_AttackTick+s_LastIntraTick)/5.0f; if(a < 1) Recoil = sinf(a*pi); p = Position + Dir * g_pData->m_Weapons.m_aId[iw].m_Offsetx - Dir*Recoil*10.0f; @@ -415,15 +429,22 @@ void CPlayers::RenderPlayer( } int IteX = rand() % g_pData->m_Weapons.m_aId[iw].m_NumSpriteMuzzles; + static int s_LastIteX = IteX; if(Client()->State() == IClient::STATE_DEMOPLAYBACK) { - static int s_LastIteX = IteX; const IDemoPlayer::CInfo *pInfo = DemoPlayer()->BaseInfo(); if(pInfo->m_Paused) IteX = s_LastIteX; else s_LastIteX = IteX; } + else + { + if(m_pClient->m_Snap.m_pGameInfoObj && m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags&GAMESTATEFLAG_PAUSED) + IteX = s_LastIteX; + else + s_LastIteX = IteX; + } if (Alpha > 0.0f && g_pData->m_Weapons.m_aId[iw].m_aSpriteMuzzles[IteX]) { float OffsetY = -g_pData->m_Weapons.m_aId[iw].m_Muzzleoffsety; diff --git a/src/game/server/entities/character.cpp b/src/game/server/entities/character.cpp index 5e8c29b6..1c76f655 100644 --- a/src/game/server/entities/character.cpp +++ b/src/game/server/entities/character.cpp @@ -657,6 +657,20 @@ void CCharacter::TickDefered() } } +void CCharacter::TickPaused() +{ + ++m_AttackTick; + ++m_DamageTakenTick; + ++m_Ninja.m_ActivationTick; + ++m_ReckoningTick; + if(m_LastAction != -1) + ++m_LastAction; + if(m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart > -1) + ++m_aWeapons[m_ActiveWeapon].m_AmmoRegenStart; + if(m_EmoteStop > -1) + ++m_EmoteStop; +} + bool CCharacter::IncreaseHealth(int Amount) { if(m_Health >= 10) diff --git a/src/game/server/entities/character.h b/src/game/server/entities/character.h index 02a779bb..aa127979 100644 --- a/src/game/server/entities/character.h +++ b/src/game/server/entities/character.h @@ -30,6 +30,7 @@ public: virtual void Destroy(); virtual void Tick(); virtual void TickDefered(); + virtual void TickPaused(); virtual void Snap(int SnappingClient); bool IsGrounded(); diff --git a/src/game/server/entities/flag.cpp b/src/game/server/entities/flag.cpp index d279e4df..558ee154 100644 --- a/src/game/server/entities/flag.cpp +++ b/src/game/server/entities/flag.cpp @@ -23,6 +23,13 @@ void CFlag::Reset() m_GrabTick = 0; } +void CFlag::TickPaused() +{ + ++m_DropTick; + if(m_GrabTick) + ++m_GrabTick; +} + void CFlag::Snap(int SnappingClient) { if(NetworkClipped(SnappingClient)) diff --git a/src/game/server/entities/flag.h b/src/game/server/entities/flag.h index 2f91bc02..be22d32b 100644 --- a/src/game/server/entities/flag.h +++ b/src/game/server/entities/flag.h @@ -21,6 +21,7 @@ public: CFlag(CGameWorld *pGameWorld, int Team); virtual void Reset(); + virtual void TickPaused(); virtual void Snap(int SnappingClient); }; diff --git a/src/game/server/entities/laser.cpp b/src/game/server/entities/laser.cpp index 7278995f..eb40c4e1 100644 --- a/src/game/server/entities/laser.cpp +++ b/src/game/server/entities/laser.cpp @@ -91,6 +91,11 @@ void CLaser::Tick() DoBounce(); } +void CLaser::TickPaused() +{ + ++m_EvalTick; +} + void CLaser::Snap(int SnappingClient) { if(NetworkClipped(SnappingClient)) diff --git a/src/game/server/entities/laser.h b/src/game/server/entities/laser.h index 1d7fa227..8ae6f792 100644 --- a/src/game/server/entities/laser.h +++ b/src/game/server/entities/laser.h @@ -12,6 +12,7 @@ public: virtual void Reset(); virtual void Tick(); + virtual void TickPaused(); virtual void Snap(int SnappingClient); protected: diff --git a/src/game/server/entities/pickup.cpp b/src/game/server/entities/pickup.cpp index ba26d85b..1aff5750 100644 --- a/src/game/server/entities/pickup.cpp +++ b/src/game/server/entities/pickup.cpp @@ -117,6 +117,12 @@ void CPickup::Tick() } } +void CPickup::TickPaused() +{ + if(m_SpawnTick != -1) + ++m_SpawnTick; +} + void CPickup::Snap(int SnappingClient) { if(m_SpawnTick != -1 || NetworkClipped(SnappingClient)) diff --git a/src/game/server/entities/pickup.h b/src/game/server/entities/pickup.h index 77347de2..fe45b5ae 100644 --- a/src/game/server/entities/pickup.h +++ b/src/game/server/entities/pickup.h @@ -14,6 +14,7 @@ public: virtual void Reset(); virtual void Tick(); + virtual void TickPaused(); virtual void Snap(int SnappingClient); private: diff --git a/src/game/server/entities/projectile.cpp b/src/game/server/entities/projectile.cpp index 2baa24b1..e89e0e6f 100644 --- a/src/game/server/entities/projectile.cpp +++ b/src/game/server/entities/projectile.cpp @@ -82,6 +82,11 @@ void CProjectile::Tick() } } +void CProjectile::TickPaused() +{ + ++m_StartTick; +} + void CProjectile::FillInfo(CNetObj_Projectile *pProj) { pProj->m_X = (int)m_Pos.x; diff --git a/src/game/server/entities/projectile.h b/src/game/server/entities/projectile.h index 5df04bcd..7b5c5e0e 100644 --- a/src/game/server/entities/projectile.h +++ b/src/game/server/entities/projectile.h @@ -14,6 +14,7 @@ public: virtual void Reset(); virtual void Tick(); + virtual void TickPaused(); virtual void Snap(int SnappingClient); private: diff --git a/src/game/server/entity.h b/src/game/server/entity.h index b9b33eb7..0f838730 100644 --- a/src/game/server/entity.h +++ b/src/game/server/entity.h @@ -105,6 +105,12 @@ public: */ virtual void TickDefered() {} + /* + Function: TickPaused + Called when the game is paused, to freeze the state and position of the entity. + */ + virtual void TickPaused() {} + /* Function: snap Called when a new snapshot is being generated for a specific diff --git a/src/game/server/gamecontext.cpp b/src/game/server/gamecontext.cpp index fdd78f60..87b9b3b7 100644 --- a/src/game/server/gamecontext.cpp +++ b/src/game/server/gamecontext.cpp @@ -1036,6 +1036,16 @@ void CGameContext::ConTuneDump(IConsole::IResult *pResult, void *pUserData) } } +void CGameContext::ConPause(IConsole::IResult *pResult, void *pUserData) +{ + CGameContext *pSelf = (CGameContext *)pUserData; + + if(pSelf->m_pController->IsGameOver()) + return; + + pSelf->m_World.m_Paused ^= 1; +} + void CGameContext::ConChangeMap(IConsole::IResult *pResult, void *pUserData) { CGameContext *pSelf = (CGameContext *)pUserData; @@ -1409,6 +1419,7 @@ void CGameContext::OnConsoleInit() Console()->Register("tune_reset", "", CFGFLAG_SERVER, ConTuneReset, this, "Reset tuning"); Console()->Register("tune_dump", "", CFGFLAG_SERVER, ConTuneDump, this, "Dump tuning"); + Console()->Register("pause", "", CFGFLAG_SERVER, ConPause, this, "Pause/unpause game"); Console()->Register("change_map", "?r", CFGFLAG_SERVER|CFGFLAG_STORE, ConChangeMap, this, "Change map"); Console()->Register("restart", "?i", CFGFLAG_SERVER|CFGFLAG_STORE, ConRestart, this, "Restart in x seconds (0 = abort)"); Console()->Register("broadcast", "r", CFGFLAG_SERVER, ConBroadcast, this, "Broadcast message"); diff --git a/src/game/server/gamecontext.h b/src/game/server/gamecontext.h index 559d1c0d..2ffb0ab4 100644 --- a/src/game/server/gamecontext.h +++ b/src/game/server/gamecontext.h @@ -48,6 +48,7 @@ class CGameContext : public IGameServer static void ConTuneParam(IConsole::IResult *pResult, void *pUserData); static void ConTuneReset(IConsole::IResult *pResult, void *pUserData); static void ConTuneDump(IConsole::IResult *pResult, void *pUserData); + static void ConPause(IConsole::IResult *pResult, void *pUserData); static void ConChangeMap(IConsole::IResult *pResult, void *pUserData); static void ConRestart(IConsole::IResult *pResult, void *pUserData); static void ConBroadcast(IConsole::IResult *pResult, void *pUserData); diff --git a/src/game/server/gamecontroller.cpp b/src/game/server/gamecontroller.cpp index 181e5052..7001ca32 100644 --- a/src/game/server/gamecontroller.cpp +++ b/src/game/server/gamecontroller.cpp @@ -430,8 +430,12 @@ void IGameController::Tick() } } + // game is Paused + if(GameServer()->m_World.m_Paused) + ++m_RoundStartTick; + // do team-balancing - if (IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60) + if(IsTeamplay() && m_UnbalancedTick != -1 && Server()->Tick() > m_UnbalancedTick+g_Config.m_SvTeambalanceTime*Server()->TickSpeed()*60) { GameServer()->Console()->Print(IConsole::OUTPUT_LEVEL_DEBUG, "game", "Balancing teams"); diff --git a/src/game/server/gamecontroller.h b/src/game/server/gamecontroller.h index 4706df48..1675fe35 100644 --- a/src/game/server/gamecontroller.h +++ b/src/game/server/gamecontroller.h @@ -64,6 +64,7 @@ public: const char *m_pGameType; bool IsTeamplay() const; + bool IsGameOver() const { return m_GameOverTick != -1; } IGameController(class CGameContext *pGameServer); virtual ~IGameController(); diff --git a/src/game/server/gameworld.cpp b/src/game/server/gameworld.cpp index 89f4808d..d803ae67 100644 --- a/src/game/server/gameworld.cpp +++ b/src/game/server/gameworld.cpp @@ -173,6 +173,17 @@ void CGameWorld::Tick() pEnt = m_pNextTraverseEntity; } } + else + { + // update all objects + for(int i = 0; i < NUM_ENTTYPES; i++) + for(CEntity *pEnt = m_apFirstEntityTypes[i]; pEnt; ) + { + m_pNextTraverseEntity = pEnt->m_pNextTypeEntity; + pEnt->TickPaused(); + pEnt = m_pNextTraverseEntity; + } + } RemoveEntities(); } diff --git a/src/game/server/player.cpp b/src/game/server/player.cpp index df9727a9..75c2c1c6 100644 --- a/src/game/server/player.cpp +++ b/src/game/server/player.cpp @@ -60,26 +60,37 @@ 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(!GameServer()->m_World.m_Paused) + { + 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; + if(!m_pCharacter && m_DieTick+Server()->TickSpeed()*3 <= Server()->Tick()) + m_Spawning = true; - if(m_pCharacter) - { - if(m_pCharacter->IsAlive()) - { - m_ViewPos = m_pCharacter->m_Pos; - } - else + if(m_pCharacter) { - delete m_pCharacter; - m_pCharacter = 0; + if(m_pCharacter->IsAlive()) + { + m_ViewPos = m_pCharacter->m_Pos; + } + else + { + delete m_pCharacter; + m_pCharacter = 0; + } } + else if(m_Spawning && m_RespawnTick <= Server()->Tick()) + TryRespawn(); } - else if(m_Spawning && m_RespawnTick <= Server()->Tick()) - TryRespawn(); + else + { + ++m_RespawnTick; + ++m_DieTick; + ++m_ScoreStartTick; + ++m_LastActionTick; + ++m_TeamChangeTick; + } } void CPlayer::PostTick() -- cgit 1.4.1