nav: re-added goal history for a round in some reworked way

This commit is contained in:
jeefo 2023-06-14 19:36:46 +03:00
commit 04503963c5
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
6 changed files with 42 additions and 15 deletions

View file

@ -819,7 +819,7 @@ private:
int findDefendNode (const Vector &origin);
int findBestGoal ();
int findBestGoalWhenBombAction ();
int findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive);
int findGoalPost (int tactic, IntArray *defensive, IntArray *offensive);
int bestPrimaryCarried ();
int bestSecondaryCarried ();
int bestGrenadeCarried ();
@ -1122,12 +1122,13 @@ public:
Vector m_position {}; // position to move to in move to position task
Vector m_doubleJumpOrigin {}; // origin of double jump
Vector m_lastEnemyOrigin {}; // vector to last enemy origin
ChatCollection m_sayTextBuffer {}; // holds the index & the actual message of the last unprocessed text message of a player
BurstMode m_weaponBurstMode {}; // bot using burst mode? (famas/glock18, but also silencer mode)
Personality m_personality {}; // bots type
Array <BotTask> m_tasks {};
Deque <int32_t> m_msgQueue {};
Array <int32_t> m_goalHist {};
public:
Bot (edict_t *bot, int difficulty, int personality, int team, int skin);

View file

@ -211,7 +211,7 @@ int BotControl::cmdCvars () {
}
for (const auto &cvar : game.getCvars ()) {
if (cvar.info.empty ()) {
if (cvar.info.empty () || !cvar.self || !cvar.self->ptr) {
continue;
}

View file

@ -678,6 +678,9 @@ void ConVar::revert () {
void Game::checkCvarsBounds () {
for (const auto &var : m_cvars) {
if (!var.self->ptr) {
continue;
}
// read only cvar is not changeable
if (var.type == Var::ReadOnly && !var.init.empty ()) {

View file

@ -1481,6 +1481,7 @@ void Bot::newRound () {
m_heardSoundTime = game.time ();
m_msgQueue.clear ();
m_goalHist.clear ();
m_ignoredBreakable.clear ();
// and put buying into its message queue

View file

@ -206,7 +206,7 @@ int Bot::findBestGoalWhenBombAction () {
return result;
}
int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
int goalChoices[4] = { kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex };
if (tactic == 0 && !(*defensive).empty ()) { // careful goal
@ -222,8 +222,8 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
postprocessGoals (graph.m_campPoints, goalChoices);
}
}
else if (tactic == 2 && !(*offsensive).empty ()) { // offensive goal
postprocessGoals (*offsensive, goalChoices);
else if (tactic == 2 && !(*offensive).empty ()) { // offensive goal
postprocessGoals (*offensive, goalChoices);
}
else if (tactic == 3 && !graph.m_goalPoints.empty ()) // map goal node
{
@ -282,15 +282,11 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
}
}
}
if (!graph.exists (m_currentNodeIndex)) {
changeNodeIndex (findNearestNode ());
}
ensureCurrentNodeIndex ();
if (goalChoices[0] == kInvalidNodeIndex) {
return m_chosenGoalIndex = graph.random ();
}
bool sorting = false;
do {
@ -313,16 +309,41 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
void Bot::postprocessGoals (const IntArray &goals, int result[]) {
// this function filters the goals, so new goal is not bot's old goal, and array of goals doesn't contains duplicate goals
int searchCount = 0;
int recurseCount = 0;
auto isRecentOrHistorical = [&] (int index) -> bool {
if (m_prevGoalIndex == index || m_previousNodes[0] == index) {
return true;
}
// too less to choice from just return all the goals
if (goals.length () < 4) {
return false;
}
// check if historical goal
for (const auto &hg : m_goalHist) {
if (hg == index) {
return true;
}
}
for (size_t i = 0; i < 4; ++i) {
if (result[i] == index) {
return true;
}
}
return isOccupiedNode (index);
};
for (int index = 0; index < 4; ++index) {
auto goal = goals.random ();
if (searchCount <= 8 && (m_prevGoalIndex == goal || ((result[0] == goal || result[1] == goal || result[2] == goal || result[3] == goal) && goals.length () > 4)) && !isOccupiedNode (goal)) {
if (recurseCount <= cr::max (4, goals.length <int> ()) && isRecentOrHistorical (goal)) {
if (index > 0) {
index--;
}
++searchCount;
++recurseCount;
continue;
}
result[index] = goal;
@ -336,6 +357,7 @@ bool Bot::hasActiveGoal () {
return false;
}
else if (goal == m_currentNodeIndex) { // no nodes needed
m_goalHist.push (goal);
return true;
}
else if (m_pathWalk.empty ()) { // no path calculated

View file

@ -67,7 +67,7 @@ void Bot::normal_ () {
// reached node is a camp node
if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) {
const bool allowedCampWeapon = hasPrimaryWeapon () || (hasSecondaryWeapon () && m_numFriendsLeft > game.maxClients () / 4);
const bool allowedCampWeapon = hasPrimaryWeapon () || (hasSecondaryWeapon () && !hasPrimaryWeapon () && m_numFriendsLeft > game.maxClients () / 6);
// check if bot has got a primary weapon and hasn't camped before
if (allowedCampWeapon && m_timeCamping + 10.0f < game.time () && !m_hasHostage) {