WIP: Pathfinding Nr. 5

This commit is contained in:
TotallyNotElite 2018-08-16 22:10:26 +02:00
parent 0054b64cb3
commit c1797dfdfa
5 changed files with 154 additions and 25 deletions

View File

@ -36,6 +36,7 @@
#endif
#if not LAGBOT_MODE
#include "Walkbot.hpp"
#include "navparser.hpp"
#endif
#include "AutoJoin.hpp"
#if not LAGBOT_MODE

View File

@ -0,0 +1,12 @@
#pragma once
#include "common.hpp"
namespace nav
{
extern bool init;
extern bool pathfinding;
std::vector<Vector> findPath(Vector loc, Vector dest);
bool Prepare();
void CreateMove();
}

View File

@ -269,6 +269,10 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
PROF_SECTION(CM_walkbot);
hacks::shared::walkbot::Move();
}
{
PROF_SECTION(CM_navbot);
nav::CreateMove();
}
// Walkbot can leave game.
if (!g_IEngine->IsInGame())
{

View File

@ -8,6 +8,7 @@
#include <menu/GuiInterface.hpp>
#include "HookedMethods.hpp"
#include "MiscTemporary.hpp"
#include "navparser.hpp"
#if !LAGBOT_MODE
#include "hacks/Backtrack.hpp"
#endif
@ -58,6 +59,7 @@ DEFINE_HOOKED_METHOD(LevelInit, void, void *this_, const char *name)
#endif
hacks::shared::autojoin::resetQueueTimer();
firstcm = true;
nav::init = false;
#if !LAGBOT_MODE
playerlist::Save();
#endif

View File

@ -1,12 +1,16 @@
#include "common.hpp"
#include "micropather.h"
#include "pwd.h"
namespace nav
{
static CNavFile navfile(nullptr);
// Todo: CNavArea* to navfile
static std::vector<CNavArea> areas;
// std::vector<CNavArea> SniperAreas;
bool init = false;
bool pathfinding = true;
static settings::Bool enabled{ "misc.pathing", "true" };
// Todo fix
int FindInVector(int id)
@ -20,6 +24,53 @@ int FindInVector(int id)
struct MAP : public micropather::Graph
{
Vector GetClosestCornerToArea(CNavArea *CornerOf, CNavArea *Target)
{
std::array<Vector, 4> corners;
corners.at(0) = CornerOf->m_nwCorner; // NW
corners.at(1) = CornerOf->m_seCorner; // SE
corners.at(2) = Vector{ CornerOf->m_seCorner.x, CornerOf->m_nwCorner.y,
CornerOf->m_nwCorner.z }; // NE
corners.at(3) = Vector{ CornerOf->m_nwCorner.x, CornerOf->m_seCorner.y,
CornerOf->m_seCorner.z }; // SW
Vector bestVec;
float bestDist = FLT_MAX;
for (int i = 0; i < corners.size(); i++)
{
float dist = corners.at(i).DistTo(Target->m_center);
if (dist < bestDist)
{
bestVec = corners.at(i);
bestDist = dist;
}
}
Vector bestVec2;
float bestDist2 = FLT_MAX;
for (int i = 0; i < corners.size(); i++)
{
if (corners.at(i) == bestVec2)
continue;
float dist = corners.at(i).DistTo(Target->m_center);
if (dist < bestDist2)
{
bestVec2 = corners.at(i);
bestDist2 = dist;
}
}
return (bestVec + bestVec2) / 2;
}
float GetZBetweenAreas(CNavArea *start, CNavArea *end)
{
float z1 = GetClosestCornerToArea(start, end).z;
float z2 = GetClosestCornerToArea(end, start).z;
return z2 - z1;
}
float LeastCostEstimate(void *stateStart, void *stateEnd)
{
CNavArea *start = static_cast<CNavArea *>(stateStart);
@ -33,6 +84,8 @@ struct MAP : public micropather::Graph
auto &neighbours = area->m_connections;
for (auto i : neighbours)
{
if (GetZBetweenAreas(area, i.area) > 40)
continue;
micropather::StateCost cost;
cost.state =
static_cast<void *>(&areas.at(FindInVector(i.area->m_id)));
@ -43,13 +96,11 @@ struct MAP : public micropather::Graph
void PrintStateInfo(void *state)
{
}
MAP()
{
logging::Info("Init Map");
}
virtual ~MAP()
~MAP()
{
}
};
@ -62,7 +113,7 @@ void Init()
lvlname = lvlname.substr(0, dotpos);
std::string lvldir("/home/");
passwd *pwd = getpwuid(getuid());
passwd *pwd = getpwuid(getuid());
lvldir.append(pwd->pw_name);
lvldir.append("/.steam/steam/steamapps/common/Team Fortress 2/tf/");
lvldir.append(lvlname);
@ -79,46 +130,49 @@ void Init()
for (auto i : navfile.m_areas)
areas.push_back(i);
}
pathfinding = true;
}
bool Prepare()
{
if (!enabled)
return false;
if (!init)
{
pathfinding = false;
init = true;
Init();
}
if (!pathfinding)
return false;
return true;
}
int findClosestNavSquare(Vector vec)
{
float bestDist = 999999.0f;
int bestSquare = -1;
for (int i = 0; i < areas.size(); i++)
{
float dist = areas.at(i).m_center.DistTo(vec);
if (dist < bestDist)
{
bestDist = dist;
bestSquare = i;
}
if (areas.at(i).Contains(vec))
return i;
}
return bestSquare;
}
std::vector<Vector> findPath(Vector loc, Vector dest)
{
logging::Info("Starting findPath");
if (areas.empty())
return std::vector<Vector>(0);
logging::Info("Finding closest Squares");
int id_loc = findClosestNavSquare(loc);
int id_dest = findClosestNavSquare(dest);
logging::Info("Initiating path_Nodes");
if (id_loc == -1 || id_dest == -1)
return std::vector<Vector>(0);
micropather::MPVector<void *> pathNodes;
float cost;
logging::Info("Initiating map");
MAP TF2MAP;
logging::Info("Initiating pather");
// Todo: Make MicroPather a member of TF2MAP
micropather::MicroPather pather(&TF2MAP, areas.size(), 8, true);
logging::Info("Solving");
float cost;
int result = pather.Solve(static_cast<void *>(&areas.at(id_loc)),
static_cast<void *>(&areas.at(id_dest)),
&pathNodes, &cost);
logging::Info(format("Result:", result).c_str());
logging::Info("Converting to vector");
logging::Info(format(result).c_str());
std::vector<Vector> path;
for (int i = 0; i < pathNodes.size(); i++)
{
@ -127,13 +181,58 @@ std::vector<Vector> findPath(Vector loc, Vector dest)
return path;
}
static Timer inactivity{};
Timer lastJump{};
static std::vector<Vector> crumbs;
bool NavTo(Vector dest)
{
if (CE_BAD(LOCAL_E))
return false;
if (!Prepare())
return false;
auto path = findPath(g_pLocalPlayer->v_Origin, dest);
if (path.empty())
return false;
crumbs.clear();
crumbs = std::move(path);
inactivity.update();
return true;
}
void CreateMove()
{
if (!enabled)
return;
if (CE_BAD(LOCAL_E))
return;
if (!crumbs.empty() && g_pLocalPlayer->v_Origin.DistTo(crumbs.at(0)) < 40.0f)
{
crumbs.erase(crumbs.begin());
inactivity.update();
}
if (crumbs.empty())
return;
if (inactivity.check(2000) && lastJump.test_and_set(1000))
{
current_user_cmd->buttons |= IN_JUMP;
}
if (inactivity.test_and_set(5000))
{
logging::Info("NavBot inactive for too long. Canceling tasks...");
crumbs.clear();
return;
}
WalkTo(crumbs.at(0));
}
CatCommand navinit("nav_init", "Debug nav init",
[](const CCommand &args) { Init(); });
[](const CCommand &args) { Prepare(); });
Vector loc;
CatCommand navset("nav_set", "Debug nav set",
[](const CCommand &args) { loc = g_pLocalPlayer->v_Origin; });
[](const CCommand &args) { loc = LOCAL_E->m_vecOrigin(); });
CatCommand navfind("nav_find", "Debug nav find", [](const CCommand &args) {
std::vector<Vector> path = findPath(g_pLocalPlayer->v_Origin, loc);
@ -150,4 +249,15 @@ CatCommand navfind("nav_find", "Debug nav find", [](const CCommand &args) {
logging::Info(output.c_str());
});
CatCommand navpath("nav_path", "Debug nav path", [](const CCommand &args) {
if (NavTo(loc))
{
logging::Info("Pathing: Success! Walking to path...");
}
else
{
logging::Info("Pathing: Failed!");
}
});
} // namespace nav