From 08ef63a64c33dc7ac30e022d1baa9e25e28a5062 Mon Sep 17 00:00:00 2001 From: trml Date: Thu, 19 Aug 2021 01:11:38 +0200 Subject: [PATCH] Add prediction for switch tiles --- src/game/client/gameclient.cpp | 28 ++++++ src/game/client/gameclient.h | 2 + .../client/prediction/entities/character.cpp | 90 ++++++++++++++----- 3 files changed, 96 insertions(+), 24 deletions(-) diff --git a/src/game/client/gameclient.cpp b/src/game/client/gameclient.cpp index e2bd3c1d6..dfe2108f1 100644 --- a/src/game/client/gameclient.cpp +++ b/src/game/client/gameclient.cpp @@ -1400,6 +1400,8 @@ void CGameClient::OnNewSnapshot() m_Snap.m_paFlags[Item.m_ID % 2] = (const CNetObj_Flag *)pData; else if(Item.m_Type == NETOBJTYPE_SWITCHSTATE) { + m_Snap.m_HasSwitchState = true; + const CNetObj_SwitchState *pSwitchStateData = (const CNetObj_SwitchState *)pData; CClientData *pClient = &m_aClients[Item.m_ID]; @@ -2198,6 +2200,32 @@ void CGameClient::UpdatePrediction() m_GameWorld.m_WorldConfig.m_InfiniteAmmo = false; m_GameWorld.m_WorldConfig.m_IsSolo = !m_Snap.m_aCharacters[m_Snap.m_LocalClientID].m_HasExtendedData && !m_Tuning[g_Config.m_ClDummy].m_PlayerCollision && !m_Tuning[g_Config.m_ClDummy].m_PlayerHooking; + // update switch state + if(Collision()->m_pSwitchers) + { + const int NumSwitchers = minimum(255, Collision()->m_NumSwitchers); + for(int i = 0; i < MAX_CLIENTS; i++) + { + int Team = m_Teams.Team(i); + if(!m_Snap.m_aCharacters[i].m_Active || !in_range(Team, 0, MAX_CLIENTS - 1)) + continue; + for(int Number = 1; Number <= NumSwitchers; Number++) + { + if(m_Snap.m_HasSwitchState && m_aClients[i].m_SwitchStates[Number]) + { + Collision()->m_pSwitchers[Number].m_Status[Team] = true; + Collision()->m_pSwitchers[Number].m_Type[Team] = TILE_SWITCHOPEN; + } + else + { + Collision()->m_pSwitchers[Number].m_Status[Team] = false; + Collision()->m_pSwitchers[Number].m_Type[Team] = TILE_SWITCHCLOSE; + } + Collision()->m_pSwitchers[Number].m_EndTick[Team] = 0; + } + } + } + // update the tuning/tunezone at the local character position with the latest tunings received before the new snapshot vec2 LocalCharPos = vec2(m_Snap.m_pLocalCharacter->m_X, m_Snap.m_pLocalCharacter->m_Y); m_GameWorld.m_Core.m_Tuning[g_Config.m_ClDummy] = m_Tuning[g_Config.m_ClDummy]; diff --git a/src/game/client/gameclient.h b/src/game/client/gameclient.h index 6bae70082..0cb29f7e3 100644 --- a/src/game/client/gameclient.h +++ b/src/game/client/gameclient.h @@ -311,6 +311,8 @@ public: vec2 m_Position; }; + bool m_HasSwitchState; + CCharacterInfo m_aCharacters[MAX_CLIENTS]; }; diff --git a/src/game/client/prediction/entities/character.cpp b/src/game/client/prediction/entities/character.cpp index 5e340a9c1..86bcd39a6 100644 --- a/src/game/client/prediction/entities/character.cpp +++ b/src/game/client/prediction/entities/character.cpp @@ -674,7 +674,9 @@ void CCharacter::HandleSkippableTiles(int Index) bool CCharacter::IsSwitchActiveCb(int Number, void *pUser) { - return false; //switch state is not implemented in prediction yet + CCharacter *pThis = (CCharacter *)pUser; + CCollision *pCollision = pThis->Collision(); + return pCollision->m_pSwitchers && pThis->Team() != TEAM_SUPER && pCollision->m_pSwitchers[Number].m_Status[pThis->Team()]; } void CCharacter::HandleTiles(int Index) @@ -701,6 +703,69 @@ void CCharacter::HandleTiles(int Index) return; } + // handle switch tiles + if(Collision()->IsSwitch(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER) + { + if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) + Freeze(Collision()->GetSwitchDelay(MapIndex)); + } + else if(Collision()->IsSwitch(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER) + { + if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) + m_DeepFreeze = true; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER) + { + if(Collision()->GetSwitchNumber(MapIndex) == 0 || Collision()->m_pSwitchers[Collision()->GetSwitchNumber(MapIndex)].m_Status[Team()]) + m_DeepFreeze = false; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_HAMMER && Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER) + { + m_Hit &= ~DISABLE_HIT_HAMMER; + m_Core.m_NoHammerHit = false; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_HAMMER) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_HAMMER) + { + m_Hit |= DISABLE_HIT_HAMMER; + m_Core.m_NoHammerHit = true; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_SHOTGUN && Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN) + { + m_Hit &= ~DISABLE_HIT_SHOTGUN; + m_Core.m_NoShotgunHit = false; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_SHOTGUN) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_SHOTGUN) + { + m_Hit |= DISABLE_HIT_SHOTGUN; + m_Core.m_NoShotgunHit = true; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_GRENADE && Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE) + { + m_Hit &= ~DISABLE_HIT_GRENADE; + m_Core.m_NoGrenadeHit = false; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_GRENADE) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_GRENADE) + { + m_Hit |= DISABLE_HIT_GRENADE; + m_Core.m_NoGrenadeHit = true; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_ENABLE && m_Hit & DISABLE_HIT_LASER && Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER) + { + m_Hit &= ~DISABLE_HIT_LASER; + m_Core.m_NoLaserHit = false; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_HIT_DISABLE && !(m_Hit & DISABLE_HIT_LASER) && Collision()->GetSwitchDelay(MapIndex) == WEAPON_LASER) + { + m_Hit |= DISABLE_HIT_LASER; + m_Core.m_NoLaserHit = true; + } + else if(Collision()->IsSwitch(MapIndex) == TILE_JUMP) + { + int newJumps = Collision()->GetSwitchDelay(MapIndex); + if(newJumps != m_Core.m_Jumps) + m_Core.m_Jumps = newJumps; + } + // freeze if(((m_TileIndex == TILE_FREEZE) || (m_TileFIndex == TILE_FREEZE)) && !m_Super && !m_DeepFreeze) { @@ -809,29 +874,6 @@ void CCharacter::HandleTiles(int Index) { m_LastRefillJumps = false; } - - // handle switch tiles - if(Collision()->IsSwitch(MapIndex) == TILE_FREEZE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) == 0) - { - Freeze(Collision()->GetSwitchDelay(MapIndex)); - } - else if(Collision()->IsSwitch(MapIndex) == TILE_DFREEZE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) == 0) - { - m_DeepFreeze = true; - } - else if(Collision()->IsSwitch(MapIndex) == TILE_DUNFREEZE && Team() != TEAM_SUPER && Collision()->GetSwitchNumber(MapIndex) == 0) - { - m_DeepFreeze = false; - } - else if(Collision()->IsSwitch(MapIndex) == TILE_JUMP) - { - int newJumps = Collision()->GetSwitchDelay(MapIndex); - - if(newJumps != m_Core.m_Jumps) - { - m_Core.m_Jumps = newJumps; - } - } } void CCharacter::HandleTuneLayer()