like amiri in my mind
Пользователь
-
Автор темы
- #1
сделал некоторые фиксы, улучшил велосити фикс, ленд фикс, убрана антипаста, жду много :: под постом сделал по фану
animation_system.cpp:
#include "animation_system.h"
#include "..\misc\misc.h"
#include "..\misc\logs.h"
std::deque <adjust_data> player_records[65];
void lagcompensation::fsn(ClientFrameStage_t stage)
{
if (stage != FRAME_NET_UPDATE_END)
return;
if (!g_cfg.ragebot.enable && !g_cfg.legitbot.enabled)
return;
for (auto i = 1; i < m_globals()->m_maxclients; i++) //-V807
{
auto e = static_cast<player_t*>(m_entitylist()->GetClientEntity(i));
//if player local we skip cuz we dont use enemy anymsync for local players
if (e == g_ctx.local())
continue;
//if enemy is out of dormant or view we countinue
if (!valid(i, e))
continue;
//some unusal things)
auto time_delta = abs(TIME_TO_TICKS(e->m_flSimulationTime()) - m_globals()->m_tickcount);
if (time_delta > 1.0f / m_globals()->m_intervalpertick)
continue;
auto update = player_records[i].empty() || e->m_flSimulationTime() != e->m_flOldSimulationTime(); //-V550
//more unusal things)
if (update && !player_records[i].empty())
{
auto server_tick = m_clientstate()->m_iServerTick - i % m_globals()->m_timestamprandomizewindow;
auto current_tick = server_tick - server_tick % m_globals()->m_timestampnetworkingbase;
if (TIME_TO_TICKS(e->m_flOldSimulationTime()) < current_tick && TIME_TO_TICKS(e->m_flSimulationTime()) == current_tick)
{
auto layer = &e->get_animlayers()[11];
auto previous_layer = &player_records[i].front().layers[11];
if (layer->m_flCycle == previous_layer->m_flCycle) //-V550
{
e->m_flSimulationTime() = e->m_flOldSimulationTime();
update = false;
}
}
}
if (update) //-V550
{
//check if player breaks lc so make this record invalid and dont shoot it
if (!player_records[i].empty() && (e->m_vecOrigin() - player_records[i].front().origin).LengthSqr() > 4096.0f)
for (auto& record : player_records[i])
record.invalid = true;
player_records[i].emplace_front(adjust_data());
update_player_animations(e);
while (player_records[i].size() > 32)
player_records[i].pop_back();
}
}
}
bool lagcompensation::valid(int i, player_t* e)
{
if (!g_cfg.ragebot.enable && !g_cfg.legitbot.enabled || !e->valid(false))
{
if (!e->is_alive())
{
is_dormant[i] = false;
player_resolver[i].reset();
g_ctx.globals.fired_shots[i] = 0;
g_ctx.globals.missed_shots[i] = 0;
}
else if (e->IsDormant())
is_dormant[i] = true;
player_records[i].clear();
return false;
}
return true;
}
void lagcompensation::update_player_animations(player_t* e)
{
//get animstate for next manipulating
auto animstate = e->get_animation_state();
//we dont have so dont do anything
if (!animstate)
return;
//create object player_info
player_info_t player_info;
if (!m_engine()->GetPlayerInfo(e->EntIndex(), &player_info))
return;
//get player records
auto records = &player_records[e->EntIndex()]; //-V826
//we dont have? so exit cuz we gotta have at least 1 record
if (records->empty())
return;
//set prev_record for next defining
adjust_data* previous_record = nullptr;
//use prev record for calculating velocity, etc...
if (records->size() >= 2)
previous_record = &records->at(1);
auto record = &records->front();
AnimationLayer animlayers[15]; // use only 13 layers dont care 'bout iam lazy to edit animlayercount func
//also if crash use 13 layers
float pose_parametrs[24]; //for storing pose parameters like(static legs and etc)
memcpy(pose_parametrs, &e->m_flPoseParameter(), 24 * sizeof(float));
memcpy(animlayers, e->get_animlayers(), e->animlayer_count() * sizeof(AnimationLayer));
memcpy(record->layers, animlayers, e->animlayer_count() * sizeof(AnimationLayer));
auto backup_lower_body_yaw_target = e->m_flLowerBodyYawTarget();
auto backup_duck_amount = e->m_flDuckAmount();
auto backup_flags = e->m_fFlags();
auto backup_eflags = e->m_iEFlags();
//sets vars to restore them after anim update
auto backup_curtime = m_globals()->m_curtime; //-V807
auto backup_realtime = m_globals()->m_realtime;
auto backup_frametime = m_globals()->m_frametime;
auto backup_framecount = m_globals()->m_framecount;
auto backup_tickcount = m_globals()->m_tickcount;
auto backup_absolute_frametime = m_globals()->m_absoluteframetime;
auto backup_interpolation_amount = m_globals()->m_interpolation_amount;
//sets updating anims every tick
m_globals()->m_curtime = e->m_flSimulationTime();
m_globals()->m_frametime = m_globals()->m_intervalpertick;
//if records.size > 2 we can predict nex origin of player like i did it next below this
if (previous_record)
{
//velo calculating
auto velocity = e->m_vecVelocity();
auto was_in_air = e->m_fFlags() & FL_ONGROUND && previous_record->flags & FL_ONGROUND;
auto time_difference = e->m_flSimulationTime() - previous_record->simulation_time;
auto origin_delta = e->m_vecOrigin() - previous_record->origin;
auto animation_speed = 0.0f;
if (!origin_delta.IsZero() && TIME_TO_TICKS(time_difference) > 0)
{
//new velo calc formula (origin_delta / time diff) like V = S(delta) / T(delta) School math formule also u can find in gamemovement
e->m_vecVelocity() = origin_delta * (1.0f / time_difference);
//u can also calculate it by 6 layer
if (e->m_fFlags() & FL_ONGROUND && animlayers[11].m_flWeight > 0.0f && animlayers[11].m_flWeight < 1.0f && animlayers[11].m_flCycle > previous_record->layers[11].m_flCycle)
{
auto weapon = e->m_hActiveWeapon().Get();
if (weapon)
{
auto max_speed = 260.0f;
auto weapon_info = e->m_hActiveWeapon().Get()->get_csweapon_info();
if (weapon_info)
max_speed = e->m_bIsScoped() ? weapon_info->flMaxPlayerSpeedAlt : weapon_info->flMaxPlayerSpeed;
auto modifier = 0.35f * (1.0f - animlayers[11].m_flWeight);
if (modifier > 0.0f && modifier < 1.0f)
animation_speed = max_speed * (modifier + 0.55f);
}
}
if (animation_speed > 0.0f)
{
animation_speed /= e->m_vecVelocity().Length2D();
e->m_vecVelocity().x *= animation_speed;
e->m_vecVelocity().y *= animation_speed;
}
auto is_jumping = !(record->flags & FL_ONGROUND && previous_record->flags & FL_ONGROUND);
//jump fix
//creds : JRE.codes
if (is_jumping) {
if (record->flags & FL_ONGROUND && !m_cvar()->FindVar(crypt_str("sv_enablebunnyhopping"))->GetInt()) {
// 260 x 1.1 = 286 units/s.
float max = e->GetMaxPlayerSpeed() * 1.1f;
// get current velocity.
float speed = e->m_vecVelocity().Length();
// reset velocity to 286 units/s.
if (max > 0.f && speed > max)
e->m_vecVelocity() *= (max / speed);
}
// assume the player is bunnyhopping here so set the upwards impulse.
e->m_vecVelocity().z = m_cvar()->FindVar(crypt_str("sv_jump_impulse"))->GetFloat();
}
else if (!(record->flags & FL_ONGROUND)) {
//if we landing we use z fix
// apply one tick of gravity.
e->m_vecVelocity().z -= m_cvar()->FindVar(crypt_str("sv_gravity"))->GetFloat() * m_globals()->m_intervalpertick;
}
else {
e->m_vecVelocity().z = 0.0f;
}
}
}
//skip calc velo
e->m_iEFlags() &= ~0x1000;
//use universal velo calc
if (e->m_fFlags() & FL_ONGROUND && e->m_vecVelocity().Length() > 0.0f && animlayers[6].m_flWeight <= 0.0f)
e->m_vecVelocity().Zero();
//change AbsVelocity
e->m_vecAbsVelocity() = e->m_vecVelocity();
//notify game that we changed velocity u can also not use e->flags skip calc velo and use it but idc lets use it together)
e->invalidate_physics_recursive(4);
//upd clientside anims like game does it
e->m_bClientSideAnimation() = true;
if (is_dormant[e->EntIndex()])
{
is_dormant[e->EntIndex()] = false;
if (e->m_fFlags() & FL_ONGROUND)
{
animstate->m_bOnGround = true;
animstate->m_bInHitGroundAnimation = false;
}
animstate->time_since_in_air() = 0.0f;
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y);
}
auto updated_animations = false;
c_baseplayeranimationstate state;
memcpy(&state, animstate, sizeof(c_baseplayeranimationstate));
auto ticks_chocked = 1; // sets tick choked value to 1 then we'll change it if necessary
if (previous_record)
{
memcpy(e->get_animlayers(), previous_record->layers, e->animlayer_count() * sizeof(AnimationLayer));
memcpy(&e->m_flPoseParameter(), pose_parametrs, 24 * sizeof(float));
auto simulation_ticks = TIME_TO_TICKS(e->m_flSimulationTime() - previous_record->simulation_time);
if (simulation_ticks > 0 && simulation_ticks <= 17) //max player chocking value is 17
ticks_chocked = simulation_ticks;
if (ticks_chocked > 1)
{
auto land_time = 0.0f;
auto land_in_cycle = false;
auto is_landed = false;
auto on_ground = false;
if (animlayers[4].m_flCycle < 0.5f && (!(e->m_fFlags() & FL_ONGROUND) || !(previous_record->flags & FL_ONGROUND)))
{
//proper land time fix creds : Enrage
// old part(not proper)
// land_time = e->m_flSimulationTime() - animlayers[4].m_flPlaybackRate * animlayers[4].m_flCycle;
//new part
land_time = e->m_flSimulationTime() - animlayers[4].m_flCycle / animlayers[4].m_flPlaybackRate;
land_in_cycle = land_time >= previous_record->simulation_time;
}
auto duck_amount_per_tick = (e->m_flDuckAmount() - previous_record->duck_amount) / ticks_chocked;
for (auto i = 0; i < ticks_chocked; i++) //iterate choked ticks
{
auto simulated_time = previous_record->simulation_time + TICKS_TO_TIME(i);
//duck amount interpolating based on prev record
if (duck_amount_per_tick) //-V550
e->m_flDuckAmount() = previous_record->duck_amount + duck_amount_per_tick * (float)i;
on_ground = e->m_fFlags() & FL_ONGROUND;
if (land_in_cycle && !is_landed)
{
if (land_time <= simulated_time)
{
is_landed = true;
on_ground = true;
//we can set these vars like this cuz we're on ground for better future calculation
animlayers[4].m_flCycle = 0.f;
animlayers[4].m_flWeight = 0.f;
}
else
on_ground = previous_record->flags & FL_ONGROUND;
}
//land fix creds lw4
auto v490 = e->sequence_activity(record->layers[5].m_nSequence);
if (record->layers[5].m_nSequence == previous_record->layers[5].m_nSequence && (previous_record->layers[5].m_flWeight != 0.0f || record->layers[5].m_flWeight == 0.0f)
|| !(v490 == ACT_CSGO_LAND_LIGHT || v490 == ACT_CSGO_LAND_HEAVY)) {
if ((record->flags & 1) != 0 && (previous_record->flags & FL_ONGROUND) == 0)
e->m_fFlags() &= ~FL_ONGROUND;
}
else
e->m_fFlags() |= FL_ONGROUND;
auto simulated_ticks = TIME_TO_TICKS(simulated_time);
//restoring globalvars like game does it
m_globals()->m_realtime = simulated_time;
m_globals()->m_curtime = simulated_time;
m_globals()->m_framecount = simulated_ticks;
m_globals()->m_tickcount = simulated_ticks;
m_globals()->m_absoluteframetime = m_globals()->m_intervalpertick;
m_globals()->m_interpolation_amount = 0.0f;
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
//restoring globalvars after updating anims
m_globals()->m_realtime = backup_realtime;
m_globals()->m_curtime = backup_curtime;
m_globals()->m_framecount = backup_framecount;
m_globals()->m_tickcount = backup_tickcount;
m_globals()->m_absoluteframetime = backup_absolute_frametime;
m_globals()->m_interpolation_amount = backup_interpolation_amount;
updated_animations = true;
}
}
}
if (!updated_animations)
{
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
}
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
//setting up bones matrices
auto setup_matrix = [&](player_t* e, AnimationLayer* layers, const int& matrix) -> void
{
//notify game that animation changed (FLAG==8) (FLAG==ANIMATION_CHANGED)
e->invalidate_physics_recursive(8);
AnimationLayer backup_layers[15]; // we only have 13 layers
//store layers for next backup
memcpy(backup_layers, e->get_animlayers(), e->animlayer_count() * sizeof(AnimationLayer));
//copying layers to player
memcpy(e->get_animlayers(), layers, e->animlayer_count() * sizeof(AnimationLayer));
switch (matrix)
{
case MAIN:
e->setup_bones_rebuild(record->matrixes_data.main, MAXSTUDIOBONES, BONE_USED_BY_ANYTHING, m_globals()->m_curtime);
break;
case NONE:
e->setup_bones_rebuild(record->matrixes_data.zero, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, m_globals()->m_curtime);
break;
case FIRST:
e->setup_bones_rebuild(record->matrixes_data.first, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, m_globals()->m_curtime);
break;
case SECOND:
e->setup_bones_rebuild(record->matrixes_data.second, MAXSTUDIOBONES, BONE_USED_BY_HITBOX, m_globals()->m_curtime);
break;
}
memcpy(e->get_animlayers(), backup_layers, e->animlayer_count() * sizeof(AnimationLayer));
};
if (g_ctx.local()->is_alive() && e->m_iTeamNum() != g_ctx.local()->m_iTeamNum() && !g_cfg.legitbot.enabled)
{
//animstate setting, matrices setup , etc...
animstate->m_flGoalFeetYaw = previous_goal_feet_yaw[e->EntIndex()]; //-V807
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
previous_goal_feet_yaw[e->EntIndex()] = animstate->m_flGoalFeetYaw;
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y); //-V807
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, NONE);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 60.0f);
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, FIRST);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 60.0f);
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, SECOND);
memcpy(animstate, &state, sizeof(c_baseplayeranimationstate));
memcpy(&e->m_flPoseParameter(), pose_parametrs, 24 * sizeof(float));
player_resolver[e->EntIndex()].initialize(e, record, previous_goal_feet_yaw[e->EntIndex()], e->m_angEyeAngles().x);
player_resolver[e->EntIndex()].resolve_yaw();
//resolver related stuff
if (g_cfg.player_list.low_delta[e->EntIndex()])
{
switch (record->side)
{
case RESOLVER_FIRST:
record->side = RESOLVER_LOW_FIRST;
break;
case RESOLVER_SECOND:
record->side = RESOLVER_LOW_SECOND;
break;
case RESOLVER_LOW_FIRST:
record->side = RESOLVER_FIRST;
break;
case RESOLVER_LOW_SECOND:
record->side = RESOLVER_SECOND;
break;
}
}
switch (record->side)
{
case RESOLVER_ORIGINAL:
animstate->m_flGoalFeetYaw = previous_goal_feet_yaw[e->EntIndex()];
break;
case RESOLVER_ZERO:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y);
break;
case RESOLVER_FIRST:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 60.0f);
break;
case RESOLVER_SECOND:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 60.0f);
break;
case RESOLVER_LOW_FIRST:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y + 30.0f);
break;
case RESOLVER_LOW_SECOND:
animstate->m_flGoalFeetYaw = math::normalize_yaw(e->m_angEyeAngles().y - 30.0f);
break;
}
e->m_angEyeAngles().x = player_resolver[e->EntIndex()].resolve_pitch();
}
g_ctx.globals.updating_animation = true;
e->update_clientside_animation();
g_ctx.globals.updating_animation = false;
setup_matrix(e, animlayers, MAIN);
memcpy(e->m_CachedBoneData().Base(), record->matrixes_data.main, e->m_CachedBoneData().Count() * sizeof(matrix3x4_t));
//reseting vars as i said
m_globals()->m_curtime = backup_curtime;
m_globals()->m_framecount = backup_framecount;
e->m_flLowerBodyYawTarget() = backup_lower_body_yaw_target;
e->m_flDuckAmount() = backup_duck_amount;
e->m_fFlags() = backup_flags;
e->m_iEFlags() = backup_eflags;
memcpy(e->get_animlayers(), animlayers, e->animlayer_count() * sizeof(AnimationLayer));
record->store_data(e, false);
//if(exploit use) record is invalid
if (e->m_flSimulationTime() < e->m_flOldSimulationTime())
record->invalid = true;
}
Последнее редактирование: