Skip to content

Commit

Permalink
not working
Browse files Browse the repository at this point in the history
  • Loading branch information
sjrc6 committed Dec 10, 2024
1 parent f0bd160 commit aa8b311
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 30 deletions.
91 changes: 62 additions & 29 deletions src/game/client/gameclient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2503,73 +2503,106 @@ void CGameClient::OnPredict()

// TClient
// New antiping smoothing
CCharacter *pSmoothLocalChar = m_PredSmoothingWorld.GetCharacterById(m_Snap.m_LocalClientId);
if(!pSmoothLocalChar)
m_PredSmoothingWorld.CopyWorld(&m_PredictedWorld);
if(g_Config.m_ClAntiPingImproved &&
Predict() && AntiPingPlayers() &&
pSmoothLocalChar &&
m_NewPredictedTick && m_PredictedTick >= MIN_TICK) // using m_NewPredictedTick instead of m_NewTick because it seems more correct?
{
int PredTime = clamp(Client()->GetPredictionTime(), 0, 8000); //Milliseconds for some reason?? TODO: Use more precision


// Nightmare: in order to get 100% accurate comparison to the previous prediction state we must
// tick the previous predicted world with our current predicted inputs
if(!pSmoothLocalChar)
{
Echo("AAA THIS IS BAD");
return;
}
CCharacter *pSmoothDummyChar = 0;
CCharacter *pPredDummyChar = 0;
if(PredictDummy())
{
pSmoothDummyChar = m_PredSmoothingWorld.GetCharacterById(m_PredictedDummyId);
pPredDummyChar = m_PredictedWorld.GetCharacterById(m_PredictedDummyId);
}
CNetObj_PlayerInput *pInputData = &m_PredictedWorld.GetCharacterById(m_Snap.m_LocalClientId)->LatestInput();
CNetObj_PlayerInput *pDummyInputData = !pPredDummyChar ? 0 : &m_PredictedWorld.GetCharacterById(m_PredictedDummyId)->LatestInput();
bool DummyFirst = pInputData && pDummyInputData && pSmoothDummyChar->GetCid() < pSmoothLocalChar->GetCid();
if(DummyFirst)
pSmoothDummyChar->OnDirectInput(pDummyInputData);
if(pInputData)
pSmoothLocalChar->OnDirectInput(pInputData);
if(pDummyInputData && !DummyFirst)
pSmoothDummyChar->OnDirectInput(pDummyInputData);
m_PredSmoothingWorld.m_GameTick++;
if(pInputData)
pSmoothLocalChar->OnPredictedInput(pInputData);
if(pDummyInputData)
pSmoothDummyChar->OnPredictedInput(pDummyInputData);
m_PredSmoothingWorld.Tick();

for(int i = 0; i < MAX_CLIENTS; i++)
{
if(!m_Snap.m_aCharacters[i].m_Active || i == m_Snap.m_LocalClientId || !m_aLastActive[i])
continue;

CCharacter *pChar = m_PredSmoothingWorld.GetCharacterById(i);
if(!pChar)
continue;

vec2 PredPos = m_aClients[i].m_Predicted.m_Pos;
vec2 PrevPredPos = m_aLastPos[i]; // TODO: This position is not accurate because it should account for predicted inputs that happened on this tick
if(g_Config.m_ClFastInputOthers && g_Config.m_ClFastInput)
PredPos = m_aClients[i].m_PrevPredicted.m_Pos;

vec2 PrevPredPos = pChar->GetCore().m_Pos; // TODO: This position is not entirely accurate because it should account for predicted inputs that happened on this tick
vec2 ServerPos = vec2(m_Snap.m_aCharacters[i].m_Cur.m_X, m_Snap.m_aCharacters[i].m_Cur.m_Y);
vec2 PredDir = normalize(PredPos - ServerPos);
vec2 LastDir = normalize(PrevPredPos - ServerPos);
float PredLength = length(PredPos - ServerPos);
float LastLength = length(PrevPredPos - ServerPos);

vec2 ConfidenceVector = m_aClients[i].m_ConfidenceVector;
float Confidence = 1.0f;
if(LastDir == vec2(0, 0))
if(LastDir == vec2(0, 0) && PredDir == vec2(0, 0))
Confidence = 1.0f;
else if(PredDir == vec2(0, 0))
Confidence = 1.0f; // TODO?: this should maybe cause uncertainty smoothing
else
{
Confidence = dot(LastDir, PredDir) * 0.5 + 0.5;
//Confidence = std::pow(Confidence, 2.0f);
Confidence = std::max(0.0f, dot(LastDir, PredDir));
//Confidence = std::pow(Confidence, 5.0f);
}
vec2 MidVector = mix(LastDir, PredDir, 0.5f);
float MidLength = length(mix(PredPos, PrevPredPos, 0.5f) - ServerPos);
MidVector = normalize(MidVector) * MidLength;
ConfidenceVector = mix(MidVector, ConfidenceVector, Confidence);


float TickSize = (float)(1000 / Client()->GameTickSpeed()) / ((float)PredTime * 2.0f); // 20ms / PredTime
float TickSize = (float)(1000 / Client()->GameTickSpeed()) / ((float)PredTime * 1.0f); // 20ms / PredTime
float PrevConfidence = 1.0f - m_aClients[i].m_Uncertainty;

float AdditionalUncertainty = PrevConfidence - std::min(Confidence, PrevConfidence);

float Smoothing = AdditionalUncertainty * 0.5f; // 0.5 factor can be lowered
m_aClients[i].m_UncertaintySmoothing = std::min(1.0f, m_aClients[i].m_UncertaintySmoothing + Smoothing);

float NewConfidence = std::min(Confidence, PrevConfidence + TickSize);
m_aClients[i].m_Uncertainty = 1.0f - NewConfidence;

vec2 ConfidencePos = mix(ServerPos, PredPos, NewConfidence);
vec2 PrevImprovedPos = m_aClients[i].m_ImprovedPredPos;
vec2 ConfidencePos = mix(ServerPos + ConfidenceVector, PredPos, NewConfidence);

// If Smoothing > 0 we mix between the PrevImprovedPos and the ConfidencePos based on the % size of the smoothing decay
float SmoothingMix = 1.0f;
if(m_aClients[i].m_UncertaintySmoothing > 0.0f)
{
SmoothingMix = 1.0f - (std::max(0.0f, m_aClients[i].m_UncertaintySmoothing - TickSize) / m_aClients[i].m_UncertaintySmoothing);
SmoothingMix = std::clamp(SmoothingMix, 0.0f, 1.0f);

// Decay smoothing
m_aClients[i].m_UncertaintySmoothing = std::max(0.0f, m_aClients[i].m_UncertaintySmoothing - TickSize);
}
vec2 SmoothingPos = mix(ServerPos, PredPos, NewConfidence);
m_aClients[i].m_ConfidenceVector = ConfidenceVector;

m_aClients[i].m_PrevImprovedPredPos = PrevImprovedPos;
m_aClients[i].m_ImprovedPredPos = SmoothingPos;
m_aClients[i].m_PrevImprovedPredPos = m_aClients[i].m_ImprovedPredPos;
m_aClients[i].m_ImprovedPredPos = PredPos;


char aBuf[256];
str_format(aBuf, sizeof(aBuf), "CalcY: %.2f ServerY: %.2f, PredY: %.2f", m_aClients[i].m_ImprovedPredPos.y, ServerPos.y, PredPos.y);
str_format(aBuf, sizeof(aBuf), "Smoothing: %.2f Confidence: %.2f", m_aClients[i].m_UncertaintySmoothing, NewConfidence);
str_format(aBuf, sizeof(aBuf), "Confidence: %.2f, CurrentConfidence: %.2f", NewConfidence, Confidence);
str_format(aBuf, sizeof(aBuf), "Confidence: %.2f", Confidence);

Echo(aBuf);
//m_aClients[i].m_ImprovedPredPos = m_aClients[i].m_Predicted.m_Pos;
//m_aClients[i].m_PrevImprovedPredPos = m_aLastPos[i];
}
// Copy the current pred world so on the next tick we have the "previous" pred work to advance and test against
m_PredSmoothingWorld.CopyWorld(&m_PredictedWorld);
}
for(int i = 0; i < MAX_CLIENTS; i++)
{
Expand Down
4 changes: 3 additions & 1 deletion src/game/client/gameclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -427,7 +427,7 @@ class CGameClient : public IGameClient
//TClient
vec2 m_ImprovedPredPos = vec2(0, 0);
vec2 m_PrevImprovedPredPos = vec2(0, 0);
vec2 m_ConfidencePos = vec2(0, 0);
vec2 m_ConfidenceVector = vec2(0, 0);

float m_Uncertainty = 0.0f;
float m_UncertaintySmoothing = 0;
Expand Down Expand Up @@ -625,7 +625,9 @@ class CGameClient : public IGameClient
CGameWorld m_GameWorld;
CGameWorld m_PredictedWorld;
CGameWorld m_PrevPredictedWorld;
//TClient
CGameWorld m_ExtraPredictedWorld;
CGameWorld m_PredSmoothingWorld;

std::vector<SSwitchers> &Switchers() { return m_GameWorld.m_Core.m_vSwitchers; }
std::vector<SSwitchers> &PredSwitchers() { return m_PredictedWorld.m_Core.m_vSwitchers; }
Expand Down
2 changes: 2 additions & 0 deletions src/game/client/prediction/entities/character.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,8 @@ class CCharacter : public CEntity
bool IsSuper() { return m_Core.m_Super; }
int m_FreezeAccumulation;
int m_AliveAccumulation;
//TClient
CNetObj_PlayerInput LatestInput() { return m_LatestInput; };

private:
// weapon info
Expand Down

0 comments on commit aa8b311

Please sign in to comment.