-
Автор темы
- #1
C++:
#include "pdranims.hpp"
Animações g_anims;
void Animations::AnimationInfo_t::UpdateAnimations( LagCompensation::LagRecord_t* pRecord, LagCompensation::LagRecord_t* pPreviousRecord ) {
if (!pRegistroAnterior) {
pRecord->m_vecVelocity = m_pEntity->m_vecVelocity( );
pRegistro->Aplicar( m_pEntity);
g_anims.UpdatePlayer(m_pEntity);
retornar;
}
vec3_t vecVelocity = m_pEntity->m_vecVelocity( );
m_pEntity->SetAnimLayers( pRecord->m_pLayers );
m_pEntity->SetAbsOrigin(pRecord->m_vecOrigin);
m_pEntity->SetAbsAngles(pRecord->m_angAbsAngles);
m_pEntity->m_vecVelocity( ) = pPreviousRecord->m_vecVelocity;
pRecord->m_vecVelocity = vecVelocity;
pRecord->m_bDidShot = pRecord->m_flLastShotTime > pPreviousRecord->m_flSimulationTime && pRecord->m_flLastShotTime <= pRecord->m_flSimulationTime;
vec3_t vecPreviousOrigin = pPreviousRecord->m_vecOrigin;
int fPreviousFlags = pPreviousRecord->m_fFlags;
for ( int i = 0; i < pRecord->m_iChoked; ++i ) {
const float flSimulationTime = pPreviousRecord->m_flSimulationTime + game::TICKS_TO_TIME( i + 1 );
const float flLerp = 1.f - ( pRecord->m_flSimulationTime - flSimulationTime ) / ( pRecord->m_flSimulationTime - pPreviousRecord->m_flSimulationTime );
if (!pGravar->m_bDidShot) {
auto vecEyeAngles = math::Interpolate( pPreviousRecord->m_angEyeAngles, pRecord->m_angEyeAngles, flLerp );
m_pEntity->m_angEyeAngles( ).y = vecEyeAngles.y;
}
m_pEntity->m_flDuckAmount( ) = math::Interpolate( pPreviousRecord->m_flDuck, pRecord->m_flDuck, flLerp );
if ( pRecord->m_iChoked - 1 == i ) {
m_pEntity->m_vecVelocity( ) = vecVelocity;
m_pEntity->m_fFlags( ) = pRecord->m_fFlags;
}
outro {
// sem chance
// g_game_movement.Extrapolate( m_pEntity, vecPreviousOrigin, m_pEntity->m_vecVelocity( ), m_pEntity->m_fFlags( ), fPreviousFlags & FL_ONGROUND );
fPreviousFlags = m_pEntity->m_fFlags( );
pRecord->m_vecVelocity = ( pRecord->m_vecOrigin - pPreviousRecord->m_vecOrigin ) * ( 1.f / game::TICKS_TO_TIME( pRecord->m_iChoked ) );
}
if (pRecord->m_bDidShot) {
/* NOTA DO ALPHA:
* Isso é para tentar resolver a dessincronização inicial dos jogadores, usando o último ângulo em que eles estavam antes de atirar
* É bom o suficiente, mas deixarei outro conceito (alternativo) que pode funcionar ao tentar resolver a dessincronização na tomada
* Não testei nada, mas a lógica está aí e em teoria deve funcionar bem (falta verificações de nullptr, obviamente, já que é um conceito)
*
* float flPseudoFireYaw = Math::NormalizeYaw( Math::CalculateAngle( m_pPlayer->GetBonePos( 8 ), m_pPlayer->GetBonePos( 0 ) ).y );
* float flLeftFireYawDelta = fabsf( Math::NormalizeYaw( flPseudoFireYaw - ( pRecord->m_angEyeAngles.y + 58.f ) ) );
* float flRightFireYawDelta = fabsf( Math::NormalizeYaw( flPseudoFireYaw - ( pRecord->m_angEyeAngles.y - 58.f ) ) );
*
* pRecord->m_pState->m_flGoalFeetYaw = pRecord->m_pState->m_flEyeYaw + ( flLeftFireYawDelta > flRightFireYawDelta ? -58.f : 58.f );
*/
m_pEntity->m_angEyeAngles( ) = pPreviousRecord->m_angLastReliableAngle;
if (pRecord->m_flLastShotTime <= flSimulationTime) {
m_pEntity->m_angEyeAngles( ) = pRecord->m_angEyeAngles;
}
}
const float flBackupSimtime = m_pEntity->m_flSimulationTime( );
m_pEntity->m_flSimulationTime( ) = flSimulationTime;
g_anims.UpdatePlayer(m_pEntity);
m_pEntity->m_flSimulationTime( ) = flBackupSimtime;
}
}
void Animations::UpdatePlayer( Player* pEntity ) {
static bool& invalidate_bone_cache = **reinterpret_cast< bool** >( pattern::find( g_csgo.m_client_dll, XOR( "C6 05 ? ? ? ? 89 47 70" ) ).add( 2 ).as<uint32_t>( ) );
const float frametime = g_csgo.m_globals->m_frametime;
const float curtime = g_csgo.m_globals->m_curtime;
CCSGOPlayerAnimState* estado const = pEntity->m_PlayerAnimState( );
if ( ! estado ) {
retornar;
}
g_csgo.m_globals->m_frametime = g_csgo.m_globals->m_interval;
g_csgo.m_globals->m_curtime = pEntity->m_flSimulationTime( );
// pula a chamada para C_BaseEntity::CalcAbsoluteVelocity
pEntity->m_iEFlags( ) &= ~0x1000; //EFL_DIRTY_ABSVELOCITY
// foda-se
//if (estado->m_iLastClientSideAnimationUpdateFramecount == g_csgo.m_globals->m_frame) {
// estado->m_iLastClientSideAnimationUpdateFramecount -= 1;
///}
const bool backup_invalidate_bone_cache = invalidate_bone_cache;
pEntity->m_bClientSideAnimation( ) = verdadeiro;
pEntity->UpdateClientSideAnimation( );
pEntity->m_bClientSideAnimation( ) = false;
pEntity->InvalidatePhysicsRecursive( ANGLES_CHANGED );
pEntity->InvalidatePhysicsRecursive( ANIMATION_CHANGED );
pEntity->InvalidatePhysicsRecursive( SEQUENCE_CHANGED );
invalidate_bone_cache = backup_invalidate_bone_cache;
g_csgo.m_globals->m_frametime = frametime;
g_csgo.m_globals->m_curtime = curtime;
}
bool Animations::GenerateMatrix( Player* pEntity, BoneArray* pBoneToWorldOut, int boneMask, float currentTime )
{
if (!pEntity || !pEntity->IsPlayer( ) || !pEntity->vivo( ) )
retorna falso;
CStudioHdr* pStudioHdr = pEntity->GetModelPtr( );
if (!pStudioHdr) {
retorna falso;
}
// obtém ptr para acessor de osso.
CBoneAccessor* acessador = &pEntity->m_BoneAccessor( );
if (!acessador)
retorna falso;
// armazena a matriz de saída original.
// provavelmente cachedbonedata.
BoneArray* backup_matrix = accessor->m_pBones;
if (!backup_matrix)
retorna falso;
vec3_t vecAbsOrigin = pEntity->GetAbsOrigin( );
ang_t vecAbsAngles = pEntity->GetAbsAngles( );
vec3_t vecBackupAbsOrigin = pEntity->GetAbsOrigin( );
ang_t vecBackupAbsAngles = pEntity->GetAbsAngles( );
matriz3x4a_t parentTransform;
math::AngleMatrix( vecAbsAngles, vecAbsOrigin, parentTransform );
pEntity->m_fEffects( ) |= 8;
pEntity->SetAbsOrigin( vecAbsOrigin );
pEntity->SetAbsAngles( vecAbsAngles );
vec3_t pos[ 128 ];
__declspec( align( 16 ) ) quaternion_t q[ 128 ];
m_bEnablePVS = verdadeiro;
uint32_t fBackupOcclusionFlags = pEntity->m_iOcclusionFlags( );
pEntity->m_iOcclusionFlags( ) |= 0xA; // pular chamada para acumulamlayers em regras de mistura padrão
pEntity->StandardBlendingRules( pStudioHdr, pos, q, currentTime, boneMask );
pEntity->m_iOcclusionFlags( ) = fBackupOcclusionFlags; // standardblendingrules foi chamado agora restore niggaaaa
acessador->m_pBones = pBoneToWorldOut;
uint8_t computado[ 0x100 ];
std::memset( calculado, 0, 0x100 );
pEntity->BuildTransformations( pStudioHdr, pos, q, parentTransform, boneMask, computado );
acessador->m_pBones = backup_matrix;
pEntity->SetAbsOrigin( vecBackupAbsOrigin );
pEntity->SetAbsAngles( vecBackupAbsAngles );
m_bEnablePVS=falso;
retornar verdadeiro;
}
Animations::AnimationInfo_t* Animations::GetAnimationInfo( Player* pEntity ) {
auto pInfo = Animations::m_ulAnimationInfo.find( pEntity->GetRefEHandle( ) );
if ( pInfo == Animations::m_ulAnimationInfo.end( ) ) {
return nullptr;
}
return &pInfo->segundo;
}
C++:
#pragma once
#include "includes.h"
class Animations {
public:
struct AnimationInfo_t {
AnimationInfo_t( Player* pEntity, std::deque<LagCompensation::LagRecord_t> pRecords )
: m_pEntity( pEntity ), m_pRecords( std::move( pRecords ) ), m_flLastSpawnTime( 0 ) {
}
void UpdateAnimations( LagCompensation::LagRecord_t* pRecord, LagCompensation::LagRecord_t* pPreviousRecord );
Player* m_pEntity;
std::deque<LagCompensation::LagRecord_t> m_pRecords;
LagCompensation::LagRecord_t m_LatestRecord;
LagCompensation::LagRecord_t m_PreviousRecord;
float m_flLastSpawnTime{ };
/* resolver info */
// .first = static
// .second = jitter (low & extended)
std::pair<int, std::pair<int, int>> m_iMissedDueToResolver{ };
int m_iMissedDueToSpread{ };
float m_flPreviousAngle{ };
float m_flBrute{ };
float m_flLatestDelta{ };
float m_flBestSide{ };
float m_flFinalResolveAngle{ };
float m_flOldYaw{ };
float m_flLastPinPulled{ };
int m_iResolverIndex{ };
bool m_bWalking{ };
bool m_bUsingMaxDesync{ };
ang_t m_vecLastReliableAngle;
};
std::unordered_map<ulong_t, AnimationInfo_t> m_ulAnimationInfo;
void UpdatePlayer( Player* pEntity );
bool GenerateMatrix( Player* pEntity, BoneArray* pBoneToWorldOut, int boneMask, float currentTime );
void UpdateLocalAnimations( );
void UpdateFakeAnimations( );
AnimationInfo_t* GetAnimationInfo( Player* pEntity );
LagCompensation::LagRecord_t m_RealData;
LagCompensation::LagRecord_t m_RealShotData;
LagCompensation::LagRecord_t m_FakeData;
LagCompensation::LagRecord_t m_FakeShotData;
bool m_bEnableBones;
bool m_bEnablePVS;
};
extern Animations g_anims;