void c_anims::update_local_animations( CCSGOPlayerAnimState* animstate )
{
bool alloc = !local_data( )->m_anim_state;
bool change = !alloc && local_data( )->m_handle != ctx.m_local->GetRefEHandle( );
bool reset = !alloc && !change && ctx.m_local->spawn_time( ) != local_data( )->m_spawn_time;
if ( change )
csgo.m_mem_alloc->Free( local_data( )->m_anim_state );
if ( reset )
{
ctx.m_local->reset_state( local_data( )->m_anim_state );
local_data( )->m_spawn_time = ctx.m_local->spawn_time( );
}
if ( alloc || change )
{
local_data( )->m_anim_state = (CCSGOPlayerAnimState*)csgo.m_mem_alloc->Alloc(sizeof(CCSGOPlayerAnimState));
if ( local_data( )->m_anim_state )
ctx.m_local->create_state( local_data( )->m_anim_state );
local_data( )->m_handle = ctx.m_local->GetRefEHandle( );
local_data( )->m_spawn_time = ctx.m_local->spawn_time( );
}
if ( !alloc && !change && !reset && local_data( )->m_update_fake )
{
float pose_parameter[ 24 ];
std::memcpy( pose_parameter, ctx.m_local->pose_parameters( ), sizeof( float ) * 24 );
CAnimationLayer layers[ 13 ];
std::memcpy( layers, ctx.m_local->anim_overlay( ), sizeof(CAnimationLayer) * 13);
float backup_frametime = csgo.m_globals( )->frametime;
float backup_curtime = csgo.m_globals( )->curtime;
csgo.m_globals( )->frametime = csgo.m_globals( )->interval_per_tick;
csgo.m_globals( )->curtime = ctx.m_local->simulation_time( );
ctx.m_local->update_state( local_data( )->m_anim_state, local_data( )->m_fake_angle );
local_data( )->m_anim_state->m_hitground_anim = false;
local_data( )->m_anim_state->m_landing_duck_additive_something( ) = 0.0f;
local_data( )->m_anim_state->m_head_height( ) = 1.0f;
ctx.m_local->invalidate_bone_cache( );
ctx.m_local->setup_bones( g_boner.desync_bone_matrix, 128, BONE_USED_BY_ANYTHING, ctx.m_local->simulation_time( ) );
for ( auto& i : g_boner.desync_bone_matrix )
{
i[ 0 ][ 3 ] -= ctx.m_local->abs_origin( ).x;
i[ 1 ][ 3 ] -= ctx.m_local->abs_origin( ).y;
i[ 2 ][ 3 ] -= ctx.m_local->abs_origin( ).z;
}
csgo.m_globals( )->frametime = backup_frametime;
csgo.m_globals( )->curtime = backup_curtime;
std::memcpy( ctx.m_local->pose_parameters( ), pose_parameter, sizeof( float ) * 24 );
std::memcpy( ctx.m_local->anim_overlay( ), layers, sizeof( CAnimationLayer ) * 13 );
}
static CAnimationLayer real_layers[13];
static float real_pose_parameters[24];
if ( local_data( )->m_update_tick != csgo.m_globals( )->tickcount )
{
local_data( )->m_update_tick = csgo.m_globals( )->tickcount;
std::memcpy( real_layers, ctx.m_local->anim_overlay( ), sizeof( CAnimationLayer ) * 13 );
if (local_data( )->m_anim_state)
animstate->m_duck_amount = local_data( )->m_anim_state->m_duck_amount;
animstate->m_update_framecount = 0;
ctx.m_local->update_state( animstate, local_data( )->m_fake_angle );
if ( local_data( )->m_update_real )
{
local_data( )->m_abs_yaw = animstate->m_goal_feet_yaw;
std::memcpy( real_pose_parameters, ctx.m_local->pose_parameters( ), sizeof( float ) * 24 );
}
}
else
animstate->m_update_framecount = csgo.m_globals( )->framecount;
animstate->m_goal_feet_yaw = local_data( )->m_real_angle.y;
ctx.m_local->set_abs_angles( vec3( 0.0f, local_data( )->m_abs_yaw, 0.0f ));
std::memcpy( ctx.m_local->pose_parameters( ), real_pose_parameters, sizeof( float ) * 24 );
std::memcpy( ctx.m_local->anim_overlay( ), real_layers, sizeof( CAnimationLayer ) * 13 );
}
void c_anims::update_local( )
{
if ( !ctx.m_local || !ctx.m_local->alive( ) )
return;
CCSGOPlayerAnimState* animstate = ctx.m_local->anim_state();
if ( !animstate )
return;
local_data( )->m_update_real = false;
local_data( )->m_update_fake = false;
if ( ctx.m_local->simulation_time( ) != local_data( )->m_real_simulation_time || ctx.m_local->simulation_time( ) != local_data( )->m_fake_simulation_time )
{
local_data( )->m_update_real = true;
local_data( )->m_update_fake = true;
local_data( )->m_real_simulation_time = ctx.m_local->simulation_time( );
local_data( )->m_fake_simulation_time = ctx.m_local->simulation_time( );
}
ctx.m_local->anim_overlay( )[ 12 ].m_flWeight = 0.0f;
update_local_animations( animstate );
}