WIP: Pathfinding Nr. 5
This commit is contained in:
parent
0054b64cb3
commit
c1797dfdfa
@ -36,6 +36,7 @@
|
||||
#endif
|
||||
#if not LAGBOT_MODE
|
||||
#include "Walkbot.hpp"
|
||||
#include "navparser.hpp"
|
||||
#endif
|
||||
#include "AutoJoin.hpp"
|
||||
#if not LAGBOT_MODE
|
||||
|
@ -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();
|
||||
}
|
@ -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())
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user