Add prediction for switch tiles

This commit is contained in:
trml 2021-08-19 01:11:38 +02:00
parent 551369cda1
commit 08ef63a64c
3 changed files with 96 additions and 24 deletions

View file

@ -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];

View file

@ -311,6 +311,8 @@ public:
vec2 m_Position;
};
bool m_HasSwitchState;
CCharacterInfo m_aCharacters[MAX_CLIENTS];
};

View file

@ -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()