diff --git a/inc/manager.h b/inc/manager.h index 5fa6f43..e6c47e4 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -37,15 +37,11 @@ private: float m_plantSearchUpdateTime {}; // time to update for searching planted bomb float m_lastChatTime {}; // global chat time timestamp 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_lastDifficulty {}; // last bots difficulty 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_botsCanPause {}; // bots can do a little pause ? bool m_roundOver {}; // well, round is over> @@ -59,6 +55,7 @@ private: SmallArray m_bots {}; // all available bots edict_t *m_killerEntity {}; // killer entity for bots + BotTeamData m_teamData[kGameTeamNum] {}; // teams shared data protected: BotCreateResult create (StringRef name, int difficulty, int personality, int team, int skin); @@ -149,7 +146,7 @@ public: } bool checkTeamEco (int team) const { - return m_economicsGood[team]; + return m_teamData[team].positiveEco; } int32_t getLastWinner () const { @@ -219,23 +216,23 @@ public: void setLastRadioTimestamp (const int team, const float timestamp) { if (team == Team::CT || team == Team::Terrorist) { - m_lastRadioTime[team] = timestamp; + m_teamData[team].lastRadioTimestamp = timestamp; } } float getLastRadioTimestamp (const int team) const { if (team == Team::CT || team == Team::Terrorist) { - return m_lastRadioTime[team]; + return m_teamData[team].lastRadioTimestamp; } return 0.0f; } void setLastRadio (const int team, const int radio) { - m_lastRadio[team] = radio; + m_teamData[team].lastRadioSlot = radio; } int getLastRadio (const int team) const { - return m_lastRadio[team]; + return m_teamData[team].lastRadioSlot; } void setLastChatTimestamp (const float timestamp) { diff --git a/inc/yapb.h b/inc/yapb.h index 408d963..396dae5 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -115,6 +115,14 @@ struct FrameDelay { 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 #include diff --git a/src/botlib.cpp b/src/botlib.cpp index 0dbfd70..7bf2607 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -441,7 +441,7 @@ void Bot::updatePickups () { allowPickup = true; pickupType = Pickup::Hostage; } - else if (isDemolitionMap && isWeaponBox && model == "backpack.mdl") { + else if (isDemolitionMap && isWeaponBox && model == "backpack.mdl" && !cv_ignore_objectives) { allowPickup = true; pickupType = Pickup::DroppedC4; } @@ -4375,7 +4375,16 @@ void Bot::donateC4ToHuman () { const float radiusSq = cr::sqrf (1024.0f); 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; } diff --git a/src/manager.cpp b/src/manager.cpp index fd027e0..370de33 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -60,12 +60,11 @@ ConVar mp_freezetime ("mp_freezetime", nullptr, Var::GameRef, true, "0"); BotManager::BotManager () { // this is a bot manager class constructor - for (int i = 0; i < kGameTeamNum; ++i) { - m_leaderChoosen[i] = false; - m_economicsGood[i] = true; - - m_lastRadioTime[i] = 0.0f; - m_lastRadio[i] = kInvalidRadioSlot; + for (auto &td : m_teamData) { + td.leaderChoosen = false; + td.positiveEco = true; + td.lastRadioSlot = kInvalidRadioSlot; + td.lastRadioTimestamp = 0.0f; } 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 // buy primary weapons. + auto &ecoStatus = m_teamData[team].positiveEco; + if (setTrue || !cv_economics_rounds) { - m_economicsGood[team] = true; + ecoStatus = true; return; // don't check economics while economics disable } - const int *econLimit = conf.getEconLimit (); + const auto econLimit = conf.getEconLimit (); int numPoorPlayers = 0; int numTeamPlayers = 0; @@ -1026,19 +1027,19 @@ void BotManager::updateTeamEconomics (int team, bool setTrue) { ++numTeamPlayers; // update count of team } } - m_economicsGood[team] = true; + ecoStatus = true; if (numTeamPlayers <= 1) { return; } // if 80 percent of team have no enough money to purchase primary weapon if ((numTeamPlayers * 80) / 100 <= numPoorPlayers) { - m_economicsGood[team] = false; + ecoStatus = false; } // winner must buy something! if (m_lastWinner == team) { - m_economicsGood[team] = true; + ecoStatus = true; } } @@ -2057,21 +2058,24 @@ void BotManager::updateInterestingEntities () { } void BotManager::selectLeaders (int team, bool reset) { + auto &leaderChoosen = m_teamData[team].leaderChoosen; + if (reset) { - m_leaderChoosen[team] = false; + leaderChoosen = false; return; } - if (m_leaderChoosen[team]) { + if (leaderChoosen) { return; } + auto &leaderChoosenT = m_teamData[Team::Terrorist].leaderChoosen; + auto &leaderChoosenCT = m_teamData[Team::CT].leaderChoosen; if (game.mapIs (MapFlags::Assassination)) { - if (team == Team::CT && !m_leaderChoosen[Team::CT]) { + if (team == Team::CT && !leaderChoosenCT) { for (const auto &bot : m_bots) { if (bot->m_isVIP) { - // vip bot is the leader - bot->m_isLeader = true; + bot->m_isLeader = true; // vip bot is the leader if (rg.chance (50)) { 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); if (bot != nullptr && bot->m_isAlive) { @@ -2091,11 +2095,11 @@ void BotManager::selectLeaders (int team, bool reset) { bot->pushRadioMessage (Radio::FollowMe); } } - m_leaderChoosen[Team::Terrorist] = true; + leaderChoosenT = true; } } 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) { if (bot->m_hasC4) { // 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)) { bot->m_isLeader = true; @@ -2123,31 +2127,31 @@ void BotManager::selectLeaders (int team, bool reset) { bot->pushRadioMessage (Radio::FollowMe); } } - m_leaderChoosen[Team::CT] = true; + leaderChoosenCT = true; } } else if (game.mapIs (MapFlags::Escape | MapFlags::KnifeArena | MapFlags::FightYard)) { auto bot = bots.findHighestFragBot (team); - if (!m_leaderChoosen[team] && bot) { + if (!leaderChoosen && bot) { bot->m_isLeader = true; if (rg.chance (30)) { bot->pushRadioMessage (Radio::FollowMe); } - m_leaderChoosen[team] = true; + leaderChoosen = true; } } else { auto bot = bots.findHighestFragBot (team); - if (!m_leaderChoosen[team] && bot) { + if (!leaderChoosen && bot) { bot->m_isLeader = true; if (rg.chance (team == Team::Terrorist ? 30 : 40)) { bot->pushRadioMessage (Radio::FollowMe); } - m_leaderChoosen[team] = true; + leaderChoosen = true; } } } @@ -2162,7 +2166,7 @@ void BotManager::initRound () { updateTeamEconomics (team); selectLeaders (team, true); - m_lastRadioTime[team] = 0.0f; + m_teamData[team].lastRadioTimestamp = 0.0f; } reset (); diff --git a/src/navigate.cpp b/src/navigate.cpp index 0d780d3..bcae486 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -199,7 +199,7 @@ int Bot::findBestGoal () { int Bot::findBestGoalWhenBombAction () { int result = kInvalidNodeIndex; - if (!bots.isBombPlanted ()) { + if (!bots.isBombPlanted () && !cv_ignore_objectives) { game.searchEntities ("classname", "weaponbox", [&] (edict_t *ent) { if (util.isModel (ent, "backpack.mdl")) { result = graph.getNearest (game.getEntityOrigin (ent));