nav: re-added goal history for a round in some reworked way
This commit is contained in:
parent
e24db4c27d
commit
04503963c5
6 changed files with 42 additions and 15 deletions
|
|
@ -819,7 +819,7 @@ private:
|
||||||
int findDefendNode (const Vector &origin);
|
int findDefendNode (const Vector &origin);
|
||||||
int findBestGoal ();
|
int findBestGoal ();
|
||||||
int findBestGoalWhenBombAction ();
|
int findBestGoalWhenBombAction ();
|
||||||
int findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive);
|
int findGoalPost (int tactic, IntArray *defensive, IntArray *offensive);
|
||||||
int bestPrimaryCarried ();
|
int bestPrimaryCarried ();
|
||||||
int bestSecondaryCarried ();
|
int bestSecondaryCarried ();
|
||||||
int bestGrenadeCarried ();
|
int bestGrenadeCarried ();
|
||||||
|
|
@ -1128,6 +1128,7 @@ public:
|
||||||
Personality m_personality {}; // bots type
|
Personality m_personality {}; // bots type
|
||||||
Array <BotTask> m_tasks {};
|
Array <BotTask> m_tasks {};
|
||||||
Deque <int32_t> m_msgQueue {};
|
Deque <int32_t> m_msgQueue {};
|
||||||
|
Array <int32_t> m_goalHist {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Bot (edict_t *bot, int difficulty, int personality, int team, int skin);
|
Bot (edict_t *bot, int difficulty, int personality, int team, int skin);
|
||||||
|
|
|
||||||
|
|
@ -211,7 +211,7 @@ int BotControl::cmdCvars () {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const auto &cvar : game.getCvars ()) {
|
for (const auto &cvar : game.getCvars ()) {
|
||||||
if (cvar.info.empty ()) {
|
if (cvar.info.empty () || !cvar.self || !cvar.self->ptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -678,6 +678,9 @@ void ConVar::revert () {
|
||||||
|
|
||||||
void Game::checkCvarsBounds () {
|
void Game::checkCvarsBounds () {
|
||||||
for (const auto &var : m_cvars) {
|
for (const auto &var : m_cvars) {
|
||||||
|
if (!var.self->ptr) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// read only cvar is not changeable
|
// read only cvar is not changeable
|
||||||
if (var.type == Var::ReadOnly && !var.init.empty ()) {
|
if (var.type == Var::ReadOnly && !var.init.empty ()) {
|
||||||
|
|
|
||||||
|
|
@ -1481,6 +1481,7 @@ void Bot::newRound () {
|
||||||
m_heardSoundTime = game.time ();
|
m_heardSoundTime = game.time ();
|
||||||
|
|
||||||
m_msgQueue.clear ();
|
m_msgQueue.clear ();
|
||||||
|
m_goalHist.clear ();
|
||||||
m_ignoredBreakable.clear ();
|
m_ignoredBreakable.clear ();
|
||||||
|
|
||||||
// and put buying into its message queue
|
// and put buying into its message queue
|
||||||
|
|
|
||||||
|
|
@ -206,7 +206,7 @@ int Bot::findBestGoalWhenBombAction () {
|
||||||
return result;
|
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 };
|
int goalChoices[4] = { kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex };
|
||||||
|
|
||||||
if (tactic == 0 && !(*defensive).empty ()) { // careful goal
|
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);
|
postprocessGoals (graph.m_campPoints, goalChoices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (tactic == 2 && !(*offsensive).empty ()) { // offensive goal
|
else if (tactic == 2 && !(*offensive).empty ()) { // offensive goal
|
||||||
postprocessGoals (*offsensive, goalChoices);
|
postprocessGoals (*offensive, goalChoices);
|
||||||
}
|
}
|
||||||
else if (tactic == 3 && !graph.m_goalPoints.empty ()) // map goal node
|
else if (tactic == 3 && !graph.m_goalPoints.empty ()) // map goal node
|
||||||
{
|
{
|
||||||
|
|
@ -282,15 +282,11 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ensureCurrentNodeIndex ();
|
||||||
if (!graph.exists (m_currentNodeIndex)) {
|
|
||||||
changeNodeIndex (findNearestNode ());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (goalChoices[0] == kInvalidNodeIndex) {
|
if (goalChoices[0] == kInvalidNodeIndex) {
|
||||||
return m_chosenGoalIndex = graph.random ();
|
return m_chosenGoalIndex = graph.random ();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sorting = false;
|
bool sorting = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
@ -313,16 +309,41 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offsensive) {
|
||||||
void Bot::postprocessGoals (const IntArray &goals, int result[]) {
|
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
|
// 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) {
|
for (int index = 0; index < 4; ++index) {
|
||||||
auto goal = goals.random ();
|
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) {
|
if (index > 0) {
|
||||||
index--;
|
index--;
|
||||||
}
|
}
|
||||||
++searchCount;
|
++recurseCount;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
result[index] = goal;
|
result[index] = goal;
|
||||||
|
|
@ -336,6 +357,7 @@ bool Bot::hasActiveGoal () {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (goal == m_currentNodeIndex) { // no nodes needed
|
else if (goal == m_currentNodeIndex) { // no nodes needed
|
||||||
|
m_goalHist.push (goal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (m_pathWalk.empty ()) { // no path calculated
|
else if (m_pathWalk.empty ()) { // no path calculated
|
||||||
|
|
|
||||||
|
|
@ -67,7 +67,7 @@ void Bot::normal_ () {
|
||||||
|
|
||||||
// reached node is a camp node
|
// reached node is a camp node
|
||||||
if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) {
|
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
|
// check if bot has got a primary weapon and hasn't camped before
|
||||||
if (allowedCampWeapon && m_timeCamping + 10.0f < game.time () && !m_hasHostage) {
|
if (allowedCampWeapon && m_timeCamping + 10.0f < game.time () && !m_hasHostage) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue