3604: Don't predict other teams r=def- a=trml

This also skips the actual physics prediction for the other teams (which could potentially reduce the cpu load very slightly on solo/dummy servers).

## Checklist

- [x] Tested the change ingame
- [ ] Provided screenshots if it is a visual change
- [ ] Tested in combination with possibly related configuration options
- [ ] Written a unit test if it works standalone, system.c especially
- [ ] Considered possible null pointers and out of bounds array indexing
- [ ] Changed no physics that affect existing maps
- [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional)


Co-authored-by: trml <trml@users.noreply.github.com>
This commit is contained in:
bors[bot] 2021-02-07 22:32:35 +00:00 committed by GitHub
commit bc4e9511ba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 20 additions and 7 deletions

View file

@ -54,8 +54,10 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemID)
if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED)) if(m_pClient->m_Snap.m_pGameInfoObj && !(m_pClient->m_Snap.m_pGameInfoObj->m_GameStateFlags & GAMESTATEFLAG_PAUSED))
s_LastGameTickTime = Client()->GameTickTime(g_Config.m_ClDummy); s_LastGameTickTime = Client()->GameTickTime(g_Config.m_ClDummy);
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
float Ct; float Ct;
if(m_pClient->Predict() && m_pClient->AntiPingGrenade() && LocalPlayerInGame && !(Client()->State() == IClient::STATE_DEMOPLAYBACK)) if(m_pClient->Predict() && m_pClient->AntiPingGrenade() && LocalPlayerInGame && !IsOtherTeam)
Ct = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)SERVER_TICK_SPEED; Ct = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)SERVER_TICK_SPEED;
else else
Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)SERVER_TICK_SPEED + s_LastGameTickTime; Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)SERVER_TICK_SPEED + s_LastGameTickTime;
@ -66,7 +68,7 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemID)
vec2 PrevPos = CalcPos(pCurrent->m_StartPos, pCurrent->m_StartVel, Curvature, Speed, Ct - 0.001f); vec2 PrevPos = CalcPos(pCurrent->m_StartPos, pCurrent->m_StartVel, Curvature, Speed, Ct - 0.001f);
float Alpha = 1.f; float Alpha = 1.f;
if(pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner)) if(IsOtherTeam)
{ {
Alpha = g_Config.m_ClShowOthersAlpha / 100.0f; Alpha = g_Config.m_ClShowOthersAlpha / 100.0f;
} }
@ -346,15 +348,17 @@ void CItems::OnRender()
{ {
if(auto *pProj = (CProjectile *)GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData)) if(auto *pProj = (CProjectile *)GameClient()->m_GameWorld.FindMatch(Item.m_ID, Item.m_Type, pData))
{ {
bool IsOtherTeam = m_pClient->IsOtherTeam(pProj->GetOwner());
if(pProj->m_LastRenderTick <= 0 && (pProj->m_Type != WEAPON_SHOTGUN || (!pProj->m_Freeze && !pProj->m_Explosive)) // skip ddrace shotgun bullets if(pProj->m_LastRenderTick <= 0 && (pProj->m_Type != WEAPON_SHOTGUN || (!pProj->m_Freeze && !pProj->m_Explosive)) // skip ddrace shotgun bullets
&& (pProj->m_Type == WEAPON_SHOTGUN || fabs(length(pProj->m_Direction) - 1.f) < 0.02) // workaround to skip grenades on ball mod && (pProj->m_Type == WEAPON_SHOTGUN || fabs(length(pProj->m_Direction) - 1.f) < 0.02) // workaround to skip grenades on ball mod
&& (pProj->GetOwner() < 0 || !GameClient()->m_aClients[pProj->GetOwner()].m_IsPredictedLocal) // skip locally predicted projectiles && (pProj->GetOwner() < 0 || !GameClient()->m_aClients[pProj->GetOwner()].m_IsPredictedLocal || IsOtherTeam) // skip locally predicted projectiles
&& !Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID)) && !Client()->SnapFindItem(IClient::SNAP_PREV, Item.m_Type, Item.m_ID))
{ {
ReconstructSmokeTrail(&Data, pProj->m_DestroyTick); ReconstructSmokeTrail(&Data, pProj->m_DestroyTick);
} }
pProj->m_LastRenderTick = Client()->GameTick(g_Config.m_ClDummy); pProj->m_LastRenderTick = Client()->GameTick(g_Config.m_ClDummy);
continue; if(!IsOtherTeam)
continue;
} }
} }
RenderProjectile(&Data, Item.m_ID); RenderProjectile(&Data, Item.m_ID);

