Health paths work, ammo ones don't.
This commit is contained in:
parent
044a9cc80f
commit
8974006bf1
@ -131,24 +131,24 @@ bool node_good(index_t node) {
|
|||||||
index_t active_node { BAD_NODE };
|
index_t active_node { BAD_NODE };
|
||||||
walkbot_node_s *active() {
|
walkbot_node_s *active() {
|
||||||
if (node_good(active_node))
|
if (node_good(active_node))
|
||||||
return active_node;
|
return &nodes[active_node];
|
||||||
return BAD_NODE;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Last reached node when replaying
|
// Last reached node when replaying
|
||||||
index_t last_node { BAD_NODE };
|
index_t last_node { BAD_NODE };
|
||||||
walkbot_node_s *last() {
|
walkbot_node_s *last() {
|
||||||
if (node_good(last_node))
|
if (node_good(last_node))
|
||||||
return last_node;
|
return &nodes[last_node];
|
||||||
return BAD_NODE;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Node closest to your crosshair when editing
|
// Node closest to your crosshair when editing
|
||||||
index_t closest_node { BAD_NODE };
|
index_t closest_node { BAD_NODE };
|
||||||
walkbot_node_s *closest() {
|
walkbot_node_s *closest() {
|
||||||
if (node_good(closest_node))
|
if (node_good(closest_node))
|
||||||
return closest_node;
|
return &nodes[closest_node];
|
||||||
return BAD_NODE;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Global state
|
// Global state
|
||||||
@ -179,6 +179,15 @@ index_t free_node() {
|
|||||||
using state::nodes;
|
using state::nodes;
|
||||||
using state::node_good;
|
using state::node_good;
|
||||||
|
|
||||||
|
bool HasLowAmmo() {
|
||||||
|
// Yes, I know m_iAmmo is a table, not an int.
|
||||||
|
return CE_INT(LOCAL_E, netvar.m_iAmmo);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool HasLowHealth() {
|
||||||
|
return float(LOCAL_E->m_iHealth) / float(LOCAL_E->m_iMaxHealth) < 0.45;
|
||||||
|
}
|
||||||
|
|
||||||
void DeleteNode(index_t node) {
|
void DeleteNode(index_t node) {
|
||||||
if (not node_good(node))
|
if (not node_good(node))
|
||||||
return;
|
return;
|
||||||
@ -324,11 +333,12 @@ CatVar active_recording(CV_SWITCH, "wb_recording", "0", "Do recording", "Use Bin
|
|||||||
CatVar draw_info(CV_SWITCH, "wb_info", "1", "Walkbot info");
|
CatVar draw_info(CV_SWITCH, "wb_info", "1", "Walkbot info");
|
||||||
CatVar draw_path(CV_SWITCH, "wb_path", "1", "Walkbot path");
|
CatVar draw_path(CV_SWITCH, "wb_path", "1", "Walkbot path");
|
||||||
CatVar draw_nodes(CV_SWITCH, "wb_nodes", "1", "Walkbot nodes");
|
CatVar draw_nodes(CV_SWITCH, "wb_nodes", "1", "Walkbot nodes");
|
||||||
CatVar draw_indices(CV_SWITCH, "wb_indices", "1", "Node indices");
|
CatVar draw_indices(CV_SWITCH, "wb_indices", "0", "Node indices");
|
||||||
CatVar free_move(CV_SWITCH, "wb_freemove", "1", "Allow free movement", "Allow free movement while pressing movement keys");
|
CatVar free_move(CV_SWITCH, "wb_freemove", "1", "Allow free movement", "Allow free movement while pressing movement keys");
|
||||||
CatVar spawn_distance(CV_FLOAT, "wb_node_spawn_distance", "48", "Node spawn distance");
|
CatVar spawn_distance(CV_FLOAT, "wb_node_spawn_distance", "48", "Node spawn distance");
|
||||||
CatVar max_distance(CV_FLOAT, "wb_replay_max_distance", "100", "Max distance to node when replaying");
|
CatVar max_distance(CV_FLOAT, "wb_replay_max_distance", "100", "Max distance to node when replaying");
|
||||||
CatVar reach_distance(CV_FLOAT, "wb_replay_reach_distance", "16", "Distance where bot can be considered 'stepping' on the node");
|
CatVar reach_distance(CV_FLOAT, "wb_replay_reach_distance", "16", "Distance where bot can be considered 'stepping' on the node");
|
||||||
|
CatVar draw_connection_flags(CV_SWITCH, "wb_connection_flags", "1", "Connection flags");
|
||||||
|
|
||||||
CatCommand c_start_recording("wb_record", "Start recording", []() { state::state = WB_RECORDING; });
|
CatCommand c_start_recording("wb_record", "Start recording", []() { state::state = WB_RECORDING; });
|
||||||
CatCommand c_start_editing("wb_edit", "Start editing", []() { state::state = WB_EDITING; });
|
CatCommand c_start_editing("wb_edit", "Start editing", []() { state::state = WB_EDITING; });
|
||||||
@ -464,7 +474,65 @@ CatCommand c_update_jump("wb_jump", "Toggle jump flag", []() {
|
|||||||
else
|
else
|
||||||
n.flags |= NF_JUMP;
|
n.flags |= NF_JUMP;
|
||||||
});
|
});
|
||||||
// Displays all info about closest node
|
// Assuming node is good and conn is in range [0; MAX_CONNECTIONS)
|
||||||
|
std::string DescribeConnection(index_t node, connection conn) {
|
||||||
|
const connection_s& c = nodes[node].connections[conn];
|
||||||
|
std::string extra;
|
||||||
|
bool broken = not node_good(c.node);
|
||||||
|
bool oneway = true;
|
||||||
|
if (not broken) {
|
||||||
|
auto& n = state::nodes[c.node];
|
||||||
|
for (size_t j = 0; j < MAX_CONNECTIONS; j++) {
|
||||||
|
if (n.connections[j].good() and n.connections[j].node == node) {
|
||||||
|
oneway = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (c.flags & CF_LOW_AMMO) {
|
||||||
|
extra += "A";
|
||||||
|
}
|
||||||
|
if (c.flags & CF_LOW_HEALTH) {
|
||||||
|
extra += "H";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::string result = format(node, ' ', (broken ? "-x>" : (oneway ? "-->" : "<->")), ' ', c.node, ' ', extra);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
CatCommand c_toggle_cf_ammo("wb_conn_ammo", "Toggle 'ammo' flag on connection from ACTIVE to CLOSEST node", []() {
|
||||||
|
auto a = state::active();
|
||||||
|
auto b = state::closest();
|
||||||
|
if (not (a and b)) return;
|
||||||
|
for (connection i = 0; i < MAX_CONNECTIONS; i++) {
|
||||||
|
auto& c = a->connections[i];
|
||||||
|
if (c.free())
|
||||||
|
continue;
|
||||||
|
if (c.node != state::closest_node)
|
||||||
|
continue;
|
||||||
|
// Actually flip the flag
|
||||||
|
if (c.flags & CF_LOW_AMMO)
|
||||||
|
c.flags &= ~CF_LOW_AMMO;
|
||||||
|
else
|
||||||
|
c.flags |= CF_LOW_AMMO;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
CatCommand c_toggle_cf_health("wb_conn_health", "Toggle 'health' flag on connection from ACTIVE to CLOSEST node", []() {
|
||||||
|
auto a = state::active();
|
||||||
|
auto b = state::closest();
|
||||||
|
if (not (a and b)) return;
|
||||||
|
for (connection i = 0; i < MAX_CONNECTIONS; i++) {
|
||||||
|
auto& c = a->connections[i];
|
||||||
|
if (c.free())
|
||||||
|
continue;
|
||||||
|
if (c.node != state::closest_node)
|
||||||
|
continue;
|
||||||
|
// Actually flip the flag
|
||||||
|
if (c.flags & CF_LOW_HEALTH)
|
||||||
|
c.flags &= ~CF_LOW_HEALTH;
|
||||||
|
else
|
||||||
|
c.flags |= CF_LOW_HEALTH;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Displays all info about closest node and its connections
|
||||||
CatCommand c_info("wb_dump", "Show info", []() {
|
CatCommand c_info("wb_dump", "Show info", []() {
|
||||||
index_t node = state::closest_node;
|
index_t node = state::closest_node;
|
||||||
if (not node_good(node))
|
if (not node_good(node))
|
||||||
@ -479,26 +547,7 @@ CatCommand c_info("wb_dump", "Show info", []() {
|
|||||||
for (size_t i = 0; i < MAX_CONNECTIONS; i++) {
|
for (size_t i = 0; i < MAX_CONNECTIONS; i++) {
|
||||||
if (n.connections[i].free())
|
if (n.connections[i].free())
|
||||||
continue;
|
continue;
|
||||||
|
logging::Info("[wb] %s", DescribeConnection(node, i).c_str());
|
||||||
if (not node_good(n.connections[i].node)) {
|
|
||||||
logging::Info("[wb] %u -x> X (%u)", node, n.connections[i].node);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto& c = state::nodes[n.connections[i].node];
|
|
||||||
bool found = false;
|
|
||||||
for (size_t j = 0; j < MAX_CONNECTIONS; j++) {
|
|
||||||
if (c.connections[j].good() and c.connections[j].node == node) {
|
|
||||||
if (found) {
|
|
||||||
logging::Info("[wb] %u <-> %u", i, state::closest_node);
|
|
||||||
}
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (not found) {
|
|
||||||
logging::Info("[wb] %u --> %u", node, n.connections[i].node);
|
|
||||||
} else {
|
|
||||||
logging::Info("[wb] %u <-> %u", node, n.connections[i].node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Deletes a whole region of nodes
|
// Deletes a whole region of nodes
|
||||||
@ -599,7 +648,14 @@ index_t SelectNextNode() {
|
|||||||
std::vector<index_t> chance {};
|
std::vector<index_t> chance {};
|
||||||
for (index_t i = 0; i < MAX_CONNECTIONS; i++) {
|
for (index_t i = 0; i < MAX_CONNECTIONS; i++) {
|
||||||
if (n.connections[i].good() and n.connections[i].node != state::last_node and node_good(n.connections[i].node)) {
|
if (n.connections[i].good() and n.connections[i].node != state::last_node and node_good(n.connections[i].node)) {
|
||||||
chance.push_back(n.connections[i].node);
|
if (HasLowAmmo() && (n.connections[i].flags & CF_LOW_AMMO)) {
|
||||||
|
return n.connections[i].node;
|
||||||
|
}
|
||||||
|
if (HasLowHealth() && (n.connections[i].flags & CF_LOW_HEALTH)) {
|
||||||
|
return n.connections[i].node;
|
||||||
|
}
|
||||||
|
if (not (n.connections[i].flags & (CF_LOW_AMMO | CF_LOW_HEALTH)))
|
||||||
|
chance.push_back(n.connections[i].node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (not chance.empty()) {
|
if (not chance.empty()) {
|
||||||
@ -657,8 +713,8 @@ void UpdateWalker() {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (not state::recovery) {
|
if (not state::recovery) {
|
||||||
logging::Info("[wb] FATAL: Next node is bad");
|
logging::Info("[wb] FATAL: Next node is bad");
|
||||||
state::recovery = true;
|
state::recovery = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -675,9 +731,10 @@ void DrawConnection(index_t a, connection_s& b) {
|
|||||||
auto& b_ = state::nodes[b.node];
|
auto& b_ = state::nodes[b.node];
|
||||||
|
|
||||||
Vector center = (a_.xyz() + b_.xyz()) / 2;
|
Vector center = (a_.xyz() + b_.xyz()) / 2;
|
||||||
|
Vector center_connection = (a_.xyz() + center) / 2;
|
||||||
|
|
||||||
Vector wts_a, wts_c;
|
Vector wts_a, wts_c, wts_cc;
|
||||||
if (not (draw::WorldToScreen(a_.xyz(), wts_a) and draw::WorldToScreen(center, wts_c)))
|
if (not (draw::WorldToScreen(a_.xyz(), wts_a) and draw::WorldToScreen(center, wts_c) and draw::WorldToScreen(center_connection, wts_cc)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rgba_t* color = &colors::white;
|
rgba_t* color = &colors::white;
|
||||||
@ -685,6 +742,15 @@ void DrawConnection(index_t a, connection_s& b) {
|
|||||||
else if ((a_.flags & b_.flags) & NF_DUCK) color = &colors::green;
|
else if ((a_.flags & b_.flags) & NF_DUCK) color = &colors::green;
|
||||||
|
|
||||||
drawgl::Line(wts_a.x, wts_a.y, wts_c.x - wts_a.x, wts_c.y - wts_a.y, color->rgba);
|
drawgl::Line(wts_a.x, wts_a.y, wts_c.x - wts_a.x, wts_c.y - wts_a.y, color->rgba);
|
||||||
|
|
||||||
|
if (draw_connection_flags && b.flags != CF_GOOD) {
|
||||||
|
std::string flags;
|
||||||
|
if (b.flags & CF_LOW_AMMO) flags += "A";
|
||||||
|
if (b.flags & CF_LOW_HEALTH) flags += "H";
|
||||||
|
int size_x = 0, size_y = 0;
|
||||||
|
FTGL_StringLength(flags, fonts::ftgl_ESP, &size_x, &size_y);
|
||||||
|
FTGL_Draw(flags, wts_cc.x - size_x / 2, wts_cc.y - size_y - 4, fonts::ftgl_ESP);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draws a node and its connections
|
// Draws a node and its connections
|
||||||
@ -790,6 +856,12 @@ void Draw() {
|
|||||||
if (free_move and free_move_used) {
|
if (free_move and free_move_used) {
|
||||||
AddSideString("Walkbot: FREE MOVEMENT (User override)", colors::green);
|
AddSideString("Walkbot: FREE MOVEMENT (User override)", colors::green);
|
||||||
}
|
}
|
||||||
|
if (HasLowAmmo()) {
|
||||||
|
AddSideString("Walkbot: LOW AMMO", colors::yellow);
|
||||||
|
}
|
||||||
|
if (HasLowHealth()) {
|
||||||
|
AddSideString("Walkbot: LOW HEALTH", colors::red);
|
||||||
|
}
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
if (draw_info) {
|
if (draw_info) {
|
||||||
|
@ -21,6 +21,7 @@ void NetVars::Init() {
|
|||||||
this->iHitboxSet = gNetvars.get_offset("DT_BaseAnimating", "m_nHitboxSet");
|
this->iHitboxSet = gNetvars.get_offset("DT_BaseAnimating", "m_nHitboxSet");
|
||||||
this->vVelocity = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecVelocity[0]");
|
this->vVelocity = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_vecVelocity[0]");
|
||||||
this->movetype = gNetvars.get_offset("DT_BaseEntity", "movetype");
|
this->movetype = gNetvars.get_offset("DT_BaseEntity", "movetype");
|
||||||
|
this->m_iAmmo = gNetvars.get_offset("DT_BasePlayer", "localdata", "m_iAmmo");
|
||||||
this->m_Collision = gNetvars.get_offset("DT_BaseEntity", "m_Collision");
|
this->m_Collision = gNetvars.get_offset("DT_BaseEntity", "m_Collision");
|
||||||
m_flSimulationTime = gNetvars.get_offset("DT_BaseEntity", "m_flSimulationTime");
|
m_flSimulationTime = gNetvars.get_offset("DT_BaseEntity", "m_flSimulationTime");
|
||||||
IF_GAME (IsTF2()) {
|
IF_GAME (IsTF2()) {
|
||||||
|
@ -63,6 +63,7 @@ public:
|
|||||||
offset_t iPipeType;
|
offset_t iPipeType;
|
||||||
offset_t iBuildingHealth;
|
offset_t iBuildingHealth;
|
||||||
offset_t iBuildingMaxHealth;
|
offset_t iBuildingMaxHealth;
|
||||||
|
offset_t m_iAmmo;
|
||||||
offset_t iHitboxSet;
|
offset_t iHitboxSet;
|
||||||
offset_t vVelocity;
|
offset_t vVelocity;
|
||||||
offset_t bGlowEnabled;
|
offset_t bGlowEnabled;
|
||||||
|
Reference in New Issue
Block a user