Navbot rewrite WIP
This commit is contained in:
parent
0e87e66362
commit
33918adb46
@ -8,9 +8,9 @@ namespace task
|
|||||||
{
|
{
|
||||||
enum task : u_int8_t
|
enum task : u_int8_t
|
||||||
{
|
{
|
||||||
sniper_spot = 0,
|
none = 0,
|
||||||
stay_near = 0,
|
sniper_spot,
|
||||||
none
|
stay_near,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
} // namespace hacks::tf2::NavBot
|
} // namespace hacks::tf2::NavBot
|
||||||
|
@ -6,8 +6,8 @@ namespace hacks::tf2::NavBot
|
|||||||
{
|
{
|
||||||
// -Rvars-
|
// -Rvars-
|
||||||
static settings::Bool enabled("navbot.enabled", "false");
|
static settings::Bool enabled("navbot.enabled", "false");
|
||||||
static settings::Bool stay_near("navbot.stay_near", "true");
|
static settings::Bool stay_near("navbot.stay-near", "true");
|
||||||
static settings::Bool heavy_mode("navbot.heavy_mode", "false");
|
static settings::Bool heavy_mode("navbot.other-node", "false");
|
||||||
|
|
||||||
// -Forward declarations-
|
// -Forward declarations-
|
||||||
bool init(bool first_cm);
|
bool init(bool first_cm);
|
||||||
@ -20,18 +20,21 @@ static std::vector<std::pair<CNavArea *, Vector>> sniper_spots;
|
|||||||
static Timer wait_until_path{};
|
static Timer wait_until_path{};
|
||||||
// What is the bot currently doing
|
// What is the bot currently doing
|
||||||
static task::task current_task;
|
static task::task current_task;
|
||||||
constexpr std::pair<float, float> MAX_MIN_DIST_OTHER(1000, 200);
|
constexpr std::pair<float, float> MIN_MAX_DIST_OTHER(200, 1000);
|
||||||
constexpr std::pair<float, float> MAX_MIN_DIST_SNIPER(1000, 200);
|
constexpr std::pair<float, float> MIN_MAX_DIST_SNIPER(1000, 4000);
|
||||||
|
|
||||||
static void CreateMove()
|
static void CreateMove()
|
||||||
{
|
{
|
||||||
if (!init(false))
|
if (!init(false))
|
||||||
return;
|
return;
|
||||||
|
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer())
|
||||||
|
return;
|
||||||
if (!nav::ReadyForCommands)
|
if (!nav::ReadyForCommands)
|
||||||
wait_until_path.update();
|
wait_until_path.update();
|
||||||
else
|
else
|
||||||
current_task = task::none;
|
current_task = task::none;
|
||||||
|
|
||||||
|
// Try to near enemies to increase efficiency
|
||||||
if (stay_near)
|
if (stay_near)
|
||||||
if (stayNear())
|
if (stayNear())
|
||||||
return;
|
return;
|
||||||
@ -52,6 +55,7 @@ bool init(bool first_cm)
|
|||||||
return false;
|
return false;
|
||||||
if (!inited)
|
if (!inited)
|
||||||
{
|
{
|
||||||
|
// Add all sniper spots to vector
|
||||||
for (auto &area : nav::navfile->m_areas)
|
for (auto &area : nav::navfile->m_areas)
|
||||||
{
|
{
|
||||||
for (auto hide : area.m_hidingSpots)
|
for (auto hide : area.m_hidingSpots)
|
||||||
@ -69,7 +73,7 @@ static bool navToSniperSpot()
|
|||||||
if (!nav::ReadyForCommands)
|
if (!nav::ReadyForCommands)
|
||||||
return true;
|
return true;
|
||||||
// Wait arround a bit before pathing again
|
// Wait arround a bit before pathing again
|
||||||
if (wait_until_path.check(2000))
|
if (!wait_until_path.check(2000))
|
||||||
return false;
|
return false;
|
||||||
// Max 10 attempts
|
// Max 10 attempts
|
||||||
for (int attempts = 0; attempts < 10; attempts++)
|
for (int attempts = 0; attempts < 10; attempts++)
|
||||||
@ -91,12 +95,12 @@ static bool navToSniperSpot()
|
|||||||
|
|
||||||
namespace stayNearHelpers
|
namespace stayNearHelpers
|
||||||
{
|
{
|
||||||
static bool isValidNearPosition(Vector vec, Vector target,
|
// Check if the location is close enough/far enough and has a visual to target
|
||||||
float min_distance,
|
static bool isValidNearPosition(Vector vec, Vector target, float min_distance,
|
||||||
float max_distance)
|
float max_distance)
|
||||||
{
|
{
|
||||||
vec.z += 20;
|
vec.z += 20;
|
||||||
target += 20;
|
target.z += 20;
|
||||||
float dist = vec.DistTo(target);
|
float dist = vec.DistTo(target);
|
||||||
if (dist < min_distance || dist > max_distance)
|
if (dist < min_distance || dist > max_distance)
|
||||||
return false;
|
return false;
|
||||||
@ -105,25 +109,31 @@ static bool isValidNearPosition(Vector vec, Vector target,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true if began pathing
|
||||||
static bool stayNearPlayer(CachedEntity *ent, float min_distance,
|
static bool stayNearPlayer(CachedEntity *ent, float min_distance,
|
||||||
float max_distance, Vector &result)
|
float max_distance, CNavArea **result)
|
||||||
{
|
{
|
||||||
|
// Find good near positions
|
||||||
std::vector<CNavArea *> checked_areas;
|
std::vector<CNavArea *> checked_areas;
|
||||||
for (auto &area : nav::navfile->m_areas)
|
for (auto &area : nav::navfile->m_areas)
|
||||||
{
|
{
|
||||||
|
if (!nav::isSafe(&area))
|
||||||
|
continue;
|
||||||
if (isValidNearPosition(area.m_center, ent->m_vecOrigin(), min_distance,
|
if (isValidNearPosition(area.m_center, ent->m_vecOrigin(), min_distance,
|
||||||
max_distance))
|
max_distance))
|
||||||
checked_areas.push_back(&area);
|
checked_areas.push_back(&area);
|
||||||
}
|
}
|
||||||
if (checked_areas.empty())
|
if (checked_areas.empty())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// Try to path up to 10 times to different areas
|
||||||
for (int attempts = 0; attempts < 10; attempts++)
|
for (int attempts = 0; attempts < 10; attempts++)
|
||||||
{
|
{
|
||||||
auto random =
|
auto random =
|
||||||
select_randomly(checked_areas.begin(), checked_areas.end());
|
select_randomly(checked_areas.begin(), checked_areas.end());
|
||||||
if (nav::navTo((*random.base())->m_center, 7, true, false))
|
if (nav::navTo((*random.base())->m_center, 7, true, false))
|
||||||
{
|
{
|
||||||
result = (*random.base())->m_center;
|
*result = *random.base();
|
||||||
current_task = task::stay_near;
|
current_task = task::stay_near;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -131,50 +141,82 @@ static bool stayNearPlayer(CachedEntity *ent, float min_distance,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool stayNearPlayers(float min_distance, float max_distance, CachedEntity *ent, Vector &result)
|
// Loop thru all players and find one we can path to
|
||||||
|
static bool stayNearPlayers(float min_distance, float max_distance,
|
||||||
|
CachedEntity **result_ent, CNavArea **result_area)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
for (int i = 0; i < g_IEngine->GetMaxClients(); i++)
|
||||||
{
|
{
|
||||||
ent = ENTITY(i);
|
CachedEntity *ent = ENTITY(i);
|
||||||
if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy())
|
if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy())
|
||||||
continue;
|
continue;
|
||||||
if (stayNearPlayer(ent, min_distance, max_distance, result))
|
if (stayNearPlayer(ent, min_distance, max_distance, result_area))
|
||||||
|
{
|
||||||
|
*result_ent = ent;
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} // namespace stayNear
|
} // namespace stayNearHelpers
|
||||||
|
|
||||||
|
// Main stay near function
|
||||||
static bool stayNear()
|
static bool stayNear()
|
||||||
{
|
{
|
||||||
static CachedEntity *lastTarget = nullptr;
|
static CachedEntity *lastTarget = nullptr;
|
||||||
static Vector result{};
|
static CNavArea *result = nullptr;
|
||||||
|
|
||||||
|
// What distances do we have to use?
|
||||||
const std::pair<float, float> *minMaxDist{};
|
const std::pair<float, float> *minMaxDist{};
|
||||||
if (heavy_mode)
|
if (heavy_mode)
|
||||||
{
|
{
|
||||||
minMaxDist = &MAX_MIN_DIST_OTHER;
|
minMaxDist = &MIN_MAX_DIST_OTHER;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
minMaxDist = &MAX_MIN_DIST_SNIPER;
|
minMaxDist = &MIN_MAX_DIST_SNIPER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current_task == task::stay_near)
|
if (current_task == task::stay_near)
|
||||||
{
|
{
|
||||||
if (CE_BAD(lastTarget) || !stayNearHelpers::isValidNearPosition(result, lastTarget->m_vecOrigin(), minMaxDist->first, minMaxDist->second))
|
// Do we already have a stay near target? Check if its still good.
|
||||||
|
if (CE_BAD(lastTarget) || !lastTarget->m_bAlivePlayer() ||
|
||||||
|
!lastTarget->m_bEnemy())
|
||||||
{
|
{
|
||||||
current_task = task::none;
|
current_task = task::none;
|
||||||
|
//nav::clearInstructions();
|
||||||
|
}
|
||||||
|
// Check if we still have LOS and are close enough/far enough
|
||||||
|
else if (!stayNearHelpers::isValidNearPosition(
|
||||||
|
result->m_center, lastTarget->m_vecOrigin(),
|
||||||
|
minMaxDist->first, minMaxDist->second))
|
||||||
|
{
|
||||||
|
current_task = task::none;
|
||||||
|
//nav::clearInstructions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Are we doing nothing? Check if our current location can still attack our
|
||||||
|
// last target
|
||||||
|
else if (current_task == task::none && CE_GOOD(lastTarget) &&
|
||||||
|
lastTarget->m_bAlivePlayer() && lastTarget->m_bEnemy())
|
||||||
|
{
|
||||||
|
if (stayNearHelpers::isValidNearPosition(
|
||||||
|
g_pLocalPlayer->v_Origin, lastTarget->m_vecOrigin(),
|
||||||
|
minMaxDist->first, minMaxDist->second))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
if (current_task == task::stay_near)
|
if (current_task == task::stay_near)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else if (wait_until_path.check(1000))
|
||||||
{
|
{
|
||||||
return stayNearHelpers::stayNearPlayers(minMaxDist->first, minMaxDist->second, lastTarget, result);
|
// We're doing nothing? Do something!
|
||||||
|
return stayNearHelpers::stayNearPlayers(
|
||||||
|
minMaxDist->first, minMaxDist->second, &lastTarget, &result);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HookedFunction cm(HookedFunctions_types::HF_CreateMove, "NavBot", 16,
|
static HookedFunction cm(HookedFunctions_types::HF_CreateMove, "NavBot", 16,
|
||||||
|
@ -14,7 +14,7 @@ namespace nav
|
|||||||
|
|
||||||
static settings::Bool enabled{ "misc.pathing", "true" };
|
static settings::Bool enabled{ "misc.pathing", "true" };
|
||||||
// Whether or not to run vischecks at pathtime
|
// Whether or not to run vischecks at pathtime
|
||||||
static settings::Bool vischecks{ "misc.pathing.pathtime-vischecks", "false" };
|
static settings::Bool vischecks{ "misc.pathing.pathtime-vischecks", "true" };
|
||||||
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;
|
||||||
|
Reference in New Issue
Block a user