bot: some fixes to enemy predictions again
This commit is contained in:
parent
1d60f19402
commit
2d088efabe
7 changed files with 37 additions and 14 deletions
|
|
@ -71,7 +71,7 @@ if((CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU"
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -funroll-loops -fomit-frame-pointer -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden)
|
target_compile_options(${PROJECT_NAME} PRIVATE -funroll-loops -fomit-frame-pointer -fno-stack-protector -fvisibility=hidden -fvisibility-inlines-hidden -fno-math-errno)
|
||||||
|
|
||||||
if(NOT WIN32 AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc")
|
if(NOT WIN32 AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64" AND NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "arm" AND NOT CMAKE_SYSTEM_PROCESSOR MATCHES "^ppc")
|
||||||
target_compile_options(${PROJECT_NAME} PRIVATE -fdata-sections -ffunction-sections -fcf-protection=none -fno-plt)
|
target_compile_options(${PROJECT_NAME} PRIVATE -fdata-sections -ffunction-sections -fcf-protection=none -fno-plt)
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit 12d339e8f272db2fe39e4f54c430bbea1f781f7d
|
Subproject commit 70dec065bc40cb7ee1dd2f59117c475747a33ca8
|
||||||
|
|
@ -135,7 +135,7 @@ if cxx == 'clang' or cxx == 'gcc'
|
||||||
# setup optimization flags
|
# setup optimization flags
|
||||||
if build_type == 'release'
|
if build_type == 'release'
|
||||||
cxxflags += [
|
cxxflags += [
|
||||||
'-funroll-loops', '-fomit-frame-pointer', '-fno-stack-protector', '-fvisibility=hidden', '-fvisibility-inlines-hidden'
|
'-funroll-loops', '-fomit-frame-pointer', '-fno-stack-protector', '-fvisibility=hidden', '-fvisibility-inlines-hidden', '-fno-math-errno'
|
||||||
]
|
]
|
||||||
|
|
||||||
if os != 'darwin' and os != 'windows' and cpu != 'aarch64' and cpu != 'arm' and not cpu.startswith('ppc')
|
if os != 'darwin' and os != 'windows' and cpu != 'aarch64' and cpu != 'arm' and not cpu.startswith('ppc')
|
||||||
|
|
|
||||||
|
|
@ -1772,7 +1772,9 @@ void Bot::syncUpdatePredictedIndex () {
|
||||||
planner.find (destIndex, currentNodeIndex, [&] (int index) {
|
planner.find (destIndex, currentNodeIndex, [&] (int index) {
|
||||||
++pathLength;
|
++pathLength;
|
||||||
|
|
||||||
if (vistab.visible (currentNodeIndex, index) && botOrigin.distanceSq (graph[index].origin) < cr::sqrf (2048.0f)) {
|
const float distToBotSq = botOrigin.distanceSq (graph[index].origin);
|
||||||
|
|
||||||
|
if (vistab.visible (currentNodeIndex, index) && distToBotSq > 128.0f && distToBotSq < cr::sqrf (768.0f)) {
|
||||||
bestIndex = index;
|
bestIndex = index;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
@ -3976,6 +3978,14 @@ void Bot::updateHearing () {
|
||||||
m_hearedEnemy = nullptr;
|
m_hearedEnemy = nullptr;
|
||||||
float nearestDistanceSq = kInfiniteDistance;
|
float nearestDistanceSq = kInfiniteDistance;
|
||||||
|
|
||||||
|
// do not hear to other enemies if just tracked old one
|
||||||
|
if (m_timeNextTracking < game.time () && util.isAlive (m_lastEnemy) && m_lastEnemy == m_trackingEdict) {
|
||||||
|
m_hearedEnemy = m_lastEnemy;
|
||||||
|
m_lastEnemyOrigin = m_lastEnemy->v.origin;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// setup potential visibility set from engine
|
// setup potential visibility set from engine
|
||||||
auto set = game.getVisibilitySet (this, false);
|
auto set = game.getVisibilitySet (this, false);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -470,7 +470,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
|
||||||
m_hindrance = nullptr;
|
m_hindrance = nullptr;
|
||||||
float distanceSq = cr::sqrf (512.0f);
|
float distanceSq = cr::sqrf (512.0f);
|
||||||
|
|
||||||
if (isOnLadder () || isInNarrowPlace ()) {
|
if (isOnLadder ()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto ownPrio = bots.getPlayerPriority (ent ());
|
const auto ownPrio = bots.getPlayerPriority (ent ());
|
||||||
|
|
@ -520,7 +520,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
|
||||||
if (game.isNullEntity (m_hindrance)) {
|
if (game.isNullEntity (m_hindrance)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const float interval = m_frameInterval * (pev->velocity.lengthSq2d () > 0.0f ? 7.5f : 2.0f);
|
const float interval = m_frameInterval * (!isDucking () && pev->velocity.lengthSq2d () > 0.0f ? 7.5f : 2.0f);
|
||||||
|
|
||||||
// use our movement angles, try to predict where we should be next frame
|
// use our movement angles, try to predict where we should be next frame
|
||||||
Vector right {}, forward {};
|
Vector right {}, forward {};
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ float Heuristic::gfunctionKills (int team, int currentIndex, int) {
|
||||||
if (current.flags & NodeFlag::Crouch) {
|
if (current.flags & NodeFlag::Crouch) {
|
||||||
cost *= 1.5f;
|
cost *= 1.5f;
|
||||||
}
|
}
|
||||||
return cost + 0.5f;
|
return cost;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Heuristic::gfunctionKillsCTWithHostage (int team, int currentIndex, int parentIndex) -> float {
|
auto Heuristic::gfunctionKillsCTWithHostage (int team, int currentIndex, int parentIndex) -> float {
|
||||||
|
|
@ -265,7 +265,7 @@ AStarResult AStarAlgo::find (int botTeam, int srcIndex, int destIndex, NodeAdder
|
||||||
|
|
||||||
// randomize path on round start now and then
|
// randomize path on round start now and then
|
||||||
if (cv_path_randomize_on_round_start && bots.getRoundStartTime () + 4.0f > game.time ()) {
|
if (cv_path_randomize_on_round_start && bots.getRoundStartTime () + 4.0f > game.time ()) {
|
||||||
rsRandomizer = rg (0.5f, static_cast <float> (botTeam) * 2.0f + 5.0f);
|
rsRandomizer = rg (0.5f, static_cast <float> (botTeam) * 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (!m_routeQue.empty ()) {
|
while (!m_routeQue.empty ()) {
|
||||||
|
|
@ -315,7 +315,7 @@ AStarResult AStarAlgo::find (int botTeam, int srcIndex, int destIndex, NodeAdder
|
||||||
// calculate the F value as F = G + H
|
// calculate the F value as F = G + H
|
||||||
const float g = curRoute->g + m_gcalc (botTeam, child.index, currentIndex) * rsRandomizer;
|
const float g = curRoute->g + m_gcalc (botTeam, child.index, currentIndex) * rsRandomizer;
|
||||||
const float h = m_hcalc (child.index, kInvalidNodeIndex, destIndex);
|
const float h = m_hcalc (child.index, kInvalidNodeIndex, destIndex);
|
||||||
const float f = g + h;
|
const float f = cr::floorf (g + h);
|
||||||
|
|
||||||
if (childRoute->state == RouteState::New || childRoute->f > f) {
|
if (childRoute->state == RouteState::New || childRoute->f > f) {
|
||||||
// put the current child into open list
|
// put the current child into open list
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include <yapb.h>
|
#include <yapb.h>
|
||||||
|
|
||||||
ConVar cv_max_nodes_for_predict ("max_nodes_for_predict", "25", "Maximum number for path length, to predict the enemy.", true, 15.0f, 256.0f);
|
ConVar cv_max_nodes_for_predict ("max_nodes_for_predict", "22", "Maximum number for path length, to predict the enemy.", true, 15.0f, 256.0f);
|
||||||
ConVar cv_whose_your_daddy ("whose_your_daddy", "0", "Enables or disables extra hard difficulty for bots.");
|
ConVar cv_whose_your_daddy ("whose_your_daddy", "0", "Enables or disables extra hard difficulty for bots.");
|
||||||
|
|
||||||
// game console variables
|
// game console variables
|
||||||
|
|
@ -494,7 +494,7 @@ void Bot::setAimDirection () {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto doFailPredict = [this] () -> void {
|
auto doFailPredict = [this] () -> void {
|
||||||
if (m_timeNextTracking > game.time ()) {
|
if (m_timeNextTracking + 0.5f > game.time ()) {
|
||||||
return; // do not fail instantly
|
return; // do not fail instantly
|
||||||
}
|
}
|
||||||
m_aimFlags &= ~AimFlags::PredictPath;
|
m_aimFlags &= ~AimFlags::PredictPath;
|
||||||
|
|
@ -507,18 +507,31 @@ void Bot::setAimDirection () {
|
||||||
auto predictNode = m_lastPredictIndex;
|
auto predictNode = m_lastPredictIndex;
|
||||||
|
|
||||||
auto isPredictedIndexApplicable = [&] () -> bool {
|
auto isPredictedIndexApplicable = [&] () -> bool {
|
||||||
if (!vistab.visible (m_currentNodeIndex, predictNode) || !vistab.visible (m_previousNodes[0], predictNode)) {
|
if (!graph.exists (predictNode) || pathLength >= cv_max_nodes_for_predict.as <int> ()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vistab.visible (m_currentNodeIndex, predictNode)
|
||||||
|
|| !vistab.visible (m_previousNodes[0], predictNode)
|
||||||
|
|| !vistab.visible (predictNode, m_currentNodeIndex)) {
|
||||||
|
|
||||||
predictNode = kInvalidNodeIndex;
|
predictNode = kInvalidNodeIndex;
|
||||||
pathLength = kInfiniteDistanceLong;
|
pathLength = kInfiniteDistanceLong;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return graph.exists (predictNode) && pathLength < cv_max_nodes_for_predict.as <int> ();
|
|
||||||
|
TraceResult result {};
|
||||||
|
game.testLine (getEyesPos (), graph[predictNode].origin + pev->view_ofs, TraceIgnore::None, ent (), &result);
|
||||||
|
|
||||||
|
return result.flFraction >= 0.8f && graph[predictNode].origin.distanceSq (pev->origin) > cr::sqrf (256.0f);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (changePredictedEnemy) {
|
if (changePredictedEnemy) {
|
||||||
if (isPredictedIndexApplicable ()) {
|
if (isPredictedIndexApplicable ()) {
|
||||||
m_lookAtPredict = graph[predictNode].origin;
|
m_lookAtPredict = graph[predictNode].origin;
|
||||||
|
|
||||||
m_timeNextTracking = game.time () + rg (0.5f, 1.0f);
|
m_timeNextTracking = game.time () + 0.75f;
|
||||||
m_trackingEdict = m_lastEnemy;
|
m_trackingEdict = m_lastEnemy;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue