Skip to content

Commit

Permalink
Added better Engine Prediction, Added toggle for SetupBones() optimiz…
Browse files Browse the repository at this point in the history
…ation

And hopefully fixed engine pred too lolol
  • Loading branch information
Viceroyy committed Aug 10, 2024
1 parent 31f1f3e commit 8ab6112
Show file tree
Hide file tree
Showing 7 changed files with 296 additions and 26 deletions.
96 changes: 73 additions & 23 deletions Fusion/src/Features/EnginePrediction/EnginePrediction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,72 +2,122 @@

#include "../TickHandler/TickHandler.h"

int CEnginePrediction::GetTickbase(CTFPlayer* pLocal, CUserCmd* pCmd)
{
static int s_nTick = 0;
static CUserCmd* s_pLastCmd = nullptr;

if (pCmd)
{
if (!s_pLastCmd || s_pLastCmd->hasbeenpredicted)
s_nTick = pLocal->m_nTickBase();
else
s_nTick++;

s_pLastCmd = pCmd;
}

return s_nTick;
}

void CEnginePrediction::Start(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd)
{
if(!pLocal || !pLocal->IsAlive() || !pWeapon || !pCmd || !I::MoveHelper)
if (!pLocal || !pLocal->IsAlive() || !pWeapon || !pCmd || !I::MoveHelper)
return;

m_nOldTickCount = I::GlobalVars->tickcount;
m_fOldCurrentTime = I::GlobalVars->curtime;
m_fOldFrameTime = I::GlobalVars->frametime;
m_nOldTickCount = I::GlobalVars->tickcount;

pLocal->SetCurrentCmd(pCmd);
*G::RandomSeed() = MD5_PseudoRandom(pCmd->command_number) & std::numeric_limits<int>::max();
nServerTicks = GetTickbase(pLocal, pCmd);

I::GlobalVars->curtime = TICKS_TO_TIME(I::GlobalVars->tickcount);
I::GlobalVars->frametime = I::Prediction->m_bEnginePaused ? 0.0f : TICK_INTERVAL;
I::GlobalVars->curtime = TICKS_TO_TIME(nServerTicks);
I::GlobalVars->frametime = (I::Prediction->m_bEnginePaused ? 0.0f : TICK_INTERVAL);
I::GlobalVars->tickcount = nServerTicks;

I::GameMovement->StartTrackPredictionErrors(pLocal);
bSimulated = false;
if (F::Ticks.GetTicks(pLocal) && Vars::CL_Move::Doubletap::AntiWarp.Value && pLocal->OnSolid())
return; // hopefully more accurate eyepos while dting

bSimulated = true;
Simulate(pLocal, pWeapon, pCmd);
}

void CEnginePrediction::Simulate(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd)
{
if (!pLocal || !pLocal->IsAlive() || !pWeapon || !I::MoveHelper)
if(!pLocal || !pLocal->IsAlive() || !pWeapon || !pCmd || !I::MoveHelper)
return;

nOldTickBase = pLocal->m_nTickBase();
memset(&m_MoveData, 0, sizeof(CMoveData));

pCmd->random_seed = MD5_PseudoRandom(pCmd->command_number) & std::numeric_limits<int>::max(); // I kinda remember cmd seed not being available here, maybe use *G::RandomSeed() again

pLocal->m_pCurrentCommand() = pCmd;
CBaseEntity::SetPredictionRandomSeed(pCmd);
CBaseEntity::SetPredictionPlayer(pLocal);

const int nOldTickBase = pLocal->m_nTickBase();
const bool bOldIsFirstPrediction = I::Prediction->m_bFirstTimePredicted;
const bool bOldInPrediction = I::Prediction->m_bInPrediction;

I::Prediction->m_bFirstTimePredicted = false;
I::Prediction->m_bInPrediction = true;

if(pCmd->weaponselect != NULL)
I::GameMovement->StartTrackPredictionErrors(pLocal);

if (pCmd->weaponselect != NULL)
{
pLocal->SelectItem(pWeapon->GetName(), pCmd->weaponsubtype);
CBaseCombatWeapon* pWeapon = dynamic_cast<CBaseCombatWeapon*>(I::ClientEntityList->GetClientEntity(pCmd->weaponselect));

if (pWeapon)
pLocal->SelectItem(pWeapon->GetName(), pCmd->weaponsubtype);
}

if (pCmd->impulse)
{
if (!pLocal->GetClientVehicle() || pLocal->UsingStandardWeaponsInVehicle()) // yeah this game has vehicles wdym
pLocal->m_nImpulse() = pCmd->impulse;
}

pLocal->UpdateButtonState(pCmd->buttons);

I::Prediction->SetLocalViewAngles(pCmd->viewangles);

pLocal->PreThink();
pLocal->Think();
if (pLocal->PhysicsRunThink())
pLocal->PreThink();

const int thinktick = pLocal->m_nNextThinkTick();

if (thinktick > 0 && thinktick < nServerTicks)
{
pLocal->m_nNextThinkTick() = -1; // TICK_NEVER_THINK
pLocal->Think();
}

I::Prediction->SetupMove(pLocal, pCmd, I::MoveHelper, &m_MoveData);
I::GameMovement->ProcessMovement(pLocal, &m_MoveData);
I::Prediction->FinishMove(pLocal, pCmd, &m_MoveData);

pLocal->PostThink();
//pLocal->PostThink();

I::GameMovement->FinishTrackPredictionErrors(pLocal);
pLocal->m_nTickBase() = nOldTickBase;

I::Prediction->m_bFirstTimePredicted = bOldIsFirstPrediction;
I::Prediction->m_bInPrediction = bOldInPrediction;
I::Prediction->m_bFirstTimePredicted = bOldIsFirstPrediction;
}

