Merge pull request #1052 from nullworks/aim_improve
Fix certain client side animation desyncs
This commit is contained in:
commit
a806c61af8
@ -177,6 +177,7 @@ public:
|
||||
offset_t m_angEyeAnglesLocal;
|
||||
offset_t m_nSequence;
|
||||
offset_t m_flSimulationTime;
|
||||
offset_t m_flAnimTime;
|
||||
offset_t m_angRotation;
|
||||
|
||||
offset_t m_hOwnerEntity;
|
||||
|
@ -17,6 +17,7 @@ public:
|
||||
static InvalidateBoneCache_t InvalidateBoneCache = InvalidateBoneCache_t(addr);
|
||||
InvalidateBoneCache(self);
|
||||
}
|
||||
// Currently unused, might be useful in the near future though
|
||||
inline static bool Interpolate(IClientEntity *self, float time)
|
||||
{
|
||||
typedef bool (*fn_t)(IClientEntity *, float);
|
||||
|
@ -29,6 +29,7 @@ void NetVars::Init()
|
||||
this->m_iClip2 = gNetvars.get_offset("DT_BaseCombatWeapon", "LocalWeaponData", "m_iClip2");
|
||||
this->m_Collision = gNetvars.get_offset("DT_BaseEntity", "m_Collision");
|
||||
this->m_flSimulationTime = gNetvars.get_offset("DT_BaseEntity", "m_flSimulationTime");
|
||||
this->m_flAnimTime = gNetvars.get_offset("DT_BaseEntity", "AnimTimeMustBeFirst", "m_flAnimTime");
|
||||
this->m_angRotation = gNetvars.get_offset("DT_BaseEntity", "m_angRotation");
|
||||
|
||||
IF_GAME(IsTF2())
|
||||
|
@ -129,12 +129,7 @@ matrix3x4_t *EntityHitboxCache::GetBones(int numbones)
|
||||
{
|
||||
// Reset game cache
|
||||
if (!bonecache_enabled && CE_GOOD(parent_ref))
|
||||
{
|
||||
re::C_BaseAnimating::InvalidateBoneCache(RAW_ENT(parent_ref));
|
||||
// Only use when nolerp is on as this breaks game visuals a tad
|
||||
if (nolerp)
|
||||
re::C_BaseAnimating::Interpolate(RAW_ENT(parent_ref), bones_setup_time);
|
||||
}
|
||||
|
||||
// If numbones is not set, get it from some terrible and unnamed variable
|
||||
if (numbones == -1)
|
||||
|
@ -10,6 +10,7 @@ set(files "${CMAKE_CURRENT_LIST_DIR}/CanPacket.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/nographics.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/others.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Paint.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PlayerAnimFix.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/PreDataUpdate.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RandomInt.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/RunCommand.cpp"
|
||||
|
57
src/hooks/PlayerAnimFix.cpp
Normal file
57
src/hooks/PlayerAnimFix.cpp
Normal file
@ -0,0 +1,57 @@
|
||||
#include "common.hpp"
|
||||
#include "DetourHook.hpp"
|
||||
|
||||
namespace hacks::tf2::animfix
|
||||
{
|
||||
DetourHook frameadvance_detour{};
|
||||
typedef float (*FrameAdvance_t)(IClientEntity *, float);
|
||||
|
||||
std::vector<float> previous_simtimes;
|
||||
|
||||
// Credits to Blackfire62 for telling me how this could be realized
|
||||
float FrameAdvance_hook(IClientEntity *self, float flInterval)
|
||||
{
|
||||
float newInterval = flInterval;
|
||||
|
||||
// Check if the entity is valid
|
||||
if (self && IDX_GOOD(self->entindex()) && self->entindex() > 0 && self->entindex() <= (int) previous_simtimes.size())
|
||||
{
|
||||
// Check if they are an alive player
|
||||
CachedEntity *ent = ENTITY(self->entindex());
|
||||
// Set new interval based on their simtime
|
||||
if (CE_GOOD(ent) && ent->m_Type() == ENTITY_PLAYER && ent->m_bAlivePlayer())
|
||||
{
|
||||
float simtime = CE_FLOAT(ent, netvar.m_flSimulationTime);
|
||||
// Calculate the time we need to animate by
|
||||
float time_difference = simtime - previous_simtimes.at(ent->m_IDX - 1);
|
||||
if (time_difference > 0.0f)
|
||||
newInterval = time_difference;
|
||||
previous_simtimes.at(ent->m_IDX - 1) = simtime;
|
||||
// If the simtime didn't update we need to make sure that the original function also does not update
|
||||
if (newInterval == 0.0f)
|
||||
CE_FLOAT(ent, netvar.m_flAnimTime) = g_GlobalVars->curtime;
|
||||
}
|
||||
}
|
||||
|
||||
FrameAdvance_t original = (FrameAdvance_t) frameadvance_detour.GetOriginalFunc();
|
||||
float return_value = original(self, newInterval);
|
||||
frameadvance_detour.RestorePatch();
|
||||
return return_value;
|
||||
}
|
||||
|
||||
void LevelInit()
|
||||
{
|
||||
previous_simtimes.clear();
|
||||
previous_simtimes.resize(g_IEngine->GetMaxClients());
|
||||
}
|
||||
|
||||
static InitRoutine init([]() {
|
||||
static auto FrameAdvance_signature = gSignatures.GetClientSignature("55 89 E5 57 56 53 83 EC 4C 8B 5D ? 80 BB ? ? ? ? 00 0F 85 ? ? ? ? 8B B3");
|
||||
frameadvance_detour.Init(FrameAdvance_signature, (void *) FrameAdvance_hook);
|
||||
EC::Register(EC::LevelInit, LevelInit, "levelinit_animfix");
|
||||
LevelInit();
|
||||
|
||||
EC::Register(
|
||||
EC::Shutdown, []() { frameadvance_detour.Shutdown(); }, "shutdown_animfix");
|
||||
});
|
||||
} // namespace hacks::tf2::animfix
|
Reference in New Issue
Block a user