Advertisement
Guest User

Untitled

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