Wip wont compile blabla

This commit is contained in:
TotallyNotElite 2018-08-19 17:39:26 +02:00
parent d991a3223b
commit a98d8dcb5b
5 changed files with 183 additions and 50 deletions

View File

@ -3,15 +3,21 @@
#include "common.hpp" #include "common.hpp"
#include "micropather.h" #include "micropather.h"
#include "pwd.h" #include "pwd.h"
#if ENABLE_VISUALS
#include <glez/draw.hpp>
#endif
namespace nav namespace nav
{ {
extern bool init; extern bool init;
extern bool ReadyForCommands; extern bool ReadyForCommands;
extern int priority;
extern std::vector<CNavArea> areas; extern std::vector<CNavArea> areas;
std::vector<Vector> findPath(Vector loc, Vector dest); std::vector<Vector> findPath(Vector loc, Vector dest, int &id_loc, int &id_dest);
bool NavTo(Vector dest, bool navToLocalCenter = true, bool persistent = true, int instructionPriority = 5); bool NavTo(Vector dest, bool navToLocalCenter = true, bool persistent = true, int instructionPriority = 5);
void clearInstructions();
int findClosestNavSquare(Vector vec); int findClosestNavSquare(Vector vec);
bool Prepare(); bool Prepare();
void CreateMove(); void CreateMove();
void Draw();
} // namespace nav } // namespace nav

View File

@ -4,11 +4,13 @@
#pragma once #pragma once
#include <config.h>
#include <string> #include <string>
#include <functional> #include <functional>
#include <glez/color.hpp>
#include <config.h> #if ENABLE_VISUALS
#include <glez/color.hpp>
#endif
/* /*
@ -142,4 +144,4 @@ protected:
#if ENABLE_VISUALS #if ENABLE_VISUALS
#include "Rgba.hpp" #include "Rgba.hpp"
#endif #endif

View File

@ -273,11 +273,11 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
hacks::shared::walkbot::Move(); hacks::shared::walkbot::Move();
} }
{ {
PROF_SECTION(CM_navbot); PROF_SECTION(CM_navparse);
nav::CreateMove(); nav::CreateMove();
} }
{ {
PROF_SECTION(CM_NavParse); PROF_SECTION(CM_navbot);
hacks::tf2::NavBot::CreateMove(); hacks::tf2::NavBot::CreateMove();
} }
// Walkbot can leave game. // Walkbot can leave game.

View File

@ -3,19 +3,45 @@
namespace nav namespace nav
{ {
static CNavFile navfile(nullptr); static CNavFile navfile(nullptr);
// Vector containing areas on map
std::vector<CNavArea> areas; std::vector<CNavArea> areas;
// std::vector<CNavArea> SniperAreas; bool init = false;
bool init = false; static bool pathfinding = true;
bool pathfinding = true; bool ReadyForCommands = false;
bool ReadyForCommands = false; // Vector containing ignored connections
std::vector<std::pair<int, int>> ignoredConnections; //static std::vector<std::pair<size_t, size_t>> ignoredConnections;
static settings::Bool enabled{ "misc.pathing", "true" }; static settings::Bool enabled{ "misc.pathing", "true" };
static settings::Bool draw{ "misc.pathing.draw", "false" };
struct inactivityTracker
{
void ininactivityTracker(){};
~inactivityTracker(){};
// Unordered map for storing inactivity per connection
std::unordered_map<std::pair<int, int>, unsigned int> inactives;
void reset()
{
inactives.clear();
}
void addTime(std::pair<int, int> connection, Timer &timer)
{
if (inactives.find(connection) == inactives.end())
{
inactives[connection] = 0;
}
}
};
// Todo fix // Todo fix
int FindInVector(int id) size_t FindInVector(size_t id)
{ {
for (int i = 0; i < areas.size(); i++) for (size_t i = 0; i < areas.size(); i++)
{ {
if (areas.at(i).m_id == id) if (areas.at(i).m_id == id)
return i; return i;
@ -25,9 +51,10 @@ int FindInVector(int id)
struct MAP : public micropather::Graph struct MAP : public micropather::Graph
{ {
std::unique_ptr<micropather::MicroPather> pather; std::unique_ptr<micropather::MicroPather> pather;
bool IsIgnored(int currState, int connectionID) // Function to check if a connection is ignored
bool IsIgnored(size_t currState, size_t connectionID)
{ {
for (int i = 0; i < ignoredConnections.size(); i++) for (size_t i = 0; i < ignoredConnections.size(); i++)
{ {
if (ignoredConnections.at(i).first == currState && if (ignoredConnections.at(i).first == currState &&
ignoredConnections.at(i).second == connectionID) ignoredConnections.at(i).second == connectionID)
@ -50,7 +77,7 @@ struct MAP : public micropather::Graph
Vector bestVec; Vector bestVec;
float bestDist = FLT_MAX; float bestDist = FLT_MAX;
for (int i = 0; i < corners.size(); i++) for (size_t i = 0; i < corners.size(); i++)
{ {
float dist = corners.at(i).DistTo(Target->m_center); float dist = corners.at(i).DistTo(Target->m_center);
if (dist < bestDist) if (dist < bestDist)
@ -63,7 +90,7 @@ struct MAP : public micropather::Graph
Vector bestVec2; Vector bestVec2;
float bestDist2 = FLT_MAX; float bestDist2 = FLT_MAX;
for (int i = 0; i < corners.size(); i++) for (size_t i = 0; i < corners.size(); i++)
{ {
if (corners.at(i) == bestVec2) if (corners.at(i) == bestVec2)
continue; continue;
@ -84,6 +111,7 @@ struct MAP : public micropather::Graph
return z2 - z1; return z2 - z1;
} }
// Function required by MicroPather for getting an estimated cost
float LeastCostEstimate(void *stateStart, void *stateEnd) float LeastCostEstimate(void *stateStart, void *stateEnd)
{ {
CNavArea *start = static_cast<CNavArea *>(stateStart); CNavArea *start = static_cast<CNavArea *>(stateStart);
@ -91,6 +119,8 @@ struct MAP : public micropather::Graph
float dist = start->m_center.DistTo(end->m_center); float dist = start->m_center.DistTo(end->m_center);
return dist; return dist;
} }
// Function required by MicroPather to retrieve neighbours and their
// associated costs.
void AdjacentCost(void *state, MP_VECTOR<micropather::StateCost> *adjacent) void AdjacentCost(void *state, MP_VECTOR<micropather::StateCost> *adjacent)
{ {
CNavArea *area = static_cast<CNavArea *>(state); CNavArea *area = static_cast<CNavArea *>(state);
@ -110,6 +140,10 @@ struct MAP : public micropather::Graph
} }
void PrintStateInfo(void *state) void PrintStateInfo(void *state)
{ {
CNavArea *area = static_cast<CNavArea *>(state);
logging::Info(format(area->m_center.x, " ", area->m_center.y, " ",
area->m_center.z)
.c_str());
} }
MAP(size_t size) MAP(size_t size)
{ {
@ -122,14 +156,14 @@ struct MAP : public micropather::Graph
} }
}; };
std::unique_ptr<MAP> TF2MAP; static std::unique_ptr<MAP> TF2MAP;
void Init() void Init()
{ {
// TODO: Improve performance // Get NavFile location
std::string lvlname(g_IEngine->GetLevelName()); std::string lvlname(g_IEngine->GetLevelName());
int dotpos = lvlname.find('.'); size_t dotpos = lvlname.find('.');
lvlname = lvlname.substr(0, dotpos); lvlname = lvlname.substr(0, dotpos);
std::string lvldir("/home/"); std::string lvldir("/home/");
passwd *pwd = getpwuid(getuid()); passwd *pwd = getpwuid(getuid());
@ -140,6 +174,7 @@ void Init()
logging::Info(format("Pathing: Nav File location: ", lvldir).c_str()); logging::Info(format("Pathing: Nav File location: ", lvldir).c_str());
areas.clear(); areas.clear();
// Load the NavFile
navfile = CNavFile(lvldir.c_str()); navfile = CNavFile(lvldir.c_str());
if (!navfile.m_isOK) if (!navfile.m_isOK)
logging::Info("Pathing: Invalid Nav File"); logging::Info("Pathing: Invalid Nav File");
@ -149,15 +184,20 @@ void Init()
logging::Info( logging::Info(
format("Pathing: Number of areas to index:", size).c_str()); format("Pathing: Number of areas to index:", size).c_str());
areas.reserve(size); areas.reserve(size);
// Add areas from CNavFile to our Vector
for (auto i : navfile.m_areas) for (auto i : navfile.m_areas)
areas.push_back(i); areas.push_back(i);
// Don't reserve more than 7000 states
if (size > 7000) if (size > 7000)
size = 7000; size = 7000;
// Initiate "Map", contains micropather object
TF2MAP = std::make_unique<MAP>(size); TF2MAP = std::make_unique<MAP>(size);
} }
pathfinding = true; pathfinding = true;
} }
std::string lastmap;
static std::string lastmap;
// Function that decides if pathing is possible, and inits pathing if necessary
bool Prepare() bool Prepare()
{ {
if (!enabled) if (!enabled)
@ -181,24 +221,29 @@ bool Prepare()
return true; return true;
} }
std::vector<int> localAreas(6); // This prevents the bot from gettings completely stuck in some cases
static std::vector<int> findClosestNavSquare_localAreas(6);
// Function for getting closest Area to player, aka "LocalNav"
int findClosestNavSquare(Vector vec) int findClosestNavSquare(Vector vec)
{ {
if (localAreas.size() > 5) if (findClosestNavSquare_localAreas.size() > 5)
localAreas.erase(localAreas.begin()); findClosestNavSquare_localAreas.erase(findClosestNavSquare_localAreas.begin());
std::vector<std::pair<int, CNavArea *>> overlapping; std::vector<std::pair<int, CNavArea *>> overlapping;
for (int i = 0; i < areas.size(); i++) for (size_t i = 0; i < areas.size(); i++)
{ {
// Check if we are within x and y bounds of an area
if (areas.at(i).IsOverlapping(vec)) if (areas.at(i).IsOverlapping(vec))
{ {
if (std::count(localAreas.begin(), localAreas.end(), i) < 2) // Make sure we're not stuck on the same area for too long
if (std::count(findClosestNavSquare_localAreas.begin(), findClosestNavSquare_localAreas.end(), i) < 3)
overlapping.push_back({ i, &areas.at(i) }); overlapping.push_back({ i, &areas.at(i) });
} }
} }
// If multiple candidates for LocalNav have been found, pick the closest
float bestDist = FLT_MAX; float bestDist = FLT_MAX;
int bestSquare = -1; int bestSquare = -1;
for (int i = 0; i < overlapping.size(); i++) for (size_t i = 0; i < overlapping.size(); i++)
{ {
float dist = overlapping.at(i).second->m_center.DistTo(vec); float dist = overlapping.at(i).second->m_center.DistTo(vec);
if (dist < bestDist) if (dist < bestDist)
@ -210,15 +255,16 @@ int findClosestNavSquare(Vector vec)
if (bestSquare != -1) if (bestSquare != -1)
{ {
if (vec == g_pLocalPlayer->v_Origin) if (vec == g_pLocalPlayer->v_Origin)
localAreas.push_back(bestSquare); findClosestNavSquare_localAreas.push_back(bestSquare);
return bestSquare; return bestSquare;
} }
for (int i = 0; i < areas.size(); i++) // If no LocalNav was found, pick the closest available Area
for (size_t i = 0; i < areas.size(); i++)
{ {
float dist = areas.at(i).m_center.DistTo(vec); float dist = areas.at(i).m_center.DistTo(vec);
if (dist < bestDist) if (dist < bestDist)
{ {
if (std::count(localAreas.begin(), localAreas.end(), i) < 2) if (std::count(findClosestNavSquare_localAreas.begin(), findClosestNavSquare_localAreas.end(), i) < 3)
{ {
bestDist = dist; bestDist = dist;
bestSquare = i; bestSquare = i;
@ -226,41 +272,58 @@ int findClosestNavSquare(Vector vec)
} }
} }
if (vec == g_pLocalPlayer->v_Origin) if (vec == g_pLocalPlayer->v_Origin)
localAreas.push_back(bestSquare); findClosestNavSquare_localAreas.push_back(bestSquare);
return bestSquare; return bestSquare;
} }
std::vector<Vector> findPath(Vector loc, Vector dest) std::vector<Vector> findPath(Vector loc, Vector dest, int &id_loc, int &id_dest)
{ {
if (areas.empty()) if (areas.empty())
return std::vector<Vector>(0); return std::vector<Vector>(0);
int id_loc = findClosestNavSquare(loc); // Get areas of Vector loc and dest
int id_dest = findClosestNavSquare(dest); id_loc = findClosestNavSquare(loc);
id_dest = findClosestNavSquare(dest);
if (id_loc == -1 || id_dest == -1) if (id_loc == -1 || id_dest == -1)
return std::vector<Vector>(0); return std::vector<Vector>(0);
float cost; float cost;
micropather::MPVector<void *> pathNodes; micropather::MPVector<void *> pathNodes;
// Find a solution to get to location
int result = TF2MAP->pather->Solve(static_cast<void *>(&areas.at(id_loc)), int result = TF2MAP->pather->Solve(static_cast<void *>(&areas.at(id_loc)),
static_cast<void *>(&areas.at(id_dest)), static_cast<void *>(&areas.at(id_dest)),
&pathNodes, &cost); &pathNodes, &cost);
logging::Info(format(result).c_str()); logging::Info(format(result).c_str());
if (result == 1) // If no result found, return empty Vector
if (result == micropather::MicroPather::NO_SOLUTION)
return std::vector<Vector>(0); return std::vector<Vector>(0);
// Convert (void *) CNavArea * to Vector
std::vector<Vector> path; std::vector<Vector> path;
for (int i = 0; i < pathNodes.size(); i++) for (size_t i = 0; i < pathNodes.size(); i++)
{ {
path.push_back(static_cast<CNavArea *>(pathNodes[i])->m_center); path.push_back(static_cast<CNavArea *>(pathNodes[i])->m_center);
} }
// Add our destination to the std::vector
path.push_back(dest); path.push_back(dest);
return path; return path;
} }
// Timer for measuring inactivity, aka time between not reaching a crumb
static Timer inactivity{}; static Timer inactivity{};
static Timer lastJump{};
static std::vector<Vector> crumbs;
static bool ensureArrival;
int priority = 0;
// Time since our last Jump
static Timer lastJump{};
// std::vector containing our path
static std::vector<Vector> crumbs;
// Bot will keep trying to get to the target even if it fails a few times
static bool ensureArrival;
// Priority value for current instructions, only higher priority can overwrite
// itlocalAreas
int priority = 0;
// This prevents the bot from getting stuck in situations where NavTo is spammed (eg NavBot Ammo/Health), prevents updates to inactivity timer
//static std::vector<int> NavTo_localAreas(6);
// dest = Destination, navToLocalCenter = Should bot travel to local center
// first before resuming pathing activity? (Increases accuracy) persistent =
// ensureArrival above, instructionPriority = priority above
bool NavTo(Vector dest, bool navToLocalCenter, bool persistent, bool NavTo(Vector dest, bool navToLocalCenter, bool persistent,
int instructionPriority) int instructionPriority)
{ {
@ -268,29 +331,45 @@ bool NavTo(Vector dest, bool navToLocalCenter, bool persistent,
return false; return false;
if (!Prepare()) if (!Prepare())
return false; return false;
if (instructionPriority <= priority) // Only allow instructions to overwrite others if their priority is higher
if (instructionPriority < priority)
return false; return false;
auto path = findPath(g_pLocalPlayer->v_Origin, dest); int locNav, tarNav;
auto path = findPath(g_pLocalPlayer->v_Origin, dest, locNav, tarNav);
if (path.empty()) if (path.empty())
return false; return false;
// // Prevent Vector from getting too large
// if (NavTo_localAreas.size() > 5)
// NavTo_localAreas.erase(NavTo_localAreas.begin());
// NavTo_localAreas.push_back(locNav);
// if (std::count(NavTo_localAreas.begin(), NavTo_localAreas.end(), locNav) < 2)
// inactivity.update();
crumbs.clear(); crumbs.clear();
crumbs = std::move(path); crumbs = std::move(path);
if (!navToLocalCenter) if (!navToLocalCenter)
crumbs.erase(crumbs.begin()); crumbs.erase(crumbs.begin());
ensureArrival = persistent; ensureArrival = persistent;
localAreas.clear(); findClosestNavSquare_localAreas.clear();
priority = instructionPriority; priority = instructionPriority;
return true; return true;
} }
void clearInstructions()
{
crumbs.clear();
}
static Vector lastArea = { 0.0f, 0.0f, 0.0f }; static Vector lastArea = { 0.0f, 0.0f, 0.0f };
// Function for ignoring a connection
void ignoreConnection() void ignoreConnection()
{ {
if (crumbs.size() < 1) if (crumbs.size() < 1)
return; return;
CNavArea *currnode = nullptr; CNavArea *currnode = nullptr;
for (int i = 0; i < areas.size(); i++) for (size_t i = 0; i < areas.size(); i++)
{ {
if (areas.at(i).m_center == lastArea) if (areas.at(i).m_center == lastArea)
{ {
@ -302,7 +381,7 @@ void ignoreConnection()
return; return;
CNavArea *nextnode = nullptr; CNavArea *nextnode = nullptr;
for (int i = 0; i < areas.size(); i++) for (size_t i = 0; i < areas.size(); i++)
{ {
if (areas.at(i).m_center == crumbs.at(0)) if (areas.at(i).m_center == crumbs.at(0))
{ {
@ -325,6 +404,7 @@ void ignoreConnection()
} }
static Timer ignoreReset{}; static Timer ignoreReset{};
// Function for removing ignores
void clearIgnores() void clearIgnores()
{ {
if (ignoreReset.test_and_set(180000)) if (ignoreReset.test_and_set(180000))
@ -335,6 +415,7 @@ void clearIgnores()
} }
} }
// Main movement function, gets path from NavTo
void CreateMove() void CreateMove()
{ {
if (!enabled) if (!enabled)
@ -343,10 +424,12 @@ void CreateMove()
return; return;
if (!LOCAL_E->m_bAlivePlayer()) if (!LOCAL_E->m_bAlivePlayer())
{ {
// Clear path if player dead
crumbs.clear(); crumbs.clear();
return; return;
} }
clearIgnores(); clearIgnores();
// Crumbs empty, prepare for next instruction
if (crumbs.empty()) if (crumbs.empty())
{ {
priority = 0; priority = 0;
@ -355,6 +438,7 @@ void CreateMove()
return; return;
} }
ReadyForCommands = false; ReadyForCommands = false;
// Remove old crumbs
if (g_pLocalPlayer->v_Origin.DistTo(Vector{ crumbs.at(0).x, crumbs.at(0).y, if (g_pLocalPlayer->v_Origin.DistTo(Vector{ crumbs.at(0).x, crumbs.at(0).y,
g_pLocalPlayer->v_Origin.z }) < g_pLocalPlayer->v_Origin.z }) <
30.0f) 30.0f)
@ -365,32 +449,68 @@ void CreateMove()
} }
if (crumbs.empty()) if (crumbs.empty())
return; return;
// Detect when jumping is necessary
if (crumbs.at(0).z - g_pLocalPlayer->v_Origin.z > 18 && if (crumbs.at(0).z - g_pLocalPlayer->v_Origin.z > 18 &&
lastJump.test_and_set(200)) lastJump.test_and_set(200))
current_user_cmd->buttons |= IN_JUMP; current_user_cmd->buttons |= IN_JUMP;
// If inactive for too long
if (inactivity.test_and_set(5000)) if (inactivity.test_and_set(5000))
{ {
// Ignore connection
ignoreConnection(); ignoreConnection();
if (ensureArrival) if (ensureArrival)
{ {
logging::Info("Pathing: NavBot inactive for too long. Ignoring " logging::Info("Pathing: NavBot inactive for too long. Ignoring "
"connection and finding another path..."); "connection and finding another path...");
// NavTo(crumbs.back(), true, true); // Find a new path
crumbs = findPath(g_pLocalPlayer->v_Origin, crumbs.back()); int i1, i2;
inactivity.update(); crumbs = findPath(g_pLocalPlayer->v_Origin, crumbs.back(), i1, i2);
} }
else else
{ {
logging::Info( logging::Info(
"Pathing: NavBot inactive for too long. Canceling tasks and " "Pathing: NavBot inactive for too long. Canceling tasks and "
"ignoring connection..."); "ignoring connection...");
// Wait for new instructions
crumbs.clear(); crumbs.clear();
} }
return; return;
} }
// Walk to next crumb
WalkTo(crumbs.at(0)); WalkTo(crumbs.at(0));
} }
void Draw()
{
#if ENABLE_VISUALS
if (!enabled || !draw)
return;
if (!enabled)
return;
if (CE_BAD(LOCAL_E))
return;
if (!LOCAL_E->m_bAlivePlayer())
return;
if (crumbs.size() < 2)
return;
for (size_t i = 0; i < crumbs.size() - 1; i++)
{
Vector wts1, wts2;
if (draw::WorldToScreen(crumbs[i], wts1) &&
draw::WorldToScreen(crumbs[i + 1], wts2))
{
glez::draw::line(wts1.x, wts1.y, wts2.x - wts1.x, wts2.y - wts1.y,
colors::white, 0.1f);
}
}
Vector wts;
if (!draw::WorldToScreen(crumbs[0], wts))
return;
glez::draw::rect(wts.x - 4, wts.y - 4, 8, 8, colors::white);
glez::draw::rect_outline(wts.x - 4, wts.y - 4, 7, 7, colors::white, 1.0f);
#endif
}
CatCommand navinit("nav_init", "Debug nav init", [](const CCommand &args) { CatCommand navinit("nav_init", "Debug nav init", [](const CCommand &args) {
lastmap = ""; lastmap = "";
init = false; init = false;
@ -407,7 +527,8 @@ CatCommand navprint("nav_print", "Debug nav print", [](const CCommand &args) {
}); });
CatCommand navfind("nav_find", "Debug nav find", [](const CCommand &args) { CatCommand navfind("nav_find", "Debug nav find", [](const CCommand &args) {
std::vector<Vector> path = findPath(g_pLocalPlayer->v_Origin, loc); int i1,i2;
std::vector<Vector> path = findPath(g_pLocalPlayer->v_Origin, loc, i1, i2);
if (path.empty()) if (path.empty())
{ {
logging::Info("Pathing: No path found"); logging::Info("Pathing: No path found");

View File

@ -143,6 +143,10 @@ void DrawCheatVisuals()
PROF_SECTION(DRAW_walkbot); PROF_SECTION(DRAW_walkbot);
hacks::shared::walkbot::Draw(); hacks::shared::walkbot::Draw();
} }
{
PROF_SECTION(DRAW_navparse);
nav::Draw();
}
IF_GAME(IsTF()) IF_GAME(IsTF())
{ {
PROF_SECTION(PT_antidisguise); PROF_SECTION(PT_antidisguise);