Don't predict other players in solo

This commit is contained in:
trml 2023-05-29 13:35:39 +02:00
parent 57f1b1a8c6
commit a090ba8cb3
3 changed files with 41 additions and 23 deletions

View file

@ -1381,6 +1381,8 @@ void CGameClient::OnNewSnapshot()
pClient->m_HasTelegunLaser = pCharacterData->m_Flags & CHARACTERFLAG_TELEGUN_LASER; pClient->m_HasTelegunLaser = pCharacterData->m_Flags & CHARACTERFLAG_TELEGUN_LASER;
pClient->m_Predicted.ReadDDNet(pCharacterData); pClient->m_Predicted.ReadDDNet(pCharacterData);
m_Teams.SetSolo(Item.m_ID, pClient->m_Solo);
} }
} }
else if(Item.m_Type == NETOBJTYPE_SPECCHAR) else if(Item.m_Type == NETOBJTYPE_SPECCHAR)
@ -2441,9 +2443,8 @@ void CGameClient::UpdatePrediction()
} }
// update the local gameworld with the new snapshot // update the local gameworld with the new snapshot
m_GameWorld.m_Teams = m_Teams; m_GameWorld.NetObjBegin(m_Teams, m_Snap.m_LocalClientID);
m_GameWorld.NetObjBegin();
for(int i = 0; i < MAX_CLIENTS; i++) for(int i = 0; i < MAX_CLIENTS; i++)
if(m_Snap.m_aCharacters[i].m_Active) if(m_Snap.m_aCharacters[i].m_Active)
{ {
@ -2457,7 +2458,7 @@ void CGameClient::UpdatePrediction()
for(const CSnapEntities &EntData : SnapEntities()) for(const CSnapEntities &EntData : SnapEntities())
m_GameWorld.NetObjAdd(EntData.m_Item.m_ID, EntData.m_Item.m_Type, EntData.m_pData, EntData.m_pDataEx); m_GameWorld.NetObjAdd(EntData.m_Item.m_ID, EntData.m_Item.m_Type, EntData.m_pData, EntData.m_pDataEx);
m_GameWorld.NetObjEnd(m_Snap.m_LocalClientID); m_GameWorld.NetObjEnd();
} }
void CGameClient::UpdateRenderedCharacters() void CGameClient::UpdateRenderedCharacters()
@ -2476,7 +2477,8 @@ 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() && !IsOtherTeam(i)))) CCharacter *pChar = m_PredictedWorld.GetCharacterByID(i);
if(Predict() && (i == m_Snap.m_LocalClientID || (AntiPingPlayers() && !IsOtherTeam(i))) && pChar)
{ {
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);
@ -2491,8 +2493,7 @@ void CGameClient::UpdateRenderedCharacters()
if(i == m_Snap.m_LocalClientID) if(i == m_Snap.m_LocalClientID)
{ {
m_aClients[i].m_IsPredictedLocal = true; m_aClients[i].m_IsPredictedLocal = true;
CCharacter *pChar = m_PredictedWorld.GetCharacterByID(i); if(AntiPingGunfire() && ((pChar->m_NinjaJetpack && pChar->m_FreezeTime == 0) || m_Snap.m_aCharacters[i].m_Cur.m_Weapon != WEAPON_NINJA || m_Snap.m_aCharacters[i].m_Cur.m_Weapon == m_aClients[i].m_Predicted.m_ActiveWeapon))
if(pChar && AntiPingGunfire() && ((pChar->m_NinjaJetpack && pChar->m_FreezeTime == 0) || m_Snap.m_aCharacters[i].m_Cur.m_Weapon != WEAPON_NINJA || m_Snap.m_aCharacters[i].m_Cur.m_Weapon == m_aClients[i].m_Predicted.m_ActiveWeapon))
{ {
m_aClients[i].m_RenderCur.m_AttackTick = pChar->GetAttackTick(); m_aClients[i].m_RenderCur.m_AttackTick = pChar->GetAttackTick();
if(m_Snap.m_aCharacters[i].m_Cur.m_Weapon != WEAPON_NINJA && !(pChar->m_NinjaJetpack && pChar->Core()->m_ActiveWeapon == WEAPON_GUN)) if(m_Snap.m_aCharacters[i].m_Cur.m_Weapon != WEAPON_NINJA && !(pChar->m_NinjaJetpack && pChar->Core()->m_ActiveWeapon == WEAPON_GUN))

View file

@ -377,8 +377,16 @@ void CGameWorld::CreateExplosion(vec2 Pos, int Owner, int Weapon, bool NoDamage,
} }
} }
void CGameWorld::NetObjBegin() bool CGameWorld::IsLocalTeam(int OwnerID)
{ {
return OwnerID < 0 || m_Teams.CanCollide(m_LocalClientID, OwnerID);
}
void CGameWorld::NetObjBegin(CTeamsCore Teams, int LocalClientID)
{
m_Teams = Teams;
m_LocalClientID = LocalClientID;
for(int i = 0; i < NUM_ENTTYPES; i++) for(int i = 0; i < NUM_ENTTYPES; i++)
for(CEntity *pEnt = FindFirst(i); pEnt; pEnt = pEnt->TypeNext()) for(CEntity *pEnt = FindFirst(i); pEnt; pEnt = pEnt->TypeNext())
{ {
@ -391,20 +399,23 @@ void CGameWorld::NetObjBegin()
void CGameWorld::NetCharAdd(int ObjID, CNetObj_Character *pCharObj, CNetObj_DDNetCharacter *pExtended, int GameTeam, bool IsLocal) void CGameWorld::NetCharAdd(int ObjID, CNetObj_Character *pCharObj, CNetObj_DDNetCharacter *pExtended, int GameTeam, bool IsLocal)
{ {
CCharacter *pChar; if(IsLocalTeam(ObjID))
if((pChar = (CCharacter *)GetEntity(ObjID, ENTTYPE_CHARACTER)))
{ {
pChar->Read(pCharObj, pExtended, IsLocal); CCharacter *pChar;
pChar->Keep(); if((pChar = (CCharacter *)GetEntity(ObjID, ENTTYPE_CHARACTER)))
} {
else pChar->Read(pCharObj, pExtended, IsLocal);
{ pChar->Keep();
pChar = new CCharacter(this, ObjID, pCharObj, pExtended); }
InsertEntity(pChar); else
} {
pChar = new CCharacter(this, ObjID, pCharObj, pExtended);
InsertEntity(pChar);
}
if(pChar) if(pChar)
pChar->m_GameTeam = GameTeam; pChar->m_GameTeam = GameTeam;
}
} }
void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const CNetObj_EntityEx *pDataEx) void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const CNetObj_EntityEx *pDataEx)
@ -412,6 +423,9 @@ void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const C
if((ObjType == NETOBJTYPE_PROJECTILE || ObjType == NETOBJTYPE_DDRACEPROJECTILE || ObjType == NETOBJTYPE_DDNETPROJECTILE) && m_WorldConfig.m_PredictWeapons) if((ObjType == NETOBJTYPE_PROJECTILE || ObjType == NETOBJTYPE_DDRACEPROJECTILE || ObjType == NETOBJTYPE_DDNETPROJECTILE) && m_WorldConfig.m_PredictWeapons)
{ {
CProjectileData Data = ExtractProjectileInfo(ObjType, pObjData, this, pDataEx); CProjectileData Data = ExtractProjectileInfo(ObjType, pObjData, this, pDataEx);
if(!IsLocalTeam(Data.m_Owner))
return;
CProjectile NetProj = CProjectile(this, ObjID, &Data); CProjectile NetProj = CProjectile(this, ObjID, &Data);
if(NetProj.m_Type != WEAPON_SHOTGUN && absolute(length(NetProj.m_Direction) - 1.f) > 0.02f) // workaround to skip grenades on ball mod if(NetProj.m_Type != WEAPON_SHOTGUN && absolute(length(NetProj.m_Direction) - 1.f) > 0.02f) // workaround to skip grenades on ball mod
@ -483,7 +497,7 @@ void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const C
else if((ObjType == NETOBJTYPE_LASER || ObjType == NETOBJTYPE_DDNETLASER) && m_WorldConfig.m_PredictWeapons) else if((ObjType == NETOBJTYPE_LASER || ObjType == NETOBJTYPE_DDNETLASER) && m_WorldConfig.m_PredictWeapons)
{ {
CLaserData Data = ExtractLaserInfo(ObjType, pObjData, this, pDataEx); CLaserData Data = ExtractLaserInfo(ObjType, pObjData, this, pDataEx);
if(Data.m_Type >= 0 && Data.m_Type != LASERTYPE_RIFLE && Data.m_Type != LASERTYPE_SHOTGUN) if((Data.m_Type >= 0 && Data.m_Type != LASERTYPE_RIFLE && Data.m_Type != LASERTYPE_SHOTGUN) || !IsLocalTeam(Data.m_Owner))
{ {
return; return;
} }
@ -519,7 +533,7 @@ void CGameWorld::NetObjAdd(int ObjID, int ObjType, const void *pObjData, const C
} }
} }
void CGameWorld::NetObjEnd(int LocalID) void CGameWorld::NetObjEnd()
{ {
// keep predicting hooked characters, based on hook position // keep predicting hooked characters, based on hook position
for(int i = 0; i < MAX_CLIENTS; i++) for(int i = 0; i < MAX_CLIENTS; i++)

View file

@ -84,11 +84,14 @@ public:
CGameWorld *m_pParent; CGameWorld *m_pParent;
CGameWorld *m_pChild; CGameWorld *m_pChild;
int m_LocalClientID;
bool IsLocalTeam(int OwnerID);
void OnModified(); void OnModified();
void NetObjBegin(); void NetObjBegin(CTeamsCore Teams, int LocalClientID);
void NetCharAdd(int ObjID, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, int GameTeam, bool IsLocal); void NetCharAdd(int ObjID, CNetObj_Character *pChar, CNetObj_DDNetCharacter *pExtended, int GameTeam, bool IsLocal);
void NetObjAdd(int ObjID, int ObjType, const void *pObjData, const CNetObj_EntityEx *pDataEx); void NetObjAdd(int ObjID, int ObjType, const void *pObjData, const CNetObj_EntityEx *pDataEx);
void NetObjEnd(int LocalID); void NetObjEnd();
void CopyWorld(CGameWorld *pFrom); void CopyWorld(CGameWorld *pFrom);
CEntity *FindMatch(int ObjID, int ObjType, const void *pObjData); CEntity *FindMatch(int ObjID, int ObjType, const void *pObjData);
void Clear(); void Clear();