void CEnginePrediction::End(CTFPlayer* pLocal, CUserCmd* pCmd)
{
if (!pLocal || !pLocal->IsAlive() || !I::MoveHelper)
return;

pLocal->m_nTickBase() = nOldTickBase;

I::GlobalVars->tickcount = m_nOldTickCount;
I::GlobalVars->curtime = m_fOldCurrentTime;
I::GlobalVars->frametime = m_fOldFrameTime;
I::GameMovement->FinishTrackPredictionErrors(pLocal);

pLocal->SetCurrentCmd(nullptr);
pLocal->m_pCurrentCommand() = NULL;
CBaseEntity::SetPredictionRandomSeed(NULL);
CBaseEntity::SetPredictionPlayer(NULL);

*G::RandomSeed() = -1;
I::GlobalVars->curtime = m_fOldCurrentTime;
I::GlobalVars->frametime = m_fOldFrameTime;
I::GlobalVars->tickcount = m_nOldTickCount;
}
3 changes: 2 additions & 1 deletion Fusion/src/Features/EnginePrediction/EnginePrediction.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ class CEnginePrediction
CMoveData m_MoveData = {};

private:
int GetTickbase(CTFPlayer* pLocal, CUserCmd* pCmd);
void Simulate(CTFPlayer* pLocal, CBaseCombatWeapon* pWeapon, CUserCmd* pCmd);

int m_nOldTickCount = 0;
int nOldTickBase = 0;
int nServerTicks = 0;
float m_fOldCurrentTime = 0.f;
float m_fOldFrameTime = 0.f;

Expand Down
4 changes: 4 additions & 0 deletions Fusion/src/Features/ImGui/Menu/Menu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,10 @@ void CMenu::MenuMisc()
FToggle("Giant weapon sounds", Vars::Misc::Sound::GiantWeaponSounds);
FToggle("Hitsound always", Vars::Misc::Sound::HitsoundAlways, FToggle_Middle);
} EndSection();
if (Section("Game"))
{
FToggle("Optimize bones", Vars::Misc::Game::SetupBonesOptimization);
} EndSection();

/* Column 2 */
TableNextColumn();
Expand Down
2 changes: 1 addition & 1 deletion Fusion/src/Hooks/CBaseAnimating_SetupBones.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ MAKE_SIGNATURE(CBaseAnimating_SetupBones, "client.dll", "48 8B C4 44 89 40 ? 48
MAKE_HOOK(CBaseAnimating_SetupBones, S::CBaseAnimating_SetupBones(), bool, __fastcall,
void* ecx, matrix3x4* pBoneToWorldOut, int nMaxBones, int boneMask, float currentTime)
{
if (!F::Backtrack.bSettingUpBones)
if (Vars::Misc::Game::SetupBonesOptimization.Value && !F::Backtrack.bSettingUpBones)
{
auto pBaseEntity = reinterpret_cast<CBaseEntity*>(std::uintptr_t(ecx) - 8);
if (pBaseEntity)
Expand Down
Loading

0 comments on commit 8ab6112

Please sign in to comment.