View file

@ -1728,12 +1728,20 @@ void CGameClient::OnPredict()
bool Dummy = g_Config.m_ClDummy ^ m_IsDummySwapping; bool Dummy = g_Config.m_ClDummy ^ m_IsDummySwapping;
m_PredictedWorld.CopyWorld(&m_GameWorld); m_PredictedWorld.CopyWorld(&m_GameWorld);
// don't predict inactive players // don't predict inactive players, or entities from other teams
for(int i = 0; i < MAX_CLIENTS; i++) for(int i = 0; i < MAX_CLIENTS; i++)
if(CCharacter *pChar = m_PredictedWorld.GetCharacterByID(i)) if(CCharacter *pChar = m_PredictedWorld.GetCharacterByID(i))
if(!m_Snap.m_aCharacters[i].m_Active && pChar->m_SnapTicks > 10) if((!m_Snap.m_aCharacters[i].m_Active && pChar->m_SnapTicks > 10) || IsOtherTeam(i))
pChar->Destroy(); pChar->Destroy();
CProjectile *pProjNext = 0;
for(CProjectile *pProj = (CProjectile *)m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = pProjNext)
{
pProjNext = (CProjectile *)pProj->TypeNext();
if(IsOtherTeam(pProj->GetOwner()))
m_PredictedWorld.RemoveEntity(pProj);
}
CCharacter *pLocalChar = m_PredictedWorld.GetCharacterByID(m_Snap.m_LocalClientID); CCharacter *pLocalChar = m_PredictedWorld.GetCharacterByID(m_Snap.m_LocalClientID);
if(!pLocalChar) if(!pLocalChar)
return; return;
@ -2349,6 +2357,7 @@ void CGameClient::UpdatePrediction()
m_Snap.m_aCharacters[i].m_HasExtendedData ? &m_Snap.m_aCharacters[i].m_ExtendedData : 0, m_Snap.m_aCharacters[i].m_HasExtendedData ? &m_Snap.m_aCharacters[i].m_ExtendedData : 0,
GameTeam, IsLocal); GameTeam, IsLocal);
} }
for(int Index = 0; Index < Num; Index++) for(int Index = 0; Index < Num; Index++)
{ {
IClient::CSnapItem Item; IClient::CSnapItem Item;
@ -2382,7 +2391,7 @@ void CGameClient::UpdateRenderedCharacters()
Client()->IntraGameTick(g_Config.m_ClDummy)); Client()->IntraGameTick(g_Config.m_ClDummy));
vec2 Pos = UnpredPos; vec2 Pos = UnpredPos;
if(Predict() && (i == m_Snap.m_LocalClientID || AntiPingPlayers())) if(Predict() && (i == m_Snap.m_LocalClientID || (AntiPingPlayers() && !IsOtherTeam(i))))
{ {
m_aClients[i].m_Predicted.Write(&m_aClients[i].m_RenderCur); m_aClients[i].m_Predicted.Write(&m_aClients[i].m_RenderCur);
m_aClients[i].m_PrevPredicted.Write(&m_aClients[i].m_RenderPrev); m_aClients[i].m_PrevPredicted.Write(&m_aClients[i].m_RenderPrev);