Guest User

Untitled

a guest
Jan 17th, 2020
119
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include "LagFix.h"
  2. #include "Aimbot.h"
  3. #include "cvars.h"
  4. #include "GameMovement.h"
  5. #include <map>
  6.  
  7. void LagFix::save_entity_updates(CBaseEntity* player, float yaw)
  8. {
  9. int index = player->GetIndex();
  10. float entity_simulation_time = player->m_flSimulationTime();
  11.  
  12. Record current_record;
  13.  
  14. auto& entity_records = update_records[index];
  15. auto& entity_sim = simulated_records[index];
  16.  
  17. drop_old_records(entity_records);
  18. drop_old_records(vars.ticks);
  19.  
  20. if (entity_sim.size() > 8)
  21. entity_sim.pop_back();
  22.  
  23. if (entity_records.size() > 20)
  24. entity_records.pop_back();
  25.  
  26. if (current_record.m_flSimulationTime == entity_simulation_time)
  27. return;
  28.  
  29. current_record.fill_data(player);
  30.  
  31. INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  32.  
  33.  
  34. if (update_record_old[index].m_bFilled && nci)
  35. {
  36. //auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
  37. //auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time() - current_record.m_flSimulationTime));
  38.  
  39. //current_record.choked_ticks = TIME_TO_TICKS(Correct);
  40.  
  41. auto simulation_time_delta = update_record_new[index].m_flSimulationTime - update_record_old[index].m_flSimulationTime;
  42. auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
  43. auto delta_ticks = (clamp(TIME_TO_TICKS(nci->GetAvgLatency(1) + nci->GetAvgLatency(0)) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(update_record_new[index].m_flSimulationTime + get_lerp_time()), 0, 100)) - simulation_tick_delta;
  44.  
  45. current_record.choked_ticks = delta_ticks;
  46. }
  47. else
  48. current_record.choked_ticks = player->GetChokedTicks();
  49.  
  50. current_record.m_iPriority = 20;
  51. current_record.m_iPriority -= current_record.choked_ticks;
  52.  
  53. auto local = g_pTools->GetLocalPlayer();
  54.  
  55. //if (local && local->IsValid2() && vars.RagebotSimulateIfBacktrackFails)
  56. //{
  57. // if (g_pTools->IsVisible(local->GetEyePosition(), player->GetHitboxPosition(0), local, player))
  58. // current_record.m_iPriority += 2; // prioritize visible backtracks over non visible -> shoots visible b4 it shoots through walls
  59. // //technically itll shoot behind a wall if the player is choking 3 less ticks at the time
  60. //}
  61.  
  62. if (local)
  63. current_record.m_bTeammate = local->GetTeam() == player->GetTeam();
  64.  
  65. if (vars.AntiAimAdjustAngles)
  66. current_record.m_angAngles.y = yaw;
  67.  
  68. if (update_record_new[index].m_bFilled)
  69. update_record_old[index] = update_record_new[index];
  70.  
  71. if (current_record.m_bFilled)
  72. update_record_new[index] = current_record;
  73.  
  74. if (current_record.m_bFilled)
  75. {
  76. entity_records.emplace_front(current_record);
  77. entity_sim.emplace_front(current_record);
  78. vars.ticks.emplace_front(current_record);
  79. }
  80. }
  81.  
  82. void LagFix::push_update(CBaseEntity* player, float yaw, int priority, float_t correct_time)
  83. {
  84. int index = player->GetIndex();
  85. Record current_record;
  86.  
  87. auto& entity_records = update_records[index];
  88. auto& entity_sim = simulated_records[index];
  89.  
  90. if (!check_tick_validity(TIME_TO_TICKS(correct_time)))
  91. return;
  92.  
  93. current_record.fill_data(player);
  94.  
  95. INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  96.  
  97.  
  98. if (update_record_old[index].m_bFilled && nci)
  99. {
  100. //auto simulation_time_delta = current_record.m_flSimulationTime - update_record_old[index].m_flSimulationTime;
  101. //auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
  102. //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(current_record.m_flSimulationTime), 0, 16)) - simulation_tick_delta;
  103.  
  104. auto simulation_time_delta = update_record_new[index].m_flSimulationTime - update_record_old[index].m_flSimulationTime;
  105. auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 15);
  106. auto delta_ticks = (clamp(TIME_TO_TICKS(nci->GetAvgLatency(1) + nci->GetAvgLatency(0)) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(update_record_new[index].m_flSimulationTime + get_lerp_time()), 0, 64)) - simulation_tick_delta;
  107.  
  108. current_record.choked_ticks = delta_ticks;
  109. }
  110. else
  111. current_record.choked_ticks = player->GetChokedTicks();
  112.  
  113. current_record.m_iPriority = 64;
  114. current_record.m_iPriority -= current_record.choked_ticks;
  115.  
  116. if (current_record.m_vecVelocity.Length() > 100)
  117. current_record.m_iPriority *= 2;
  118.  
  119. auto local = g_pTools->GetLocalPlayer();
  120.  
  121. if (local && local->IsValid2() && vars.RagebotSimulateIfBacktrackFails)
  122. {
  123. if (g_pTools->IsVisible(local->GetEyePosition(), player->GetHitboxPosition(0), local, player))
  124. current_record.m_iPriority += 10;
  125. }
  126.  
  127. if (local)
  128. current_record.m_bTeammate = local->GetTeam() == player->GetTeam();
  129.  
  130. current_record.m_angAngles.y = yaw;
  131.  
  132. current_record.m_iPriority += priority;
  133. current_record.m_flSimulationTime = correct_time;
  134.  
  135. entity_records.emplace_front(current_record);
  136. vars.ticks.emplace_front(current_record);
  137. }
  138.  
  139. float LagFix::normalize_float(float angle)
  140. {
  141. int tmpAngNorm = (int)round(angle / 360.f);
  142.  
  143. if (angle > 180 || angle < -180)
  144. angle -= tmpAngNorm * 360.f;
  145.  
  146. return angle;
  147. }
  148.  
  149. float LagFix::generate_average_movement_curvature(CBaseEntity* player)
  150. {
  151. int index = player->GetIndex();
  152. Vector p1 = Vector(0, 0, 0);
  153. Vector p2 = Vector(0, 0, 0);
  154. float ret = 0;
  155. int ticks = 0;
  156. auto& entity_records = update_records[index];
  157. for (size_t i = 0; i < entity_records.size(); i++)
  158. {
  159. if (g_pGlobalVarsBase->curtime - entity_records.at(i).m_flSimulationTime > 0.5f && i > 3)
  160. break;
  161. else if (i > 2)
  162. {
  163.  
  164. float angle = 0;
  165. QAngle a1, a2;
  166. g_pTools->VectorAngles(p1, a1);
  167. g_pTools->VectorAngles(p2, a2);
  168. if (a1.y < 0.0f)
  169. a1.y += 360.0f;
  170. if (a2.y < 0.0f)
  171. a2.y += 360.0f;
  172. angle = a2.y - a1.y;
  173. if (angle > 180.0f)
  174. angle -= 360.0f;
  175. ret += angle;
  176. ticks++;
  177. }
  178.  
  179. p1 = p2;
  180. if (i > 0)
  181. p2 = (entity_records.at(i).m_vecOrigin - entity_records.at(i - 1).m_vecOrigin);
  182. p2.z = 0;
  183. p2.NormalizeInPlace();
  184. }
  185.  
  186. ret /= std::fmaxf(1, ticks);
  187.  
  188. return ret;
  189. }
  190.  
  191. float LagFix::entity_average_acceleration(CBaseEntity* player)
  192. {
  193. float vel = player->GetVelocity().Length2D();
  194. int index = player->GetIndex();
  195. float ret = 0;
  196. int ticks = 0;
  197. auto& entity_records = simulated_records[index];
  198.  
  199. for (size_t i = 0; i < entity_records.size(); i++)
  200. if (g_pGlobalVarsBase->curtime - entity_records.at(i).m_flSimulationTime > 0.3f && ticks++ > 1)
  201. break;
  202. else
  203. ret += entity_records.at(i).m_vecVelocity.Length2D() - vel;
  204.  
  205. ret /= std::fmaxf(1, ticks);
  206.  
  207. return ret;
  208. }
  209.  
  210. float LagFix::get_incoming_latency()
  211. {
  212. SDK::INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  213. if (nci)
  214. {
  215. float IncomingLatency = nci->GetAvgLatency(FLOW_INCOMING);
  216. return IncomingLatency;
  217. }
  218. else
  219. {
  220. return 0.0f;
  221. }
  222. }
  223.  
  224. float LagFix::get_outgoing_latency()
  225. {
  226. SDK::INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  227. if (nci)
  228. {
  229. float OutgoingLatency = nci->GetAvgLatency(FLOW_OUTGOING);
  230. return OutgoingLatency;
  231. }
  232. else
  233. {
  234. return 0.0f;
  235. }
  236. }
  237.  
  238. void LagFix::adjust_tick_to_record(int index, CUserCmd *usercmd, Record rec)
  239. {
  240. if (!check_tick_validity(TIME_TO_TICKS(rec.m_flSimulationTime)))
  241. {
  242. usercmd->tick_count = TIME_TO_TICKS(g_pEntityList->GetBaseEntity(index)->m_flSimulationTime() + get_lerp_time());
  243. }
  244. else
  245. {
  246. usercmd->tick_count = TIME_TO_TICKS(rec.m_flSimulationTime + get_lerp_time());
  247. }
  248. }
  249.  
  250. void LagFix::extrapolate_data(SimulationData* data)
  251. {
  252. int index = data->m_pEntity->GetIndex();
  253. //CBaseEntity* pLocal = g_pTools->GetLocalPlayer();
  254. //IEngineTrace::trace_t trace;
  255. //IEngineTrace::CTraceFilter filter;
  256. //IEngineTrace::Ray_t ray;
  257.  
  258. //filter.pSkip = pLocal;
  259. //
  260. //auto sv_gravity = g_pICvar->FindVar("sv_gravity")->GetFloat();
  261. //auto sv_jump_impulse = g_pICvar->FindVar("sv_jump_impulse")->GetFloat(); // math.sqrt(91200) = 301.1
  262. //auto gravity_per_tick = sv_gravity *g_pGlobalVarsBase->interval_per_tick;
  263. //auto predicted_origin = data->origin;
  264. ////bool on_ground = (data->m_pEntity->GetFlags() & FL_ONGROUND);
  265. //
  266. //if (data->on_ground)
  267. // data->velocity.z -= gravity_per_tick;
  268. //
  269. //predicted_origin += data->velocity * g_pGlobalVarsBase->interval_per_tick;
  270. //
  271. //ray.Init(data->origin, predicted_origin, data->maxs, data->mins);
  272. //
  273. //g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
  274. //
  275. //if (trace.fraction == 1.f)
  276. // data->origin = predicted_origin;
  277. //
  278. //ray.Init(data->origin, data->origin - Vector(0.f, 0.f, 2.f), data->maxs, data->mins);
  279. //
  280. //g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
  281. //
  282. //data->on_ground = trace.fraction == 0.f;
  283.  
  284. auto mins = data->m_pEntity->GetCollideable()->OBBMins();
  285. auto maxs = data->m_pEntity->GetCollideable()->OBBMaxs();
  286.  
  287. auto src = data->origin;
  288. auto end = src + (data->velocity * g_pGlobalVarsBase->interval_per_tick);
  289.  
  290. SDK::IEngineTrace::Ray_t ray;
  291. ray.Init(src, end, mins, maxs);
  292.  
  293. SDK::IEngineTrace::trace_t trace;
  294. SDK::IEngineTrace::CTraceFilter filter;
  295. filter.pSkip = (IHandleEntity*)data->m_pEntity;
  296. g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
  297.  
  298. if (trace.fraction != 1.f)
  299. {
  300. for (int i = 0; i < 2; ++i)
  301. {
  302. data->velocity -= trace.plane.normal * data->velocity.Dot(trace.plane.normal);
  303.  
  304. auto dot = data->velocity.Dot(trace.plane.normal);
  305. if (dot < 0.f)
  306. {
  307. data->velocity.x -= dot * trace.plane.normal.x;
  308. data->velocity.y -= dot * trace.plane.normal.y;
  309. data->velocity.z -= dot * trace.plane.normal.z;
  310. }
  311.  
  312. end = trace.endpos + (data->velocity * (g_pGlobalVarsBase->interval_per_tick * (1.f - trace.fraction)));
  313. ray.Init(trace.endpos, end, mins, maxs);
  314. g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
  315.  
  316. if (trace.fraction == 1.f)
  317. break;
  318. }
  319. }
  320.  
  321. data->origin = trace.endpos;
  322. end = trace.endpos;
  323. end.z -= 2.f;
  324.  
  325. ray.Init(data->origin, end, mins, maxs);
  326. g_pEngineTrace->TraceRay(ray, CONTENTS_SOLID, &filter, &trace);
  327.  
  328. data->flags &= ~FL_ONGROUND;
  329.  
  330. if (trace.fraction != 1.f && trace.plane.normal.z > 0.7f)
  331. data->flags |= FL_ONGROUND;
  332. }
  333.  
  334. bool LagFix::do_aimbot_validity_checks_rebuild(CBaseEntity* entity, Vector &aim_point, bool &hitchanced, bool &valid)
  335. {
  336. auto *g_LocalPlayer = g_pTools->GetLocalPlayer();
  337.  
  338.  
  339. matrix3x4_t matrix[128];
  340.  
  341. if (!entity->SetupBones(matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
  342. return false;
  343.  
  344. aim_point = AimbotR->LagFixFindBestPoint(entity, 0, vars.RagebotMinimumDamage, vars.RagebotHitscan, matrix);
  345.  
  346. if (!aim_point.IsValid())
  347. {
  348. valid = false;
  349. return false;
  350. }
  351.  
  352. SDK::Vector aimAngle;
  353. g_pTools->CalcAngle(g_LocalPlayer->GetEyePosition(), aim_point, aimAngle);
  354.  
  355. valid = true;
  356.  
  357. hitchanced = AimbotR->HitChance(aimAngle, entity, vars.RagebotHitchanceValue);
  358.  
  359. return true;
  360. }
  361.  
  362. bool LagFix::do_aimbot_validity_checks(CBaseEntity* entity, Vector &aim_point, Record& entity_records, bool &hitchanced, bool &valid)
  363. {
  364. auto *g_LocalPlayer = g_pTools->GetLocalPlayer();
  365.  
  366. entity->SetBoneMatrix(entity_records.matrix);
  367.  
  368. aim_point = AimbotR->FindBestPoint(entity, 0, vars.RagebotMinimumDamage, vars.RagebotHitscan);
  369.  
  370. if (!aim_point.IsValid())
  371. {
  372. valid = false;
  373. return false;
  374. }
  375.  
  376. SDK::Vector aimAngle;
  377.  
  378. g_pTools->CalcAngle(g_LocalPlayer->GetEyePosition(), aim_point, aimAngle);
  379.  
  380. valid = true;
  381.  
  382. hitchanced = AimbotR->HitChance(aimAngle, entity, vars.RagebotHitchanceValue);
  383.  
  384. return true;
  385. }
  386.  
  387. void LagFix::predict_player(CBaseEntity* entity, Record current_record, Record next_record, Vector &aim_point, bool &hitchanced, bool &validsim)
  388. {
  389. INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  390.  
  391. if (!nci)
  392. return;
  393.  
  394. // Create Simulation Data
  395. SimulationData simulation_data;
  396. simulation_data.m_pEntity = entity;
  397. simulation_data.origin = current_record.m_vecOrigin;
  398. simulation_data.velocity = current_record.m_vecVelocity;
  399. simulation_data.on_ground = current_record.m_nFlags & FL_ONGROUND;
  400. simulation_data.data_complete = true;
  401.  
  402. // Calculate Delta's
  403. auto simulation_time_delta = current_record.m_flSimulationTime - next_record.m_flSimulationTime;
  404. auto simulation_tick_delta = clamp(TIME_TO_TICKS(simulation_time_delta), 1, 16);
  405. //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - TIME_TO_TICKS(current_record.m_flSimulationTime), 0, 16)) - simulation_tick_delta;
  406. auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
  407. auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time() - current_record.m_flSimulationTime));
  408. auto delta_ticks = TIME_TO_TICKS(Correct);
  409.  
  410. // Calculate movement delta
  411. auto current_velocity_angle = RAD2DEG(atan2(current_record.m_vecVelocity.y, current_record.m_vecVelocity.x));
  412. auto next_velocity_angle = RAD2DEG(atan2(next_record.m_vecVelocity.y, next_record.m_vecVelocity.x));
  413. auto velocity_angle_delta = normalize_float(current_velocity_angle - next_velocity_angle);
  414. auto velocity_movement_delta = velocity_angle_delta / simulation_time_delta;
  415. auto average_velocity_acceleration = entity_average_acceleration(entity);
  416. auto speed = current_record.m_vecVelocity.Length2D();
  417.  
  418. if (delta_ticks > 0 && simulation_data.data_complete)
  419. {
  420. for (; delta_ticks >= 0; delta_ticks -= simulation_tick_delta)
  421. {
  422. auto ticks_left = simulation_tick_delta;
  423.  
  424. do
  425. {
  426. current_velocity_angle += average_velocity_acceleration * g_pGlobalVarsBase->interval_per_tick;
  427.  
  428. simulation_data.velocity.x = std::cos(DEG2RAD(current_velocity_angle)) * speed;
  429. simulation_data.velocity.y = std::sin(DEG2RAD(current_velocity_angle)) * speed;
  430.  
  431. bool InAir = !(entity->GetFlags() & FL_ONGROUND);
  432.  
  433. if (!(simulation_data.flags & FL_ONGROUND))
  434. simulation_data.velocity.z -= (g_pGlobalVarsBase->interval_per_tick * g_pICvar->FindVar("sv_gravity")->GetFloat());
  435. else if (InAir)
  436. simulation_data.velocity.z = sqrt(91200.f);
  437.  
  438.  
  439. extrapolate_data(&simulation_data);
  440.  
  441. current_record.m_flSimulationTime += g_pGlobalVarsBase->interval_per_tick;
  442.  
  443. --ticks_left;
  444. } while (ticks_left);
  445. }
  446.  
  447. if (move_entity_to_simulation(&simulation_data))
  448. do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
  449.  
  450. return;
  451. }
  452. }
  453.  
  454. Record LagFix::find_best_record(CBaseEntity* entity)
  455. {
  456. int index = entity->GetIndex();
  457. auto& entity_records = update_records[index];
  458. Record new_record;
  459. Record best_record;
  460. int best_priority = 0;
  461. int best_damage = 0;
  462. backtrack_records.clear();
  463.  
  464. for (auto it : entity_records)
  465. {
  466. if (it.m_flSimulationTime > update_record_old->m_flSimulationTime)
  467. new_record = it;
  468.  
  469. if (check_tick_validity(TIME_TO_TICKS(it.m_flSimulationTime)))
  470. {
  471. backtrack_records.emplace_front(it);
  472.  
  473. float damage = 0;
  474.  
  475. AimbotR->CanWallbang(entity->GetHitboxPosition(0), damage);
  476.  
  477. if (damage > best_damage)
  478. {
  479. best_record = it;
  480. best_damage = damage;
  481. best_priority = it.m_iPriority;
  482.  
  483. if (damage > entity->GetHealth())
  484. return it;
  485. }
  486. }
  487. }
  488.  
  489. //backtrack_records.emplace_front(new_record);
  490.  
  491. //std::sort(backtrack_records.begin(), backtrack_records.end(), [](Record const &a, Record const &b) { return a.m_iPriority > b.m_iPriority; });
  492.  
  493. //backtrack_records.emplace_front(best_record);
  494.  
  495. //return backtrack_records.front();
  496.  
  497. if (best_record.m_bFilled)
  498. return best_record;
  499. else
  500. return new_record;
  501. }
  502.  
  503. void LagFix::handle_entity(CUserCmd *cmd, CBaseEntity* entity, Vector &aim_point, bool &hitchanced, bool &validsim)
  504. {
  505. int index = entity->GetIndex();
  506. auto& entity_records = update_records[index];
  507. bool breaking_lagcomp = false;
  508.  
  509. if (!update_record_new[entity->GetIndex()].m_bFilled || !update_record_old[entity->GetIndex()].m_bFilled)
  510. {
  511. validsim = false;
  512. return;
  513. }
  514.  
  515. if (entity_records.size() > 0)
  516. {
  517. if (update_record_old[index].m_bFilled)
  518. {
  519. breaking_lagcomp = (entity->GetAbsOrigin() - update_record_old[index].m_vecOrigin).Length2DSqr() > 4096;
  520. }
  521. int choked_ticks = update_record_new[index].choked_ticks;
  522.  
  523. if (!breaking_lagcomp)
  524. {
  525. if (vars.lagfixmode[0].selected)
  526. {
  527. Record rec = find_best_record(entity);
  528. if (rec.m_bFilled)
  529. {
  530. if (move_entity_to_record(entity, rec))
  531. {
  532. if (do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim))
  533. adjust_tick_to_record(index, cmd, rec);
  534.  
  535. move_entity_to_current(entity);
  536.  
  537. if (vars.lagfixmode[2].selected)
  538. {
  539. if (!validsim && entity->GetVelocity().Length() > 20)
  540. {
  541. for (; choked_ticks > 0; choked_ticks--)
  542. RebuildGameMovement::Get().FullWalkMove(entity);
  543.  
  544. do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
  545.  
  546. move_entity_to_record(entity, update_record_new[index], true);
  547. }
  548. }
  549. }
  550. }
  551. }
  552. }
  553. else
  554. {
  555. if (vars.lagfixmode[1].selected)
  556. {
  557. for (; choked_ticks > 0; choked_ticks--)
  558. RebuildGameMovement::Get().FullWalkMove(entity);
  559.  
  560. do_aimbot_validity_checks_rebuild(entity, aim_point, hitchanced, validsim);
  561.  
  562. move_entity_to_record(entity, update_record_new[index], true);
  563. }
  564. }
  565. }
  566. }
  567.  
  568. bool LagFix::move_entity_to_simulation(SimulationData* data)
  569. {
  570. int ent_index = data->m_pEntity->GetIndex();
  571.  
  572. CBaseEntity* player = data->m_pEntity;
  573.  
  574. player->InvalidateBoneCache();
  575.  
  576. player->GetCollideable()->OBBMins() = data->mins;
  577. player->GetCollideable()->OBBMaxs() = data->maxs;
  578.  
  579. player->SetAbsOrigin(data->origin);
  580.  
  581. player->UpdateClientSideAnimation();
  582.  
  583. return true;
  584. }
  585.  
  586. bool LagFix::move_entity_to_current(CBaseEntity* player)
  587. {
  588. int ent_index = player->GetIndex();
  589. auto cur = update_record_new[ent_index];
  590.  
  591. player->InvalidateBoneCache();
  592.  
  593. player->GetCollideable()->OBBMins() = cur.m_vecMins;
  594. player->GetCollideable()->OBBMaxs() = cur.m_vecMax;
  595. player->m_flPoseParameter() = cur.m_arrflPoseParameters;
  596.  
  597. int layerCount = player->GetNumAnimOverlays();
  598. for (int i = 0; i < layerCount; ++i)
  599. {
  600. AnimationLayer *currentLayer = player->GetAnimOverlay(i);
  601. currentLayer->m_nOrder = cur.m_LayerRecords[i].m_nOrder;
  602. currentLayer->m_nSequence = cur.m_LayerRecords[i].m_nSequence;
  603. currentLayer->m_flWeight = cur.m_LayerRecords[i].m_flWeight;
  604. currentLayer->m_flCycle = cur.m_LayerRecords[i].m_flCycle;
  605. }
  606.  
  607.  
  608. player->GetEyeAngles().y = cur.m_angAngles.y;
  609. player->SetPoseAngles(cur.m_angAngles.y, cur.m_angAngles.x);
  610. player->SetAbsAngles(QAngle(0, cur.m_angAngles.y, 0));
  611. player->m_angRotation() = QAngle(0, 0, 0);
  612. player->SetAbsOrigin(cur.m_vecOrigin);
  613. *player->GetOriginPtr() = cur.m_vecOrigin;
  614.  
  615. if (!player->SetupBones(cur.matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
  616. return false;
  617.  
  618. return true;
  619. }
  620. static AnimationLayer empty;
  621. void LagFix::fix_anims(ClientFrameStage_t stage)
  622. {
  623. auto g_LocalPlayer = g_pTools->GetLocalPlayer();
  624.  
  625. if (!g_LocalPlayer)
  626. return;
  627.  
  628. static int userId[64];
  629. static AnimationLayer
  630. backupLayersUpdate[64][15],
  631. backupLayersInterp[64][15];
  632.  
  633. for (int i = 1; i < g_pEntityList->GetHighestEntityIndex(); i++)
  634. {
  635. CBaseEntity* player;
  636.  
  637. if (!(player = g_pEntityList->GetBaseEntity(i)))
  638. continue;
  639.  
  640. if (!player ||
  641. player == g_LocalPlayer ||
  642. player->GetTeam() == g_LocalPlayer->GetTeam() ||
  643. !player->IsValid())
  644. continue;
  645.  
  646. player_info_t player_info;
  647.  
  648. if (!g_pIVEngineClient->GetPlayerInfo(i, &player_info))
  649. continue;
  650.  
  651. auto overlays = player->GetAnimOverlays();
  652.  
  653. if (!overlays)
  654. continue;
  655.  
  656. auto numoverlays = player->GetNumAnimOverlays();
  657.  
  658. if (!numoverlays)
  659. continue;
  660.  
  661. switch (stage)
  662. {
  663. case ClientFrameStage_t::FRAME_NET_UPDATE_START: // Copy new, server layers to use when drawing.
  664. userId[i] = player_info.userId;
  665. memcpy(&backupLayersUpdate[i], overlays, (sizeof AnimationLayer) * numoverlays);
  666. break;
  667. case ClientFrameStage_t::FRAME_RENDER_START: // Render started, don't use inaccurately extrapolated layers but save them to not mess shit up either.
  668. if (userId[i] != player_info.userId) continue;
  669. memcpy(&backupLayersInterp[i], overlays, (sizeof AnimationLayer) * numoverlays);
  670. memcpy(overlays, &backupLayersUpdate[i], (sizeof AnimationLayer) * numoverlays);
  671. break;
  672. case ClientFrameStage_t::FRAME_RENDER_END: // Restore layers to keep being accurate when backtracking.
  673. if (userId[i] != player_info.userId) continue;
  674. memcpy(overlays, &backupLayersInterp[i], (sizeof AnimationLayer) * numoverlays);
  675. break;
  676. default:
  677. return;
  678. }
  679. }
  680. }
  681.  
  682. bool LagFix::move_entity_to_record(CBaseEntity* player, Record& entity_records, bool rebuild)
  683. {
  684. int ent_index = player->GetIndex();
  685.  
  686. player->InvalidateBoneCache();
  687.  
  688. player->GetCollideable()->OBBMins() = entity_records.m_vecMins;
  689. player->GetCollideable()->OBBMaxs() = entity_records.m_vecMax;
  690. player->m_flPoseParameter() = entity_records.m_arrflPoseParameters;
  691.  
  692. int layerCount = player->GetNumAnimOverlays();
  693. for (int i = 0; i < layerCount; ++i)
  694. {
  695. AnimationLayer *currentLayer = player->GetAnimOverlay(i);
  696. currentLayer->m_nOrder = entity_records.m_LayerRecords[i].m_nOrder;
  697. currentLayer->m_nSequence = entity_records.m_LayerRecords[i].m_nSequence;
  698. currentLayer->m_flWeight = entity_records.m_LayerRecords[i].m_flWeight;
  699. currentLayer->m_flCycle = entity_records.m_LayerRecords[i].m_flCycle;
  700. }
  701.  
  702.  
  703. player->GetEyeAngles().y = entity_records.m_angAngles.y;
  704. player->SetPoseAngles(entity_records.m_angAngles.y, entity_records.m_angAngles.x);
  705. player->SetAbsAngles(QAngle(0, entity_records.m_angAngles.y, 0));
  706.  
  707. player->SetAbsOrigin(entity_records.m_vecOrigin);
  708. *player->GetOriginPtr() = entity_records.m_vecOrigin;
  709.  
  710. if (rebuild)
  711. if (!player->SetupBones(entity_records.matrix, 128, BONE_USED_BY_HITBOX, g_pIVEngineClient->GetLastTimeStamp()))
  712. return false;
  713.  
  714. return true;
  715. }
  716.  
  717. void LagFix::drop_all_records(std::deque<Record>& records)
  718. {
  719. auto& m_LagRecords = records;
  720. for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
  721. {
  722. m_LagRecords.erase(lag_record);
  723. }
  724. }
  725.  
  726. void LagFix::drop_all_log_records()
  727. {
  728. //for (int i = 0; i < 64; i++)
  729. int i = 0;
  730. while (i != 64)
  731. {
  732. auto& m_LagRecords = update_records[i];
  733. for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
  734. {
  735. m_LagRecords.erase(lag_record);
  736. }
  737. i++;
  738. }
  739. }
  740.  
  741. void LagFix::drop_old_records(std::deque<Record>& records)
  742. {
  743. auto& m_LagRecords = records;
  744. for (auto lag_record = m_LagRecords.begin(); lag_record != m_LagRecords.end(); lag_record++)
  745. {
  746. if (!check_tick_validity(TIME_TO_TICKS(lag_record->m_flSimulationTime)))
  747. {
  748. m_LagRecords.erase(lag_record);
  749. if (!m_LagRecords.empty())
  750. lag_record = m_LagRecords.begin();
  751. else break;
  752. }
  753. }
  754. }
  755.  
  756. bool LagFix::check_tick_validity(int tick)
  757. {
  758. INetChannelInfo *nci = g_pIVEngineClient->GetNetChannelInfo();
  759.  
  760. if (!nci)
  761. return false;
  762.  
  763. //float correct = clamp(nci->GetLatency(FLOW_OUTGOING) + get_lerp_time(), 0.f, 1.f);
  764.  
  765. //float deltaTime = correct - (g_pGlobalVarsBase->curtime - TICKS_TO_TIME(tick));
  766.  
  767. //return fabsf(deltaTime) < 0.2f;
  768.  
  769.  
  770. auto PredictedCmdArrivalTick = g_pGlobalVarsBase->tickcount + TIME_TO_TICKS(nci->GetAvgLatency(FLOW_INCOMING) + nci->GetAvgLatency(FLOW_OUTGOING));
  771. auto Correct = clamp(get_lerp_time() + nci->GetLatency(FLOW_OUTGOING), 0.f, 1.f) - TICKS_TO_TIME(PredictedCmdArrivalTick + TIME_TO_TICKS(get_lerp_time()) - tick);
  772.  
  773. //auto delta_ticks = (clamp(TIME_TO_TICKS(get_incoming_latency() + get_outgoing_latency()) + g_pGlobalVarsBase->tickcount - tick, 0, 20));
  774.  
  775. return fabsf(Correct) < 0.2f;
  776. }
  777. std::map<float *, Entry> m_Map;
  778.  
  779. float mirv_cycle_mod(float value)
  780. {
  781. if (value < 0)
  782. while (value < 0) value += 1.0f;
  783. else
  784. while (1 < value) value -= 1.0f;
  785.  
  786. return value;
  787. }
  788.  
  789. bool check_if_changed(float_t new_cycle, float_t old_cycle, float_t* output)
  790. {
  791. float newNetValue = new_cycle;
  792. float newEngineValue = old_cycle;
  793.  
  794. const std::pair<const std::map<float *, Entry>::iterator, bool> & res = m_Map.insert(std::make_pair(&old_cycle, Entry(newNetValue, newEngineValue, 0)));
  795.  
  796. if (!res.second)
  797. {
  798. if (0.0f != newNetValue)
  799. {
  800. float oldNetValue = res.first->second.oldNet;
  801. res.first->second.oldNet = newNetValue;
  802.  
  803. float oldEngineValue = res.first->second.oldEngine;
  804. res.first->second.oldEngine = newEngineValue;
  805.  
  806. float deltaNet = newNetValue >= oldNetValue ? newNetValue - oldNetValue : newNetValue + 1.0f - oldNetValue;
  807.  
  808. float net = oldNetValue;
  809. float engine = newEngineValue;
  810. float totalError;
  811.  
  812. // I wish I was better at math, the correction values could need some numerical optimization!
  813.  
  814. if (net >= engine)
  815. {
  816. if (0.5f >= net - engine)
  817. totalError = net - engine;
  818. else
  819. totalError = net - 1.0f - engine;
  820. }
  821. else
  822. {
  823. if (0.5f >= net + 1.0f - engine)
  824. totalError = net + 1.0f - engine;
  825. else
  826. totalError = net + 1.0f - 1.0f - engine;
  827. }
  828.  
  829. if (totalError < -0.5f)
  830. {
  831. // actually should never happen, just for readability.
  832. totalError = -0.5f;
  833. }
  834. else
  835. if (0.5f < totalError)
  836. {
  837. // actually should never happen, just for readability.
  838. totalError = 0.5f;
  839. }
  840. res.first->second.oldError = totalError;
  841.  
  842. float targetVal;
  843.  
  844. if (0.3f <= abs(totalError))
  845. {
  846. targetVal = newNetValue; // give up
  847. }
  848. else
  849. {
  850. float targetDelta = deltaNet + totalError;
  851. if (targetDelta < 0) targetDelta = 0;
  852. targetVal = mirv_cycle_mod(newEngineValue + targetDelta);
  853.  
  854. //float targetDelta = 0;
  855. //targetVal = newEngineValue;
  856. }
  857.  
  858. *output = targetVal;
  859.  
  860. return true;
  861. }
  862. }
  863. return false;
  864. }
  865.  
  866. void LagFix::update_player_animations()
  867. {
  868. for (auto i = 0; i < g_pEntityList->GetHighestEntityIndex(); i++)
  869. {
  870. SDK::CBaseEntity* player = nullptr;
  871.  
  872. if (!(player = g_pEntityList->GetBaseEntity(i)))
  873. continue;
  874.  
  875. SDK::player_info_t pTemp;
  876.  
  877. if (!g_pIVEngineClient->GetPlayerInfo(i, &pTemp))
  878. continue;
  879.  
  880. if (player->IsValid2())
  881. continue;
  882.  
  883. //int layerCount = player->GetNumAnimOverlays();
  884. //auto animstate = player->GetAnimState();
  885. int idx = player->GetIndex();
  886.  
  887. auto update_player = [&](CBaseEntity* e) {
  888. // the refhandle is something that changes when the entity is updated
  889. // (entity disconnected and a new player joined at it's index)
  890. player_info_t info;
  891. g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
  892.  
  893. auto handle = info.szSteamID;
  894.  
  895. e->m_bClientSideAnimation() = true;
  896.  
  897. if (e->GetAnimState()->m_flLastClientSideAnimationUpdateTime >= g_pGlobalVarsBase->curtime) {
  898. // decrement update time
  899. e->GetAnimState()->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime - g_pGlobalVarsBase->interval_per_tick;
  900. }
  901.  
  902. // framecount is also a factor
  903. if (e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount >= g_pGlobalVarsBase->framecount) {
  904. // decrement framecount
  905. e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount - 1;
  906. }
  907.  
  908. // force an update on the client-side animation
  909. e->UpdateClientSideAnimation();
  910.  
  911. e->m_bClientSideAnimation() = false;
  912. };
  913.  
  914. update_player(player);
  915. }
  916. }
  917.  
  918. void LagFix::adjust_cycle(ClientFrameStage_t curStage)
  919. {
  920. for (auto i = 0; i < g_pEntityList->GetHighestEntityIndex(); i++)
  921. {
  922. SDK::CBaseEntity* player = nullptr;
  923.  
  924. if (!(player = g_pEntityList->GetBaseEntity(i)))
  925. continue;
  926.  
  927. SDK::player_info_t pTemp;
  928.  
  929. if (!g_pIVEngineClient->GetPlayerInfo(i, &pTemp))
  930. continue;
  931.  
  932. if (player->IsValid2())
  933. continue;
  934.  
  935. //int layerCount = player->GetNumAnimOverlays();
  936. //auto animstate = player->GetAnimState();
  937. int idx = player->GetIndex();
  938.  
  939.  
  940. auto update_player = [&](CBaseEntity* e) {
  941. // the refhandle is something that changes when the entity is updated
  942. // (entity disconnected and a new player joined at it's index)
  943. player_info_t info;
  944. g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
  945.  
  946. auto handle = info.szSteamID;
  947.  
  948. e->m_bClientSideAnimation() = true;
  949.  
  950. if (e->GetAnimState()->m_flLastClientSideAnimationUpdateTime >= g_pGlobalVarsBase->curtime) {
  951. // decrement update time
  952. e->GetAnimState()->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime - g_pGlobalVarsBase->interval_per_tick;
  953. }
  954.  
  955. // framecount is also a factor
  956. if (e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount >= g_pGlobalVarsBase->framecount) {
  957. // decrement framecount
  958. e->GetAnimState()->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount - 1;
  959. }
  960.  
  961. // force an update on the client-side animation
  962. e->UpdateClientSideAnimation();
  963.  
  964. e->m_bClientSideAnimation() = false;
  965. };
  966.  
  967. auto fix_animation = [&](CBaseEntity* e) {
  968. // the refhandle is something that changes when the entity is updated
  969. // (entity disconnected and a new player joined at it's index)
  970. player_info_t info;
  971. g_pIVEngineClient->GetPlayerInfo(e->GetIndex(), &info);
  972.  
  973. auto handle = info.szSteamID;
  974.  
  975. // do the appropriate action in the appropriate stage
  976. switch (curStage) {
  977. // in this case, we've only just received fresh, uninterpolated animation data
  978. case FRAME_NET_UPDATE_START:
  979. {
  980. steamid[idx] = handle;
  981. memcpy(&m_anim_uninterpolated[idx], e->GetAnimOverlays(), sizeof(AnimationLayer) * e->GetNumAnimOverlays());
  982.  
  983. for (int i = 0; i < 24; i++)
  984. m_poses_uninterpolated[i][idx] = player->get_pose_parameter(i);
  985.  
  986. }break;
  987.  
  988. // haven't done much reversing into this, however, i assume that the localplayer has interpolated
  989. // the data, so we swap it with the uninterpolated, fresh data instead
  990. case FRAME_RENDER_START:
  991. {
  992. // the entity changed
  993. if (handle != steamid[idx]) {
  994. return;
  995. }
  996.  
  997. memcpy(&m_anim_interpolated[idx], e->GetAnimOverlays(), sizeof(AnimationLayer) * e->GetNumAnimOverlays());
  998.  
  999. for (int i = 0; i < 24; i++)
  1000. m_poses_interpolated[i][idx] = player->get_pose_parameter(i);
  1001.  
  1002. memcpy(e->GetAnimOverlays(), &m_anim_uninterpolated[idx], sizeof(AnimationLayer) * e->GetNumAnimOverlays());
  1003.  
  1004. for (int i = 0; i < 24; i++)
  1005. player->get_pose_parameter(i) = m_poses_uninterpolated[i][idx];
  1006.  
  1007. }break;
  1008.  
  1009. case FRAME_RENDER_END:
  1010. {
  1011. // the entity changed
  1012. if (handle != steamid[idx]) {
  1013. return;
  1014. }
  1015.  
  1016. memcpy(e->GetAnimOverlays(), &m_anim_interpolated[idx], sizeof(AnimationLayer) * e->GetNumAnimOverlays());
  1017.  
  1018. for (int i = 0; i < 24; i++)
  1019. player->get_pose_parameter(i) = m_poses_interpolated[i][idx];
  1020.  
  1021. }break;
  1022.  
  1023. default: {
  1024. break;
  1025. }break;
  1026. }
  1027. };
  1028.  
  1029. fix_animation(player);
  1030.  
  1031. // backup ------------------------------------------------------------------------------------------------------------------
  1032. //if (curStage == FRAME_NET_UPDATE_START)
  1033. //{
  1034. // for (int i = 0; i < 24; i++)
  1035. // backup_poses[i][idx] = player->get_pose_parameter(i);
  1036.  
  1037. // for (int i = 0; i < 13; i++) {
  1038. // backup_layers[i][idx].m_flCycle = player->GetAnimOverlay(i)->m_flCycle;
  1039. // backup_layers[i][idx].m_flPlaybackRate = player->GetAnimOverlay(i)->m_flPlaybackRate;
  1040. // backup_layers[i][idx].m_flPrevCycle = player->GetAnimOverlay(i)->m_flPrevCycle;
  1041. // backup_layers[i][idx].m_flWeight = player->GetAnimOverlay(i)->m_flWeight;
  1042. // backup_layers[i][idx].m_flWeightDeltaRate = player->GetAnimOverlay(i)->m_flWeightDeltaRate;
  1043. // backup_layers[i][idx].m_nOrder = player->GetAnimOverlay(i)->m_nOrder;
  1044. // backup_layers[i][idx].m_nSequence = player->GetAnimOverlay(i)->m_nSequence;
  1045. // }
  1046. //}
  1047. //// restore -----------------------------------------------------------------------------------------------------------------
  1048. //if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START)
  1049. //{
  1050. // player->SetAbsOrigin(backup_absorigin[idx]);
  1051. // player->SetAbsAngles(backup_absangles[idx]);
  1052. // for (int i = 0; i < 24; i++)
  1053. // player->get_pose_parameter(i) = backup_poses[i][idx];
  1054. // for (int i = 0; i < 13; i++) {
  1055. // player->GetAnimOverlay(i)->m_flCycle = backup_layers[i][idx].m_flCycle;
  1056. // player->GetAnimOverlay(i)->m_flPlaybackRate = backup_layers[i][idx].m_flPlaybackRate;
  1057. // player->GetAnimOverlay(i)->m_flPrevCycle = backup_layers[i][idx].m_flPrevCycle;
  1058. // player->GetAnimOverlay(i)->m_flWeight = backup_layers[i][idx].m_flWeight;
  1059. // player->GetAnimOverlay(i)->m_flWeightDeltaRate = backup_layers[i][idx].m_flWeightDeltaRate;
  1060. // player->GetAnimOverlay(i)->m_nOrder = backup_layers[i][idx].m_nOrder;
  1061. // player->GetAnimOverlay(i)->m_nSequence = backup_layers[i][idx].m_nSequence;
  1062. // }
  1063. //}
  1064. //if (curStage == FRAME_NET_UPDATE_START)
  1065. //{
  1066. // for (int i = 0; i < layerCount; ++i)
  1067. // {
  1068. // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
  1069. // m_nsaved_Order[i][idx] = currentLayer->m_nOrder;
  1070. // m_nsaved_Sequence[i][idx] = currentLayer->m_nSequence;
  1071. // m_flsaved_Weight[i][idx] = currentLayer->m_flWeight;
  1072. // m_flsaved_Cycle[i][idx] = currentLayer->m_flCycle;
  1073. // m_flsaved_PrevCycle[i][idx] = currentLayer->m_flPrevCycle;
  1074. // m_flsaved_PlaybackRate[i][idx] = currentLayer->m_flPlaybackRate;
  1075. // m_flsaved_WeightDeltaRate[i][idx] = currentLayer->m_flWeightDeltaRate;
  1076. // }
  1077. //}
  1078.  
  1079. //if (curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_START || curStage == FRAME_RENDER_END || curStage == FRAME_NET_UPDATE_POSTDATAUPDATE_END)
  1080. //{
  1081. // for (int i = 0; i < layerCount; ++i)
  1082. // {
  1083. // auto new_cycle = m_flsaved_Cycle[i][idx];
  1084. // auto old_cycle = m_flsaved_PrevCycle[i][idx];
  1085. // float_t new_value;
  1086.  
  1087. // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
  1088.  
  1089. // currentLayer->m_nOrder = m_nsaved_Order[i][idx];
  1090. // currentLayer->m_nSequence = m_nsaved_Sequence[i][idx];
  1091. // currentLayer->m_flWeight = m_flsaved_Weight[i][idx];
  1092. // currentLayer->m_flPrevCycle = m_flsaved_PrevCycle[i][idx];
  1093. // currentLayer->m_flPlaybackRate = m_flsaved_PlaybackRate[i][idx];
  1094. // currentLayer->m_flWeightDeltaRate = m_flsaved_WeightDeltaRate[i][idx];
  1095.  
  1096. // //if (check_if_changed(new_cycle, old_cycle, &new_value))
  1097. // // currentLayer->m_flCycle = new_value;
  1098.  
  1099. // currentLayer->m_flCycle = m_flsaved_Cycle[i][idx];
  1100. // }
  1101. //}
  1102.  
  1103.  
  1104. //for (int i = 0; i < layerCount; ++i)
  1105. //{
  1106. // AnimationLayer *currentLayer = player->GetAnimOverlay(i);
  1107. // auto new_cycle = currentLayer->m_flCycle;
  1108. // auto old_cycle = currentLayer->m_flPrevCycle;
  1109. // float_t new_value;
  1110. // //currentLayer->m_nOrder = entity_records.m_LayerRecords[i].m_nOrder;
  1111. // //currentLayer->m_nSequence = entity_records.m_LayerRecords[i].m_nSequence;
  1112. // //currentLayer->m_flWeight = entity_records.m_LayerRecords[i].m_flWeight;
  1113. // //currentLayer->m_flCycle = entity_records.m_LayerRecords[i].m_flCycle;
  1114.  
  1115. // bool broken = 0.0f != new_cycle && (
  1116. // old_cycle > new_cycle && 0.5f > old_cycle - new_cycle
  1117. // || old_cycle < new_cycle && 0.5f < new_cycle - old_cycle
  1118. // );
  1119.  
  1120. // if (check_if_changed(new_cycle, old_cycle, new_value))
  1121. // {
  1122. // currentLayer->m_flCycle = new_value;
  1123. // animstate->m_flLastClientSideAnimationUpdateTime = g_pGlobalVarsBase->curtime;
  1124. // animstate->m_iLastClientSideAnimationUpdateFramecount = g_pGlobalVarsBase->framecount;
  1125. // }
  1126. //}
  1127. }
  1128. }
  1129.  
  1130. float LagFix::get_lerp_time()
  1131. {
  1132. int ud_rate = g_pICvar->FindVar("cl_updaterate")->GetFloat();
  1133. ConVar *min_ud_rate = g_pICvar->FindVar("sv_minupdaterate");
  1134. ConVar *max_ud_rate = g_pICvar->FindVar("sv_maxupdaterate");
  1135.  
  1136. if (min_ud_rate && max_ud_rate)
  1137. ud_rate = max_ud_rate->GetFloat();
  1138.  
  1139. float ratio = g_pICvar->FindVar("cl_interp_ratio")->GetFloat();
  1140.  
  1141. if (ratio == 0)
  1142. ratio = 1.0f;
  1143.  
  1144. float lerp = g_pICvar->FindVar("cl_interp")->GetFloat();
  1145. ConVar *c_min_ratio = g_pICvar->FindVar("sv_client_min_interp_ratio");
  1146. ConVar *c_max_ratio = g_pICvar->FindVar("sv_client_max_interp_ratio");
  1147.  
  1148. if (c_min_ratio && c_max_ratio && c_min_ratio->GetFloat() != 1)
  1149. ratio = clamp(ratio, c_min_ratio->GetFloat(), c_max_ratio->GetFloat());
  1150.  
  1151. return max(lerp, (ratio / ud_rate));
  1152. }
  1153.  
  1154. template<class T, class U>
  1155. T LagFix::clamp(T in, U low, U high)
  1156. {
  1157. if (in <= low)
  1158. return low;
  1159.  
  1160. if (in >= high)
  1161. return high;
  1162.  
  1163. return in;
  1164. }
RAW Paste Data