fix: behavior with bomb, when ignoring objectives (ref #696)
This commit is contained in:
parent
1311406544
commit
9cb8171030
5 changed files with 58 additions and 40 deletions
|
|
@ -37,15 +37,11 @@ private:
|
||||||
float m_plantSearchUpdateTime {}; // time to update for searching planted bomb
|
float m_plantSearchUpdateTime {}; // time to update for searching planted bomb
|
||||||
float m_lastChatTime {}; // global chat time timestamp
|
float m_lastChatTime {}; // global chat time timestamp
|
||||||
float m_timeBombPlanted {}; // time the bomb were planted
|
float m_timeBombPlanted {}; // time the bomb were planted
|
||||||
float m_lastRadioTime[kGameTeamNum] {}; // global radio time
|
|
||||||
|
|
||||||
int m_lastWinner {}; // the team who won previous round
|
int m_lastWinner {}; // the team who won previous round
|
||||||
int m_lastDifficulty {}; // last bots difficulty
|
int m_lastDifficulty {}; // last bots difficulty
|
||||||
int m_bombSayStatus {}; // some bot is issued whine about bomb
|
int m_bombSayStatus {}; // some bot is issued whine about bomb
|
||||||
int m_lastRadio[kGameTeamNum] {}; // last radio message for team
|
|
||||||
|
|
||||||
bool m_leaderChoosen[kGameTeamNum] {}; // is team leader choose thees round
|
|
||||||
bool m_economicsGood[kGameTeamNum] {}; // is team able to buy anything
|
|
||||||
bool m_bombPlanted {}; // is bomb planted ?
|
bool m_bombPlanted {}; // is bomb planted ?
|
||||||
bool m_botsCanPause {}; // bots can do a little pause ?
|
bool m_botsCanPause {}; // bots can do a little pause ?
|
||||||
bool m_roundOver {}; // well, round is over>
|
bool m_roundOver {}; // well, round is over>
|
||||||
|
|
@ -59,6 +55,7 @@ private:
|
||||||
SmallArray <UniqueBot> m_bots {}; // all available bots
|
SmallArray <UniqueBot> m_bots {}; // all available bots
|
||||||
|
|
||||||
edict_t *m_killerEntity {}; // killer entity for bots
|
edict_t *m_killerEntity {}; // killer entity for bots
|
||||||
|
BotTeamData m_teamData[kGameTeamNum] {}; // teams shared data
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BotCreateResult create (StringRef name, int difficulty, int personality, int team, int skin);
|
BotCreateResult create (StringRef name, int difficulty, int personality, int team, int skin);
|
||||||
|
|
@ -149,7 +146,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool checkTeamEco (int team) const {
|
bool checkTeamEco (int team) const {
|
||||||
return m_economicsGood[team];
|
return m_teamData[team].positiveEco;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t getLastWinner () const {
|
int32_t getLastWinner () const {
|
||||||
|
|
@ -219,23 +216,23 @@ public:
|
||||||
|
|
||||||
void setLastRadioTimestamp (const int team, const float timestamp) {
|
void setLastRadioTimestamp (const int team, const float timestamp) {
|
||||||
if (team == Team::CT || team == Team::Terrorist) {
|
if (team == Team::CT || team == Team::Terrorist) {
|
||||||
m_lastRadioTime[team] = timestamp;
|
m_teamData[team].lastRadioTimestamp = timestamp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float getLastRadioTimestamp (const int team) const {
|
float getLastRadioTimestamp (const int team) const {
|
||||||
if (team == Team::CT || team == Team::Terrorist) {
|
if (team == Team::CT || team == Team::Terrorist) {
|
||||||
return m_lastRadioTime[team];
|
return m_teamData[team].lastRadioTimestamp;
|
||||||
}
|
}
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLastRadio (const int team, const int radio) {
|
void setLastRadio (const int team, const int radio) {
|
||||||
m_lastRadio[team] = radio;
|
m_teamData[team].lastRadioSlot = radio;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getLastRadio (const int team) const {
|
int getLastRadio (const int team) const {
|
||||||
return m_lastRadio[team];
|
return m_teamData[team].lastRadioSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLastChatTimestamp (const float timestamp) {
|
void setLastChatTimestamp (const float timestamp) {
|
||||||
|
|
|
||||||
|
|
@ -115,6 +115,14 @@ struct FrameDelay {
|
||||||
float time {};
|
float time {};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// shared team data for bot
|
||||||
|
struct BotTeamData {
|
||||||
|
bool leaderChoosen {}; // is team leader choose thees round
|
||||||
|
bool positiveEco {}; // is team able to buy anything
|
||||||
|
float lastRadioTimestamp {}; // global radio time
|
||||||
|
int32_t lastRadioSlot = { kInvalidRadioSlot }; // last radio message for team
|
||||||
|
};
|
||||||
|
|
||||||
// include bot graph stuff
|
// include bot graph stuff
|
||||||
#include <graph.h>
|
#include <graph.h>
|
||||||
#include <vision.h>
|
#include <vision.h>
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,7 @@ void Bot::updatePickups () {
|
||||||
allowPickup = true;
|
allowPickup = true;
|
||||||
pickupType = Pickup::Hostage;
|
pickupType = Pickup::Hostage;
|
||||||
}
|
}
|
||||||
else if (isDemolitionMap && isWeaponBox && model == "backpack.mdl") {
|
else if (isDemolitionMap && isWeaponBox && model == "backpack.mdl" && !cv_ignore_objectives) {
|
||||||
allowPickup = true;
|
allowPickup = true;
|
||||||
pickupType = Pickup::DroppedC4;
|
pickupType = Pickup::DroppedC4;
|
||||||
}
|
}
|
||||||
|
|
@ -4375,7 +4375,16 @@ void Bot::donateC4ToHuman () {
|
||||||
const float radiusSq = cr::sqrf (1024.0f);
|
const float radiusSq = cr::sqrf (1024.0f);
|
||||||
|
|
||||||
for (const auto &client : util.getClients ()) {
|
for (const auto &client : util.getClients ()) {
|
||||||
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team != m_team || client.ent == ent ()) {
|
if (!(client.flags & ClientFlags::Used)
|
||||||
|
|| !(client.flags & ClientFlags::Alive)
|
||||||
|
|| client.team != m_team
|
||||||
|
|| client.ent == ent ()) {
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// skip the bots
|
||||||
|
if (bots[client.ent]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,12 +60,11 @@ ConVar mp_freezetime ("mp_freezetime", nullptr, Var::GameRef, true, "0");
|
||||||
BotManager::BotManager () {
|
BotManager::BotManager () {
|
||||||
// this is a bot manager class constructor
|
// this is a bot manager class constructor
|
||||||
|
|
||||||
for (int i = 0; i < kGameTeamNum; ++i) {
|
for (auto &td : m_teamData) {
|
||||||
m_leaderChoosen[i] = false;
|
td.leaderChoosen = false;
|
||||||
m_economicsGood[i] = true;
|
td.positiveEco = true;
|
||||||
|
td.lastRadioSlot = kInvalidRadioSlot;
|
||||||
m_lastRadioTime[i] = 0.0f;
|
td.lastRadioTimestamp = 0.0f;
|
||||||
m_lastRadio[i] = kInvalidRadioSlot;
|
|
||||||
}
|
}
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
|
|
@ -1008,11 +1007,13 @@ void BotManager::updateTeamEconomics (int team, bool setTrue) {
|
||||||
// that have not enough money to buy primary (with economics), and if this result higher 80%, player is can't
|
// that have not enough money to buy primary (with economics), and if this result higher 80%, player is can't
|
||||||
// buy primary weapons.
|
// buy primary weapons.
|
||||||
|
|
||||||
|
auto &ecoStatus = m_teamData[team].positiveEco;
|
||||||
|
|
||||||
if (setTrue || !cv_economics_rounds) {
|
if (setTrue || !cv_economics_rounds) {
|
||||||
m_economicsGood[team] = true;
|
ecoStatus = true;
|
||||||
return; // don't check economics while economics disable
|
return; // don't check economics while economics disable
|
||||||
}
|
}
|
||||||
const int *econLimit = conf.getEconLimit ();
|
const auto econLimit = conf.getEconLimit ();
|
||||||
|
|
||||||
int numPoorPlayers = 0;
|
int numPoorPlayers = 0;
|
||||||
int numTeamPlayers = 0;
|
int numTeamPlayers = 0;
|
||||||
|
|
@ -1026,19 +1027,19 @@ void BotManager::updateTeamEconomics (int team, bool setTrue) {
|
||||||
++numTeamPlayers; // update count of team
|
++numTeamPlayers; // update count of team
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_economicsGood[team] = true;
|
ecoStatus = true;
|
||||||
|
|
||||||
if (numTeamPlayers <= 1) {
|
if (numTeamPlayers <= 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// if 80 percent of team have no enough money to purchase primary weapon
|
// if 80 percent of team have no enough money to purchase primary weapon
|
||||||
if ((numTeamPlayers * 80) / 100 <= numPoorPlayers) {
|
if ((numTeamPlayers * 80) / 100 <= numPoorPlayers) {
|
||||||
m_economicsGood[team] = false;
|
ecoStatus = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// winner must buy something!
|
// winner must buy something!
|
||||||
if (m_lastWinner == team) {
|
if (m_lastWinner == team) {
|
||||||
m_economicsGood[team] = true;
|
ecoStatus = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2057,21 +2058,24 @@ void BotManager::updateInterestingEntities () {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BotManager::selectLeaders (int team, bool reset) {
|
void BotManager::selectLeaders (int team, bool reset) {
|
||||||
|
auto &leaderChoosen = m_teamData[team].leaderChoosen;
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
m_leaderChoosen[team] = false;
|
leaderChoosen = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_leaderChoosen[team]) {
|
if (leaderChoosen) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
auto &leaderChoosenT = m_teamData[Team::Terrorist].leaderChoosen;
|
||||||
|
auto &leaderChoosenCT = m_teamData[Team::CT].leaderChoosen;
|
||||||
|
|
||||||
if (game.mapIs (MapFlags::Assassination)) {
|
if (game.mapIs (MapFlags::Assassination)) {
|
||||||
if (team == Team::CT && !m_leaderChoosen[Team::CT]) {
|
if (team == Team::CT && !leaderChoosenCT) {
|
||||||
for (const auto &bot : m_bots) {
|
for (const auto &bot : m_bots) {
|
||||||
if (bot->m_isVIP) {
|
if (bot->m_isVIP) {
|
||||||
// vip bot is the leader
|
bot->m_isLeader = true; // vip bot is the leader
|
||||||
bot->m_isLeader = true;
|
|
||||||
|
|
||||||
if (rg.chance (50)) {
|
if (rg.chance (50)) {
|
||||||
bot->pushRadioMessage (Radio::FollowMe);
|
bot->pushRadioMessage (Radio::FollowMe);
|
||||||
|
|
@ -2079,9 +2083,9 @@ void BotManager::selectLeaders (int team, bool reset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_leaderChoosen[Team::CT] = true;
|
leaderChoosenCT = true;
|
||||||
}
|
}
|
||||||
else if (team == Team::Terrorist && !m_leaderChoosen[Team::Terrorist]) {
|
else if (team == Team::Terrorist && !leaderChoosenT) {
|
||||||
auto bot = bots.findHighestFragBot (team);
|
auto bot = bots.findHighestFragBot (team);
|
||||||
|
|
||||||
if (bot != nullptr && bot->m_isAlive) {
|
if (bot != nullptr && bot->m_isAlive) {
|
||||||
|
|
@ -2091,11 +2095,11 @@ void BotManager::selectLeaders (int team, bool reset) {
|
||||||
bot->pushRadioMessage (Radio::FollowMe);
|
bot->pushRadioMessage (Radio::FollowMe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_leaderChoosen[Team::Terrorist] = true;
|
leaderChoosenT = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (game.mapIs (MapFlags::Demolition)) {
|
else if (game.mapIs (MapFlags::Demolition)) {
|
||||||
if (team == Team::Terrorist && !m_leaderChoosen[Team::Terrorist]) {
|
if (team == Team::Terrorist && !leaderChoosenT) {
|
||||||
for (const auto &bot : m_bots) {
|
for (const auto &bot : m_bots) {
|
||||||
if (bot->m_hasC4) {
|
if (bot->m_hasC4) {
|
||||||
// bot carrying the bomb is the leader
|
// bot carrying the bomb is the leader
|
||||||
|
|
@ -2113,9 +2117,9 @@ void BotManager::selectLeaders (int team, bool reset) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_leaderChoosen[Team::Terrorist] = true;
|
leaderChoosenT = true;
|
||||||
}
|
}
|
||||||
else if (!m_leaderChoosen[Team::CT]) {
|
else if (!leaderChoosenCT) {
|
||||||
if (auto bot = bots.findHighestFragBot (team)) {
|
if (auto bot = bots.findHighestFragBot (team)) {
|
||||||
bot->m_isLeader = true;
|
bot->m_isLeader = true;
|
||||||
|
|
||||||
|
|
@ -2123,31 +2127,31 @@ void BotManager::selectLeaders (int team, bool reset) {
|
||||||
bot->pushRadioMessage (Radio::FollowMe);
|
bot->pushRadioMessage (Radio::FollowMe);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_leaderChoosen[Team::CT] = true;
|
leaderChoosenCT = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (game.mapIs (MapFlags::Escape | MapFlags::KnifeArena | MapFlags::FightYard)) {
|
else if (game.mapIs (MapFlags::Escape | MapFlags::KnifeArena | MapFlags::FightYard)) {
|
||||||
auto bot = bots.findHighestFragBot (team);
|
auto bot = bots.findHighestFragBot (team);
|
||||||
|
|
||||||
if (!m_leaderChoosen[team] && bot) {
|
if (!leaderChoosen && bot) {
|
||||||
bot->m_isLeader = true;
|
bot->m_isLeader = true;
|
||||||
|
|
||||||
if (rg.chance (30)) {
|
if (rg.chance (30)) {
|
||||||
bot->pushRadioMessage (Radio::FollowMe);
|
bot->pushRadioMessage (Radio::FollowMe);
|
||||||
}
|
}
|
||||||
m_leaderChoosen[team] = true;
|
leaderChoosen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto bot = bots.findHighestFragBot (team);
|
auto bot = bots.findHighestFragBot (team);
|
||||||
|
|
||||||
if (!m_leaderChoosen[team] && bot) {
|
if (!leaderChoosen && bot) {
|
||||||
bot->m_isLeader = true;
|
bot->m_isLeader = true;
|
||||||
|
|
||||||
if (rg.chance (team == Team::Terrorist ? 30 : 40)) {
|
if (rg.chance (team == Team::Terrorist ? 30 : 40)) {
|
||||||
bot->pushRadioMessage (Radio::FollowMe);
|
bot->pushRadioMessage (Radio::FollowMe);
|
||||||
}
|
}
|
||||||
m_leaderChoosen[team] = true;
|
leaderChoosen = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2162,7 +2166,7 @@ void BotManager::initRound () {
|
||||||
updateTeamEconomics (team);
|
updateTeamEconomics (team);
|
||||||
selectLeaders (team, true);
|
selectLeaders (team, true);
|
||||||
|
|
||||||
m_lastRadioTime[team] = 0.0f;
|
m_teamData[team].lastRadioTimestamp = 0.0f;
|
||||||
}
|
}
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -199,7 +199,7 @@ int Bot::findBestGoal () {
|
||||||
int Bot::findBestGoalWhenBombAction () {
|
int Bot::findBestGoalWhenBombAction () {
|
||||||
int result = kInvalidNodeIndex;
|
int result = kInvalidNodeIndex;
|
||||||
|
|
||||||
if (!bots.isBombPlanted ()) {
|
if (!bots.isBombPlanted () && !cv_ignore_objectives) {
|
||||||
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
|
game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) {
|
||||||
if (util.isModel (ent, "backpack.mdl")) {
|
if (util.isModel (ent, "backpack.mdl")) {
|
||||||
result = graph.getNearest (game.getEntityOrigin (ent));
|
result = graph.getNearest (game.getEntityOrigin (ent));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue