mirror of
https://github.com/ddnet/ddnet.git
synced 2024-09-19 17:14:18 +00:00
Merge 6c0427d23c
into e0a95d14a6
This commit is contained in:
commit
5b2c089155
|
@ -1019,11 +1019,11 @@ void CClient::Render()
|
|||
GameClient()->OnRender();
|
||||
DebugRender();
|
||||
|
||||
if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
|
||||
{
|
||||
int64_t Now = time_get();
|
||||
g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
|
||||
}
|
||||
// if(State() == IClient::STATE_ONLINE && g_Config.m_ClAntiPingLimit)
|
||||
// {
|
||||
// int64_t Now = time_get();
|
||||
// g_Config.m_ClAntiPing = (m_PredictedTime.Get(Now) - m_aGameTime[g_Config.m_ClDummy].Get(Now)) * 1000 / (float)time_freq() > g_Config.m_ClAntiPingLimit;
|
||||
// }
|
||||
}
|
||||
|
||||
const char *CClient::LoadMap(const char *pName, const char *pFilename, SHA256_DIGEST *pWantedSha256, unsigned WantedCrc)
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
// client
|
||||
MACRO_CONFIG_INT(ClPredict, cl_predict, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict client movements")
|
||||
MACRO_CONFIG_INT(ClPredictDummy, cl_predict_dummy, 1, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Predict dummy movements")
|
||||
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Antiping limit (0 to disable)")
|
||||
MACRO_CONFIG_INT(ClAntiPingLimit, cl_antiping_limit, 0, 0, 200, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Adds delay to antiping (0 to disable)")
|
||||
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")
|
||||
MACRO_CONFIG_INT(ClAntiPing, cl_antiping, 0, 0, 1, CFGFLAG_CLIENT | CFGFLAG_SAVE, "Enable antiping, i. e. more aggressive prediction.")
|
||||
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)")
|
||||
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)")
|
||||
|
|
|
@ -58,9 +58,11 @@ void CItems::RenderProjectile(const CProjectileData *pCurrent, int ItemId)
|
|||
|
||||
bool IsOtherTeam = (pCurrent->m_ExtraInfo && pCurrent->m_Owner >= 0 && m_pClient->IsOtherTeam(pCurrent->m_Owner));
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
float Ct;
|
||||
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)Client()->GameTickSpeed();
|
||||
Ct = ((float)(predictTick - 1 - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
else
|
||||
Ct = (Client()->PrevGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) / (float)Client()->GameTickSpeed() + s_LastGameTickTime;
|
||||
if(Ct < 0)
|
||||
|
@ -304,9 +306,11 @@ void CItems::RenderLaser(const CLaserData *pCurrent, bool IsPredicted)
|
|||
{
|
||||
Dir = normalize_pre_length(Pos - From, Len);
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
float Ticks;
|
||||
if(IsPredicted)
|
||||
Ticks = (float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
|
||||
Ticks = (float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy);
|
||||
else
|
||||
Ticks = (float)(Client()->GameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->IntraGameTick(g_Config.m_ClDummy);
|
||||
float Ms = (Ticks / Client()->GameTickSpeed()) * 1000.0f;
|
||||
|
@ -377,7 +381,7 @@ void CItems::OnRender()
|
|||
auto &aSwitchers = GameClient()->Switchers();
|
||||
if(UsePredicted)
|
||||
{
|
||||
for(auto *pProj = (CProjectile *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
|
||||
for(auto *pProj = (CProjectile *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PROJECTILE); pProj; pProj = (CProjectile *)pProj->NextEntity())
|
||||
{
|
||||
if(!IsSuper && pProj->m_Number > 0 && pProj->m_Number < (int)aSwitchers.size() && !aSwitchers[pProj->m_Number].m_aStatus[SwitcherTeam] && (pProj->m_Explosive ? BlinkingProjEx : BlinkingProj))
|
||||
continue;
|
||||
|
@ -385,7 +389,7 @@ void CItems::OnRender()
|
|||
CProjectileData Data = pProj->GetData();
|
||||
RenderProjectile(&Data, pProj->GetId());
|
||||
}
|
||||
for(CEntity *pEnt = GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
|
||||
for(CEntity *pEnt = GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_LASER); pEnt; pEnt = pEnt->NextEntity())
|
||||
{
|
||||
auto *const pLaser = dynamic_cast<CLaser *>(pEnt);
|
||||
if(!pLaser || pLaser->GetOwner() < 0 || !GameClient()->m_aClients[pLaser->GetOwner()].m_IsPredictedLocal)
|
||||
|
@ -393,7 +397,7 @@ void CItems::OnRender()
|
|||
CLaserData Data = pLaser->GetData();
|
||||
RenderLaser(&Data, true);
|
||||
}
|
||||
for(auto *pPickup = (CPickup *)GameClient()->m_PredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
||||
for(auto *pPickup = (CPickup *)GameClient()->m_PrevPredictedWorld.FindFirst(CGameWorld::ENTTYPE_PICKUP); pPickup; pPickup = (CPickup *)pPickup->NextEntity())
|
||||
{
|
||||
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)
|
||||
continue;
|
||||
|
@ -601,7 +605,10 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
|
|||
LocalPlayerInGame = m_pClient->m_aClients[m_pClient->m_Snap.m_pLocalInfo->m_ClientId].m_Team != TEAM_SPECTATORS;
|
||||
if(!m_pClient->AntiPingGunfire() || !LocalPlayerInGame)
|
||||
return;
|
||||
if(Client()->PredGameTick(g_Config.m_ClDummy) == pCurrent->m_StartTick)
|
||||
|
||||
int predictTick = GameClient()->GetPredictionTick();
|
||||
|
||||
if(predictTick == pCurrent->m_StartTick)
|
||||
return;
|
||||
|
||||
// get positions
|
||||
|
@ -625,7 +632,7 @@ void CItems::ReconstructSmokeTrail(const CProjectileData *pCurrent, int DestroyT
|
|||
Speed = pTuning->m_GunSpeed;
|
||||
}
|
||||
|
||||
float Pt = ((float)(Client()->PredGameTick(g_Config.m_ClDummy) - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
float Pt = ((float)(predictTick - pCurrent->m_StartTick) + Client()->PredIntraGameTick(g_Config.m_ClDummy)) / (float)Client()->GameTickSpeed();
|
||||
if(Pt < 0)
|
||||
return; // projectile haven't been shot yet
|
||||
|
||||
|
|
|
@ -2100,6 +2100,25 @@ void CGameClient::UpdateEditorIngameMoved()
|
|||
}
|
||||
}
|
||||
|
||||
int CGameClient::GetPredictionTick()
|
||||
{
|
||||
int predictTick = Client()->GetPredictionTime() * Client()->GameTickSpeed() / 1000.0f;
|
||||
|
||||
float predictPercentage = 1 - g_Config.m_ClAntiPingpercent / 100.0f;
|
||||
int predictMin = std::floor(predictTick * predictPercentage);
|
||||
int predictMin2 = g_Config.m_ClAntiPingLimit * Client()->GameTickSpeed() / 1000.0f;
|
||||
if (g_Config.m_ClAntiPingLimit != 0)
|
||||
predictMin = predictMin2;
|
||||
|
||||
predictTick = Client()->PredGameTick(g_Config.m_ClDummy) - predictMin;
|
||||
|
||||
if(predictTick < Client()->GameTick(g_Config.m_ClDummy) + 1)
|
||||
{
|
||||
predictTick = Client()->GameTick(g_Config.m_ClDummy) + 1;
|
||||
}
|
||||
return predictTick;
|
||||
}
|
||||
|
||||
void CGameClient::OnPredict()
|
||||
{
|
||||
// store the previous values so we can detect prediction errors
|
||||
|
@ -2157,19 +2176,32 @@ void CGameClient::OnPredict()
|
|||
if(PredictDummy())
|
||||
pDummyChar = m_PredictedWorld.GetCharacterById(m_PredictedDummyId);
|
||||
|
||||
int predictTick = GetPredictionTick();
|
||||
// predict
|
||||
for(int Tick = Client()->GameTick(g_Config.m_ClDummy) + 1; Tick <= Client()->PredGameTick(g_Config.m_ClDummy); Tick++)
|
||||
{
|
||||
// fetch the previous characters
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
|
||||
m_PredictedPrevChar = pLocalChar->GetCore();
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
m_aClients[i].m_PrevPredicted = pChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
{
|
||||
m_PredictedPrevChar = pLocalChar->GetCore();
|
||||
m_aClients[m_Snap.m_LocalClientId].m_PrevPredicted = pLocalChar->GetCore();
|
||||
|
||||
if(pDummyChar)
|
||||
m_aClients[m_PredictedDummyId].m_PrevPredicted = pDummyChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PrevPredictedWorld.CopyWorld(&m_PredictedWorld);
|
||||
}
|
||||
|
||||
// optionally allow some movement in freeze by not predicting freeze the last one to two ticks
|
||||
if(g_Config.m_ClPredictFreeze == 2 && Client()->PredGameTick(g_Config.m_ClDummy) - 1 - Client()->PredGameTick(g_Config.m_ClDummy) % 2 <= Tick)
|
||||
pLocalChar->m_CanMoveInFreeze = true;
|
||||
|
@ -2193,14 +2225,22 @@ void CGameClient::OnPredict()
|
|||
m_PredictedWorld.Tick();
|
||||
|
||||
// fetch the current characters
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
if(Tick == predictTick)
|
||||
{
|
||||
m_PredictedChar = pLocalChar->GetCore();
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
m_aClients[i].m_Predicted = pChar->GetCore();
|
||||
}
|
||||
|
||||
if(Tick == Client()->PredGameTick(g_Config.m_ClDummy))
|
||||
{
|
||||
m_PredictedChar = pLocalChar->GetCore();
|
||||
m_aClients[m_Snap.m_LocalClientId].m_Predicted = pLocalChar->GetCore();
|
||||
|
||||
if(pDummyChar)
|
||||
m_aClients[m_PredictedDummyId].m_Predicted = pDummyChar->GetCore();
|
||||
}
|
||||
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
if(CCharacter *pChar = m_PredictedWorld.GetCharacterById(i))
|
||||
{
|
||||
|
|
|
@ -499,6 +499,7 @@ public:
|
|||
CRenderTools m_RenderTools;
|
||||
|
||||
void OnReset();
|
||||
int GetPredictionTick();
|
||||
|
||||
size_t ComponentCount() { return m_vpAll.size(); }
|
||||
|
||||
|
|
Loading…
Reference in a new issue