Skip to content

Commit 9f306fc

Browse files
authored
Merge pull request ddnet#8375 from JSaurusRex/partialAntiping
Partial antiping
2 parents ea7a4ab + 6229802 commit 9f306fc

File tree

6 files changed

+70
-19
lines changed

6 files changed

+70
-19
lines changed

src/engine/client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ class IClient : public IInterface
223223
virtual bool ServerCapAnyPlayerFlag() const = 0;
224224

225225
virtual int GetPredictionTime() = 0;
226+
virtual int GetPredictionTick() = 0;
226227

227228
// snapshot interface
228229

src/engine/client/client.cpp

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,12 +1055,6 @@ void CClient::Render()
10551055

10561056
GameClient()->OnRender();
10571057
DebugRender();
1058-
1059-
if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
1060-
{
1061-
int64_t Now = time_get();
1062-
g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
1063-
}
10641058
}
10651059

10661060
const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc)
@@ -5103,6 +5097,32 @@ int CClient::GetPredictionTime()
51035097
return (int)((m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq());
51045098
}
51055099

5100+
int CClient::GetPredictionTick()
5101+
{
5102+
int PredictionTick = GetPredictionTime() * GameTickSpeed() / 1000.0f;
5103+
5104+
int PredictionMin = g_Config.m_ClAntiPingLimit * GameTickSpeed() / 1000.0f;
5105+
5106+
if(g_Config.m_ClAntiPingLimit == 0)
5107+
{
5108+
float PredictionPercentage = 1 - g_Config.m_ClAntiPingPercent / 100.0f;
5109+
PredictionMin = std::floor(PredictionTick * PredictionPercentage);
5110+
}
5111+
5112+
if(PredictionMin > PredictionTick - 1)
5113+
{
5114+
PredictionMin = PredictionTick - 1;
5115+
}
5116+
5117+
PredictionTick = PredGameTick(g_Config.m_ClDummy) - PredictionMin;
5118+
5119+
if(PredictionTick < GameTick(g_Config.m_ClDummy) + 1)
5120+
{
5121+
PredictionTick = GameTick(g_Config.m_ClDummy) + 1;
5122+
}
5123+
return PredictionTick;
5124+
}
5125+
51065126
void CClient::GetSmoothTick(int *pSmoothTick, float *pSmoothIntraTick, float MixAmount)
51075127
{
51085128
int64_t GameTime = m_aGameTime[g_Config.m_ClDummy].Get(time_get());

src/engine/client/client.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ class CClient : public IClient, public CDemoPlayer::IListener
344344

345345
int GetPredictionTime() override;
346346
CSnapItem SnapGetItem(int SnapId, int Index) const override;
347+
int GetPredictionTick() override;
347348
const void *SnapFindItem(int SnapId, int Type, int Id) const override;
348349
int SnapNumItems(int SnapId) const override;
349350
void SnapSetStaticsize(int ItemType, int Size) override;

src/engine/shared/config_variables.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
// client
1414
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict client movements")
1515
MACRO_CONFIG_INT(ClPredictDummy, cl_predict_dummy, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict dummy movements")
16-
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Antiping limit (0 to disable)")
16+
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 500, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Adds delay to antiping (0 to disable)")
17+
MACRO_CONFIG_INT(ClAntiPingPercent, cl_antiping_percent, 100, 0, 100, CFGFLAG_CLIENT | CFGFLAG_SAVE, "How far ahead antiping predicts, ignored when antiping limit is used")
1718
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable antiping, i. e. more aggressive prediction.")
1819
MACRO_CONFIG_INT(ClAntiPingPlayers, cl_antiping_players, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict other player's movement more aggressively (only enabled if cl_antiping is set to 1)")
1920
MACRO_CONFIG_INT(ClAntiPingGrenade, cl_antiping_grenade, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict grenades (only enabled if cl_antiping is set to 1)")

src/game/client/components/items.cpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,11 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemId)
5858

5959
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
6060

61+
int PredictionTick = Client()->GetPredictionTick();
62+
6163
float Ct;
6264
if(m_pClient->Predict() && m_pClient->AntiPingGrenade() && LocalPlayerInGame && !IsOtherTeam)
63-
Ct = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
65+
Ct = ((float)(PredictionTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
6466
else
6567
Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)Client()->GameTickSpeed() + s_LastGameTickTime;
6668
if(Ct < 0)
@@ -304,9 +306,11 @@ void CItems::RenderLaser(const CLaserData *pCurrent, bool IsPredicted)
304306
{
305307
Dir = normalize_pre_length(Pos - From, Len);
306308

309+
int PredictionTick = Client()->GetPredictionTick();
310+
307311
float Ticks;
308312
if(IsPredicted)
309-
Ticks = (float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
313+
Ticks = (float)(PredictionTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
310314
else
311315
Ticks = (float)(Client()->GameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->IntraGameTick(g_Config.m_ClDummy);
312316
float Ms = (Ticks / Client()->GameTickSpeed()) * 1000.0f;
@@ -377,23 +381,23 @@ void CItems::OnRender()
377381
auto &aSwitchers = GameClient()->Switchers();
378382
if(UsePredicted)
379383
{
380-
for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
384+
for(auto *pProj = (CProjectile *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
381385
{
382386
if(!IsSuper && pProj->m_Number > 0 && pProj->m_Number < (int)aSwitchers.size() && !aSwitchers[pProj->m_Number].m_aStatus[SwitcherTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj))
383387
continue;
384388

385389
CProjectileData Data = pProj->GetData();
386390
RenderProjectile(&Data, pProj->GetId());
387391
}
388-
for(CEntity *pEnt = GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
392+
for(CEntity *pEnt = GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
389393
{
390394
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
391395
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
392396
continue;
393397
CLaserData Data = pLaser->GetData();
394398
RenderLaser(&Data, true);
395399
}
396-
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
400+
for(auto *pPickup = (CPickup *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
397401
{
398402
if(!IsSuper && pPickup->m_Layer == LAYER_SWITCH && pPickup->m_Number > 0 && pPickup->m_Number < (int)aSwitchers.size() && !aSwitchers[pPickup->m_Number].m_aStatus[SwitcherTeam] && BlinkingPickup)
399403
continue;
@@ -601,7 +605,10 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
601605
LocalPlayerInGame = m_pClient->m_aClients[m_pClient->m_Snap.m_pLocalInfo->m_ClientId].m_Team != TEAM_SPECTATORS;
602606
if(!m_pClient->AntiPingGunfire() || !LocalPlayerInGame)
603607
return;
604-
if(Client()->PredGameTick(g_Config.m_ClDummy) == pCurrent->m_StartTick)
608+
609+
int PredictionTick = Client()->GetPredictionTick();
610+
611+
if(PredictionTick == pCurrent->m_StartTick)
605612
return;
606613

607614
// get positions
@@ -625,7 +632,7 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
625632
Speed = pTuning->m_GunSpeed;
626633
}
627634

628-
float Pt = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
635+
float Pt = ((float)(PredictionTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
629636
if(Pt < 0)
630637
return; // projectile haven't been shot yet
631638

src/game/client/gameclient.cpp

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,19 +2307,32 @@ void CGameClient::OnPredict()
23072307
if(PredictDummy())
23082308
pDummyChar = m_PredictedWorld.GetCharacterById(m_PredictedDummyId);
23092309

2310+
int PredictionTick = Client()->GetPredictionTick();
23102311
// predict
23112312
for(int Tick = Client()->GameTick(g_Config.m_ClDummy) + 1; Tick <= Client()->PredGameTick(g_Config.m_ClDummy); Tick++)
23122313
{
23132314
// fetch the previous characters
2314-
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
2315+
if(Tick == PredictionTick)
23152316
{
2316-
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
2317-
m_PredictedPrevChar = pLocalChar->GetCore();
23182317
for(int i = 0; i < MAX_CLIENTS; i++)
23192318
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
23202319
m_aClients[i].m_PrevPredicted = pChar->GetCore();
23212320
}
23222321

2322+
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
2323+
{
2324+
m_PredictedPrevChar = pLocalChar->GetCore();
2325+
m_aClients[m_Snap.m_LocalClientId].m_PrevPredicted = pLocalChar->GetCore();
2326+
2327+
if(pDummyChar)
2328+
m_aClients[m_PredictedDummyId].m_PrevPredicted = pDummyChar->GetCore();
2329+
}
2330+
2331+
if(Tick == PredictionTick)
2332+
{
2333+
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
2334+
}
2335+
23232336
// optionally allow some movement in freeze by not predicting freeze the last one to two ticks
23242337
if(g_Config.m_ClPredictFreeze == 2 && Client()->PredGameTick(g_Config.m_ClDummy) - 1 - Client()->PredGameTick(g_Config.m_ClDummy) % 2 <= Tick)
23252338
pLocalChar->m_CanMoveInFreeze = true;
@@ -2343,14 +2356,22 @@ void CGameClient::OnPredict()
23432356
m_PredictedWorld.Tick();
23442357

23452358
// fetch the current characters
2346-
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
2359+
if(Tick == PredictionTick)
23472360
{
2348-
m_PredictedChar = pLocalChar->GetCore();
23492361
for(int i = 0; i < MAX_CLIENTS; i++)
23502362
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
23512363
m_aClients[i].m_Predicted = pChar->GetCore();
23522364
}
23532365

2366+
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
2367+
{
2368+
m_PredictedChar = pLocalChar->GetCore();
2369+
m_aClients[m_Snap.m_LocalClientId].m_Predicted = pLocalChar->GetCore();
2370+
2371+
if(pDummyChar)
2372+
m_aClients[m_PredictedDummyId].m_Predicted = pDummyChar->GetCore();
2373+
}
2374+
23542375
for(int i = 0; i < MAX_CLIENTS; i++)
23552376
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
23562377
{

0 commit comments

Comments
 (0)