-
Автор темы
- #1
Привет.
В моем ренейме начинают лагать противники, когда включаю бектрек.
Как это пофиксить?
Код:
p.s. сам бектрек работает, но, как понимаете, играть с лагающими парнями не очень приятно.
В моем ренейме начинают лагать противники, когда включаю бектрек.
Как это пофиксить?
Код:
C++:
// backtrack.cpp
#include "backtrack.hpp"
c_backtrack backtrack;
std::deque<stored_records> records[65];
convars cvars;
float c_backtrack::get_lerp_time() noexcept {
auto ratio = std::clamp(cvars.interp_ratio->get_float(), cvars.min_interp_ratio->get_float(), cvars.max_interp_ratio->get_float());
return max(cvars.interp->get_float(), (ratio / ((cvars.max_update_rate) ? cvars.max_update_rate->get_float() : cvars.update_rate->get_float())));
}
int c_backtrack::time_to_ticks(float time) noexcept {
return static_cast<int>((0.5f + static_cast<float>(time) / interfaces::globals->interval_per_tick));
}
bool c_backtrack::valid_tick(float simtime) noexcept {
auto network = interfaces::engine->get_net_channel_info();
if (!network)
return false;
auto delta = std::clamp(network->get_latency(0) + get_lerp_time(), 0.f, cvars.max_unlag->get_float()) - (interfaces::globals->cur_time - simtime);
return std::fabsf(delta) <= 0.2f;
}
void c_backtrack::update() noexcept {
auto local_player = reinterpret_cast<player_t*>(interfaces::entity_list->get_client_entity(interfaces::engine->get_local_player()));
if (!config_system.item.backtrack || !local_player || !local_player->is_alive()) {
if (!records->empty())
records->clear();
return;
}
for (int i = 1; i <= interfaces::globals->max_clients; i++) {
auto entity = reinterpret_cast<player_t*>(interfaces::entity_list->get_client_entity(i));
if (!entity || entity == local_player || entity->dormant() || !entity->is_alive() || !entity->is_enemy()) {
records[i].clear();
continue;
}
if (records[i].size() && (records[i].front().simulation_time == entity->simulation_time()))
continue;
auto var_map = reinterpret_cast<uintptr_t>(entity) + 0x24;
auto vars_count = *reinterpret_cast<int*>(static_cast<uintptr_t>(var_map) + 0x14);
for (int j = 0; j < vars_count; j++)
* reinterpret_cast<uintptr_t*>(*reinterpret_cast<uintptr_t*>(var_map) + j * 0xC) = 0;
stored_records record{ };
record.head = local_player->get_hitbox_position(entity, hitbox_head);
record.simulation_time = entity->simulation_time();
entity->setup_bones(record.matrix, 128, 0x7FF00, interfaces::globals->cur_time);
records[i].push_front(record);
while (records[i].size() > 3 && records[i].size() > static_cast<size_t>(time_to_ticks(static_cast<float>(config_system.item.backtrack_ms) / 1000.f)))
records[i].pop_back();
if (auto invalid = std::find_if(std::cbegin(records[i]), std::cend(records[i]), [](const stored_records & rec) { return !backtrack.valid_tick(rec.simulation_time); }); invalid != std::cend(records[i]))
records[i].erase(invalid, std::cend(records[i]));
}
}
void c_backtrack::run(c_usercmd * cmd) noexcept {
if (!config_system.item.backtrack)
return;
if (!(cmd->buttons & in_attack))
return;
auto local_player = reinterpret_cast<player_t*>(interfaces::entity_list->get_client_entity(interfaces::engine->get_local_player()));
if (!local_player)
return;
auto best_fov{ 255.f };
player_t* best_target{ };
int besst_target_index{ };
vec3_t best_target_head_position{ };
int best_record{ };
for (int i = 1; i <= interfaces::globals->max_clients; i++) {
auto entity = reinterpret_cast<player_t*>(interfaces::entity_list->get_client_entity(i));
if (!entity || entity == local_player || entity->dormant() || !entity->is_alive()
|| !entity->is_enemy())
continue;
auto head_position = entity->get_bone_position(8);
auto angle = math.calculate_angle(local_player->get_eye_pos(), head_position, cmd->viewangles);
auto fov = std::hypotf(angle.x, angle.y);
if (fov < best_fov) {
best_fov = fov;
best_target = entity;
besst_target_index = i;
best_target_head_position = head_position;
}
}
if (best_target) {
if (records[besst_target_index].size() <= 3)
return;
best_fov = 255.f;
for (size_t i = 0; i < records[besst_target_index].size(); i++) {
auto record = &records[besst_target_index][i];
if (!record || !valid_tick(record->simulation_time))
continue;
auto angle = math.calculate_angle(local_player->get_eye_pos(), record->head, cmd->viewangles);
auto fov = std::hypotf(angle.x, angle.y);
if (fov < best_fov) {
best_fov = fov;
best_record = i;
}
}
}
if (best_record) {
auto record = records[besst_target_index][best_record];
cmd->tick_count = time_to_ticks(record.simulation_time);
}
}
C++:
// backtrack.hpp
#pragma once
#include "../../../dependencies/common_includes.hpp"
#include "../../../dependencies/math/math.hpp"
struct stored_records {
vec3_t head;
float simulation_time;
matrix_t matrix[128];
};
struct convars {
convar* update_rate;
convar* max_update_rate;
convar* interp;
convar* interp_ratio;
convar* min_interp_ratio;
convar* max_interp_ratio;
convar* max_unlag;
};
extern std::deque<stored_records> records[65];
extern convars cvars;
class c_backtrack {
public:
void update() noexcept;
void run(c_usercmd*) noexcept;
float get_lerp_time() noexcept;
int time_to_ticks(float time) noexcept;
bool valid_tick(float simtime) noexcept;
static void init() {
records->clear();
cvars.update_rate = interfaces::console->get_convar("cl_updaterate");
cvars.max_update_rate = interfaces::console->get_convar("sv_maxupdaterate");
cvars.interp = interfaces::console->get_convar("cl_interp");
cvars.interp_ratio = interfaces::console->get_convar("cl_interp_ratio");
cvars.min_interp_ratio = interfaces::console->get_convar("sv_client_min_interp_ratio");
cvars.max_interp_ratio = interfaces::console->get_convar("sv_client_max_interp_ratio");
cvars.max_unlag = interfaces::console->get_convar("sv_maxunlag");
}
};
extern c_backtrack backtrack;
p.s. сам бектрек работает, но, как понимаете, играть с лагающими парнями не очень приятно.