Merge branch 'experimental' of https://github.com/nullworks/cathook into experimental

This commit is contained in:
LightCat 2018-10-28 16:16:38 +01:00
commit be89c95145
2 changed files with 100 additions and 23 deletions

View File

@ -32,5 +32,7 @@ bool navTo(Vector destination, int priority = 5, bool should_repath = true,
bool prepare(); bool prepare();
// Clear current path // Clear current path
void clearInstructions(); void clearInstructions();
// Check if area is safe from stickies and sentries
bool isSafe(CNavArea *area);
} // namespace nav } // namespace nav

View File

@ -4,6 +4,7 @@
#include "micropather.h" #include "micropather.h"
#include <pwd.h> #include <pwd.h>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
#include <boost/container/flat_set.hpp>
#if ENABLE_VISUALS #if ENABLE_VISUALS
#include <glez/draw.hpp> #include <glez/draw.hpp>
#endif #endif
@ -16,7 +17,6 @@ static settings::Bool enabled{ "misc.pathing", "true" };
static settings::Bool vischecks{ "misc.pathing.pathtime-vischecks", "false" }; static settings::Bool vischecks{ "misc.pathing.pathtime-vischecks", "false" };
static settings::Bool draw{ "misc.pathing.draw", "false" }; static settings::Bool draw{ "misc.pathing.draw", "false" };
static std::vector<Vector> crumbs; static std::vector<Vector> crumbs;
enum ignore_status : uint8_t enum ignore_status : uint8_t
@ -30,7 +30,9 @@ enum ignore_status : uint8_t
// No LOS between areas // No LOS between areas
vischeck_failed, vischeck_failed,
// Failed to actually walk thru connection // Failed to actually walk thru connection
explicit_ignored explicit_ignored,
// Danger like sentry gun or sticky
danger_found
}; };
void ResetPather(); void ResetPather();
@ -125,8 +127,61 @@ class ignoremanager
else else
return vischeck_failed; return vischeck_failed;
} }
static void updateDanger()
{
for (size_t i = 0; i < HIGHEST_ENTITY; i++)
{
CachedEntity *ent = ENTITY(i);
if (CE_BAD(ent))
continue;
if (ent->m_iClassID() == CL_CLASS(CObjectSentrygun))
{
if (!ent->m_bEnemy())
continue;
Vector loc = GetBuildingPosition(ent);
for (auto &i : navfile->m_areas)
{
Vector area = i.m_center;
area.z += 41.5f;
if (loc.DistTo(area) > 1100)
continue;
// Check if sentry can see us
if (!IsVectorVisible(loc, area, true))
continue;
ignoredata &data = ignores[{ &i, nullptr }];
data.status = danger_found;
data.ignoreTimeout.update();
}
}
else if (ent->m_iClassID() ==
CL_CLASS(CTFGrenadePipebombProjectile))
{
if (!ent->m_bEnemy())
continue;
if (CE_INT(ent, netvar.iPipeType) == 1)
continue;
Vector loc = ent->m_vecOrigin();
for (auto &i : navfile->m_areas)
{
Vector area = i.m_center;
if (loc.DistTo(area) > 130)
continue;
area.z += 41.5f;
// Check if sentry can see us
if (!IsVectorVisible(loc, area, true))
continue;
ignoredata &data = ignores[{ &i, nullptr }];
data.status = danger_found;
data.ignoreTimeout.update();
}
}
}
}
static void checkPath() static void checkPath()
{ {
bool perform_repath = false;
// Vischecks
for (size_t i = 0; i < crumbs.size() - 1; i++) for (size_t i = 0; i < crumbs.size() - 1; i++)
{ {
CNavArea *begin = getNavArea(crumbs.at(i)); CNavArea *begin = getNavArea(crumbs.at(i));
@ -140,26 +195,32 @@ class ignoremanager
{ {
data.status = vischeck_failed; data.status = vischeck_failed;
data.ignoreTimeout.update(); data.ignoreTimeout.update();
perform_repath = true;
}
else if (ignores[{ end, nullptr }].status == danger_found)
{
perform_repath = true;
}
}
if (perform_repath)
repath(); repath();
return;
}
}
} }
public: public:
// 0 = Not ignored, 1 = low priority, 2 = ignored // 0 = Not ignored, 1 = low priority, 2 = ignored
static int isIgnored(CNavArea *begin, CNavArea *end) static int isIgnored(CNavArea *begin, CNavArea *end)
{ {
// if (ignores[{ end, nullptr }].status == danger_found)
return 2;
ignore_status &status = ignores[{ begin, end }].status; ignore_status &status = ignores[{ begin, end }].status;
if (status == unknown) if (status == unknown)
status = runIgnoreChecks(begin, end); status = runIgnoreChecks(begin, end);
if (status == const_ignored || status == explicit_ignored) if (status == vischeck_success)
return 2; return 0;
else if (status == vischeck_failed) else if (status == vischeck_failed)
return 1; return 1;
else else
return 0; return 2;
} }
static void addTime(CNavArea *begin, CNavArea *end, Timer &time) static void addTime(CNavArea *begin, CNavArea *end, Timer &time)
{ {
@ -204,20 +265,13 @@ public:
static Timer update{}; static Timer update{};
if (!update.test_and_set(500)) if (!update.test_and_set(500))
return; return;
updateDanger();
if (crumbs.empty()) if (crumbs.empty())
{ {
for (auto &i : ignores) for (auto &i : ignores)
{ {
switch (i.second.status) switch (i.second.status)
{ {
case vischeck_failed:
case vischeck_success:
if (i.second.ignoreTimeout.check(30000))
{
i.second.status = unknown;
i.second.stucktime = 0;
}
break;
case explicit_ignored: case explicit_ignored:
if (i.second.ignoreTimeout.check(60000)) if (i.second.ignoreTimeout.check(60000))
{ {
@ -225,7 +279,20 @@ public:
i.second.stucktime = 0; i.second.stucktime = 0;
} }
break; break;
case unknown:
break;
case danger_found:
if (i.second.ignoreTimeout.check(20000))
i.second.status = unknown;
break;
case vischeck_failed:
case vischeck_success:
default: default:
if (i.second.ignoreTimeout.check(30000))
{
i.second.status = unknown;
i.second.stucktime = 0;
}
break; break;
} }
} }
@ -233,6 +300,10 @@ public:
else else
checkPath(); checkPath();
} }
static bool isSafe(CNavArea *area)
{
return !(ignores[{ area, nullptr }].status == danger_found);
}
ignoremanager() = delete; ignoremanager() = delete;
}; };
std::unordered_map<std::pair<CNavArea *, CNavArea *>, ignoredata, std::unordered_map<std::pair<CNavArea *, CNavArea *>, ignoredata,
@ -349,7 +420,6 @@ CNavArea *findClosestNavSquare(Vector vec)
bool is_local = vec == g_pLocalPlayer->v_Origin; bool is_local = vec == g_pLocalPlayer->v_Origin;
auto &areas = navfile->m_areas; auto &areas = navfile->m_areas;
std::vector<CNavArea *> overlapping; std::vector<CNavArea *> overlapping;
@ -423,7 +493,8 @@ std::vector<Vector> findPath(Vector start, Vector end)
int result = int result =
Map.pather->Solve(static_cast<void *>(local), static_cast<void *>(dest), Map.pather->Solve(static_cast<void *>(local), static_cast<void *>(dest),
&pathNodes, &cost); &pathNodes, &cost);
long long timetaken = std::chrono::duration_cast<std::chrono::nanoseconds>( long long timetaken =
std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::high_resolution_clock::now() - begin_pathing) std::chrono::high_resolution_clock::now() - begin_pathing)
.count(); .count();
logging::Info("Pathing: Pather result: %i. Time taken (NS): %lld", result, logging::Info("Pathing: Pather result: %i. Time taken (NS): %lld", result,
@ -548,8 +619,7 @@ static HookedFunction
}); });
#if ENABLE_VISUALS #if ENABLE_VISUALS
static HookedFunction drawcrumbs(HF_Draw, "navparser", 10, []() static HookedFunction drawcrumbs(HF_Draw, "navparser", 10, []() {
{
if (!enabled || !draw) if (!enabled || !draw)
return; return;
if (!enabled) if (!enabled)
@ -583,6 +653,11 @@ void ResetPather()
Map.pather->Reset(); Map.pather->Reset();
} }
bool isSafe(CNavArea *area)
{
return ignoremanager::isSafe(area);
}
static CatCommand nav_find("nav_find", "Debug nav find", []() { static CatCommand nav_find("nav_find", "Debug nav find", []() {
std::vector<Vector> path = findPath(g_pLocalPlayer->v_Origin, loc); std::vector<Vector> path = findPath(g_pLocalPlayer->v_Origin, loc);
if (path.empty()) if (path.empty())