diff --git a/ext/crlib b/ext/crlib index 3596ac4..ea7a91b 160000 --- a/ext/crlib +++ b/ext/crlib @@ -1 +1 @@ -Subproject commit 3596ac42ccc21d93d7fe2a937870d76e944f7f07 +Subproject commit ea7a91bd042599132e60482f51087d9669dbe1c4 diff --git a/ext/linkage b/ext/linkage index b99f0ba..3e2bd99 160000 --- a/ext/linkage +++ b/ext/linkage @@ -1 +1 @@ -Subproject commit b99f0bac831b823a1e5a57ef3bd7c7dcaf8dee22 +Subproject commit 3e2bd997a6048a0c2d9318e65a63b30a35c67dfa diff --git a/inc/control.h b/inc/control.h index 6c514b4..b70b496 100644 --- a/inc/control.h +++ b/inc/control.h @@ -193,25 +193,25 @@ public: m_printQueueFlushTimestamp = 0.0f; } - int intValue (size_t arg) const { - if (!hasArg (arg)) { - return 0; + template constexpr U arg (const size_t index) const { + if constexpr (cr::is_same ::value) { + if (!hasArg (index)) { + return 0.0f; + } + return m_args[index].as (); } - return m_args[arg].int_ (); - } - - float floatValue (size_t arg) const { - if (!hasArg (arg)) { - return 0.0f; + else if constexpr (cr::is_same ::value) { + if (!hasArg (index)) { + return 0; + } + return m_args[index].as (); } - return m_args[arg].float_ (); - } - - StringRef strValue (size_t arg) { - if (!hasArg (arg)) { - return ""; + else if constexpr (cr::is_same ::value) { + if (!hasArg (index)) { + return ""; + } + return m_args[index]; } - return m_args[arg]; } bool hasArg (size_t arg) const { diff --git a/inc/engine.h b/inc/engine.h index e5ffc70..878ef10 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -188,7 +188,7 @@ public: void prepareBotArgs (edict_t *ent, String str); // adds cvar to registration stack - void addNewCvar (const char *name, const char *value, const char *info, bool bounded, float min, float max, int32_t varType, bool missingAction, const char *regval, class ConVar *self); + void pushConVar (StringRef name, StringRef value, StringRef info, bool bounded, float min, float max, int32_t varType, bool missingAction, StringRef regval, class ConVar *self); // check the cvar bounds void checkCvarsBounds (); @@ -470,18 +470,18 @@ public: ~ConVar () = default; public: - ConVar (const char *name, const char *initval, int32_t type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : ptr (nullptr) { + ConVar (StringRef name, StringRef initval, int32_t type = Var::NoServer, bool regMissing = false, StringRef regVal = nullptr) : ptr (nullptr) { setPrefix (name, type); - Game::instance ().addNewCvar (name_.chars (), initval, "", false, 0.0f, 0.0f, type, regMissing, regVal, this); + Game::instance ().pushConVar (name_.chars (), initval, "", false, 0.0f, 0.0f, type, regMissing, regVal, this); } - ConVar (const char *name, const char *initval, const char *info, bool bounded = true, float min = 0.0f, float max = 1.0f, int32_t type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : ptr (nullptr) { + ConVar (StringRef name, StringRef initval, StringRef info, bool bounded = true, float min = 0.0f, float max = 1.0f, int32_t type = Var::NoServer, bool regMissing = false, const char *regVal = nullptr) : ptr (nullptr) { setPrefix (name, type); - Game::instance ().addNewCvar (name_.chars (), initval, info, bounded, min, max, type, regMissing, regVal, this); + Game::instance ().pushConVar (name_.chars (), initval, info, bounded, min, max, type, regMissing, regVal, this); } public: - template constexpr U get () const { + template constexpr U as () const { if constexpr (cr::is_same ::value) { return ptr->value; } @@ -498,34 +498,22 @@ public: public: operator bool () const { - return bool_ (); + return as (); } operator float () const { - return float_ (); + return as (); + } + + operator int () const { + return as (); } operator StringRef () { - return str (); + return as (); } public: - bool bool_ () const { - return get (); - } - - int int_ () const { - return get (); - } - - float float_ () const { - return get (); - } - - StringRef str () const { - return get (); - } - StringRef name () const { return ptr->name; } @@ -546,7 +534,7 @@ public: void revert (); // set the cvar prefix if needed - void setPrefix (const char *name, int32_t type); + void setPrefix (StringRef name, int32_t type); }; class MessageWriter final { diff --git a/inc/graph.h b/inc/graph.h index 21e03c2..24fa82b 100644 --- a/inc/graph.h +++ b/inc/graph.h @@ -317,7 +317,7 @@ public: // get the random node on map int32_t random () const { - return rg.get (0, length () - 1); + return rg (0, length () - 1); } // check if has editor diff --git a/inc/yapb.h b/inc/yapb.h index 0f24ec6..188bdd4 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -309,7 +309,7 @@ private: bool m_jumpSequence {}; // next path link will be jump link PathWalk m_pathWalk {}; // pointer to current node from path - Dodge m_combatStrafeDir {}; // direction to strafe + Dodge m_dodgeStrafeDir {}; // direction to strafe Fight m_fightStyle {}; // combat style to use CollisionState m_collisionState {}; // collision State FindPath m_pathType {}; // which pathfinder to use @@ -354,6 +354,7 @@ private: CountdownTimer m_forgetLastVictimTimer {}; // time to forget last victim position ? CountdownTimer m_approachingLadderTimer {}; // bot is approaching ladder + CountdownTimer m_lostReachableNodeTimer {}; // bot's issuing next node, probably he's lost private: int pickBestWeapon (Array &vec, int moneySave); diff --git a/src/analyze.cpp b/src/analyze.cpp index 3083cbf..613c22d 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -18,7 +18,7 @@ ConVar cv_graph_analyze_mark_goals_on_finish ("graph_analyze_mark_goals_on_finis void GraphAnalyze::start () { // start analyzer in few seconds after level initialized - if (cv_graph_analyze_auto_start.bool_ ()) { + if (cv_graph_analyze_auto_start) { m_updateInterval = game.time () + 3.0f; m_basicsCreated = false; @@ -79,7 +79,7 @@ void GraphAnalyze::update () { setUpdateInterval (); auto pos = graph[i].origin; - const auto range = cv_graph_analyze_distance.float_ (); + const auto range = cv_graph_analyze_distance.as (); for (int dir = 1; dir < kMaxNodeLinks; ++dir) { switch (dir) { @@ -149,7 +149,7 @@ void GraphAnalyze::finish () { ctrl.msg ("Completed map analysis."); // auto save bots graph - if (cv_graph_analyze_auto_save.bool_ ()) { + if (cv_graph_analyze_auto_save) { if (!graph.saveGraphData ()) { ctrl.msg ("Can't save analyzed graph. Internal error."); return; @@ -171,7 +171,7 @@ void GraphAnalyze::optimize () { return; } - if (!cv_graph_analyze_optimize_nodes_on_finish.bool_ ()) { + if (!cv_graph_analyze_optimize_nodes_on_finish) { return; } cleanup (); @@ -220,7 +220,7 @@ void GraphAnalyze::optimize () { } // clear the useless connections - if (cv_graph_analyze_clean_paths_on_finish.bool_ ()) { + if (cv_graph_analyze_clean_paths_on_finish) { for (auto i = 0; i < graph.length (); ++i) { graph.clearConnections (i); } @@ -352,13 +352,13 @@ void GraphAnalyze::flood (const Vector &pos, const Vector &next, float range) { void GraphAnalyze::setUpdateInterval () { const auto frametime = globals->frametime; - if ((cv_graph_analyze_fps.float_ () + frametime) <= 1.0f / frametime) { + if ((cv_graph_analyze_fps.as () + frametime) <= 1.0f / frametime) { m_updateInterval = game.time () + frametime * 0.06f; } } void GraphAnalyze::markGoals () { - if (!cv_graph_analyze_mark_goals_on_finish.bool_ ()) { + if (!cv_graph_analyze_mark_goals_on_finish) { return; } diff --git a/src/botlib.cpp b/src/botlib.cpp index e9dc0f5..155d92b 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -106,7 +106,7 @@ void Bot::avoidGrenades () { m_lookAt.y = cr::wrapAngle ((game.getEntityOrigin (pent) - getEyesPos ()).angles ().y + 180.0f); m_canChooseAimDirection = false; - m_preventFlashing = game.time () + rg.get (1.0f, 2.0f); + m_preventFlashing = game.time () + rg (1.0f, 2.0f); } } else if (game.isNullEntity (m_avoidGrenade) && model == kExplosiveModelName) { @@ -132,7 +132,7 @@ void Bot::avoidGrenades () { } } } - else if (cv_smoke_grenade_checks.int_ () == 1 && (pent->v.flags & FL_ONGROUND) && model == kSmokeModelName) { + else if (cv_smoke_grenade_checks.as () == 1 && (pent->v.flags & FL_ONGROUND) && model == kSmokeModelName) { if (isInFOV (pent->v.origin - getEyesPos ()) < pev->fov / 3.0f) { const auto &entOrigin = game.getEntityOrigin (pent); const auto &betweenUs = (entOrigin - pev->origin).normalize_apx (); @@ -175,7 +175,7 @@ void Bot::checkBreakable (edict_t *touch) { void Bot::checkBreakablesAround () { if (!m_buyingFinished - || !cv_destroy_breakables_around.bool_ () + || !cv_destroy_breakables_around || usesKnife () || rg.chance (25) || !game.hasBreakables () @@ -185,7 +185,7 @@ void Bot::checkBreakablesAround () { return; } - const auto radius = cv_object_destroy_radius.float_ (); + const auto radius = cv_object_destroy_radius.as (); // check if we're have some breakables in 400 units range for (const auto &breakable : game.getBreakables ()) { @@ -280,7 +280,7 @@ edict_t *Bot::lookupBreakable () { } void Bot::setIdealReactionTimers (bool actual) { - if (cv_whose_your_daddy.bool_ ()) { + if (cv_whose_your_daddy) { m_idealReactionTime = 0.05f; m_actualReactionTime = 0.095f; @@ -294,7 +294,7 @@ void Bot::setIdealReactionTimers (bool actual) { return; } - m_idealReactionTime = rg.get (tweak->reaction[0], tweak->reaction[1]); + m_idealReactionTime = rg (tweak->reaction[0], tweak->reaction[1]); } void Bot::updatePickups () { @@ -323,7 +323,7 @@ void Bot::updatePickups () { } // knife mode is in progress ? - else if (cv_jasonmode.bool_ ()) { + else if (cv_jasonmode) { return true; } @@ -343,7 +343,7 @@ void Bot::updatePickups () { } const auto &interesting = bots.getInterestingEntities (); - const float radius = cr::sqrf (cv_object_pickup_radius.float_ ()); + const float radius = cr::sqrf (cv_object_pickup_radius.as ()); if (!game.isNullEntity (m_pickupItem)) { bool itemExists = false; @@ -426,7 +426,7 @@ void Bot::updatePickups () { allowPickup = true; pickupType = Pickup::Weapon; - if (cv_pickup_ammo_and_kits.bool_ ()) { + if (cv_pickup_ammo_and_kits) { const int primaryWeaponCarried = bestPrimaryCarried (); const int secondaryWeaponCarried = bestSecondaryCarried (); @@ -494,7 +494,7 @@ void Bot::updatePickups () { } // weapon replacement is not allowed - if (!cv_pickup_best.bool_ ()) { + if (!cv_pickup_best) { allowPickup = false; pickupType = Pickup::None; } @@ -504,7 +504,7 @@ void Bot::updatePickups () { pickupType = Pickup::Shield; // weapon replacement is not allowed - if (!cv_pickup_best.bool_ ()) { + if (!cv_pickup_best) { allowPickup = false; pickupType = Pickup::None; } @@ -517,7 +517,7 @@ void Bot::updatePickups () { allowPickup = true; pickupType = Pickup::PlantedC4; } - else if (cv_pickup_custom_items.bool_ () && util.isItem (ent) && !classname.startsWith ("item_thighpack")) { + else if (cv_pickup_custom_items && util.isItem (ent) && !classname.startsWith ("item_thighpack")) { allowPickup = true; pickupType = Pickup::Items; } @@ -577,8 +577,8 @@ void Bot::updatePickups () { const int index = findDefendNode (origin); - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (cv_camping_time_min.float_ (), cv_camping_time_max.float_ ()), true); // push camp task on to stack - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (3.0f, 6.0f), true); // push move command + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (cv_camping_time_min.as (), cv_camping_time_max.as ()), true); // push camp task on to stack + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg (3.0f, 6.0f), true); // push move command // decide to duck or not to duck selectCampButtons (index); @@ -597,7 +597,7 @@ void Bot::updatePickups () { const int index = findDefendNode (origin); const Path &path = graph[index]; - const float bombTimer = mp_c4timer.float_ (); + const float bombTimer = mp_c4timer.as (); const float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin); if (timeMidBlowup > game.time ()) { @@ -672,7 +672,7 @@ void Bot::updatePickups () { const int index = findDefendNode (origin); const auto &path = graph[index]; - const float timeToExplode = bots.getTimeBombPlanted () + mp_c4timer.float_ () - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin); + const float timeToExplode = bots.getTimeBombPlanted () + mp_c4timer.as () - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin); clearTask (Task::MoveToPosition); // remove any move tasks @@ -700,8 +700,8 @@ void Bot::updatePickups () { if (!m_defendedBomb && m_difficulty >= Difficulty::Normal && rg.chance (75) && m_healthValue < 60) { const int index = findDefendNode (origin); - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (cv_camping_time_min.float_ (), cv_camping_time_max.float_ ()), true); // push camp task on to stack - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (10.0f, 30.0f), true); // push move command + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (cv_camping_time_min.as (), cv_camping_time_max.as ()), true); // push camp task on to stack + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg (10.0f, 30.0f), true); // push move command // decide to duck or not to duck selectCampButtons (index); @@ -839,7 +839,7 @@ Vector Bot::getCampDirection (const Vector &dest) { void Bot::showChatterIcon (bool show, bool disconnect) { // this function depending on show boolean, shows/remove chatter, icon, on the head of bot. - if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.int_ () != 2) { + if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.as () != 2) { return; } @@ -877,7 +877,7 @@ void Bot::showChatterIcon (bool show, bool disconnect) { void Bot::instantChatter (int type) { // this function sends instant chatter messages. if (!game.is (GameFlags::HasBotVoice) - || cv_radio_mode.int_ () != 2 + || cv_radio_mode.as () != 2 || !conf.hasChatterBank (type) || !conf.hasChatterBank (Chatter::DiePain)) { @@ -894,7 +894,7 @@ void Bot::instantChatter (int type) { const int ownIndex = index (); auto writeChatterSound = [&msg] (ChatterItem item) { - msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.str (), kPathSeparator, item.name)); + msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.as (), kPathSeparator, item.name)); }; for (auto &client : util.getClients ()) { @@ -920,12 +920,12 @@ void Bot::instantChatter (int type) { void Bot::pushRadioMessage (int message) { // this function inserts the radio message into the message queue - if (cv_radio_mode.int_ () == 0 || m_numFriendsLeft == 0) { + if (cv_radio_mode.as () == 0 || m_numFriendsLeft == 0) { return; } m_forceRadio = !game.is (GameFlags::HasBotVoice) || !conf.hasChatterBank (message) - || cv_radio_mode.int_ () != 2; // use radio instead voice + || cv_radio_mode.as () != 2; // use radio instead voice m_radioSelect = message; pushMsgQueue (BotMsg::Radio); @@ -934,7 +934,7 @@ void Bot::pushRadioMessage (int message) { void Bot::pushChatterMessage (int message) { // this function inserts the voice message into the message queue (mostly same as above) - if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.int_ () != 2 || !conf.hasChatterBank (message) || m_numFriendsLeft == 0) { + if (!game.is (GameFlags::HasBotVoice) || cv_radio_mode.as () != 2 || !conf.hasChatterBank (message) || m_numFriendsLeft == 0) { return; } bool sendMessage = false; @@ -991,21 +991,21 @@ void Bot::checkMsgQueue () { } m_buyPending = false; - m_nextBuyTime = game.time () + rg.get (0.5f, 1.3f); + m_nextBuyTime = game.time () + rg (0.5f, 1.3f); // if freezetime is very low do not delay the buy process - if (mp_freezetime.float_ () <= 1.0f) { + if (mp_freezetime.as () <= 1.0f) { m_nextBuyTime = game.time (); m_ignoreBuyDelay = true; } // if bot buying is off then no need to buy - if (!cv_botbuy.bool_ ()) { + if (!cv_botbuy) { m_buyState = BuyState::Done; } // if fun-mode no need to buy - if (cv_jasonmode.bool_ ()) { + if (cv_jasonmode) { m_buyState = BuyState::Done; selectWeaponById (Weapon::Knife); } @@ -1067,7 +1067,7 @@ void Bot::checkMsgQueue () { if (m_radioSelect != -1) { if ((m_radioSelect != Radio::ReportingIn && m_forceRadio) - || cv_radio_mode.int_ () != 2 + || cv_radio_mode.as () != 2 || !conf.hasChatterBank (m_radioSelect) || !game.is (GameFlags::HasBotVoice)) { @@ -1116,7 +1116,7 @@ void Bot::checkMsgQueue () { bool Bot::isWeaponRestricted (int wid) { // this function checks for weapon restrictions. - auto val = cv_restricted_weapons.str (); + auto val = cv_restricted_weapons.as (); if (val.empty ()) { return isWeaponRestrictedAMX (wid); // no banned weapons @@ -1213,7 +1213,7 @@ int Bot::pickBestWeapon (Array &vec, int moneySave) { // swap array values vec.reverse (); - return vec[static_cast (static_cast (vec.length () - 1) * cr::log10 (rg.get (1.0f, cr::powf (10.0f, buyFactor))) / buyFactor + 0.5f)]; + return vec[static_cast (static_cast (vec.length () - 1) * cr::log10 (rg (1.0f, cr::powf (10.0f, buyFactor))) / buyFactor + 0.5f)]; } int chance = 95; @@ -1232,7 +1232,7 @@ int Bot::pickBestWeapon (Array &vec, int moneySave) { const auto &weapon = tab[w]; // if we have enough money for weapon, buy it - if (weapon.price + moneySave < m_moneyAmount + rg.get (50, 200) && rg.chance (chance)) { + if (weapon.price + moneySave < m_moneyAmount + rg (50, 200) && rg.chance (chance)) { return w; } } @@ -1246,7 +1246,7 @@ void Bot::buyStuff () { m_nextBuyTime = game.time (); if (!m_ignoreBuyDelay) { - m_nextBuyTime += rg.get (0.3f, 0.5f); + m_nextBuyTime += rg (0.3f, 0.5f); } int count = 0; @@ -1263,7 +1263,7 @@ void Bot::buyStuff () { const bool isOldGame = game.is (GameFlags::Legacy); const bool hasDefaultPistols = (pev->weapons & (cr::bit (Weapon::USP) | cr::bit (Weapon::Glock18))); - const bool isFirstRound = m_moneyAmount == mp_startmoney.int_ (); + const bool isFirstRound = m_moneyAmount == mp_startmoney.as (); switch (m_buyState) { case BuyState::PrimaryWeapon: // if no primary weapon and bot has some money, buy a primary weapon @@ -1308,7 +1308,7 @@ void Bot::buyStuff () { const int *limit = conf.getEconLimit (); int prostock = 0; - const int disrespectEconomicsPct = 100 - cv_economics_disrespect_percent.int_ (); + const int disrespectEconomicsPct = 100 - cv_economics_disrespect_percent.as (); // filter out weapons with bot economics switch (m_personality) { @@ -1389,12 +1389,12 @@ void Bot::buyStuff () { break; } - if (ignoreWeapon && tab[25].teamStandard == 1 && cv_economics_rounds.bool_ ()) { + if (ignoreWeapon && tab[25].teamStandard == 1 && cv_economics_rounds) { continue; } // save money for grenade for example? - moneySave = rg.get (500, 1000); + moneySave = rg (500, 1000); if (bots.getLastWinner () == m_team) { moneySave = 0; @@ -1441,7 +1441,7 @@ void Bot::buyStuff () { break; case BuyState::ArmorVestHelm: // if armor is damaged and bot has some money, buy some armor - if (pev->armorvalue < rg.get (50.0f, 80.0f) + if (pev->armorvalue < rg (50.0f, 80.0f) && teamHasGoodEconomics && (isPistolMode || (teamHasGoodEconomics && hasPrimaryWeapon ()))) { @@ -1458,8 +1458,8 @@ void Bot::buyStuff () { case BuyState::SecondaryWeapon: // if bot has still some money, buy a better secondary weapon if (isPistolMode || (isFirstRound && hasDefaultPistols && rg.chance (60)) - || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg.get (2000, 3000)) - || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg.get (7500, 9000))) { + || (hasDefaultPistols && bots.getLastWinner () == m_team && m_moneyAmount > rg (2000, 3000)) + || (hasPrimaryWeapon () && hasDefaultPistols && m_moneyAmount > rg (7500, 9000))) { do { pref--; @@ -1492,7 +1492,7 @@ void Bot::buyStuff () { continue; } - if (selectedWeapon->price <= (m_moneyAmount - rg.get (100, 200))) { + if (selectedWeapon->price <= (m_moneyAmount - rg (100, 200))) { choices.emplace (*pref); } @@ -1500,7 +1500,7 @@ void Bot::buyStuff () { // found a desired weapon? if (!choices.empty ()) { - selectedWeapon = &tab[pickBestWeapon (choices, rg.get (100, 200))]; + selectedWeapon = &tab[pickBestWeapon (choices, rg (100, 200))]; } else { selectedWeapon = nullptr; @@ -1527,7 +1527,7 @@ void Bot::buyStuff () { case BuyState::Ammo: // buy enough primary & secondary ammo (do not check for money here) for (int i = 0; i < 7; ++i) { - issueCommand ("buyammo%d", rg.get (1, 2)); // simulate human + issueCommand ("buyammo%d", rg (1, 2)); // simulate human } // buy enough ammo @@ -1654,7 +1654,7 @@ void Bot::overrideConditions () { } // special handling, if we have a knife in our hands - if (isKnifeMode () && (util.isPlayer (m_enemy) || (cv_attack_monsters.bool_ () && util.isMonster (m_enemy)))) { + if (isKnifeMode () && (util.isPlayer (m_enemy) || (cv_attack_monsters && util.isMonster (m_enemy)))) { const float length = pev->origin.distance2d (m_enemy->v.origin); // do nodes movement if enemy is not reachable with a knife @@ -1802,7 +1802,7 @@ void Bot::setLastVictim (edict_t *ent) { m_lastVictim = ent; m_lastVictimOrigin = ent->v.origin; - m_forgetLastVictimTimer.start (rg.get (1.0f, 2.0f)); + m_forgetLastVictimTimer.start (rg (1.0f, 2.0f)); } void Bot::setConditions () { @@ -1897,7 +1897,7 @@ void Bot::setConditions () { } // don't listen if seeing enemy, just checked for sounds or being blinded (because its inhuman) - if (!cv_ignore_enemies.bool_ () + if (!cv_ignore_enemies && m_soundUpdateTime < game.time () && m_blindTime < game.time () && m_seeEnemyTime + 1.0f < game.time ()) { @@ -1991,12 +1991,12 @@ void Bot::filterTasks () { if (util.isPlayer (m_lastEnemy) && !m_lastEnemyOrigin.empty () && !m_hasC4) { float retreatLevel = (100.0f - (m_healthValue > 70.0f ? 100.0f : m_healthValue)) * tempFear; // retreat level depends on bot health - if (m_numEnemiesLeft > m_numFriendsLeft / 2 && m_retreatTime < game.time () && m_seeEnemyTime - rg.get (2.0f, 4.0f) < game.time ()) { + if (m_numEnemiesLeft > m_numFriendsLeft / 2 && m_retreatTime < game.time () && m_seeEnemyTime - rg (2.0f, 4.0f) < game.time ()) { float timeSeen = m_seeEnemyTime - game.time (); float timeHeard = m_heardSoundTime - game.time (); float ratio = 0.0f; - m_retreatTime = game.time () + rg.get (1.0f, 4.0f); + m_retreatTime = game.time () + rg (1.0f, 4.0f); if (timeSeen > timeHeard) { timeSeen += 10.0f; @@ -2042,7 +2042,7 @@ void Bot::filterTasks () { && !m_isUsingGrenade && m_currentNodeIndex != graph.getNearest (m_lastEnemyOrigin) && m_personality != Personality::Careful - && !cv_ignore_enemies.bool_ ()) { + && !cv_ignore_enemies) { float desireLevel = 4096.0f - ((1.0f - tempAgression) * m_lastEnemyOrigin.distance (pev->origin)); @@ -2166,7 +2166,7 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) { } // this is best place to handle some voice commands report team some info - if (cv_radio_mode.int_ () > 1) { + if (cv_radio_mode.as () > 1) { if (rg.chance (90)) { if (tid == Task::Blind) { pushChatterMessage (Chatter::Blind); @@ -2190,8 +2190,8 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) { } } - if (cv_debug_goal.int_ () != kInvalidNodeIndex) { - m_chosenGoalIndex = cv_debug_goal.int_ (); + if (cv_debug_goal.as () != kInvalidNodeIndex) { + m_chosenGoalIndex = cv_debug_goal.as (); } else { m_chosenGoalIndex = getTask ()->data; @@ -2346,7 +2346,7 @@ void Bot::checkRadioQueue () { } } } - int allowedFollowers = cv_user_max_followers.int_ (); + int allowedFollowers = cv_user_max_followers.as (); if (m_radioEntity->v.weapons & cr::bit (Weapon::C4)) { allowedFollowers = 1; @@ -2395,7 +2395,7 @@ void Bot::checkRadioQueue () { pushRadioMessage (Radio::RogerThat); m_campButtons = 0; - startTask (Task::Pause, TaskPri::Pause, kInvalidNodeIndex, game.time () + rg.get (30.0f, 60.0f), false); + startTask (Task::Pause, TaskPri::Pause, kInvalidNodeIndex, game.time () + rg (30.0f, 60.0f), false); } } break; @@ -2414,10 +2414,10 @@ void Bot::checkRadioQueue () { m_fearLevel = 0.0f; } - if (rg.chance (45) && cv_radio_mode.int_ () == 2) { + if (rg.chance (45) && cv_radio_mode.as () == 2) { pushChatterMessage (Chatter::OnMyWay); } - else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.int_ () != 2) { + else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as () != 2) { pushRadioMessage (Radio::RogerThat); } tryHeadTowardRadioMessage (); @@ -2448,10 +2448,10 @@ void Bot::checkRadioQueue () { m_fearLevel = 0.0f; } - if (rg.chance (45) && cv_radio_mode.int_ () == 2) { + if (rg.chance (45) && cv_radio_mode.as () == 2) { pushChatterMessage (Chatter::OnMyWay); } - else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.int_ () != 2 && rg.chance (50)) { + else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as () != 2 && rg.chance (50)) { pushRadioMessage (Radio::RogerThat); } tryHeadTowardRadioMessage (); @@ -2463,10 +2463,10 @@ void Bot::checkRadioQueue () { case Radio::GoGoGo: if (m_radioEntity == m_targetEntity) { - if (rg.chance (45) && cv_radio_mode.int_ () == 2) { + if (rg.chance (45) && cv_radio_mode.as () == 2) { pushRadioMessage (Radio::RogerThat); } - else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.int_ () != 2) { + else if (m_radioOrder == Radio::NeedBackup && cv_radio_mode.as () != 2) { pushRadioMessage (Radio::RogerThat); } @@ -2492,7 +2492,7 @@ void Bot::checkRadioQueue () { getTask ()->time = game.time (); m_targetEntity = nullptr; - m_position = m_radioEntity->v.origin + m_radioEntity->v.v_angle.forward () * rg.get (1024.0f, 2048.0f); + m_position = m_radioEntity->v.origin + m_radioEntity->v.v_angle.forward () * rg (1024.0f, 2048.0f); clearSearchNodes (); startTask (Task::MoveToPosition, TaskPri::MoveToPosition, kInvalidNodeIndex, 0.0f, true); @@ -2546,7 +2546,7 @@ void Bot::checkRadioQueue () { getTask ()->time = game.time (); } m_targetEntity = nullptr; - m_position = m_radioEntity->v.origin + m_radioEntity->v.v_angle.forward () * rg.get (1024.0f, 2048.0f); + m_position = m_radioEntity->v.origin + m_radioEntity->v.v_angle.forward () * rg (1024.0f, 2048.0f); clearSearchNodes (); startTask (Task::MoveToPosition, TaskPri::MoveToPosition, kInvalidNodeIndex, 0.0f, true); @@ -2577,7 +2577,7 @@ void Bot::checkRadioQueue () { m_agressionLevel = 0.0f; } if (getCurrentTaskId () == Task::Camp) { - getTask ()->time += rg.get (10.0f, 15.0f); + getTask ()->time += rg (10.0f, 15.0f); } else { // don't pause/camp anymore @@ -2735,7 +2735,7 @@ void Bot::checkRadioQueue () { pushRadioMessage (Radio::RogerThat); if (getCurrentTaskId () == Task::Camp) { - getTask ()->time = game.time () + rg.get (30.0f, 60.0f); + getTask ()->time = game.time () + rg (30.0f, 60.0f); } else { // don't pause anymore @@ -2774,10 +2774,10 @@ void Bot::checkRadioQueue () { const int index = findDefendNode (m_radioEntity->v.origin); // push camp task on to stack - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (30.0f, 60.0f), true); + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (30.0f, 60.0f), true); // push move command - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (30.0f, 60.0f), true); + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg (30.0f, 60.0f), true); // decide to duck or not to duck selectCampButtons (index); @@ -2874,7 +2874,7 @@ void Bot::frame () { } // kick the bot if stay time is over, the quota maintain will add new bot for us later - if (cv_rotate_bots.bool_ () && m_stayTime < game.time ()) { + if (cv_rotate_bots && m_stayTime < game.time ()) { m_kickedByRotation = true; // kicked by rotation, so not save bot name if save bot names is active kick (); @@ -2894,7 +2894,7 @@ void Bot::update () { if (m_team == Team::Terrorist && game.mapIs (MapFlags::Demolition)) { m_hasC4 = !!(pev->weapons & cr::bit (Weapon::C4)); - if (m_hasC4 && (cv_ignore_objectives.bool_ () || cv_jasonmode.bool_ ())) { + if (m_hasC4 && (cv_ignore_objectives || cv_jasonmode)) { m_hasC4 = false; } } @@ -2920,12 +2920,12 @@ void Bot::update () { } else if (!m_isAlive) { // we got a teamkiller? vote him away... - if (m_voteKickIndex != m_lastVoteKick && cv_tkpunish.bool_ ()) { + if (m_voteKickIndex != m_lastVoteKick && cv_tkpunish) { issueCommand ("vote %d", m_voteKickIndex); m_lastVoteKick = m_voteKickIndex; // if bot tk punishment is enabled slay the tk - if (cv_tkpunish.int_ () != 2 || util.isFakeClient (game.entityOfIndex (m_voteKickIndex))) { + if (cv_tkpunish.as () != 2 || util.isFakeClient (game.entityOfIndex (m_voteKickIndex))) { return; } auto killer = game.entityOfIndex (m_lastVoteKick); @@ -2942,7 +2942,7 @@ void Bot::update () { } else if (m_buyingFinished && !(pev->maxspeed < 10.0f && tid != Task::PlantBomb && tid != Task::DefuseBomb) - && !cv_freeze_bots.bool_ () + && !cv_freeze_bots && !graph.hasChanged ()) { botMovement = true; @@ -2961,17 +2961,13 @@ void Bot::update () { } void Bot::logicDuringFreezetime () { + pev->button = 0; + if (m_changeViewTime > game.time ()) { return; } - // simply skip randomly - if (rg.chance (10)) { - return; - } - pev->button &= ~IN_DUCK; - - if (rg.chance (15) && m_jumpTime + rg.get (1.0, 2.0f) < game.time ()) { + if (rg.chance (15) && m_jumpTime + rg (1.0f, 2.0f) < game.time ()) { pev->button |= IN_JUMP; m_jumpTime = game.time (); } @@ -2979,7 +2975,7 @@ void Bot::logicDuringFreezetime () { teammates.clear (); for (const auto &bot : bots) { - if (bot->m_isAlive && bot->m_team == m_team && seesEntity (bot->pev->origin) && bot.get () != this) { + if (bot->m_isAlive && bot->m_team == m_team && bot.get () != this && seesEntity (bot->pev->origin)) { teammates.push (bot.get ()); } } @@ -2997,7 +2993,7 @@ void Bot::logicDuringFreezetime () { m_needToSendWelcomeChat = false; } } - m_changeViewTime = game.time () + rg.get (1.25f, 2.0f); + m_changeViewTime = game.time () + rg (1.25f, 2.0f); } void Bot::executeTasks () { @@ -3013,8 +3009,8 @@ void Bot::checkSpawnConditions () { // this function is called instead of ai when buying finished, but freezetime is not yet left. // switch to knife if time to do this - if (m_checkKnifeSwitch && m_buyingFinished && m_spawnTime + rg.get (5.0f, 7.5f) < game.time ()) { - if (rg.get (1, 100) < 2 && cv_spraypaints.bool_ ()) { + if (m_checkKnifeSwitch && m_buyingFinished && m_spawnTime + rg (5.0f, 7.5f) < game.time ()) { + if (rg (1, 100) < 2 && cv_spraypaints) { startTask (Task::Spraypaint, TaskPri::Spraypaint, kInvalidNodeIndex, game.time () + 1.0f, false); } @@ -3032,13 +3028,13 @@ void Bot::checkSpawnConditions () { } m_checkKnifeSwitch = false; - if (rg.chance (cv_user_follow_percent.int_ ()) && game.isNullEntity (m_targetEntity) && !m_isLeader && !m_hasC4 && rg.chance (50)) { + if (rg.chance (cv_user_follow_percent.as ()) && game.isNullEntity (m_targetEntity) && !m_isLeader && !m_hasC4 && rg.chance (50)) { decideFollowUser (); } } // check if we already switched weapon mode - if (m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + rg.get (3.0f, 4.5f) < game.time ()) { + if (m_checkWeaponSwitch && m_buyingFinished && m_spawnTime + rg (3.0f, 4.5f) < game.time ()) { if (hasShield () && isShieldDrawn ()) { pev->button |= IN_ATTACK2; } @@ -3118,7 +3114,7 @@ void Bot::logic () { } // some stuff required by by chatter engine - if (cv_radio_mode.int_ () == 2) { + if (cv_radio_mode.as () == 2) { if ((m_states & Sense::SeeingEnemy) && !game.isNullEntity (m_enemy)) { int hasFriendNearby = numFriendsNear (pev->origin, 512.0f); @@ -3160,7 +3156,7 @@ void Bot::logic () { m_wantsToFire = false; // avoid flyings grenades, if needed - if (cv_avoid_grenades.bool_ () && !m_isCreature) { + if (cv_avoid_grenades && !m_isCreature) { avoidGrenades (); } m_isUsingGrenade = false; @@ -3208,7 +3204,7 @@ void Bot::logic () { } // check the darkness - if (cv_check_darkness.bool_ ()) { + if (cv_check_darkness) { checkDarkness (); } @@ -3226,7 +3222,7 @@ void Bot::logic () { checkParachute (); // display some debugging thingy to host entity - if (cv_debug.int_ () >= 1) { + if (cv_debug.as () >= 1) { showDebugOverlay (); } @@ -3255,7 +3251,7 @@ void Bot::showDebugOverlay () { displayDebugOverlay = true; } - if (!displayDebugOverlay && cv_debug.int_ () >= 2) { + if (!displayDebugOverlay && cv_debug.as () >= 2) { Bot *nearest = nullptr; if (util.findNearestPlayer (reinterpret_cast (&nearest), overlayEntity, 128.0f, false, true, true, true) && nearest == this) { @@ -3394,7 +3390,7 @@ void Bot::showDebugOverlay () { } bool Bot::hasHostage () { - if (cv_ignore_objectives.bool_ () || game.mapIs (MapFlags::Demolition)) { + if (cv_ignore_objectives || game.mapIs (MapFlags::Demolition)) { return false; } @@ -3422,10 +3418,10 @@ void Bot::takeDamage (edict_t *inflictor, int damage, int armor, int bits) { updatePracticeValue (damage); } - if (util.isPlayer (inflictor) || (cv_attack_monsters.bool_ () && util.isMonster (inflictor))) { + if (util.isPlayer (inflictor) || (cv_attack_monsters && util.isMonster (inflictor))) { const auto inflictorTeam = game.getTeam (inflictor); - if (!util.isMonster (inflictor) && cv_tkpunish.bool_ () && inflictorTeam == m_team && !util.isFakeClient (inflictor)) { + if (!util.isMonster (inflictor) && cv_tkpunish && inflictorTeam == m_team && !util.isFakeClient (inflictor)) { // alright, die you team killer!!! m_actualReactionTime = 0.0f; m_seeEnemyTime = game.time (); @@ -3483,7 +3479,7 @@ void Bot::takeBlind (int alpha) { // this function gets called by network message handler, when screenfade message get's send // it's used to make bot blind from the grenade. - m_viewDistance = rg.get (10.0f, 20.0f); + m_viewDistance = rg (10.0f, 20.0f); // do not take in effect some unique map effects on round start if (bots.getRoundStartTime () + 5.0f < game.time ()) { @@ -3595,7 +3591,7 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) { } void Bot::pushChatMessage (int type, bool isTeamSay) { - if (!conf.hasChatBank (type) || !cv_chat.bool_ ()) { + if (!conf.hasChatBank (type) || !cv_chat) { return; } @@ -3668,7 +3664,7 @@ void Bot::debugMsgInternal (StringRef str) { if (game.isDedicated ()) { return; } - const int level = cv_debug.int_ (); + const int level = cv_debug.as (); if (level <= 2) { return; @@ -3707,7 +3703,7 @@ Vector Bot::isBombAudible () { } const Vector &bombOrigin = graph.getBombOrigin (); - const float timeElapsed = ((game.time () - bots.getTimeBombPlanted ()) / mp_c4timer.float_ ()) * 100.0f; + const float timeElapsed = ((game.time () - bots.getTimeBombPlanted ()) / mp_c4timer.as ()) * 100.0f; float desiredRadius = 768.0f; // start the manual calculations @@ -3792,7 +3788,7 @@ float Bot::getBombTimeleft () const { if (!bots.isBombPlanted ()) { return 0.0f; } - return cr::max (bots.getTimeBombPlanted () + mp_c4timer.float_ () - game.time (), 0.0f); + return cr::max (bots.getTimeBombPlanted () + mp_c4timer.as () - game.time (), 0.0f); } bool Bot::isOutOfBombTimer () { @@ -3904,8 +3900,8 @@ void Bot::updateHearing () { auto error = kSprayDistance * cr::powf (nearestDistanceSq, 0.5f) / 2048.0f; auto origin = hearedEnemy->v.origin; - origin.x = origin.x + rg.get (-error, error); - origin.y = origin.y + rg.get (-error, error); + origin.x = origin.x + rg (-error, error); + origin.y = origin.y + rg (-error, error); return origin; }; @@ -3951,7 +3947,7 @@ void Bot::updateHearing () { // check if heard enemy can be shoot through some obstacle else { - if (cv_shoots_thru_walls.bool_ () + if (cv_shoots_thru_walls && m_lastEnemy == hearedEnemy && rg.chance (conf.getDifficultyTweaks (m_difficulty)->hearThruPct) && m_seeEnemyTime + 3.0f > game.time () @@ -3981,7 +3977,7 @@ void Bot::enteredBuyZone (int buyState) { if (m_seeEnemyTime + 12.0f < game.time () && m_lastEquipTime + 15.0f < game.time () && m_inBuyZone - && (bots.getRoundStartTime () + rg.get (10.0f, 20.0f) + mp_buytime.float_ () < game.time ()) + && (bots.getRoundStartTime () + rg (10.0f, 20.0f) + mp_buytime.as () < game.time ()) && !bots.isBombPlanted () && m_moneyAmount > econLimit[EcoLimit::PrimaryGreater]) { @@ -4074,7 +4070,8 @@ float Bot::getShiftSpeed () { || isInWater () || isKnifeMode () || m_isStuck - || m_numEnemiesLeft <= 0) { + || m_numEnemiesLeft <= 0 + || !m_lostReachableNodeTimer.elapsed ()) { return pev->maxspeed; } diff --git a/src/chatlib.cpp b/src/chatlib.cpp index c3498ac..01a1a07 100644 --- a/src/chatlib.cpp +++ b/src/chatlib.cpp @@ -55,14 +55,14 @@ void BotChatManager::humanizePlayerName (String &playerName) { } // sometimes switch name to lower characters, only valid for the english languge - if (rg.chance (8) && cv_language.str () == "en") { + if (rg.chance (8) && cv_language.as () == "en") { playerName.lowercase (); } } void BotChatManager::addChatErrors (String &line) { // sometimes switch name to lower characters, only valid for the english languge - if (rg.chance (8) && cv_language.str () == "en") { + if (rg.chance (8) && cv_language.as () == "en") { line.lowercase (); } const auto length = static_cast (line.length ()); @@ -72,12 +72,13 @@ void BotChatManager::addChatErrors (String &line) { // "length / 2" percent of time drop a character if (rg.chance (percentile)) { - line.erase (static_cast (rg.get (length / 8, length - length / 8), 1)); + auto pos = rg (length / 8, length - length / 8); + line.erase (static_cast (pos)); } // "length" / 4 precent of time swap character if (rg.chance (percentile / 2)) { - size_t pos = static_cast (rg.get (length / 8, 3 * length / 8)); // choose random position in string + auto pos = static_cast (rg (length / 8, 3 * length / 8)); // choose random position in string cr::swap (line[pos], line[pos + 1]); } } @@ -86,7 +87,7 @@ void BotChatManager::addChatErrors (String &line) { bool BotChatManager::checkKeywords (StringRef line, String &reply) { // this function checks is string contain keyword, and generates reply to it - if (!cv_chat.bool_ () || line.empty ()) { + if (!cv_chat || line.empty ()) { return false; } @@ -135,7 +136,7 @@ bool BotChatManager::checkKeywords (StringRef line, String &reply) { void Bot::prepareChatMessage (StringRef message) { // this function parses messages from the botchat, replaces keywords and converts names into a more human style - if (!cv_chat.bool_ () || message.empty ()) { + if (!cv_chat || message.empty ()) { return; } m_chatBuffer = message; @@ -306,10 +307,10 @@ bool Bot::isReplyingToChat () { if (m_sayTextBuffer.entityIndex != -1 && !m_sayTextBuffer.sayText.empty ()) { // check is time to chat is good - if (m_sayTextBuffer.timeNextChat < game.time () + rg.get (m_sayTextBuffer.chatDelay / 2, m_sayTextBuffer.chatDelay)) { + if (m_sayTextBuffer.timeNextChat < game.time () + rg (m_sayTextBuffer.chatDelay / 2, m_sayTextBuffer.chatDelay)) { String replyText; - if (rg.chance (m_sayTextBuffer.chatProbability + rg.get (40, 70)) && checkChatKeywords (replyText)) { + if (rg.chance (m_sayTextBuffer.chatProbability + rg (40, 70)) && checkChatKeywords (replyText)) { prepareChatMessage (replyText); pushMsgQueue (BotMsg::Say); @@ -329,14 +330,14 @@ bool Bot::isReplyingToChat () { void Bot::checkForChat () { // say a text every now and then - if (m_isAlive || !cv_chat.bool_ () || game.is (GameFlags::CSDM)) { + if (m_isAlive || !cv_chat || game.is (GameFlags::CSDM)) { return; } // bot chatting turned on? - if (rg.chance (cv_chat_percent.int_ ()) - && m_lastChatTime + rg.get (6.0f, 10.0f) < game.time () - && bots.getLastChatTimestamp () + rg.get (2.5f, 5.0f) < game.time () + if (rg.chance (cv_chat_percent.as ()) + && m_lastChatTime + rg (6.0f, 10.0f) < game.time () + && bots.getLastChatTimestamp () + rg (2.5f, 5.0f) < game.time () && !isReplyingToChat ()) { if (conf.hasChatBank (Chat::Dead)) { @@ -364,7 +365,7 @@ void Bot::checkForChat () { } // clear the used line buffer every now and then - if (static_cast (m_sayTextBuffer.lastUsedSentences.length ()) > rg.get (4, 6)) { + if (static_cast (m_sayTextBuffer.lastUsedSentences.length ()) > rg (4, 6)) { m_sayTextBuffer.lastUsedSentences.clear (); } } @@ -373,7 +374,7 @@ void Bot::checkForChat () { void Bot::sendToChat (StringRef message, bool teamOnly) { // this function prints saytext message to all players - if (message.empty () || !cv_chat.bool_ ()) { + if (message.empty () || !cv_chat) { return; } issueCommand ("%s \"%s\"", teamOnly ? "say_team" : "say", message); diff --git a/src/combat.cpp b/src/combat.cpp index bf1a93a..7686570 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -58,7 +58,7 @@ int Bot::numEnemiesNear (const Vector &origin, const float radius) { } bool Bot::isEnemyHidden (edict_t *enemy) { - if (!cv_check_enemy_rendering.bool_ () || game.isNullEntity (enemy)) { + if (!cv_check_enemy_rendering || game.isNullEntity (enemy)) { return false; } const auto &v = enemy->v; @@ -100,7 +100,7 @@ bool Bot::isEnemyHidden (edict_t *enemy) { } bool Bot::isEnemyInvincible (edict_t *enemy) { - if (!cv_check_enemy_invincibility.bool_ () || game.isNullEntity (enemy)) { + if (!cv_check_enemy_invincibility || game.isNullEntity (enemy)) { return false; } const auto &v = enemy->v; @@ -217,7 +217,7 @@ bool Bot::checkBodyParts (edict_t *target) { bool Bot::seesEnemy (edict_t *player) { auto isBehindSmokeClouds = [&] (const Vector &pos) { - if (cv_smoke_grenade_checks.int_ () == 2) { + if (cv_smoke_grenade_checks.as () == 2) { return bots.isLineBlockedBySmoke (getEyesPos (), pos); } return false; @@ -228,7 +228,7 @@ bool Bot::seesEnemy (edict_t *player) { } bool ignoreFieldOfView = false; - if (cv_whose_your_daddy.bool_ () && util.isPlayer (pev->dmg_inflictor) && game.getTeam (pev->dmg_inflictor) != m_team) { + if (cv_whose_your_daddy && util.isPlayer (pev->dmg_inflictor) && game.getTeam (pev->dmg_inflictor) != m_team) { ignoreFieldOfView = true; } @@ -257,7 +257,7 @@ bool Bot::lookupEnemies () { // this function tries to find the best suitable enemy for the bot // do not search for enemies while we're blinded, or shooting disabled by user - if (m_enemyIgnoreTimer > game.time () || m_blindTime > game.time () || cv_ignore_enemies.bool_ ()) { + if (m_enemyIgnoreTimer > game.time () || m_blindTime > game.time () || cv_ignore_enemies) { return false; } edict_t *player, *newEnemy = nullptr; @@ -270,10 +270,12 @@ bool Bot::lookupEnemies () { else if (game.isNullEntity (m_enemy) && m_seeEnemyTime + 4.0f > game.time () && util.isAlive (m_lastEnemy)) { m_states |= Sense::SuspectEnemy; - // check if last enemy can be penetrated - const auto penetratePower = conf.findWeaponById (m_currentWeapon).penetratePower * 4; + const bool denyLastEnemy = pev->velocity.lengthSq2d () > 0.0f + && pev->origin.distanceSq2d (m_lastEnemyOrigin) < cr::sqrf (256.0f) + && m_shootTime + 1.5f > game.time (); - if (isPenetrableObstacle1 (m_lastEnemyOrigin, penetratePower)) { + if (!(m_aimFlags & (AimFlags::Enemy | AimFlags::PredictPath | AimFlags::Danger)) + && !denyLastEnemy && seesEntity (m_lastEnemyOrigin, true)) { m_aimFlags |= AimFlags::LastEnemy; } } @@ -298,14 +300,14 @@ bool Bot::lookupEnemies () { auto set = nullptr; // setup potential visibility set from engine - if (cv_use_engine_pvs_check.bool_ ()) { + if (cv_use_engine_pvs_check) { game.getVisibilitySet (this, true); } // ignore shielded enemies, while we have real one edict_t *shieldEnemy = nullptr; - if (cv_attack_monsters.bool_ ()) { + if (cv_attack_monsters) { // search the world for monsters... for (const auto &interesting : bots.getInterestingEntities ()) { if (!util.isMonster (interesting)) { @@ -313,7 +315,7 @@ bool Bot::lookupEnemies () { } // check the engine PVS - if (cv_use_engine_pvs_check.bool_ () && !game.checkVisibility (interesting, set)) { + if (cv_use_engine_pvs_check && !game.checkVisibility (interesting, set)) { continue; } @@ -343,12 +345,12 @@ bool Bot::lookupEnemies () { player = client.ent; // check the engine PVS - if (cv_use_engine_pvs_check.bool_ () && !game.checkVisibility (player, set)) { + if (cv_use_engine_pvs_check && !game.checkVisibility (player, set)) { continue; } // extra skill player can see through smoke... if being attacked - if (cv_whose_your_daddy.bool_ () && (player->v.button & (IN_ATTACK | IN_ATTACK2)) && m_viewDistance < m_maxViewDistance) { + if (cv_whose_your_daddy && (player->v.button & (IN_ATTACK | IN_ATTACK2)) && m_viewDistance < m_maxViewDistance) { nearestDistanceSq = cr::sqrf (m_maxViewDistance); } @@ -378,7 +380,7 @@ bool Bot::lookupEnemies () { } } - if (newEnemy != nullptr && (util.isPlayer (newEnemy) || (cv_attack_monsters.bool_ () && util.isMonster (newEnemy)))) { + if (newEnemy != nullptr && (util.isPlayer (newEnemy) || (cv_attack_monsters && util.isMonster (newEnemy)))) { bots.setCanPause (true); m_aimFlags |= AimFlags::Enemy; @@ -401,7 +403,7 @@ bool Bot::lookupEnemies () { } m_targetEntity = nullptr; // stop following when we see an enemy... - if (cv_whose_your_daddy.bool_ ()) { + if (cv_whose_your_daddy) { m_enemySurpriseTime = m_actualReactionTime * 0.5f; } else { @@ -475,7 +477,7 @@ bool Bot::lookupEnemies () { } // if no enemy visible check if last one shoot able through wall - if (cv_shoots_thru_walls.bool_ () + if (cv_shoots_thru_walls && rg.chance (conf.getDifficultyTweaks (m_difficulty)->seenThruPct) && isPenetrableObstacle (newEnemy->v.origin)) { @@ -528,12 +530,12 @@ Vector Bot::getBodyOffsetError (float distance) { const float hitError = distance / (cr::clamp (static_cast (m_difficulty), 1.0f, 4.0f) * 1280.0f); const auto &maxs = m_enemy->v.maxs, &mins = m_enemy->v.mins; - m_aimLastError = Vector (rg.get (mins.x * hitError, maxs.x * hitError), rg.get (mins.y * hitError, maxs.y * hitError), rg.get (mins.z * hitError * 0.5f, maxs.z * hitError * 0.5f)); + m_aimLastError = Vector (rg (mins.x * hitError, maxs.x * hitError), rg (mins.y * hitError, maxs.y * hitError), rg (mins.z * hitError * 0.5f, maxs.z * hitError * 0.5f)); const auto &aimError = conf.getDifficultyTweaks (m_difficulty) ->aimError; - m_aimLastError += Vector (rg.get (-aimError.x, aimError.x), rg.get (-aimError.y, aimError.y), rg.get (-aimError.z, aimError.z)); + m_aimLastError += Vector (rg (-aimError.x, aimError.x), rg (-aimError.y, aimError.y), rg (-aimError.z, aimError.z)); - m_aimErrorTime = game.time () + rg.get (0.4f, 0.8f); + m_aimErrorTime = game.time () + rg (0.4f, 0.8f); } return m_aimLastError; } @@ -582,6 +584,9 @@ Vector Bot::getEnemyBodyOffset () { if (distance > kSprayDistance && (isRecoilHigh () || usesShotgun ())) { headshotPct = 0; } + else if (distance <= kSprayDistance && isRecoilHigh ()) { + headshotPct = 0; + } // now check is our skill match to aim at head, else aim at enemy body if (m_enemyBodyPartSet == m_enemy || rg.chance (headshotPct)) { @@ -665,7 +670,7 @@ Vector Bot::getCustomHeight (float distance) { bool Bot::isFriendInLineOfFire (float distance) { // bot can't hurt teammates, if friendly fire is not enabled... - if (!mp_friendlyfire.bool_ () || game.is (GameFlags::CSDM)) { + if (!mp_friendlyfire || game.is (GameFlags::CSDM)) { return false; } @@ -710,7 +715,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) { if (penetratePower == 0) { return false; } - const auto method = cv_shoots_thru_walls.int_ (); + const auto method = cv_shoots_thru_walls.as (); // switch methods switch (method) { @@ -858,13 +863,13 @@ bool Bot::needToPauseFiring (float distance) { const float yPunch = cr::sqrf (cr::deg2rad (pev->punchangle.y)); const float tolerance = (100.0f - static_cast (m_difficulty) * 25.0f) / 99.0f; - const float baseTime = distance > kSprayDistance ? 0.65f : 0.48f; + const float baseTime = distance > kSprayDistance ? 0.55f : 0.38f; const float maxRecoil = static_cast (conf.getDifficultyTweaks (m_difficulty)->maxRecoil); // check if we need to compensate recoil if (cr::tanf (cr::sqrtf (cr::abs (xPunch) + cr::abs (yPunch))) * distance > offset + maxRecoil + tolerance) { if (m_firePause < game.time ()) { - m_firePause = game.time () + rg.get (baseTime, baseTime + maxRecoil * 0.01f * tolerance) - m_frameInterval; + m_firePause = game.time () + rg (baseTime, baseTime + maxRecoil * 0.01f * tolerance) - m_frameInterval; } return true; } @@ -1024,7 +1029,7 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) { const int offset = cr::abs (m_difficulty * 25 / 20 - 5); - m_shootTime = game.time () + 0.1f + rg.get (kMinFireDelay[offset], kMaxFireDelay[offset]); + m_shootTime = game.time () + 0.1f + rg (kMinFireDelay[offset], kMaxFireDelay[offset]); m_zoomCheckTime = game.time (); } } @@ -1059,7 +1064,7 @@ void Bot::fireWeapons () { } // use knife if near and good difficulty (l33t dude!) - if (cv_stab_close_enemies.bool_ () && m_difficulty >= Difficulty::Normal + if (cv_stab_close_enemies && m_difficulty >= Difficulty::Normal && m_healthValue > 80.0f && !game.isNullEntity (m_enemy) && m_healthValue >= m_enemy->v.health @@ -1255,13 +1260,14 @@ void Bot::attackMovement () { m_moveSpeed = pev->maxspeed; } } + const bool isFullView = !!(m_enemyParts & (Visibility::Head | Visibility::Body)); if (m_lastFightStyleCheck + 3.0f < game.time ()) { if (usesSniper ()) { m_fightStyle = Fight::Stay; } else if (usesRifle () || usesSubmachine () || usesHeavy ()) { - const int rand = rg.get (1, 100); + const int rand = rg (1, 100); if (distance < 768.0f) { m_fightStyle = Fight::Strafe; @@ -1297,7 +1303,7 @@ void Bot::attackMovement () { } // do not try to strafe while ducking - if (isDucking () || isInNarrowPlace ()) { + if (isDucking () || isInNarrowPlace () || !isFullView) { m_fightStyle = Fight::Stay; } const auto pistolStrafeDistance = game.is (GameFlags::CSDM) ? kSprayDistanceX2 * 3.0f : kSprayDistanceX2; @@ -1320,12 +1326,12 @@ void Bot::attackMovement () { } if (m_fightStyle == Fight::Strafe) { - auto swapStrafeCombatDir = [&] () { - m_combatStrafeDir = (m_combatStrafeDir == Dodge::Left ? Dodge::Right : Dodge::Left); + auto swapDodgeDirection = [&] () { + m_dodgeStrafeDir = (m_dodgeStrafeDir == Dodge::Left ? Dodge::Right : Dodge::Left); }; auto strafeUpdateTime = [] () { - return game.time () + rg.get (0.3f, 1.0f); + return game.time () + rg (0.3f, 1.0f); }; // to start strafing, we have to first figure out if the target is on the left side or right side @@ -1334,14 +1340,14 @@ void Bot::attackMovement () { const auto &rightSide = m_enemy->v.v_angle.right ().normalize2d_apx (); if ((dirToPoint | rightSide) < 0.0f) { - m_combatStrafeDir = Dodge::Right; + m_dodgeStrafeDir = Dodge::Right; } else { - m_combatStrafeDir = Dodge::Left; + m_dodgeStrafeDir = Dodge::Left; } if (rg.chance (30)) { - swapStrafeCombatDir (); + swapDodgeDirection (); } m_strafeSetTime = strafeUpdateTime (); } @@ -1349,12 +1355,12 @@ void Bot::attackMovement () { const bool wallOnRight = checkWallOnRight (); const bool wallOnLeft = checkWallOnLeft (); - if (m_combatStrafeDir == Dodge::Left) { + if (m_dodgeStrafeDir == Dodge::Left) { if (!wallOnLeft) { m_strafeSpeed = -pev->maxspeed; } else if (!wallOnRight) { - swapStrafeCombatDir (); + swapDodgeDirection (); m_strafeSetTime = strafeUpdateTime (); m_strafeSpeed = pev->maxspeed; @@ -1369,7 +1375,7 @@ void Bot::attackMovement () { m_strafeSpeed = pev->maxspeed; } else if (!wallOnLeft) { - swapStrafeCombatDir (); + swapDodgeDirection (); m_strafeSetTime = strafeUpdateTime (); m_strafeSpeed = -pev->maxspeed; @@ -1388,7 +1394,7 @@ void Bot::attackMovement () { if (m_difficulty >= Difficulty::Normal && (m_jumpTime + 5.0f < game.time () && isOnFloor () - && rg.get (0, 1000) < (m_isReloading ? 8 : 2) + && rg (0, 1000) < (m_isReloading ? 8 : 2) && pev->velocity.length2d () > 150.0f) && !usesSniper ()) { pev->button |= IN_JUMP; @@ -1401,7 +1407,7 @@ void Bot::attackMovement () { m_duckTime = game.time () + m_frameInterval * 3.0f; } else if ((distance > kSprayDistanceX2 && hasPrimaryWeapon ()) - && (m_enemyParts & (Visibility::Head | Visibility::Body)) + && isFullView && getCurrentTaskId () != Task::SeekCover && getCurrentTaskId () != Task::Hunt) { @@ -1418,7 +1424,7 @@ void Bot::attackMovement () { if (m_difficulty >= Difficulty::Normal && isOnFloor () && m_duckTime < game.time ()) { if (distance < kSprayDistanceX2) { - if (rg.get (0, 1000) < rg.get (5, 10) && pev->velocity.length2d () > 150.0f && isInViewCone (m_enemy->v.origin)) { + if (rg (0, 1000) < rg (5, 10) && pev->velocity.length2d () > 150.0f && isInViewCone (m_enemy->v.origin)) { pev->button |= IN_JUMP; } } @@ -1585,7 +1591,7 @@ bool Bot::hasAnyWeapons () { } bool Bot::isKnifeMode () { - return cv_jasonmode.bool_ () || (usesKnife () && !hasAnyWeapons ()) || m_isCreature; + return cv_jasonmode || (usesKnife () && !hasAnyWeapons ()) || m_isCreature; } bool Bot::isGrenadeWar () { @@ -1597,7 +1603,7 @@ bool Bot::isGrenadeWar () { } // if we're forced to via cvar - if (cv_grenadier_mode.bool_ ()) { + if (cv_grenadier_mode) { return true; } return game.mapIs (MapFlags::GrenadeWar); // in case map was flagged @@ -1717,7 +1723,7 @@ void Bot::decideFollowUser () { void Bot::updateTeamCommands () { // prevent spamming - if (m_timeTeamOrder > game.time () + 2.0f || game.is (GameFlags::FreeForAll) || !cv_radio_mode.int_ ()) { + if (m_timeTeamOrder > game.time () + 2.0f || game.is (GameFlags::FreeForAll) || !cv_radio_mode.as ()) { return; } @@ -1739,20 +1745,20 @@ void Bot::updateTeamCommands () { // has teammates? if (memberNear) { - if (m_personality == Personality::Rusher && cv_radio_mode.int_ () == 2) { + if (m_personality == Personality::Rusher && cv_radio_mode.as () == 2) { pushRadioMessage (Radio::StormTheFront); } - else if (m_personality != Personality::Rusher && cv_radio_mode.int_ () == 2) { + else if (m_personality != Personality::Rusher && cv_radio_mode.as () == 2) { pushRadioMessage (Radio::TeamFallback); } } - else if (memberExists && cv_radio_mode.int_ () == 1) { + else if (memberExists && cv_radio_mode.as () == 1) { pushRadioMessage (Radio::TakingFireNeedAssistance); } - else if (memberExists && cv_radio_mode.int_ () == 2) { + else if (memberExists && cv_radio_mode.as () == 2) { pushChatterMessage (Chatter::ScaredEmotion); } - m_timeTeamOrder = game.time () + rg.get (15.0f, 30.0f); + m_timeTeamOrder = game.time () + rg (15.0f, 30.0f); } bool Bot::isGroupOfEnemies (const Vector &location, int numEnemies, float radius) { @@ -1871,7 +1877,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) { // returns null vector if toss is not feasible. TraceResult tr {}; - const float gravity = sv_gravity.float_ () * 0.55f; + const float gravity = sv_gravity.as () * 0.55f; // prevent div by zero in some strange situations if (cr::fzero (gravity)) { @@ -1931,7 +1937,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) { Vector velocity = stop - start; TraceResult tr {}; - const float gravity = sv_gravity.float_ () * 0.55f; + const float gravity = sv_gravity.as () * 0.55f; // prevent div by zero in some strange situations if (cr::fzero (gravity)) { @@ -2010,7 +2016,7 @@ void Bot::checkGrenadesThrow () { ? m_lastEnemyOrigin.empty () : (preventibleTasks || isInNarrowPlace () - || cv_ignore_enemies.bool_ () + || cv_ignore_enemies || m_isUsingGrenade || m_isReloading || (isKnifeMode () && !bots.isBombPlanted ()) @@ -2094,7 +2100,7 @@ void Bot::checkGrenadesThrow () { // care about different grenades switch (grenadeToThrow) { case Weapon::Explosive: - if (mp_friendlyfire.bool_ () && numFriendsNear (m_lastEnemy->v.origin, 256.0f) > 0) { + if (mp_friendlyfire && numFriendsNear (m_lastEnemy->v.origin, 256.0f) > 0) { allowThrowing = false; } else { @@ -2245,7 +2251,7 @@ bool Bot::isEnemyNoticeable (float range) { } if (m_enemyParts & Visibility::Other) { - coverRatio += rg.get (10.0f, 25.0f); + coverRatio += rg (10.0f, 25.0f); } constexpr float kCloseRange = 300.0f; constexpr float kFarRange = 1000.0f; @@ -2311,7 +2317,7 @@ bool Bot::isEnemyNoticeable (float range) { } noticeChance = cr::max (0.1f, noticeChance * cr::abs (m_agressionLevel - m_fearLevel)); - return rg.get (0.0f, 100.0f) < noticeChance; + return rg (0.0f, 100.0f) < noticeChance; } int Bot::getAmmo () { diff --git a/src/config.cpp b/src/config.cpp index 7c1377f..8bc93ad 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -65,7 +65,7 @@ void BotConfig::loadMainConfig (bool isFirstLoad) { auto keyval = line.split (" "); if (keyval.length () > 1) { - auto ignore = String (cv_ignore_cvars_on_changelevel.str ()).split (","); + auto ignore = String (cv_ignore_cvars_on_changelevel.as ()).split (","); auto key = keyval[0].trim ().chars (); auto cvar = engfuncs.pfnCVarGetPointer (key); @@ -76,7 +76,7 @@ void BotConfig::loadMainConfig (bool isFirstLoad) { if (needsToIgnoreVar (ignore, key) && !strings.matches (value, cvar->string)) { // preserve quota number if it's zero - if (cv_quota.name () == cvar->name && cv_quota.int_ () <= 0) { + if (cv_quota.name () == cvar->name && cv_quota.as () <= 0) { engfuncs.pfnCvar_DirectSet (cvar, value); continue; } @@ -101,13 +101,13 @@ void BotConfig::loadMainConfig (bool isFirstLoad) { } // android is a bit hard to play, lower the difficulty by default - if (plat.android && cv_difficulty.int_ () > 3) { + if (plat.android && cv_difficulty.as () > 3) { cv_difficulty.set (3); } // bind the correct menu key for bot menu... if (!game.isDedicated ()) { - auto val = cv_bind_menu_key.str (); + auto val = cv_bind_menu_key.as (); if (!val.empty ()) { game.serverCommand ("bind \"%s\" \"yb menu\"", val); @@ -115,7 +115,7 @@ void BotConfig::loadMainConfig (bool isFirstLoad) { } // disable logger if requested - logger.disableLogWrite (cv_logger_disable_logfile.bool_ ()); + logger.disableLogWrite (cv_logger_disable_logfile); } void BotConfig::loadNamesConfig () { @@ -161,10 +161,10 @@ void BotConfig::loadWeaponsConfig () { for (size_t i = 0; i < data.length (); ++i) { if (as) { - weapons[i].teamAS = data[i].int_ (); + weapons[i].teamAS = data[i].as (); } else { - weapons[i].teamStandard = data[i].int_ (); + weapons[i].teamStandard = data[i].as (); } } }; @@ -176,7 +176,7 @@ void BotConfig::loadWeaponsConfig () { } for (size_t i = 0; i < to.length (); ++i) { - to[i] = data[i].int_ (); + to[i] = data[i].as (); } }; String line; @@ -235,7 +235,7 @@ void BotConfig::loadChatterConfig () { MemFile file; // chatter initialization - if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.int_ () == 2 && openConfig ("chatter", "Couldn't open chatter system configuration", &file)) { + if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.as () == 2 && openConfig ("chatter", "Couldn't open chatter system configuration", &file)) { m_chatter.clear (); struct EventMap { @@ -518,7 +518,7 @@ void BotConfig::loadLanguageConfig () { } file.close (); } - else if (cv_language.str () != "en") { + else if (cv_language.as () != "en") { logger.error ("Couldn't load language configuration"); } } @@ -589,15 +589,15 @@ void BotConfig::loadDifficultyConfig () { } auto diff = &m_difficulty[level]; - diff->reaction[0] = values[0].float_ (); - diff->reaction[1] = values[1].float_ (); - diff->headshotPct = values[2].int_ (); - diff->seenThruPct = values[3].int_ (); - diff->hearThruPct = values[4].int_ (); - diff->maxRecoil = values[5].int_ (); - diff->aimError.x = values[6].float_ (); - diff->aimError.y = values[7].float_ (); - diff->aimError.z = values[8].float_ (); + diff->reaction[0] = values[0].as (); + diff->reaction[1] = values[1].as (); + diff->headshotPct = values[2].as (); + diff->seenThruPct = values[3].as (); + diff->hearThruPct = values[4].as (); + diff->maxRecoil = values[5].as (); + diff->aimError.x = values[6].as (); + diff->aimError.y = values[7].as (); + diff->aimError.z = values[8].as (); }; // difficulty initialization @@ -879,10 +879,10 @@ bool BotConfig::openConfig (StringRef fileName, StringRef errorIfNotExists, MemF auto configDir = strings.joinPath (bstor.getRunningPathVFS (), folders.config); if (languageDependant) { - if (fileName.startsWith ("lang") && cv_language.str () == "en") { + if (fileName.startsWith ("lang") && cv_language.as () == "en") { return false; } - auto langConfig = strings.joinPath (configDir, folders.lang, strings.format ("%s_%s.%s", cv_language.str (), fileName, kConfigExtension)); + auto langConfig = strings.joinPath (configDir, folders.lang, strings.format ("%s_%s.%s", cv_language.as (), fileName, kConfigExtension)); // check is file is exists for this language if (!outFile->open (langConfig)) { diff --git a/src/control.cpp b/src/control.cpp index 4eab00c..1f5419f 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -25,19 +25,19 @@ int BotControl::cmdAddBot () { m_args.resize (max); // if team is specified, modify args to set team - if (strValue (alias).endsWith ("_ct")) { + if (arg (alias).endsWith ("_ct")) { m_args.set (team, "2"); } - else if (strValue (alias).endsWith ("_t")) { + else if (arg (alias).endsWith ("_t")) { m_args.set (team, "1"); } // if high-skilled bot is requested set personality to rusher and max-out difficulty - if (strValue (alias).contains ("addhs")) { + if (arg (alias).contains ("addhs")) { m_args.set (difficulty, "4"); m_args.set (personality, "1"); } - bots.addbot (strValue (name), strValue (difficulty), strValue (personality), strValue (team), strValue (model), true); + bots.addbot (arg (name), arg (difficulty), arg (personality), arg (team), arg (model), true); return BotCommandResult::Handled; } @@ -46,10 +46,10 @@ int BotControl::cmdKickBot () { enum args { alias = 1, team }; // if team is specified, kick from specified tram - if (strValue (alias).endsWith ("_ct") || intValue (team) == 2 || strValue (team) == "ct") { + if (arg (alias).endsWith ("_ct") || arg (team) == 2 || arg (team) == "ct") { bots.kickFromTeam (Team::CT); } - else if (strValue (alias).endsWith ("_t") || intValue (team) == 1 || strValue (team) == "t") { + else if (arg (alias).endsWith ("_t") || arg (team) == 1 || arg (team) == "t") { bots.kickFromTeam (Team::Terrorist); } else { @@ -62,13 +62,13 @@ int BotControl::cmdKickBots () { enum args { alias = 1, instant, team }; // check if we're need to remove bots instantly - const auto kickInstant = strValue (instant) == "instant"; + const auto kickInstant = arg (instant) == "instant"; // if team is specified, kick from specified tram - if (strValue (alias).endsWith ("_ct") || intValue (team) == 2 || strValue (team) == "ct") { + if (arg (alias).endsWith ("_ct") || arg (team) == 2 || arg (team) == "ct") { bots.kickFromTeam (Team::CT, true); } - else if (strValue (alias).endsWith ("_t") || intValue (team) == 1 || strValue (team) == "t") { + else if (arg (alias).endsWith ("_t") || arg (team) == 1 || arg (team) == "t") { bots.kickFromTeam (Team::Terrorist, true); } else { @@ -81,13 +81,13 @@ int BotControl::cmdKillBots () { enum args { alias = 1, team, silent, max }; // do not issue any messages - bool silentKill = hasArg (silent) && strValue (silent).startsWith ("si"); + bool silentKill = hasArg (silent) && arg (silent).startsWith ("si"); // if team is specified, kick from specified tram - if (strValue (alias).endsWith ("_ct") || intValue (team) == 2 || strValue (team) == "ct") { + if (arg (alias).endsWith ("_ct") || arg (team) == 2 || arg (team) == "ct") { bots.killAllBots (Team::CT, silentKill); } - else if (strValue (alias).endsWith ("_t") || intValue (team) == 1 || strValue (team) == "t") { + else if (arg (alias).endsWith ("_t") || arg (team) == 1 || arg (team) == "t") { bots.killAllBots (Team::Terrorist, silentKill); } else { @@ -102,7 +102,10 @@ int BotControl::cmdFill () { if (!hasArg (team)) { return BotCommandResult::BadFormat; } - bots.serverFill (intValue (team), hasArg (personality) ? intValue (personality) : -1, hasArg (difficulty) ? intValue (difficulty) : -1, hasArg (count) ? intValue (count) - 1 : -1); + bots.serverFill (arg (team), + hasArg (personality) ? arg (personality) : -1, + hasArg (difficulty) ? arg (difficulty) : -1, + hasArg (count) ? arg (count) - 1 : -1); return BotCommandResult::Handled; } @@ -113,7 +116,7 @@ int BotControl::cmdVote () { if (!hasArg (mapid)) { return BotCommandResult::BadFormat; } - const int mapID = intValue (mapid); + const int mapID = arg (mapid); // loop through all players for (const auto &bot : bots) { @@ -139,7 +142,7 @@ int BotControl::cmdWeaponMode () { { "sniper", 6 }, { "standard", 7 } }; - auto mode = strValue (type); + auto mode = arg (type); // check if selected mode exists if (!modes.exists (mode)) { @@ -180,7 +183,7 @@ int BotControl::cmdMenu () { // reset the current menu closeMenu (); - if (strValue (cmd) == "cmd" && util.isAlive (m_ent)) { + if (arg (cmd) == "cmd" && util.isAlive (m_ent)) { showMenu (Menu::Commands); } else { @@ -199,7 +202,7 @@ int BotControl::cmdList () { int BotControl::cmdCvars () { enum args { alias = 1, pattern }; - auto match = strValue (pattern); + auto match = arg (pattern); // revert all the cvars to their default values if (match == "defaults") { @@ -257,7 +260,7 @@ int BotControl::cmdCvars () { if (isSave && !cfg) { continue; } - auto val = cvar.self->str (); + auto val = cvar.self->as (); // float value ? bool isFloat = !val.empty () && val.find (".") != StringRef::InvalidIndex; @@ -276,20 +279,20 @@ int BotControl::cmdCvars () { } } else { - cfg.puts ("// Default: \"%s\"\n", cvar.self->str ()); + cfg.puts ("// Default: \"%s\"\n", cvar.self->as ()); } cfg.puts ("// \n"); if (cvar.bounded) { if (isFloat) { - cfg.puts ("%s \"%.1f\"\n", cvar.reg.name, cvar.self->float_ ()); + cfg.puts ("%s \"%.1f\"\n", cvar.reg.name, cvar.self->as ()); } else { - cfg.puts ("%s \"%i\"\n", cvar.reg.name, cvar.self->int_ ()); + cfg.puts ("%s \"%i\"\n", cvar.reg.name, cvar.self->as ()); } } else { - cfg.puts ("%s \"%s\"\n", cvar.reg.name, cvar.self->str ()); + cfg.puts ("%s \"%s\"\n", cvar.reg.name, cvar.self->as ()); } cfg.puts ("\n"); } @@ -327,7 +330,7 @@ int BotControl::cmdExec () { if (!hasArg (target) || !hasArg (command)) { return BotCommandResult::BadFormat; } - const auto userId = intValue (target); + const auto userId = arg (target); // find our little target auto bot = bots.findBotByIndex (userId); @@ -337,7 +340,7 @@ int BotControl::cmdExec () { msg ("Bot with #%d not found or not a bot.", userId); return BotCommandResult::Handled; } - bot->issueCommand (strValue (command).chars ()); + bot->issueCommand (arg (command).chars ()); return BotCommandResult::Handled; } @@ -366,7 +369,7 @@ int BotControl::cmdNode () { }; // graph editor supported only with editor - if (game.isDedicated () && !graph.hasEditor () && !isAllowedOnDedicatedServer (strValue (cmd))) { + if (game.isDedicated () && !graph.hasEditor () && !isAllowedOnDedicatedServer (arg (cmd))) { msg ("Unable to use graph edit commands without setting graph editor player. Please use \"graph acquire_editor\" to acquire rights for graph editing."); return BotCommandResult::Handled; } @@ -426,8 +429,8 @@ int BotControl::cmdNode () { addGraphCmd ("release_editor", "release_editor [noarguments]", "Releases graph editing rights.", &BotControl::cmdNodeReleaseEditor); } } - if (commands.exists (strValue (cmd))) { - const auto &item = commands[strValue (cmd)]; + if (commands.exists (arg (cmd))) { + const auto &item = commands[arg (cmd)]; // graph have only bad format return status int status = (this->*item.handler) (); @@ -439,8 +442,8 @@ int BotControl::cmdNode () { } } else { - if (strValue (cmd) == "help" && hasArg (cmd2) && commands.exists (strValue (cmd2))) { - auto &item = commands[strValue (cmd2)]; + if (arg (cmd) == "help" && hasArg (cmd2) && commands.exists (arg (cmd2))) { + auto &item = commands[arg (cmd2)]; msg ("Command: \"%s %s %s\"", m_args[root], m_args[alias], item.name); msg ("Format: %s", item.format); @@ -461,13 +464,13 @@ int BotControl::cmdNodeOn () { enum args { alias = 1, cmd, option }; // enable various features of editor - if (strValue (option).empty () || strValue (option) == "display" || strValue (option) == "models") { + if (arg (option).empty () || arg (option) == "display" || arg (option) == "models") { graph.setEditFlag (GraphEdit::On); enableDrawModels (true); msg ("Graph editor has been enabled."); } - else if (strValue (option) == "noclip") { + else if (arg (option) == "noclip") { m_ent->v.movetype = MOVETYPE_NOCLIP; if (graph.hasEditFlag (GraphEdit::On)) { @@ -482,7 +485,7 @@ int BotControl::cmdNodeOn () { msg ("Graph editor has been enabled with noclip mode."); } } - else if (strValue (option) == "auto") { + else if (arg (option) == "auto") { if (graph.hasEditFlag (GraphEdit::On)) { graph.setEditFlag (GraphEdit::Auto); @@ -497,9 +500,9 @@ int BotControl::cmdNodeOn () { } if (graph.hasEditFlag (GraphEdit::On)) { - m_graphSaveVarValues.roundtime = mp_roundtime.float_ (); - m_graphSaveVarValues.freezetime = mp_freezetime.float_ (); - m_graphSaveVarValues.timelimit = mp_timelimit.float_ (); + m_graphSaveVarValues.roundtime = mp_roundtime.as (); + m_graphSaveVarValues.freezetime = mp_freezetime.as (); + m_graphSaveVarValues.timelimit = mp_timelimit.as (); mp_roundtime.set (9); mp_freezetime.set (0); @@ -512,7 +515,7 @@ int BotControl::cmdNodeOff () { enum args { graph_cmd = 1, cmd, option }; // enable various features of editor - if (strValue (option).empty () || strValue (option) == "display") { + if (arg (option).empty () || arg (option) == "display") { graph.clearEditFlag (GraphEdit::On | GraphEdit::Auto | GraphEdit::Noclip); enableDrawModels (false); @@ -523,18 +526,18 @@ int BotControl::cmdNodeOff () { msg ("Graph editor has been disabled."); } - else if (strValue (option) == "models") { + else if (arg (option) == "models") { enableDrawModels (false); msg ("Graph editor has disabled spawn points highlighting."); } - else if (strValue (option) == "noclip") { + else if (arg (option) == "noclip") { m_ent->v.movetype = MOVETYPE_WALK; graph.clearEditFlag (GraphEdit::Noclip); msg ("Graph editor has disabled noclip mode."); } - else if (strValue (option) == "auto") { + else if (arg (option) == "auto") { graph.clearEditFlag (GraphEdit::Auto); msg ("Graph editor has disabled auto add node mode."); } @@ -567,12 +570,12 @@ int BotControl::cmdNodeSave () { enum args { graph_cmd = 1, cmd, option }; // if no check is set save anyway - if (strValue (option) == "nocheck") { + if (arg (option) == "nocheck") { graph.saveGraphData (); msg ("All nodes has been saved and written to disk (IGNORING QUALITY CONTROL)."); } - else if (strValue (option) == "old" || strValue (option) == "oldformat") { + else if (arg (option) == "old" || arg (option) == "oldformat") { if (graph.length () >= 1024) { msg ("Unable to save POD-Bot Format waypoint file. Number of nodes exceeds 1024."); @@ -611,7 +614,7 @@ int BotControl::cmdNodeErase () { enum args { graph_cmd = 1, cmd, iamsure }; // prevent accidents when graph are deleted unintentionally - if (strValue (iamsure) == "iamsure") { + if (arg (iamsure) == "iamsure") { bstor.unlinkFromDisk (); } else { @@ -627,11 +630,11 @@ int BotControl::cmdNodeDelete () { graph.setEditFlag (GraphEdit::On); // if "nearest" or nothing passed delete nearest, else delete by index - if (strValue (nearest).empty () || strValue (nearest) == "nearest") { + if (arg (nearest).empty () || arg (nearest) == "nearest") { graph.erase (kInvalidNodeIndex); } else { - int index = intValue (nearest); + const auto index = arg (nearest); // check for existence if (graph.exists (index)) { @@ -662,11 +665,11 @@ int BotControl::cmdNodeCache () { graph.setEditFlag (GraphEdit::On); // if "nearest" or nothing passed delete nearest, else delete by index - if (strValue (nearest).empty () || strValue (nearest) == "nearest") { + if (arg (nearest).empty () || arg (nearest) == "nearest") { graph.cachePoint (kInvalidNodeIndex); } else { - const int index = intValue (nearest); + const int index = arg (nearest); // check for existence if (graph.exists (index)) { @@ -683,7 +686,7 @@ int BotControl::cmdNodeClean () { graph.setEditFlag (GraphEdit::On); // if "all" passed clean up all the paths - if (strValue (option) == "all") { + if (arg (option) == "all") { int removed = 0; for (auto i = 0; i < graph.length (); ++i) { @@ -691,13 +694,13 @@ int BotControl::cmdNodeClean () { } msg ("Done. Processed %d nodes. %d useless paths was cleared.", graph.length (), removed); } - else if (strValue (option).empty () || strValue (option) == "nearest") { + else if (arg (option).empty () || arg (option) == "nearest") { int removed = graph.clearConnections (graph.getEditorNearest ()); msg ("Done. Processed node %d. %d useless paths was cleared.", graph.getEditorNearest (), removed); } else { - const int index = intValue (option); + const int index = arg (option); // check for existence if (graph.exists (index)) { @@ -721,13 +724,13 @@ int BotControl::cmdNodeSetRadius () { } int radiusIndex = kInvalidNodeIndex; - if (strValue (index).empty () || strValue (index) == "nearest") { + if (arg (index).empty () || arg (index) == "nearest") { radiusIndex = graph.getEditorNearest (); } else { - radiusIndex = intValue (index); + radiusIndex = arg (index); } - graph.setRadius (radiusIndex, strValue (radius).float_ ()); + graph.setRadius (radiusIndex, arg (radius).as ()); return BotCommandResult::Handled; } @@ -749,7 +752,7 @@ int BotControl::cmdNodeTeleport () { if (!hasArg (teleport_index)) { return BotCommandResult::BadFormat; } - int index = intValue (teleport_index); + int index = arg (teleport_index); // check for existence if (graph.exists (index)) { @@ -773,16 +776,16 @@ int BotControl::cmdNodePathCreate () { graph.setEditFlag (GraphEdit::On); // choose the direction for path creation - if (strValue (cmd).endsWith ("_jump")) { + if (arg (cmd).endsWith ("_jump")) { graph.pathCreate (PathConnection::Jumping); } - else if (strValue (cmd).endsWith ("_both")) { + else if (arg (cmd).endsWith ("_both")) { graph.pathCreate (PathConnection::Bidirectional); } - else if (strValue (cmd).endsWith ("_in")) { + else if (arg (cmd).endsWith ("_in")) { graph.pathCreate (PathConnection::Incoming); } - else if (strValue (cmd).endsWith ("_out")) { + else if (arg (cmd).endsWith ("_out")) { graph.pathCreate (PathConnection::Outgoing); } else { @@ -819,7 +822,7 @@ int BotControl::cmdNodePathCleanAll () { auto requestedNode = kInvalidNodeIndex; if (hasArg (index)) { - requestedNode = intValue (index); + requestedNode = arg (index); } graph.resetPath (requestedNode); @@ -871,7 +874,7 @@ int BotControl::cmdNodeUpload () { msg ("Sorry, unable to upload graph file that contains errors. Please type \"graph check\" to verify graph consistency."); return BotCommandResult::Handled; } - String uploadUrlAddress = cv_graph_url_upload.str (); + String uploadUrlAddress = cv_graph_url_upload.as (); // only allow to upload to non-https endpoint if (uploadUrlAddress.startsWith ("https")) { @@ -930,7 +933,7 @@ int BotControl::cmdNodeIterateCamp () { graph.setEditFlag (GraphEdit::On); // get the option describing operation - auto op = strValue (option); + auto op = arg (option); if (op != "begin" && op != "end" && op != "next") { return BotCommandResult::BadFormat; @@ -998,7 +1001,7 @@ int BotControl::cmdNodeAdjustHeight () { if (!hasArg (offset)) { return BotCommandResult::BadFormat; } - auto heightOffset = floatValue (offset); + auto heightOffset = arg (offset); // adjust the height for all the nodes (negative values possible) for (auto &path : graph) { @@ -1026,7 +1029,7 @@ int BotControl::menuMain (int item) { break; case 4: - if (game.is (GameFlags::ReGameDLL) && !cv_bots_kill_on_endround.bool_ ()) { + if (game.is (GameFlags::ReGameDLL) && !cv_bots_kill_on_endround) { game.serverCommand ("endround"); } else { @@ -1069,7 +1072,7 @@ int BotControl::menuFeatures (int item) { break; case 4: - cv_debug.set (cv_debug.int_ () ^ 1); + cv_debug.set (cv_debug.as () ^ 1); showMenu (Menu::Features); break; @@ -1549,8 +1552,8 @@ int BotControl::menuGraphDebug (int item) { switch (item) { case 1: cv_debug_goal.set (graph.getEditorNearest ()); - if (cv_debug_goal.int_ () != kInvalidNodeIndex) { - msg ("Debug goal is set to node %d.", cv_debug_goal.int_ ()); + if (cv_debug_goal.as () != kInvalidNodeIndex) { + msg ("Debug goal is set to node %d.", cv_debug_goal.as ()); } else { msg ("Cannot find the node. Debug goal is disabled."); @@ -1560,8 +1563,8 @@ int BotControl::menuGraphDebug (int item) { case 2: cv_debug_goal.set (graph.getFacingIndex ()); - if (cv_debug_goal.int_ () != kInvalidNodeIndex) { - msg ("Debug goal is set to node %d.", cv_debug_goal.int_ ()); + if (cv_debug_goal.as () != kInvalidNodeIndex) { + msg ("Debug goal is set to node %d.", cv_debug_goal.as ()); } else { msg ("Cannot find the node. Debug goal is disabled."); @@ -1871,7 +1874,7 @@ bool BotControl::executeCommands () { String cmd; // give some help - if (hasArg (1) && strValue (1) == "help") { + if (hasArg (1) && arg (1) == "help") { const auto hasSecondArg = hasArg (2); for (auto &item : m_cmds) { @@ -1879,7 +1882,7 @@ bool BotControl::executeCommands () { cmd = item.name.split ("/").first (); } - if (!hasSecondArg || aliasMatch (item.name, strValue (2), cmd)) { + if (!hasSecondArg || aliasMatch (item.name, arg (2), cmd)) { msg ("Command: \"%s %s\"", prefix, cmd); msg ("Format: %s", item.format); msg ("Help: %s", conf.translate (item.help)); @@ -1903,7 +1906,7 @@ bool BotControl::executeCommands () { return true; } else { - msg ("No help found for \"%s\"", strValue (2)); + msg ("No help found for \"%s\"", arg (2)); } return true; } @@ -1961,14 +1964,14 @@ bool BotControl::executeMenus () { const auto &issuer = util.getClient (game.indexOfPlayer (m_ent)); // check if it's menu select, and some key pressed - if (strValue (0) != "menuselect" || strValue (1).empty () || issuer.menu == Menu::None) { + if (arg (0) != "menuselect" || arg (1).empty () || issuer.menu == Menu::None) { return false; } // let's get handle for (auto &menu : m_menus) { if (menu.ident == issuer.menu) { - return (this->*menu.handler) (strValue (1).int_ ()) == BotCommandResult::Handled; + return (this->*menu.handler) (arg (1).as ()) == BotCommandResult::Handled; } } return false; @@ -2013,7 +2016,7 @@ void BotControl::showMenu (int id) { for (const auto &display : m_menus) { if (display.ident == id) { - String text = (game.is (GameFlags::Xash3D | GameFlags::Mobility) && !cv_display_menu_text.bool_ ()) ? " " : display.text.chars (); + String text = (game.is (GameFlags::Xash3D | GameFlags::Mobility) && !cv_display_menu_text) ? " " : display.text.chars (); // split if needed if (text.length () > maxMenuSentLength) { @@ -2106,8 +2109,8 @@ void BotControl::assignAdminRights (edict_t *ent, char *infobuffer) { if (!game.isDedicated () || util.isFakeClient (ent)) { return; } - StringRef key = cv_password_key.str (); - StringRef password = cv_password.str (); + StringRef key = cv_password_key.as (); + StringRef password = cv_password.as (); if (!key.empty () && !password.empty ()) { auto &client = util.getClient (game.indexOfPlayer (ent)); @@ -2126,8 +2129,8 @@ void BotControl::maintainAdminRights () { return; } - StringRef key = cv_password_key.str (); - StringRef password = cv_password.str (); + StringRef key = cv_password_key.as (); + StringRef password = cv_password.as (); for (auto &client : util.getClients ()) { if (!(client.flags & ClientFlags::Used) || util.isFakeClient (client.ent)) { diff --git a/src/engine.cpp b/src/engine.cpp index f61ecf4..2f72752 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -11,7 +11,7 @@ ConVar cv_csdm_mode ("csdm_mode", "0", "Enables or disables CSDM / FFA mode for ConVar cv_ignore_map_prefix_game_mode ("ignore_map_prefix_game_mode", "0", "If enabled, bots will not apply game modes based on map name prefix (fy_ and ka_ specifically)."); ConVar cv_threadpool_workers ("threadpool_workers", "-1", "Maximum number of threads bot will run to process some tasks. -1 means half of CPU cores used.", true, -1.0f, static_cast (plat.hardwareConcurrency ())); ConVar cv_grenadier_mode ("grenadier_mode", "0", "If enabled, bots will not apply throwing condition on grenades."); -ConVar cv_ignore_enemies_after_spawn_time ("ignore_enemies_after_spawn_time", "0", "Make bots ignore enemies for a specified here time in seconds on new round. Useful for Zombie Plague mods.", true, 0.0f, 540.0f); +ConVar cv_ignore_enemies_after_spawn_time ("ignore_enemies_after_spawn_time", "0", "Make bots ignore enemies for a specified here time in seconds on new round. Useful for Zombie Plague mods.", false); ConVar sv_skycolor_r ("sv_skycolor_r", nullptr, Var::GameRef); ConVar sv_skycolor_g ("sv_skycolor_g", nullptr, Var::GameRef); @@ -55,7 +55,7 @@ void Game::levelInitialize (edict_t *entities, int max) { bots.destroy (); // startup threaded worker - worker.startup (cv_threadpool_workers.int_ ()); + worker.startup (cv_threadpool_workers.as ()); m_spawnCount[Team::CT] = 0; m_spawnCount[Team::Terrorist] = 0; @@ -154,7 +154,7 @@ void Game::levelInitialize (edict_t *entities, int max) { } // next maps doesn't have map-specific entities, so determine it by name - if (!cv_ignore_map_prefix_game_mode.bool_ ()) { + if (!cv_ignore_map_prefix_game_mode) { StringRef prefix = getMapName (); if (prefix.startsWith ("fy_")) { @@ -590,27 +590,27 @@ bool Game::is25thAnniversaryUpdate () { return sv_use_steam_networking.exists (); } -void Game::addNewCvar (const char *name, const char *value, const char *info, bool bounded, float min, float max, int32_t varType, bool missingAction, const char *regval, ConVar *self) { +void Game::pushConVar (StringRef name, StringRef value, StringRef info, bool bounded, float min, float max, int32_t varType, bool missingAction, StringRef regval, ConVar *self) { // this function adds globally defined variable to registration stack ConVarReg reg {}; - reg.reg.name = const_cast (name); - reg.reg.string = const_cast (value); + reg.reg.name = name.chars (); + reg.reg.string = value.chars (); reg.name = name; reg.missing = missingAction; reg.init = value; reg.info = info; reg.bounded = bounded; - if (regval) { + if (!regval.empty ()) { reg.regval = regval; } if (bounded) { reg.min = min; reg.max = max; - reg.initial = static_cast (atof (value)); + reg.initial = value.as (); } int eflags = FCVAR_EXTDLL; @@ -646,7 +646,7 @@ void ConVar::revert () { } } -void ConVar::setPrefix (const char *name, int32_t type) { +void ConVar::setPrefix (StringRef name, int32_t type) { if (type == Var::GameRef) { name_ = name; return; @@ -662,7 +662,7 @@ void Game::checkCvarsBounds () { // read only cvar is not changeable if (var.type == Var::ReadOnly && !var.init.empty ()) { - if (var.init != var.self->str ()) { + if (var.init != var.self->as ()) { var.self->set (var.init.chars ()); } continue; @@ -671,8 +671,8 @@ void Game::checkCvarsBounds () { if (!var.bounded || !var.self) { continue; } - auto value = var.self->float_ (); - auto str = String (var.self->str ()); + auto value = var.self->as (); + auto str = String (var.self->as ()); // check the bounds and set default if out of bounds if (value > var.max || value < var.min || (!str.empty () && isalpha (str[0]))) { @@ -685,7 +685,7 @@ void Game::checkCvarsBounds () { // special case for xash3d, by default engine is not calling startframe if no players on server, but our quota management and bot adding // mechanism assumes that starframe is called even if no players on server, so, set the xash3d's sv_forcesimulating cvar to 1 in case it's not - if (is (GameFlags::Xash3D)) { + if (is (GameFlags::Xash3DLegacy)) { static ConVarRef sv_forcesimulating ("sv_forcesimulating"); if (sv_forcesimulating.exists () && !cr::fequal (sv_forcesimulating.value (), 1.0f)) { @@ -929,7 +929,7 @@ void Game::applyGameModes () { } // handle cvar cases - switch (cv_csdm_mode.int_ ()) { + switch (cv_csdm_mode.as ()) { default: case 0: break; @@ -1312,5 +1312,5 @@ float LightMeasure::getLightLevel (const Vector &point) { } float LightMeasure::getSkyColor () { - return static_cast (Color (sv_skycolor_r.int_ (), sv_skycolor_g.int_ (), sv_skycolor_b.int_ ()).avg ()); + return static_cast (Color (sv_skycolor_r.as (), sv_skycolor_g.as (), sv_skycolor_b.as ()).avg ()); } diff --git a/src/graph.cpp b/src/graph.cpp index 888ef57..4a6762f 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -729,7 +729,7 @@ void BotGraph::add (int type, const Vector &pos) { } // autosave nodes here and there - if (!analyzer.isAnalyzing () && cv_graph_auto_save_count.bool_ () && ++m_autoSaveCount >= cv_graph_auto_save_count.int_ ()) { + if (!analyzer.isAnalyzing () && cv_graph_auto_save_count && ++m_autoSaveCount >= cv_graph_auto_save_count.as ()) { if (saveGraphData ()) { msg ("Nodes has been autosaved..."); } @@ -1324,7 +1324,7 @@ void BotGraph::syncCollectOnline () { if (localGraphs.empty ()) { return; } - String uploadUrlAddress = cv_graph_url_upload.str (); + String uploadUrlAddress = cv_graph_url_upload.as (); // only allow to upload to non-https endpoint if (uploadUrlAddress.startsWith ("https")) { @@ -1416,7 +1416,7 @@ void BotGraph::syncCollectOnline () { } void BotGraph::collectOnline () { - if (m_isOnlineCollected || !cv_graph_auto_collect_db.bool_ ()) { + if (m_isOnlineCollected || !cv_graph_auto_collect_db) { return; } @@ -1818,7 +1818,7 @@ bool BotGraph::loadGraphData () { } bool BotGraph::canDownload () { - return !cv_graph_url.str ().empty (); + return !cv_graph_url.as ().empty (); } bool BotGraph::saveGraphData () { @@ -2019,7 +2019,7 @@ bool BotGraph::isNodeReacheable (const Vector &src, const Vector &destination) { } bool BotGraph::isNodeReacheableWithJump (const Vector &src, const Vector &destination) { - return isNodeReacheableEx (src, destination, cv_graph_analyze_max_jump_height.float_ ()); + return isNodeReacheableEx (src, destination, cv_graph_analyze_max_jump_height.as ()); } void BotGraph::frame () { @@ -2092,7 +2092,7 @@ void BotGraph::frame () { const float distanceSq = path.origin.distanceSq (m_editor->v.origin); // check if node is within a distance, and is visible - if (distanceSq < cr::sqrf (cv_graph_draw_distance.float_ ()) + if (distanceSq < cr::sqrf (cv_graph_draw_distance.as ()) && ((util.isVisible (path.origin, m_editor) && util.isInViewCone (path.origin, m_editor)) || !util.isAlive (m_editor) || distanceSq < cr::sqrf (64.0f))) { @@ -2844,7 +2844,7 @@ void BotGraph::convertFromPOD (Path &path, const PODPath &pod) { path.start = Vector (pod.csx, pod.csy, 0.0f); path.end = Vector (pod.cex, pod.cey, 0.0f); - if (cv_graph_fixcamp.bool_ ()) { + if (cv_graph_fixcamp) { convertCampDirection (path); } path.radius = pod.radius; diff --git a/src/hooks.cpp b/src/hooks.cpp index d6527f1..04cebc8 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -61,7 +61,7 @@ int32_t ServerQueryHook::sendTo (int socket, const void *message, size_t length, void ServerQueryHook::init () { // if previously requested to disable? - if (!cv_enable_query_hook.bool_ ()) { + if (!cv_enable_query_hook) { if (m_sendToDetour.detoured ()) { disable (); } diff --git a/src/linkage.cpp b/src/linkage.cpp index 1ca8a8f..0f4e8c0 100644 --- a/src/linkage.cpp +++ b/src/linkage.cpp @@ -394,7 +394,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int interfaceVersion) { auto ent = const_cast (player); // if we're handle pings for bots and clients, clear IN_SCORE button so SV_ShouldUpdatePing engine function return false, and SV_EmitPings will not overwrite our results - if (cv_show_latency.int_ () == 2) { + if (cv_show_latency.as () == 2) { if (!util.isFakeClient (ent) && (ent->v.oldbuttons | ent->v.button | cmd->buttons) & IN_SCORE) { cmd->buttons &= ~IN_SCORE; util.emitPings (ent); @@ -863,10 +863,10 @@ CR_EXPORT int Meta_Query (char *ifvers, plugin_info_t **pPlugInfo, mutil_funcs_t gpMetaUtilFuncs->pfnLogError (PLID, "%s: meta-interface version mismatch (metamod: %s, %s: %s)", Plugin_info.name, ifvers, Plugin_info.name, Plugin_info.ifvers); - const auto mmajor = mdll[0].int_ () ; - const auto mminor = mdll[1].int_ (); - const auto pmajor = pdll[0].int_ (); - const auto pminor = pdll[1].int_ (); + const auto mmajor = mdll[0].as (); + const auto mminor = mdll[1].as (); + const auto pmajor = pdll[0].as (); + const auto pminor = pdll[1].as (); if (pmajor > mmajor || (pmajor == mmajor && pminor > mminor)) { gpMetaUtilFuncs->pfnLogError (PLID, "metamod version is too old for this plugin; update metamod"); diff --git a/src/manager.cpp b/src/manager.cpp index e125c43..68736ee 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -192,10 +192,10 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal return BotCreateResult::TeamStacked; } if (difficulty < Difficulty::Noob || difficulty > Difficulty::Expert) { - difficulty = cv_difficulty.int_ (); + difficulty = cv_difficulty.as (); if (difficulty < Difficulty::Noob || difficulty > Difficulty::Expert) { - difficulty = rg.get (3, 4); + difficulty = rg (3, 4); cv_difficulty.set (difficulty); } } @@ -211,8 +211,8 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal if (personality < Personality::Normal || personality > Personality::Careful) { // assign preferred if we're forced with cvar - if (personalityMap.exists (cv_preferred_personality.str ())) { - personality = personalityMap[cv_preferred_personality.str ()]; + if (personalityMap.exists (cv_preferred_personality.as ())) { + personality = personalityMap[cv_preferred_personality.as ()]; } // do a holy random @@ -240,22 +240,22 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal resultName = botName->name; } else { - resultName.assignf ("%s_%d.%d", product.nameLower, rg.get (100, 10000), rg.get (100, 10000)); // just pick ugly random name + resultName.assignf ("%s_%d.%d", product.nameLower, rg (100, 10000), rg (100, 10000)); // just pick ugly random name } } else { resultName = name; } - const bool hasNamePrefix = !cv_name_prefix.str ().empty (); + const bool hasNamePrefix = !cv_name_prefix.as ().empty (); // disable save bots names if prefix is enabled - if (hasNamePrefix && cv_save_bots_names.bool_ ()) { + if (hasNamePrefix && cv_save_bots_names) { cv_save_bots_names.set (0); } if (hasNamePrefix) { String prefixed; // temp buffer for storing modified name - prefixed.assignf ("%s %s", cv_name_prefix.str (), resultName); + prefixed.assignf ("%s %s", cv_name_prefix.as (), resultName); // buffer has been modified, copy to real name resultName = cr::move (prefixed); @@ -336,7 +336,7 @@ void BotManager::addbot (StringRef name, int difficulty, int personality, int te request.manual = manual; // restore the bot name - if (cv_save_bots_names.bool_ () && name.empty () && !m_saveBotNames.empty ()) { + if (cv_save_bots_names && name.empty () && !m_saveBotNames.empty ()) { request.name = m_saveBotNames.popFront (); } @@ -351,10 +351,10 @@ void BotManager::addbot (StringRef name, StringRef difficulty, StringRef persona static StringRef any = "*"; request.name = (name.empty () || name == any) ? StringRef ("\0") : name; - request.difficulty = (difficulty.empty () || difficulty == any) ? -1 : difficulty.int_ (); - request.team = (team.empty () || team == any) ? -1 : team.int_ (); - request.skin = (skin.empty () || skin == any) ? -1 : skin.int_ (); - request.personality = (personality.empty () || personality == any) ? -1 : personality.int_ (); + request.difficulty = (difficulty.empty () || difficulty == any) ? -1 : difficulty.as (); + request.team = (team.empty () || team == any) ? -1 : team.as (); + request.skin = (skin.empty () || skin == any) ? -1 : skin.as (); + request.personality = (personality.empty () || personality == any) ? -1 : personality.as (); request.manual = manual; addbot (request.name, request.difficulty, request.personality, request.team, request.skin, request.manual); @@ -365,7 +365,7 @@ void BotManager::maintainQuota () { // while creation process in process. if (graph.length () < 1 || graph.hasChanged ()) { - if (cv_quota.int_ () > 0) { + if (cv_quota.as () > 0) { ctrl.msg ("There is no graph found. Cannot create bot."); } cv_quota.set (0); @@ -383,7 +383,7 @@ void BotManager::maintainQuota () { const BotCreateResult createResult = create (request.name, request.difficulty, request.personality, request.team, request.skin); if (request.manual) { - cv_quota.set (cr::min (cv_quota.int_ () + 1, game.maxClients ())); + cv_quota.set (cr::min (cv_quota.as () + 1, game.maxClients ())); } // check the result of creation @@ -403,14 +403,14 @@ void BotManager::maintainQuota () { m_addRequests.clear (); cv_quota.set (getBotCount ()); } - m_maintainTime = game.time () + cv_quota_adding_interval.float_ (); + m_maintainTime = game.time () + cv_quota_adding_interval.as (); } // now keep bot number up to date if (m_quotaMaintainTime > game.time ()) { return; } - cv_quota.set (cr::clamp (cv_quota.int_ (), 0, game.maxClients ())); + cv_quota.set (cr::clamp (cv_quota.as (), 0, game.maxClients ())); const int totalHumansInGame = getHumansCount (); const int humanPlayersInGame = getHumansCount (true); @@ -419,29 +419,29 @@ void BotManager::maintainQuota () { return; } - int desiredBotCount = cv_quota.int_ (); + int desiredBotCount = cv_quota.as (); int botsInGame = getBotCount (); - if (cv_quota_mode.str () == "fill") { + if (cv_quota_mode.as () == "fill") { botsInGame += humanPlayersInGame; } - else if (cv_quota_mode.str () == "match") { - int detectQuotaMatch = cv_quota_match.int_ () == 0 ? cv_quota.int_ () : cv_quota_match.int_ (); + else if (cv_quota_mode.as () == "match") { + int detectQuotaMatch = cv_quota_match.as () == 0 ? cv_quota.as () : cv_quota_match.as (); desiredBotCount = cr::max (0, detectQuotaMatch * humanPlayersInGame); } - if (cv_join_after_player.bool_ () && humanPlayersInGame == 0) { + if (cv_join_after_player && humanPlayersInGame == 0) { desiredBotCount = 0; } int maxClients = game.maxClients (); - if (cv_autovacate.bool_ ()) { - if (cv_kick_after_player_connect.bool_ ()) { - desiredBotCount = cr::min (desiredBotCount, maxClients - (totalHumansInGame + cv_autovacate_keep_slots.int_ ())); + if (cv_autovacate) { + if (cv_kick_after_player_connect) { + desiredBotCount = cr::min (desiredBotCount, maxClients - (totalHumansInGame + cv_autovacate_keep_slots.as ())); } else { - desiredBotCount = cr::min (desiredBotCount, maxClients - (humanPlayersInGame + cv_autovacate_keep_slots.int_ ())); + desiredBotCount = cr::min (desiredBotCount, maxClients - (humanPlayersInGame + cv_autovacate_keep_slots.as ())); } } else { @@ -482,11 +482,11 @@ void BotManager::maintainQuota () { } else { // clear the saved names when quota balancing ended - if (cv_save_bots_names.bool_ () && !m_saveBotNames.empty ()) { + if (cv_save_bots_names && !m_saveBotNames.empty ()) { m_saveBotNames.clear (); } } - m_quotaMaintainTime = game.time () + cv_quota_maintain_interval.float_ (); + m_quotaMaintainTime = game.time () + cv_quota_maintain_interval.as (); } void BotManager::maintainLeaders () { @@ -503,7 +503,7 @@ void BotManager::maintainLeaders () { } void BotManager::maintainAutoKill () { - const float killDelay = cv_autokill_delay.float_ (); + const float killDelay = cv_autokill_delay.as (); if (killDelay < 1.0f || m_roundOver) { return; @@ -594,15 +594,15 @@ void BotManager::resetFilters () { void BotManager::decrementQuota (int by) { if (by != 0) { - cv_quota.set (cr::clamp (cv_quota.int_ () - by, 0, cv_quota.int_ ())); + cv_quota.set (cr::clamp (cv_quota.as () - by, 0, cv_quota.as ())); return; } cv_quota.set (0); } void BotManager::initQuota () { - m_maintainTime = game.time () + cv_join_delay.float_ (); - m_quotaMaintainTime = game.time () + cv_join_delay.float_ (); + m_maintainTime = game.time () + cv_join_delay.as (); + m_quotaMaintainTime = game.time () + cv_join_delay.as (); m_addRequests.clear (); } @@ -611,8 +611,8 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int // this function fill server with bots, with specified team & personality // always keep one slot - const int maxClients = cv_autovacate.bool_ () - ? game.maxClients () - cv_autovacate_keep_slots.int_ () - (game.isDedicated () ? 0 : getHumansCount ()) : game.maxClients (); + const int maxClients = cv_autovacate + ? game.maxClients () - cv_autovacate_keep_slots.as () - (game.isDedicated () ? 0 : getHumansCount ()) : game.maxClients (); if (getBotCount () >= maxClients - getHumansCount ()) { return; @@ -636,7 +636,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int void BotManager::kickEveryone (bool instant, bool zeroQuota) { // this function drops all bot clients from server (this function removes only yapb's) - if (cv_quota.bool_ () && hasBotsOnline ()) { + if (cv_quota && hasBotsOnline ()) { ctrl.msg ("Bots are removed from server."); } @@ -645,7 +645,7 @@ void BotManager::kickEveryone (bool instant, bool zeroQuota) { } // if everyone is kicked, clear the saved bot names - if (cv_save_bots_names.bool_ () && !m_saveBotNames.empty ()) { + if (cv_save_bots_names && !m_saveBotNames.empty ()) { m_saveBotNames.clear (); } @@ -794,7 +794,7 @@ void BotManager::setLastWinner (int winner) { m_lastWinner = winner; m_roundOver = true; - if (cv_radio_mode.int_ () != 2) { + if (cv_radio_mode.as () != 2) { return; } auto notify = findAliveBot (); @@ -893,7 +893,7 @@ void BotManager::listBots () { }; for (const auto &bot : bots) { - auto timelimitStr = cv_rotate_bots.bool_ () ? strings.format ("%-3.0f secs", bot->m_stayTime - game.time ()) : "unlimited"; + auto timelimitStr = cv_rotate_bots ? strings.format ("%-3.0f secs", bot->m_stayTime - game.time ()) : "unlimited"; ctrl.msg ("[%-2.1d]\t%-22.16s\t%-10.12s\t%-3.4s\t%-3.1d\t%-3.1d\t%-3.4s\t%s", bot->index (), bot->pev->netname.chars (), bot->m_personality == Personality::Rusher ? "rusher" : bot->m_personality == Personality::Normal ? "normal" : "careful", @@ -975,7 +975,7 @@ 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. - if (setTrue || !cv_economics_rounds.bool_ ()) { + if (setTrue || !cv_economics_rounds) { m_economicsGood[team] = true; return; // don't check economics while economics disable } @@ -1011,10 +1011,10 @@ void BotManager::updateTeamEconomics (int team, bool setTrue) { void BotManager::updateBotDifficulties () { // if min/max difficulty is specified this should not have effect - if (cv_difficulty_min.int_ () != Difficulty::Invalid || cv_difficulty_max.int_ () != Difficulty::Invalid || cv_difficulty_auto.bool_ ()) { + if (cv_difficulty_min.as () != Difficulty::Invalid || cv_difficulty_max.as () != Difficulty::Invalid || cv_difficulty_auto) { return; } - const auto difficulty = cv_difficulty.int_ (); + const auto difficulty = cv_difficulty.as (); if (difficulty != m_lastDifficulty) { @@ -1033,11 +1033,11 @@ void BotManager::balanceBotDifficulties () { }; // with nightmare difficulty, there is no balance - if (cv_whose_your_daddy.bool_ ()) { + if (cv_whose_your_daddy) { return; } - if (cv_difficulty_auto.bool_ () && m_difficultyBalanceTime < game.time ()) { + if (cv_difficulty_auto && m_difficultyBalanceTime < game.time ()) { const auto ratioPlayer = getAverageTeamKPD (false); const auto ratioBots = getAverageTeamKPD (true); @@ -1053,7 +1053,7 @@ void BotManager::balanceBotDifficulties () { updateDifficulty (bot.get (), -1); } } - m_difficultyBalanceTime = game.time () + cv_difficulty_auto_balance_interval.float_ (); + m_difficultyBalanceTime = game.time () + cv_difficulty_auto_balance_interval.as (); } } @@ -1090,12 +1090,12 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { engfuncs.pfnSetClientKeyValue (clientIndex, buffer, "_ah", "0"); if (!game.is (GameFlags::Legacy)) { - if (cv_show_latency.int_ () == 1) { + if (cv_show_latency.as () == 1) { engfuncs.pfnSetClientKeyValue (clientIndex, buffer, "*bot", "1"); } auto avatar = conf.getRandomAvatar (); - if (cv_show_avatars.bool_ () && !avatar.empty ()) { + if (cv_show_avatars && !avatar.empty ()) { engfuncs.pfnSetClientKeyValue (clientIndex, buffer, "*sid", avatar.chars ()); } } @@ -1124,32 +1124,32 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { m_moneyAmount = 0; m_logotypeIndex = conf.getRandomLogoIndex (); - if (cv_rotate_bots.bool_ ()) { - m_stayTime = game.time () + rg.get (cv_rotate_stay_min.float_ (), cv_rotate_stay_max.float_ ()); + if (cv_rotate_bots) { + m_stayTime = game.time () + rg (cv_rotate_stay_min.as (), cv_rotate_stay_max.as ()); } else { m_stayTime = game.time () + kInfiniteDistance; } // assign how talkative this bot will be - m_sayTextBuffer.chatDelay = rg.get (3.8f, 10.0f); - m_sayTextBuffer.chatProbability = rg.get (10, 100); + m_sayTextBuffer.chatDelay = rg (3.8f, 10.0f); + m_sayTextBuffer.chatProbability = rg (10, 100); m_isAlive = false; m_weaponBurstMode = BurstMode::Off; m_difficulty = cr::clamp (static_cast (difficulty), Difficulty::Noob, Difficulty::Expert); - auto minDifficulty = cv_difficulty_min.int_ (); - auto maxDifficulty = cv_difficulty_max.int_ (); + auto minDifficulty = cv_difficulty_min.as (); + auto maxDifficulty = cv_difficulty_max.as (); // if we're have min/max difficulty specified, choose value from they if (minDifficulty != Difficulty::Invalid && maxDifficulty != Difficulty::Invalid) { if (maxDifficulty > minDifficulty) { cr::swap (maxDifficulty, minDifficulty); } - m_difficulty = rg.get (minDifficulty, maxDifficulty); + m_difficulty = rg (minDifficulty, maxDifficulty); } - m_basePing = rg.get (cv_ping_base_min.int_ (), cv_ping_base_max.int_ ()); + m_basePing = rg (cv_ping_base_min.as (), cv_ping_base_max.as ()); m_previousThinkTime = game.time () - 0.1f; m_frameInterval = game.time (); @@ -1158,26 +1158,26 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { m_kpdRatio = 0.0f; // stuff from jk_botti - m_playServerTime = 60.0f * rg.get (30.0f, 240.0f); - m_joinServerTime = plat.seconds () - m_playServerTime * rg.get (0.2f, 0.8f); + m_playServerTime = 60.0f * rg (30.0f, 240.0f); + m_joinServerTime = plat.seconds () - m_playServerTime * rg (0.2f, 0.8f); switch (personality) { case 1: m_personality = Personality::Rusher; - m_baseAgressionLevel = rg.get (0.7f, 1.0f); - m_baseFearLevel = rg.get (0.0f, 0.4f); + m_baseAgressionLevel = rg (0.7f, 1.0f); + m_baseFearLevel = rg (0.0f, 0.4f); break; case 2: m_personality = Personality::Careful; - m_baseAgressionLevel = rg.get (0.2f, 0.5f); - m_baseFearLevel = rg.get (0.7f, 1.0f); + m_baseAgressionLevel = rg (0.2f, 0.5f); + m_baseFearLevel = rg (0.7f, 1.0f); break; default: m_personality = Personality::Normal; - m_baseAgressionLevel = rg.get (0.4f, 0.7f); - m_baseFearLevel = rg.get (0.4f, 0.7f); + m_baseAgressionLevel = rg (0.4f, 0.7f); + m_baseFearLevel = rg (0.4f, 0.7f); break; } @@ -1187,7 +1187,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { m_currentWeapon = 0; // current weapon is not assigned at start m_weaponType = WeaponType::None; // current weapon type is not assigned at start - m_voicePitch = rg.get (80, 115); // assign voice pitch + m_voicePitch = rg (80, 115); // assign voice pitch // copy them over to the temp level variables m_agressionLevel = m_baseAgressionLevel; @@ -1220,8 +1220,8 @@ float Bot::getConnectionTime () { const auto current = plat.seconds (); if (current - m_joinServerTime > m_playServerTime || current - m_joinServerTime <= 0.0f) { - m_playServerTime = 60.0f * rg.get (30.0f, 240.0f); - m_joinServerTime = current - m_playServerTime * rg.get (0.2f, 0.8f); + m_playServerTime = 60.0f * rg (30.0f, 240.0f); + m_joinServerTime = current - m_playServerTime * rg (0.2f, 0.8f); } return current - m_joinServerTime; } @@ -1283,7 +1283,7 @@ bool BotManager::isTeamStacked (int team) { if (team != Team::CT && team != Team::Terrorist) { return false; } - const int limitTeams = mp_limitteams.int_ (); + const int limitTeams = mp_limitteams.as (); if (!limitTeams) { return false; @@ -1304,7 +1304,7 @@ void BotManager::erase (Bot *bot) { continue; } - if (!bot->m_kickedByRotation && cv_save_bots_names.bool_ ()) { + if (!bot->m_kickedByRotation && cv_save_bots_names) { m_saveBotNames.emplaceLast (bot->pev->netname.str ()); } bot->markStale (); @@ -1321,7 +1321,7 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) { const auto killerTeam = game.getRealTeam (killer); const auto victimTeam = game.getRealTeam (victim); - if (cv_radio_mode.int_ () == 2) { + if (cv_radio_mode.as () == 2) { // need to send congrats on well placed shot for (const auto ¬ify : bots) { if (notify->m_isAlive @@ -1443,14 +1443,14 @@ void Bot::newRound () { m_preventFlashing = 0.0f; m_timeTeamOrder = 0.0f; - m_askCheckTime = rg.get (30.0f, 90.0f); + m_askCheckTime = rg (30.0f, 90.0f); m_minSpeed = 260.0f; m_prevSpeed = 0.0f; m_prevVelocity = 0.0f; m_prevOrigin = Vector (kInfiniteDistance, kInfiniteDistance, kInfiniteDistance); m_prevTime = game.time (); m_lookUpdateTime = game.time (); - m_changeViewTime = game.time () + (rg.chance (25) ? mp_freezetime.float_ () : 0.0f); + m_changeViewTime = game.time () + (rg.chance (25) ? mp_freezetime.as () : 0.0f); m_aimErrorTime = game.time (); m_viewDistance = Frustum::kMaxViewDistance; @@ -1555,8 +1555,8 @@ void Bot::newRound () { m_flashLevel = 100; m_checkDarkTime = game.time (); - m_knifeAttackTime = game.time () + rg.get (1.3f, 2.6f); - m_nextBuyTime = game.time () + rg.get (0.6f, 2.0f); + m_knifeAttackTime = game.time () + rg (1.3f, 2.6f); + m_nextBuyTime = game.time () + rg (0.6f, 2.0f); m_buyPending = false; m_inBombZone = false; @@ -1568,7 +1568,7 @@ void Bot::newRound () { m_shieldCheckTime = 0.0f; m_zoomCheckTime = 0.0f; m_strafeSetTime = 0.0f; - m_combatStrafeDir = Dodge::None; + m_dodgeStrafeDir = Dodge::None; m_fightStyle = Fight::None; m_lastFightStyleCheck = 0.0f; m_stuckTimestamp = 0.0f; @@ -1583,7 +1583,7 @@ void Bot::newRound () { m_defendHostage = false; m_headedTime = 0.0f; - m_timeLogoSpray = game.time () + rg.get (5.0f, 30.0f); + m_timeLogoSpray = game.time () + rg (5.0f, 30.0f); m_spawnTime = game.time (); m_lastChatTime = game.time (); @@ -1600,8 +1600,8 @@ void Bot::newRound () { m_ignoredBreakable.clear (); // ignore enemies for some time if needed - if (cv_ignore_enemies_after_spawn_time.float_ () > 0.0f) { - m_enemyIgnoreTimer = game.time () + cv_ignore_enemies_after_spawn_time.float_ (); + if (cv_ignore_enemies_after_spawn_time.as () > 0.0f) { + m_enemyIgnoreTimer = game.time () + cv_ignore_enemies_after_spawn_time.as (); } else { m_enemyIgnoreTimer = 0.0f; @@ -1620,11 +1620,11 @@ void Bot::newRound () { if (rg.chance (50)) { pushChatterMessage (Chatter::NewRound); } - auto thinkFps = cr::clamp (cv_think_fps.float_ (), 30.0f, 90.0f); + auto thinkFps = cr::clamp (cv_think_fps.as (), 30.0f, 90.0f); auto updateInterval = 1.0f / thinkFps; if (game.is (GameFlags::Xash3D)) { - if (cv_think_fps_disable.bool_ ()) { + if (cv_think_fps_disable) { updateInterval = 0.0f; } else if (thinkFps < 50) { @@ -1657,7 +1657,7 @@ void Bot::resetPathSearchType () { } // if debug goal - set the fastest - if (cv_debug_goal.int_ () != kInvalidNodeIndex) { + if (cv_debug_goal.as () != kInvalidNodeIndex) { m_pathType = FindPath::Fast; } @@ -1749,7 +1749,7 @@ void Bot::updateTeamJoin () { m_startAction = BotMsg::None; // switch back to idle if (m_wantedTeam == -1) { - char teamJoin = cv_join_team.str ()[0]; + char teamJoin = cv_join_team.as ()[0]; if (teamJoin == 'C' || teamJoin == 'c') { m_wantedTeam = 2; @@ -1772,7 +1772,7 @@ void Bot::updateTeamJoin () { m_wantedTeam = 1; } else { - m_wantedTeam = rg.get (1, 2); + m_wantedTeam = rg (1, 2); } } @@ -1788,16 +1788,16 @@ void Bot::updateTeamJoin () { // setup enforced skin based on selected team if (m_wantedTeam == 1 || botTeam == Team::Terrorist) { - enforcedSkin = cv_botskin_t.int_ (); + enforcedSkin = cv_botskin_t.as (); } else if (m_wantedTeam == 2 || botTeam == Team::CT) { - enforcedSkin = cv_botskin_ct.int_ (); + enforcedSkin = cv_botskin_ct.as (); } enforcedSkin = cr::clamp (enforcedSkin, 0, maxChoice); // try to choice manually if (m_wantedSkin < 1 || m_wantedSkin > maxChoice) { - m_wantedSkin = rg.get (1, maxChoice); // use random if invalid + m_wantedSkin = rg (1, maxChoice); // use random if invalid } // and set enforced if any @@ -1852,7 +1852,7 @@ void BotManager::captureChatRadio (StringRef cmd, StringRef arg, edict_t *ent) { // check if this player alive, and issue something if ((target.flags & ClientFlags::Alive) && target.radio != 0 && cmd.startsWith ("menuselect")) { - auto radioCommand = arg.int_ (); + auto radioCommand = arg.as (); if (radioCommand != 0) { radioCommand += 10 * (target.radio - 1); @@ -1872,7 +1872,7 @@ void BotManager::captureChatRadio (StringRef cmd, StringRef arg, edict_t *ent) { target.radio = 0; } else if (cmd.startsWith ("radio")) { - target.radio = cmd.substr (5).int_ (); + target.radio = cmd.substr (5).as (); } } @@ -1890,7 +1890,7 @@ void BotManager::notifyBombDefuse () { && task != Task::DefuseBomb && task != Task::EscapeFromBomb) { - if (bot->m_team == Team::Terrorist && bot->pev->origin.distanceSq (bombPos) < cr::sqrf (384.0f)) { + if (bot->m_team == Team::Terrorist && bot->pev->origin.distanceSq (bombPos) < cr::sqrf (512.0f)) { bot->clearSearchNodes (); bot->m_pathType = FindPath::Fast; @@ -1955,7 +1955,7 @@ void BotManager::updateInterestingEntities () { m_interestingEntities.push (e); } - if (cv_attack_monsters.bool_ () && util.isMonster (e)) { + if (cv_attack_monsters && util.isMonster (e)) { m_interestingEntities.push (e); } @@ -2012,7 +2012,7 @@ void BotManager::selectLeaders (int team, bool reset) { // terrorist carrying a bomb needs to have some company if (rg.chance (75)) { - if (cv_radio_mode.int_ () == 2) { + if (cv_radio_mode.as () == 2) { bot->pushChatterMessage (Chatter::GoingToPlantBomb); } else { @@ -2098,13 +2098,13 @@ void BotManager::initRound () { practice.update (); // update practice data on round start // calculate the round mid/end in world time - m_timeRoundStart = game.time () + mp_freezetime.float_ (); - m_timeRoundMid = m_timeRoundStart + mp_roundtime.float_ () * 60.0f * 0.5f; - m_timeRoundEnd = m_timeRoundStart + mp_roundtime.float_ () * 60.0f; + m_timeRoundStart = game.time () + mp_freezetime.as (); + m_timeRoundMid = m_timeRoundStart + mp_roundtime.as () * 60.0f * 0.5f; + m_timeRoundEnd = m_timeRoundStart + mp_roundtime.as () * 60.0f; } void BotManager::setBombPlanted (bool isPlanted) { - if (cv_ignore_objectives.bool_ ()) { + if (cv_ignore_objectives) { m_bombPlanted = false; return; } diff --git a/src/message.cpp b/src/message.cpp index 275aa8d..cc6fa97 100644 --- a/src/message.cpp +++ b/src/message.cpp @@ -43,7 +43,7 @@ void MessageDispatcher::netMsgTextMsg () { // set balance for all players bots.forEach ([] (Bot *bot) { - bot->m_moneyAmount = mp_startmoney.int_ (); + bot->m_moneyAmount = mp_startmoney.as (); return false; }); @@ -63,7 +63,7 @@ void MessageDispatcher::netMsgTextMsg () { // clear only camp tasks notify->clearTask (Task::Camp); - if (cv_radio_mode.int_ () == 2 && rg.chance (55) && notify->m_team == Team::CT) { + if (cv_radio_mode.as () == 2 && rg.chance (55) && notify->m_team == Team::CT) { notify->pushChatterMessage (Chatter::WhereIsTheC4); } } diff --git a/src/navigate.cpp b/src/navigate.cpp index c5fc08d..e79c9de 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -163,11 +163,11 @@ int Bot::findBestGoal () { } } - const float goalDesire = rg.get (0.0f, 100.0f) + offensive; - const float forwardDesire = rg.get (0.0f, 100.0f) + offensive; - const float backoffDesire = rg.get (0.0f, 100.0f) + defensive; + const float goalDesire = rg (0.0f, 100.0f) + offensive; + const float forwardDesire = rg (0.0f, 100.0f) + offensive; + const float backoffDesire = rg (0.0f, 100.0f) + defensive; - float campDesire = rg.get (0.0f, 100.0f) + defensive; + float campDesire = rg (0.0f, 100.0f) + defensive; if (!usesCampGun ()) { campDesire *= 0.5f; @@ -226,7 +226,7 @@ int Bot::findBestGoalWhenBombAction () { result = findDefendNode (bombOrigin); const Path &path = graph[result]; - const float bombTimer = mp_c4timer.float_ (); + const float bombTimer = mp_c4timer.as (); const float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin); if (timeMidBlowup > game.time ()) { @@ -334,7 +334,7 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) { // rusher bots does not care any danger (idea from pbmm) if (m_personality == Personality::Rusher) { - const auto randomGoal = goalChoices[rg.get (0, 3)]; + const auto randomGoal = goalChoices[rg (0, 3)]; if (graph.exists (randomGoal)) { return m_chosenGoalIndex = randomGoal; @@ -454,7 +454,7 @@ void Bot::ignoreCollision () { } void Bot::doPlayerAvoidance (const Vector &normal) { - if (cv_has_team_semiclip.bool_ () || game.is (GameFlags::FreeForAll)) { + if (cv_has_team_semiclip || game.is (GameFlags::FreeForAll)) { return; // no player avoiding when with semiclip plugin } @@ -517,7 +517,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) { // is player that near now or in future that we need to steer away? if (movedDistanceSq <= cr::sqrf (64.0f) || (distanceSq <= cr::sqrf (72.0f) && nextFrameDistanceSq < distanceSq)) { - auto dir = (pev->origin - m_hindrance->v.origin).normalize2d_apx (); + const auto &dir = (pev->origin - m_hindrance->v.origin).normalize2d_apx (); // to start strafing, we have to first figure out if the target is on the left side or right side if ((dir | right.normalize2d_apx ()) > 0.0f) { @@ -570,7 +570,7 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) { // not stuck? if (!m_isStuck) { - if (m_probeTime + rg.get (0.75f, 1.15f) < game.time ()) { + if (m_probeTime + rg (0.75f, 1.15f) < game.time ()) { resetCollision (); // reset collision memory if not being stuck for 0.5 secs } else { @@ -928,7 +928,7 @@ bool Bot::updateNavigation () { // pressing the jump button gives the illusion of the bot actual jumping. if (isOnFloor () || isOnLadder ()) { if (m_desiredVelocity.length2d () > 0.0f) { - pev->velocity = m_desiredVelocity + m_desiredVelocity * m_frameInterval; + pev->velocity = m_desiredVelocity; } else { auto feet = pev->origin + pev->mins; @@ -965,12 +965,12 @@ bool Bot::updateNavigation () { // cool down a little if next path after current will be jump if (m_jumpSequence) { - startTask (Task::Pause, TaskPri::Pause, kInvalidNodeIndex, game.time () + rg.get (0.75, 1.2f) + m_frameInterval, false); + startTask (Task::Pause, TaskPri::Pause, kInvalidNodeIndex, game.time () + rg (0.75f, 1.2f) + m_frameInterval, false); m_jumpSequence = false; } } } - else if (!cv_jasonmode.bool_ () && usesKnife () && isOnFloor () && getCurrentTaskId () != Task::EscapeFromBomb) { + else if (!cv_jasonmode && usesKnife () && isOnFloor () && getCurrentTaskId () != Task::EscapeFromBomb) { selectBestWeapon (); } } @@ -1031,7 +1031,7 @@ bool Bot::updateNavigation () { && cr::abs (pev->origin.z - client.ent->v.origin.z) > 15.0f && (client.ent->v.movetype == MOVETYPE_FLY)) { - const auto numPreviousNode = rg.get (0, 2); + const auto numPreviousNode = rg (0, 2); for (int i = 0; i < numPreviousNode; ++i) { if (graph.exists (m_previousNodes[i]) && (graph[m_previousNodes[i]].flags & NodeFlag::Ladder)) { @@ -1115,7 +1115,7 @@ bool Bot::updateNavigation () { util.findNearestPlayer (reinterpret_cast (&nearest), ent (), 192.0f, false, false, true, true, false); // check if enemy is penetrable - if (util.isAlive (nearest) && isPenetrableObstacle (nearest->v.origin) && !cv_ignore_enemies.bool_ ()) { + if (util.isAlive (nearest) && isPenetrableObstacle (nearest->v.origin) && !cv_ignore_enemies) { m_seeEnemyTime = game.time (); m_states |= Sense::SeeingEnemy | Sense::SuspectEnemy; @@ -1137,7 +1137,7 @@ bool Bot::updateNavigation () { } } - float desiredDistanceSq = cr::sqrf (4.0f); + float desiredDistanceSq = cr::sqrf (8.0f); const float nodeDistanceSq = pev->origin.distanceSq (m_pathOrigin); // initialize the radius for a special node type, where the node is considered to be reached @@ -1145,7 +1145,7 @@ bool Bot::updateNavigation () { desiredDistanceSq = cr::sqrf (50.0f); } else if (isDucking () || (m_pathFlags & NodeFlag::Goal)) { - desiredDistanceSq = cr::sqrf (12.0f); + desiredDistanceSq = cr::sqrf (9.0f); // on cs_ maps goals are usually hostages, so increase reachability distance for them, they (hostages) picked anyway if (game.mapIs (MapFlags::HostageRescue) && (m_pathFlags & NodeFlag::Goal)) { @@ -1155,17 +1155,14 @@ bool Bot::updateNavigation () { else if (m_pathFlags & NodeFlag::Ladder) { desiredDistanceSq = cr::sqrf (16.0f); } - else if (m_pathFlags & NodeFlag::Camp) { - desiredDistanceSq = cr::sqrf (32.0f); - } else if (m_currentTravelFlags & PathFlag::Jump) { desiredDistanceSq = 0.0f; } - else if (m_path->number == cv_debug_goal.int_ ()) { + else if (m_path->number == cv_debug_goal.as ()) { desiredDistanceSq = 0.0f; } else if (isOccupiedNode (m_path->number)) { - desiredDistanceSq = cr::sqrf (120.0f); + desiredDistanceSq = cr::sqrf (148.0f); } else { desiredDistanceSq = cr::max (cr::sqrf (m_path->radius), desiredDistanceSq); @@ -1180,7 +1177,7 @@ bool Bot::updateNavigation () { } // needs precise placement - check if we get past the point - if (desiredDistanceSq < cr::sqrf (16.0f) + if (desiredDistanceSq < cr::sqrf (22.0f) && nodeDistanceSq < cr::sqrf (30.0f) && m_pathOrigin.distanceSq (pev->origin + pev->velocity * m_frameInterval) >= nodeDistanceSq) { @@ -1720,10 +1717,10 @@ bool Bot::findNextBestNode () { // choice from found if (lessIndex[2] != kInvalidNodeIndex) { - index = rg.get (0, 2); + index = rg (0, 2); } else if (lessIndex[1] != kInvalidNodeIndex) { - index = rg.get (0, 1); + index = rg (0, 1); } else if (lessIndex[0] != kInvalidNodeIndex) { index = 0; @@ -1739,7 +1736,13 @@ bool Bot::findNextBestNode () { if (selected == kInvalidNodeIndex) { selected = findNearestNode (); } + + // mark bot as searching for new best next node + if (selected != kInvalidNodeIndex) { + m_lostReachableNodeTimer.start (pev->origin.distanceSq (graph[selected].origin) / cr::sqrf (pev->maxspeed) * 4.0f); + } changeNodeIndex (selected); + return true; } @@ -1806,7 +1809,7 @@ void Bot::findValidNode () { int Bot::changeNodeIndex (int index) { if (index == kInvalidNodeIndex) { - return 0; + return kInvalidNodeIndex; } m_previousNodes[4] = m_previousNodes[3]; m_previousNodes[3] = m_previousNodes[2]; @@ -2077,7 +2080,7 @@ int Bot::findDefendNode (const Vector &origin) { break; } } - return nodeIndex[rg.get (0, (index - 1) / 2)]; + return nodeIndex[rg (0, (index - 1) / 2)]; } int Bot::findCoverNode (float maxDistance) { @@ -2334,8 +2337,8 @@ bool Bot::advanceMovement () { } if (m_baseAgressionLevel < kills && hasPrimaryWeapon ()) { - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (static_cast (m_difficulty / 2), static_cast (m_difficulty)) * 5.0f, true); - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, findDefendNode (graph[nextIndex].origin), game.time () + rg.get (3.0f, 10.0f), true); + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (static_cast (m_difficulty / 2), static_cast (m_difficulty)) * 5.0f, true); + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, findDefendNode (graph[nextIndex].origin), game.time () + rg (3.0f, 10.0f), true); } } else if (bots.canPause () && !isOnLadder () && !isInWater () && !m_currentTravelFlags && isOnFloor ()) { @@ -2366,7 +2369,7 @@ bool Bot::advanceMovement () { for (const auto &link : m_path->links) { if (link.index == destIndex) { m_currentTravelFlags = link.flags; - m_desiredVelocity = link.velocity - link.velocity * m_frameInterval; + m_desiredVelocity = link.velocity; m_jumpFinished = false; isCurrentJump = true; @@ -2467,7 +2470,7 @@ void Bot::setPathOrigin () { Vector orgs[kMaxAlternatives] {}; for (int i = 0; i < kMaxAlternatives; ++i) { - orgs[i] = m_pathOrigin + Vector (rg.get (-m_path->radius, m_path->radius), rg.get (-m_path->radius, m_path->radius), 0.0f); + orgs[i] = m_pathOrigin + Vector (rg (-m_path->radius, m_path->radius), rg (-m_path->radius, m_path->radius), 0.0f); } float nearestDistanceSq = kInfiniteDistance; @@ -2487,7 +2490,7 @@ void Bot::setPathOrigin () { } if (nearestIndex == kInvalidNodeIndex) { - m_pathOrigin += Vector (pev->angles.x, cr::wrapAngle (pev->angles.y + rg.get (-90.0f, 90.0f)), 0.0f).forward () * rg.get (0.0f, m_path->radius); + m_pathOrigin += Vector (pev->angles.x, cr::wrapAngle (pev->angles.y + rg (-90.0f, 90.0f)), 0.0f).forward () * rg (0.0f, m_path->radius); } } @@ -2938,7 +2941,7 @@ bool Bot::isDeadlyMove (const Vector &to) { TraceResult tr {}; constexpr auto kUnitsDown = 1000.0f; - constexpr auto kFallLimit = 150.0f; + constexpr auto kFallLimit = 160.0f; Vector check = to, down = to; down.z -= kUnitsDown; // straight down 1000 units @@ -2981,7 +2984,7 @@ bool Bot::isNotSafeToMove (const Vector &to) { // simplified version of isDeadlyMove() just for combat movement checking constexpr auto kUnitsDown = 1000.0f; - constexpr auto kFallLimit = 150.0f; + constexpr auto kFallLimit = 160.0f; TraceResult tr {}; game.testLine (to, to + Vector { 0.0f, 0.0f, -kUnitsDown }, TraceIgnore::Monsters, ent (), &tr); @@ -3031,7 +3034,7 @@ int Bot::getRandomCampDir () { count--; if (count >= 0) { - return indices[rg.get (0, count)]; + return indices[rg (0, count)]; } return graph.random (); } @@ -3146,46 +3149,43 @@ bool Bot::isReachableNode (int index) { if (!graph.exists (index)) { return false; } - const Vector &src = pev->origin; - const Vector &dst = graph[index].origin; + const auto &src = pev->origin; + const auto &dst = graph[index].origin; // is the destination close enough? - if (dst.distanceSq (src) >= cr::sqrf (400.0f)) { + if (dst.distanceSq (src) > cr::sqrf (600.0f)) { return false; } + // it's should be not a problem to reach node inside water... + if (pev->waterlevel == 2 || pev->waterlevel == 3) { + return true; + } + const float distanceSq2d = dst.distanceSq2d (src); + + // check for ladder + const bool nonLadder = !(graph[index].flags & NodeFlag::Ladder) || distanceSq2d > cr::sqrf (16.0f); + + // is dest node higher than src? (62 is max jump height) + if (nonLadder && dst.z > src.z + 62.0f) { + return false; // can't reach this one + } + + // is dest node lower than src? + if (nonLadder && dst.z < src.z - 100.0f) { + return false; // can't reach this one + } + // some one seems to camp at this node if (isOccupiedNode (index, true)) { - return false; + return false; // can't reach this one } TraceResult tr {}; - game.testHull (src, dst, TraceIgnore::Monsters, head_hull, ent (), &tr); + game.testLine (src, dst, TraceIgnore::Monsters, ent (), &tr); // if node is visible from current position (even behind head)... - if (tr.flFraction >= 1.0f && !tr.fStartSolid) { - - // it's should be not a problem to reach node inside water... - if (pev->waterlevel == 2 || pev->waterlevel == 3) { - return true; - } - const float ladderDistSq = dst.distanceSq2d (src); - - // check for ladder - const bool nonLadder = !(graph[index].flags & NodeFlag::Ladder) || ladderDistSq > cr::sqrf (16.0f); - - // is dest node higher than src? (62 is max jump height) - if (nonLadder && dst.z > src.z + 62.0f) { - return false; // can't reach this one - } - - // is dest node lower than src? - if (nonLadder && dst.z < src.z - 100.0f) { - return false; // can't reach this one - } - return true; - } - return false; + return tr.flFraction >= 1.0f; } bool Bot::isOnLadderPath () { @@ -3309,7 +3309,7 @@ void Bot::syncFindPath (int srcIndex, int destIndex, FindPath pathType) { // fallback to shortest path findShortestPath (srcIndex, destIndex); // A* found no path, try floyd pathfinder instead - if (cv_debug.bool_ ()) { + if (cv_debug) { fprintf (stderr, "A* Search for bot \"%s\" has failed. Falling back to shortest-path algorithm. Seems to be graph is broken.\n", pev->netname.chars ()); } break; diff --git a/src/planner.cpp b/src/planner.cpp index 717d8e3..f391328 100644 --- a/src/planner.cpp +++ b/src/planner.cpp @@ -117,7 +117,7 @@ float Heuristic::hfunctionPathDist (int index, int, int goalIndex) { const float y = start.origin.y - goal.origin.y; const float z = start.origin.z - goal.origin.z; - switch (cv_path_heuristic_mode.int_ ()) { + switch (cv_path_heuristic_mode.as ()) { case 0: return cr::max (cr::max (cr::abs (x), cr::abs (y)), cr::abs (z)); // chebyshev distance @@ -255,7 +255,7 @@ AStarResult AStarAlgo::find (int botTeam, int srcIndex, int destIndex, NodeAdder m_routeQue.clear (); m_routeQue.emplace (srcIndex, srcRoute->g); - const bool postSmoothPath = cv_path_astar_post_smooth.bool_ () && vistab.isReady (); + const bool postSmoothPath = cv_path_astar_post_smooth && vistab.isReady (); // always clear constructed path m_constructedPath.clear (); @@ -264,8 +264,8 @@ AStarResult AStarAlgo::find (int botTeam, int srcIndex, int destIndex, NodeAdder auto rsRandomizer = 1.0f; // randomize path on round start now and then - if (cv_path_randomize_on_round_start.bool_ () && bots.getRoundStartTime () + 4.0f > game.time ()) { - rsRandomizer = rg.get (0.5f, static_cast (botTeam) * 2.0f + 5.0f); + if (cv_path_randomize_on_round_start && bots.getRoundStartTime () + 4.0f > game.time ()) { + rsRandomizer = rg (0.5f, static_cast (botTeam) * 2.0f + 5.0f); } while (!m_routeQue.empty ()) { @@ -512,7 +512,7 @@ PathPlanner::PathPlanner () { void PathPlanner::init () { const int length = graph.length (); - const float limitInMb = cv_path_floyd_memory_limit.float_ (); + const float limitInMb = cv_path_floyd_memory_limit.as (); const float memoryUse = static_cast (sizeof (FloydWarshallAlgo::Matrix) * cr::sqrf (static_cast (length)) / 1024 / 1024); // if we're have too much memory for floyd matrices, planner will use dijkstra or uniform planner for other than pathfinding needs @@ -528,7 +528,7 @@ void PathPlanner::init () { } bool PathPlanner::hasRealPathDistance () const { - return !m_memoryLimitHit || !cv_path_dijkstra_simple_distance.bool_ (); + return !m_memoryLimitHit || !cv_path_dijkstra_simple_distance; } bool PathPlanner::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, int *pathDistance) { @@ -553,7 +553,7 @@ float PathPlanner::dist (int srcIndex, int destIndex) { // limit hit, use dijkstra if (m_memoryLimitHit) { - if (cv_path_dijkstra_simple_distance.bool_ ()) { + if (cv_path_dijkstra_simple_distance) { return graph[srcIndex].origin.distance2d (graph[destIndex].origin); } return static_cast (m_dijkstra->dist (srcIndex, destIndex)); diff --git a/src/practice.cpp b/src/practice.cpp index 566122e..e77a8a9 100644 --- a/src/practice.cpp +++ b/src/practice.cpp @@ -154,6 +154,7 @@ void BotPractice::save () { return; // no action } SmallArray data; + data.reserve (m_data.length ()); // copy hash-map data to our vector m_data.foreach ([&data] (const DangerStorage &ds, const PracticeData &pd) { diff --git a/src/sounds.cpp b/src/sounds.cpp index f6bf98c..af6370c 100644 --- a/src/sounds.cpp +++ b/src/sounds.cpp @@ -152,7 +152,7 @@ void BotSounds::simulateNoise (int playerIndex) { } } else { - if (mp_footsteps.bool_ ()) { + if (mp_footsteps) { // moves fast enough? noise.dist = 1280.0f * (client.ent->v.velocity.length2d () / 260.0f); noise.last = game.time () + 0.3f; diff --git a/src/storage.cpp b/src/storage.cpp index 42ae17b..f873c64 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -16,8 +16,8 @@ template bool BotStorage::load (SmallArray &data, ExtenHeader * extern ConVar cv_debug, cv_graph_url; // graphs can be downloaded... - const auto isGraph = !!(type.option & StorageOption::Graph); - const auto isDebug = cv_debug.bool_ (); + const bool isGraph = !!(type.option & StorageOption::Graph); + const bool isDebug = cv_debug; MemFile file (filename); // open the file data.clear (); @@ -46,7 +46,7 @@ template bool BotStorage::load (SmallArray &data, ExtenHeader * String lowercaseMapName = game.getMapName (); lowercaseMapName = lowercaseMapName.lowercase (); - auto downloadAddress = cv_graph_url.str (); + auto downloadAddress = cv_graph_url.as (); auto toDownload = buildPath (storageToBotFile (type.option), false); auto fromDownload = strings.format ("%s://%s/graph/%s.graph", product.httpScheme, downloadAddress, lowercaseMapName); @@ -272,7 +272,7 @@ template bool BotStorage::save (const SmallArray &data, ExtenHe extern ConVar cv_debug; // notify only about graph - if (isGraph || cv_debug.bool_ ()) { + if (isGraph || cv_debug) { ctrl.msg ("Successfully saved Bots %s data.", type.name); } } diff --git a/src/support.cpp b/src/support.cpp index 6b9efcc..60c29e1 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -233,7 +233,7 @@ bool BotSupport::isShootableBreakable (edict_t *ent) { if (game.isNullEntity (ent) || ent == game.getStartEntity ()) { return false; } - const auto limit = cv_breakable_health_limit.float_ (); + const auto limit = cv_breakable_health_limit.as (); // not shootable if (ent->v.health >= limit) { @@ -263,7 +263,7 @@ bool BotSupport::isFakeClient (edict_t *ent) { void BotSupport::checkWelcome () { // the purpose of this function, is to send quick welcome message, to the listenserver entity. - if (game.isDedicated () || !cv_display_welcome_text.bool_ () || !m_needToSendWelcome) { + if (game.isDedicated () || !cv_display_welcome_text || !m_needToSendWelcome) { return; } @@ -271,7 +271,7 @@ void BotSupport::checkWelcome () { auto receiveEnt = game.getLocalEntity (); if (isAlive (receiveEnt) && m_welcomeReceiveTime < 1.0f && needToSendMsg) { - m_welcomeReceiveTime = game.time () + 2.0f + mp_freezetime.float_ (); // receive welcome message in four seconds after game has commencing + m_welcomeReceiveTime = game.time () + 2.0f + mp_freezetime.as (); // receive welcome message in four seconds after game has commencing } if (m_welcomeReceiveTime > 0.0f && m_welcomeReceiveTime < game.time () && needToSendMsg) { @@ -309,16 +309,16 @@ void BotSupport::checkWelcome () { textParams.channel = 1; textParams.x = -1.0f; textParams.y = sendLegacyWelcome ? 0.0f : -1.0f; - textParams.effect = rg.get (1, 2); + textParams.effect = rg (1, 2); - textParams.r1 = static_cast (sendLegacyWelcome ? 255 : rg.get (33, 255)); - textParams.g1 = static_cast (sendLegacyWelcome ? 0 : rg.get (33, 255)); - textParams.b1 = static_cast (sendLegacyWelcome ? 0 : rg.get (33, 255)); + textParams.r1 = static_cast (sendLegacyWelcome ? 255 : rg (33, 255)); + textParams.g1 = static_cast (sendLegacyWelcome ? 0 : rg (33, 255)); + textParams.b1 = static_cast (sendLegacyWelcome ? 0 : rg (33, 255)); textParams.a1 = static_cast (0); - textParams.r2 = static_cast (sendLegacyWelcome ? 255 : rg.get (230, 255)); - textParams.g2 = static_cast (sendLegacyWelcome ? 255 : rg.get (230, 255)); - textParams.b2 = static_cast (sendLegacyWelcome ? 255 : rg.get (230, 255)); + textParams.r2 = static_cast (sendLegacyWelcome ? 255 : rg (230, 255)); + textParams.g2 = static_cast (sendLegacyWelcome ? 255 : rg (230, 255)); + textParams.b2 = static_cast (sendLegacyWelcome ? 255 : rg (230, 255)); textParams.a2 = static_cast (200); textParams.fadeinTime = 0.0078125f; @@ -425,7 +425,7 @@ void BotSupport::calculatePings () { } void BotSupport::syncCalculatePings () { - if (!game.is (GameFlags::HasFakePings) || cv_show_latency.int_ () != 2) { + if (!game.is (GameFlags::HasFakePings) || cv_show_latency.as () != 2) { return; } MutexScopedLock lock (m_cs); @@ -434,7 +434,7 @@ void BotSupport::syncCalculatePings () { int numHumans = 0; // only count player pings if we're allowed to - if (cv_count_players_for_fakeping.bool_ ()) { + if (cv_count_players_for_fakeping) { // first get average ping on server, and store real client pings for (auto &client : m_clients) { if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) { @@ -454,7 +454,7 @@ void BotSupport::syncCalculatePings () { // https://github.com/fwgs/xash3d-fwgs/blob/f5b9826fd9bbbdc5293c1ff522de11ce28d3c9f2/engine/server/sv_game.c#L4443 // store normal client ping - client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg.get (8, 16)); // getting player ping sometimes fails + client.ping = getPingBitmask (client.ent, loss, ping > 0 ? ping : rg (8, 16)); // getting player ping sometimes fails ++numHumans; average.first += ping; @@ -466,13 +466,13 @@ void BotSupport::syncCalculatePings () { average.second /= numHumans; } else { - average.first = rg.get (10, 20); - average.second = rg.get (5, 10); + average.first = rg (10, 20); + average.second = rg (5, 10); } } else { - average.first = rg.get (10, 20); - average.second = rg.get (5, 10); + average.first = rg (10, 20); + average.second = rg (5, 10); } // now calculate bot ping based on average from players @@ -488,14 +488,14 @@ void BotSupport::syncCalculatePings () { } const int part = static_cast (static_cast (average.first) * 0.2f); - int botPing = bot->m_basePing + rg.get (average.first - part, average.first + part) + rg.get (bot->m_difficulty / 2, bot->m_difficulty); - const int botLoss = rg.get (average.second / 2, average.second); + int botPing = bot->m_basePing + rg (average.first - part, average.first + part) + rg (bot->m_difficulty / 2, bot->m_difficulty); + const int botLoss = rg (average.second / 2, average.second); if (botPing < 2) { - botPing = rg.get (10, 23); + botPing = rg (10, 23); } else if (botPing > 100) { - botPing = rg.get (30, 40); + botPing = rg (30, 40); } client.ping = getPingBitmask (client.ent, botLoss, botPing); } @@ -520,7 +520,7 @@ void BotSupport::emitPings (edict_t *to) { // no ping, no fun if (!client.ping) { - client.ping = getPingBitmask (client.ent, rg.get (5, 10), rg.get (15, 40)); + client.ping = getPingBitmask (client.ent, rg (5, 10), rg (15, 40)); } msg.start (MSG_ONE_UNRELIABLE, SVC_PINGS, nullptr, to) @@ -565,7 +565,7 @@ String BotSupport::getCurrentDateTime () { } StringRef BotSupport::getFakeSteamId (edict_t *ent) { - if (!cv_enable_fake_steamids.bool_ () || !isPlayer (ent)) { + if (!cv_enable_fake_steamids || !isPlayer (ent)) { return "BOT"; } auto botNameHash = StringRef::fnv1a32 (ent->v.netname.chars ()); @@ -610,7 +610,7 @@ public: }; float BotSupport::getWaveLength (StringRef filename) { - auto filePath = strings.joinPath (cv_chatter_path.str (), strings.format ("%s.wav", filename)); + auto filePath = strings.joinPath (cv_chatter_path.as (), strings.format ("%s.wav", filename)); MemFile fp (filePath); diff --git a/src/tasks.cpp b/src/tasks.cpp index 4e67e63..2b3d25f 100644 --- a/src/tasks.cpp +++ b/src/tasks.cpp @@ -18,7 +18,7 @@ ConVar cv_random_knife_attacks ("random_knife_attacks", "1", "Allows or disallow void Bot::normal_ () { m_aimFlags |= AimFlags::Nav; - const int debugGoal = cv_debug_goal.int_ (); + const int debugGoal = cv_debug_goal.as (); // user forced a node as a goal? if (debugGoal != kInvalidNodeIndex) { @@ -46,14 +46,14 @@ void Bot::normal_ () { } // bots rushing with knife, when have no enemy (thanks for idea to nicebot project) - if (cv_random_knife_attacks.bool_ () && usesKnife () && (game.isNullEntity (m_lastEnemy) || !util.isAlive (m_lastEnemy)) && game.isNullEntity (m_enemy) && m_knifeAttackTime < game.time () && !m_hasHostage && !hasShield () && numFriendsNear (pev->origin, 96.0f) == 0) { + if (cv_random_knife_attacks && usesKnife () && (game.isNullEntity (m_lastEnemy) || !util.isAlive (m_lastEnemy)) && game.isNullEntity (m_enemy) && m_knifeAttackTime < game.time () && !m_hasHostage && !hasShield () && numFriendsNear (pev->origin, 96.0f) == 0) { if (rg.chance (40)) { pev->button |= IN_ATTACK; } else { pev->button |= IN_ATTACK2; } - m_knifeAttackTime = game.time () + rg.get (2.5f, 6.0f); + m_knifeAttackTime = game.time () + rg (2.5f, 6.0f); } const auto &prop = conf.getWeaponProp (m_currentWeapon); @@ -92,7 +92,7 @@ void Bot::normal_ () { if (!(m_states & (Sense::SeeingEnemy | Sense::SuspectEnemy)) && m_seeEnemyTime + 5.0f < game.time () && !m_reloadState && m_timeLogoSpray < game.time () - && cv_spraypaints.bool_ () + && cv_spraypaints && rg.chance (50) && m_moveSpeed > getShiftSpeed () && game.isNullEntity (m_pickupItem)) { @@ -103,7 +103,7 @@ void Bot::normal_ () { } // 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 && !isKnifeMode ()) { const bool allowedCampWeapon = hasPrimaryWeapon () || hasShield () || (hasSecondaryWeapon () && !hasPrimaryWeapon () && m_numFriendsLeft > game.maxClients () / 6); @@ -153,7 +153,7 @@ void Bot::normal_ () { if (!(m_states & (Sense::SeeingEnemy | Sense::HearingEnemy)) && !m_reloadState) { m_reloadState = Reload::Primary; } - m_timeCamping = game.time () + rg.get (cv_camping_time_min.float_ (), cv_camping_time_max.float_ ()); + m_timeCamping = game.time () + rg (cv_camping_time_min.as (), cv_camping_time_max.as ()); startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, m_timeCamping, true); m_lookAtSafe = m_pathOrigin + m_path->start.forward () * 500.0f; @@ -185,8 +185,8 @@ void Bot::normal_ () { else if (m_team == Team::Terrorist && rg.chance (75) && !game.mapIs (MapFlags::Demolition)) { const int index = findDefendNode (m_path->origin); - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (60.0f, 120.0f), true); // push camp task on to stack - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (5.0f, 10.0f), true); // push move command + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (60.0f, 120.0f), true); // push camp task on to stack + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg (5.0f, 10.0f), true); // push move command // decide to duck or not to duck selectCampButtons (index); @@ -203,7 +203,7 @@ void Bot::normal_ () { pushRadioMessage (Radio::NeedBackup); pushChatterMessage (Chatter::ScaredEmotion); - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (4.0f, 8.0f), true); + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (4.0f, 8.0f), true); } else { startTask (Task::PlantBomb, TaskPri::PlantBomb, kInvalidNodeIndex, 0.0f, false); @@ -212,14 +212,14 @@ void Bot::normal_ () { else if (m_team == Team::CT) { if (!bots.isBombPlanted () && numFriendsNear (pev->origin, 210.0f) < 4) { const int index = findDefendNode (m_path->origin); - float campTime = rg.get (25.0f, 40.f); + float campTime = rg (25.0f, 40.f); // rusher bots don't like to camp too much if (m_personality == Personality::Rusher) { campTime *= 0.5f; } startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + campTime, true); // push camp task on to stack - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg.get (5.0f, 11.0f), true); // push move command + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, index, game.time () + rg (5.0f, 11.0f), true); // push move command // decide to duck or not to duck selectCampButtons (index); @@ -268,7 +268,7 @@ void Bot::normal_ () { } const float shiftSpeed = getShiftSpeed (); - if ((!cr::fzero (m_moveSpeed) && m_moveSpeed > shiftSpeed) && (cv_walking_allowed.bool_ () && mp_footsteps.bool_ ()) + if ((!cr::fzero (m_moveSpeed) && m_moveSpeed > shiftSpeed) && (cv_walking_allowed && mp_footsteps) && m_difficulty >= Difficulty::Normal && (m_heardSoundTime + 6.0f >= game.time () || (m_states & Sense::HearingEnemy)) && pev->origin.distanceSq (m_lastEnemyOrigin) < cr::sqrf (768.0f) @@ -279,21 +279,21 @@ void Bot::normal_ () { } // bot hasn't seen anything in a long time and is asking his teammates to report in - if (cv_radio_mode.int_ () > 1 + if (cv_radio_mode.as () > 1 && bots.getLastRadio (m_team) != Radio::ReportInTeam && bots.getRoundStartTime () + 20.0f < game.time () && m_askCheckTime < game.time () && rg.chance (15) - && m_seeEnemyTime + rg.get (45.0f, 80.0f) < game.time () + && m_seeEnemyTime + rg (45.0f, 80.0f) < game.time () && numFriendsNear (pev->origin, 1024.0f) == 0) { pushRadioMessage (Radio::ReportInTeam); - m_askCheckTime = game.time () + rg.get (45.0f, 80.0f); + m_askCheckTime = game.time () + rg (45.0f, 80.0f); // make sure everyone else will not ask next few moments for (const auto &bot : bots) { if (bot->m_isAlive) { - bot->m_askCheckTime = game.time () + rg.get (5.0f, 30.0f); + bot->m_askCheckTime = game.time () + rg (5.0f, 30.0f); } } } @@ -323,7 +323,7 @@ void Bot::spraypaint_ () { // paint the actual logo decal util.decalTrace (pev, &tr, m_logotypeIndex); - m_timeLogoSpray = game.time () + rg.get (60.0f, 90.0f); + m_timeLogoSpray = game.time () + rg (60.0f, 90.0f); } } else { @@ -391,7 +391,7 @@ void Bot::huntEnemy_ () { } // bots skill higher than 60? - if (cv_walking_allowed.bool_ () && mp_footsteps.bool_ () && m_difficulty >= Difficulty::Normal && !isKnifeMode ()) { + if (cv_walking_allowed && mp_footsteps && m_difficulty >= Difficulty::Normal && !isKnifeMode ()) { // then make him move slow if near enemy if (!(m_currentTravelFlags & PathFlag::Jump)) { if (m_currentNodeIndex != kInvalidNodeIndex) { @@ -418,7 +418,7 @@ void Bot::seekCover_ () { m_prevGoalIndex = kInvalidNodeIndex; // start hide task - startTask (Task::Hide, TaskPri::Hide, kInvalidNodeIndex, game.time () + rg.get (3.0f, 12.0f), false); + startTask (Task::Hide, TaskPri::Hide, kInvalidNodeIndex, game.time () + rg (3.0f, 12.0f), false); // get a valid look direction const Vector &dest = getCampDirection (m_lastEnemyOrigin); @@ -471,7 +471,7 @@ void Bot::seekCover_ () { destIndex = findCoverNode (900.0f); if (destIndex == kInvalidNodeIndex) { - m_retreatTime = game.time () + rg.get (1.0f, 2.0f); + m_retreatTime = game.time () + rg (1.0f, 2.0f); m_prevGoalIndex = kInvalidNodeIndex; completeTask (); @@ -595,7 +595,7 @@ void Bot::blind_ () { } void Bot::camp_ () { - if (!cv_camping_allowed.bool_ () || m_isCreature) { + if (!cv_camping_allowed || m_isCreature) { completeTask (); return; } @@ -638,7 +638,7 @@ void Bot::camp_ () { }; if (m_nextCampDirTime < game.time ()) { - m_nextCampDirTime = game.time () + rg.get (2.0f, 5.0f); + m_nextCampDirTime = game.time () + rg (2.0f, 5.0f); if (m_pathFlags & NodeFlag::Camp) { Vector dest; @@ -839,7 +839,7 @@ void Bot::plantBomb_ () { pushRadioMessage (Radio::NeedBackup); } const auto index = findDefendNode (pev->origin); - const auto guardTime = mp_c4timer.float_ () * 0.5f + mp_c4timer.float_ () * 0.25f; + const auto guardTime = mp_c4timer.as () * 0.5f + mp_c4timer.as () * 0.25f; // push camp task on to stack startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + guardTime, true); @@ -872,18 +872,18 @@ void Bot::defuseBomb_ () { if (bot->m_team == m_team && bot->m_isAlive) { auto defendPoint = graph.getFarest (bot->pev->origin); - startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg.get (30.0f, 60.0f), true); // push camp task on to stack - startTask (Task::MoveToPosition, TaskPri::MoveToPosition, defendPoint, game.time () + rg.get (3.0f, 6.0f), true); // push move command + startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + rg (30.0f, 60.0f), true); // push camp task on to stack + startTask (Task::MoveToPosition, TaskPri::MoveToPosition, defendPoint, game.time () + rg (3.0f, 6.0f), true); // push move command } } graph.setBombOrigin (true); if (m_numFriendsLeft != 0 && rg.chance (50)) { if (timeToBlowUp <= 3.0f) { - if (cv_radio_mode.int_ () == 2) { + if (cv_radio_mode.as () == 2) { pushChatterMessage (Chatter::BarelyDefused); } - else if (cv_radio_mode.int_ () == 1) { + else if (cv_radio_mode.as () == 1) { pushRadioMessage (Radio::SectorClear); } } @@ -1084,7 +1084,7 @@ void Bot::followUser_ () { } m_aimFlags |= AimFlags::Nav; - if (cv_walking_allowed.bool_ () && m_targetEntity->v.maxspeed < m_moveSpeed && !isKnifeMode ()) { + if (cv_walking_allowed && m_targetEntity->v.maxspeed < m_moveSpeed && !isKnifeMode ()) { m_moveSpeed = getShiftSpeed (); } @@ -1325,7 +1325,7 @@ void Bot::doublejump_ () { game.testLine (src, dest, TraceIgnore::None, ent (), &tr); if (tr.flFraction < 1.0f && tr.pHit == m_doubleJumpEntity && inJump) { - m_duckForJump = game.time () + rg.get (3.0f, 5.0f); + m_duckForJump = game.time () + rg (3.0f, 5.0f); getTask ()->time = game.time (); } return; @@ -1395,7 +1395,7 @@ void Bot::escapeFromBomb_ () { else if (!hasActiveGoal ()) { int bestIndex = kInvalidNodeIndex; - const float safeRadius = rg.get (1513.0f, 2048.0f); + const float safeRadius = rg (1513.0f, 2048.0f); float nearestDistanceSq = kInfiniteDistance; for (const auto &path : graph) { diff --git a/src/vision.cpp b/src/vision.cpp index b38f768..0acc34b 100644 --- a/src/vision.cpp +++ b/src/vision.cpp @@ -75,7 +75,7 @@ void Bot::checkDarkness () { const auto skyColor = illum.getSkyColor (); const auto flashOn = (pev->effects & EF_DIMLIGHT); - if (mp_flashlight.bool_ () && !m_hasNVG) { + if (mp_flashlight && !m_hasNVG) { const auto tid = getCurrentTaskId (); if (!flashOn && @@ -105,7 +105,7 @@ void Bot::checkDarkness () { issueCommand ("nightvision"); } } - m_checkDarkTime = game.time () + rg.get (2.0f, 4.0f); + m_checkDarkTime = game.time () + rg (2.0f, 4.0f); } void Bot::changePitch (float speed) { @@ -203,7 +203,7 @@ void Bot::updateLookAngles () { if (m_difficulty == Difficulty::Expert && (m_aimFlags & AimFlags::Enemy) && (m_wantsToFire || usesSniper ()) - && cv_whose_your_daddy.bool_ ()) { + && cv_whose_your_daddy) { pev->v_angle = direction; pev->v_angle.clampAngles (); @@ -311,10 +311,10 @@ void Bot::updateLookAnglesNewbie (const Vector &direction, float delta) { randomize = randomization; } // randomize targeted location bit (slightly towards the ground) - m_randomizedIdealAngles = m_idealAngles + Vector (rg.get (-randomize.x * 0.5f, randomize.x * 1.5f), rg.get (-randomize.y, randomize.y), 0.0f); + m_randomizedIdealAngles = m_idealAngles + Vector (rg (-randomize.x * 0.5f, randomize.x * 1.5f), rg (-randomize.y, randomize.y), 0.0f); // set next time to do this - m_randomizeAnglesTime = game.time () + rg.get (0.4f, offsetDelay); + m_randomizeAnglesTime = game.time () + rg (0.4f, offsetDelay); } float stiffnessMultiplier = noTargetRatio; @@ -425,6 +425,16 @@ void Bot::setAimDirection () { flags &= ~(AimFlags::LastEnemy | AimFlags::PredictPath); m_canChooseAimDirection = false; } + + // don't switch view right away after loosing focus with current enemy + if ((m_shootTime + 1.5f > game.time () || m_seeEnemyTime + 1.5 > game.time ()) + && m_forgetLastVictimTimer.elapsed () + && !m_lastEnemyOrigin.empty () + && util.isAlive (m_lastEnemy) + && game.isNullEntity (m_enemy)) { + + flags |= AimFlags::LastEnemy; + } } if (flags & AimFlags::Override) { @@ -500,14 +510,14 @@ void Bot::setAimDirection () { predictNode = kInvalidNodeIndex; pathLength = kInfiniteDistanceLong; } - return graph.exists (predictNode) && pathLength < cv_max_nodes_for_predict.int_ (); + return graph.exists (predictNode) && pathLength < cv_max_nodes_for_predict.as (); }; if (changePredictedEnemy) { if (isPredictedIndexApplicable ()) { m_lookAtPredict = graph[predictNode].origin; - m_timeNextTracking = game.time () + rg.get (0.5f, 1.0f); + m_timeNextTracking = game.time () + rg (0.5f, 1.0f); m_trackingEdict = m_lastEnemy; } else { diff --git a/src/vistable.cpp b/src/vistable.cpp index 1afc26c..1a54174 100644 --- a/src/vistable.cpp +++ b/src/vistable.cpp @@ -41,7 +41,7 @@ void GraphVistable::rebuild () { sourceCrouch.z += -18.0f + 12.0f; sourceStand.z += 28.0f; } - auto end = m_sliceIndex + rg.get (250, 400); + auto end = m_sliceIndex + rg (250, 400); if (end > m_length) { end = m_length; @@ -122,7 +122,7 @@ void GraphVistable::rebuild () { m_curIndex++; } else { - m_sliceIndex += rg.get (250, 400); + m_sliceIndex += rg (250, 400); } // notify host about rebuilding