refactor: use squared distance if possible

refactor: add some const-correctness to code
This commit is contained in:
jeefo 2023-06-24 02:36:51 +03:00
commit 4a35a87b25
No known key found for this signature in database
GPG key ID: 927BCA0779BEA8ED
24 changed files with 579 additions and 567 deletions

View file

@ -216,9 +216,6 @@ public:
// search entities in sphere
void searchEntities (const Vector &position, float radius, EntitySearch functor);
// this function is checking that pointed by ent pointer obstacle, can be destroyed
bool isShootableBreakable (edict_t *ent);
// print the version to server console on startup
void printBotVersion ();

View file

@ -199,10 +199,10 @@ public:
public:
int getFacingIndex ();
int getFarest (const Vector &origin, float maxDistance = 32.0);
int getForAnalyzer (const Vector &origin, float maxDistance);
int getNearest (const Vector &origin, float minDistance = kInfiniteDistance, int flags = -1);
int getNearestNoBuckets (const Vector &origin, float minDistance = kInfiniteDistance, int flags = -1);
int getFarest (const Vector &origin, const float maxRange = 32.0);
int getForAnalyzer (const Vector &origin, const float maxRange);
int getNearest (const Vector &origin, const float range = kInfiniteDistance, int flags = -1);
int getNearestNoBuckets (const Vector &origin, const float range = kInfiniteDistance, int flags = -1);
int getEditorNearest ();
int clearConnections (int index);
int getBspSize ();

View file

@ -27,7 +27,7 @@ public:
public:
constexpr bool operator == (const DangerStorage &rhs) const {
return rhs.data[2] == data[2] && rhs.data[1] == data[1] && rhs.data[0] == data[0];
return cr::memcmp (rhs.data, data, sizeof (data));
}
constexpr bool operator != (const DangerStorage &rhs) const {

View file

@ -57,6 +57,12 @@ public:
// check if entity is a hostage entity
bool isHostageEntity (edict_t *ent);
// check if entity is a door enitty
bool isDoorEntity (edict_t *ent);
// this function is checking that pointed by ent pointer obstacle, can be destroyed
bool isShootableBreakable (edict_t *ent);
// nearest player search helper
bool findNearestPlayer (void **holder, edict_t *to, float searchDistance = 4096.0, bool sameTeam = false, bool needBot = false, bool needAlive = false, bool needDrawn = false, bool needBotWithC4 = false);

View file

@ -69,8 +69,8 @@ struct WeaponProp {
// weapon info structure
struct WeaponInfo {
int id; // the weapon id value
const char *name; // name of the weapon when selecting it
const char *model; // model name to separate cs weapons
StringRef name; // name of the weapon when selecting it
StringRef model; // model name to separate cs weapons
int price; // price when buying
int minPrimaryAmmo; // minimum primary ammo
int teamStandard; // used by team (number) (standard map)
@ -86,8 +86,8 @@ struct WeaponInfo {
public:
WeaponInfo (int id,
const char *name,
const char *model,
StringRef name,
StringRef model,
int price,
int minPriAmmo,
int teamStd,
@ -391,8 +391,8 @@ private:
int bestGrenadeCarried ();
int bestWeaponCarried ();
int changeNodeIndex (int index);
int numEnemiesNear (const Vector &origin, float radius);
int numFriendsNear (const Vector &origin, float radius);
int numEnemiesNear (const Vector &origin, const float radius);
int numFriendsNear (const Vector &origin, const float radius);
float getBombTimeleft ();
float getEstimatedNodeReachTime ();

View file

@ -76,7 +76,7 @@ void GraphAnalyze::update () {
setUpdateInterval ();
auto pos = graph[i].origin;
auto range = cv_graph_analyze_distance.float_ ();
const auto range = cv_graph_analyze_distance.float_ ();
for (int dir = 1; dir < kMaxNodeLinks; ++dir) {
switch (dir) {
@ -269,7 +269,7 @@ void GraphAnalyze::flood (const Vector &pos, const Vector &next, float range) {
game.testHull (pos, { next.x, next.y, next.z + 19.0f }, TraceIgnore::Monsters, head_hull, nullptr, &tr);
// we're can't reach next point
if (!cr::fequal (tr.flFraction, 1.0f) && !game.isShootableBreakable (tr.pHit)) {
if (!cr::fequal (tr.flFraction, 1.0f) && !util.isShootableBreakable (tr.pHit)) {
return;
}

View file

@ -111,10 +111,10 @@ void Bot::avoidGrenades () {
}
if (!(pent->v.flags & FL_ONGROUND)) {
float distance = pent->v.origin.distanceSq (pev->origin);
float distanceMoved = pev->origin.distance (pent->v.origin + pent->v.velocity * m_frameInterval);
const float distanceSq = pent->v.origin.distanceSq (pev->origin);
const float distanceMovedSq = pev->origin.distanceSq (pent->v.origin + pent->v.velocity * m_frameInterval);
if (distanceMoved < distance && distance < cr::sqrf (500.0f)) {
if (distanceMovedSq < distanceSq && distanceSq < cr::sqrf (500.0f)) {
const auto &dirToPoint = (pev->origin - pent->v.origin).normalize2d_apx ();
const auto &rightSide = pev->v_angle.right ().normalize2d_apx ();
@ -153,7 +153,7 @@ void Bot::avoidGrenades () {
}
void Bot::checkBreakable (edict_t *touch) {
if (!game.isShootableBreakable (touch)) {
if (!util.isShootableBreakable (touch)) {
return;
}
m_breakableEntity = lookupBreakable ();
@ -169,7 +169,7 @@ void Bot::checkBreakablesAround () {
if (!m_buyingFinished || !cv_destroy_breakables_around.bool_ () || usesKnife () || rg.chance (25) || !game.hasBreakables () || m_seeEnemyTime + 4.0f > game.time () || !game.isNullEntity (m_enemy) || !hasPrimaryWeapon ()) {
return;
}
auto radius = cv_object_destroy_radius.float_ ();
const auto radius = cv_object_destroy_radius.float_ ();
// check if we're have some breakables in 400 units range
for (const auto &breakable : game.getBreakables ()) {
@ -188,20 +188,20 @@ void Bot::checkBreakablesAround () {
continue;
}
if (!game.isShootableBreakable (breakable)) {
if (!util.isShootableBreakable (breakable)) {
continue;
}
const auto &origin = game.getEntityOrigin (breakable);
const auto lengthToObstacle = origin.distanceSq (pev->origin);
const auto lengthToObstacleSq = origin.distanceSq (pev->origin);
// too far, skip it
if (lengthToObstacle > cr::sqrf (radius)) {
if (lengthToObstacleSq > cr::sqrf (radius)) {
continue;
}
// too close, skip it
if (lengthToObstacle < cr::sqrf (100.0f)) {
if (lengthToObstacleSq < cr::sqrf (100.0f)) {
continue;
}
@ -236,23 +236,23 @@ edict_t *Bot::lookupBreakable () {
// this function checks if bot is blocked by a shoot able breakable in his moving direction
TraceResult tr {};
game.testLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).normalize () * 72.0f, TraceIgnore::None, ent (), &tr);
game.testLine (pev->origin, pev->origin + (m_destOrigin - pev->origin).normalize_apx () * 72.0f, TraceIgnore::None, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
auto ent = tr.pHit;
// check if this isn't a triggered (bomb) breakable and if it takes damage. if true, shoot the crap!
if (game.isShootableBreakable (ent)) {
if (util.isShootableBreakable (ent)) {
m_breakableOrigin = game.getEntityOrigin (ent);
return ent;
}
}
game.testLine (getEyesPos (), getEyesPos () + (m_destOrigin - getEyesPos ()).normalize () * 72.0f, TraceIgnore::None, ent (), &tr);
game.testLine (getEyesPos (), getEyesPos () + (m_destOrigin - getEyesPos ()).normalize_apx () * 72.0f, TraceIgnore::None, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
auto ent = tr.pHit;
if (game.isShootableBreakable (ent)) {
if (util.isShootableBreakable (ent)) {
m_breakableOrigin = game.getEntityOrigin (ent);
return ent;
}
@ -745,19 +745,19 @@ Vector Bot::getCampDirection (const Vector &dest) {
// check if the trace hit something...
if (tr.flFraction < 1.0f) {
float length = tr.vecEndPos.distanceSq (src);
const float lengthSq = tr.vecEndPos.distanceSq (src);
if (length > cr::sqrf (1024.0f)) {
if (lengthSq > cr::sqrf (1024.0f)) {
return nullptr;
}
int enemyIndex = graph.getNearest (dest);
int tempIndex = graph.getNearest (pev->origin);
const int enemyIndex = graph.getNearest (dest);
const int tempIndex = graph.getNearest (pev->origin);
if (tempIndex == kInvalidNodeIndex || enemyIndex == kInvalidNodeIndex) {
return nullptr;
}
float minDistance = kInfiniteDistance;
float nearestDistance = kInfiniteDistance;
int lookAtNode = kInvalidNodeIndex;
const Path &path = graph[tempIndex];
@ -766,10 +766,10 @@ Vector Bot::getCampDirection (const Vector &dest) {
if (link.index == kInvalidNodeIndex) {
continue;
}
auto distance = planner.dist (link.index, enemyIndex);
const auto distance = planner.dist (link.index, enemyIndex);
if (distance < minDistance) {
minDistance = distance;
if (distance < nearestDistance) {
nearestDistance = distance;
lookAtNode = link.index;
}
}
@ -798,7 +798,7 @@ void Bot::showChatterIcon (bool show, bool disconnect) {
.writeByte (on) // switch on/off
.writeByte (ownId);
};
int ownIndex = index ();
const int ownIndex = index ();
// do not respect timers while disconnecting bot
for (auto &client : util.getClients ()) {
@ -837,7 +837,7 @@ void Bot::instantChatter (int type) {
showChatterIcon (true);
}
MessageWriter msg;
int ownIndex = index ();
const int ownIndex = index ();
auto writeChatterSound = [&msg] (ChatterItem item) {
msg.writeString (strings.format ("%s%s%s.wav", cv_chatter_path.str (), PATH_SEP, item.name));
@ -883,7 +883,7 @@ void Bot::pushChatterMessage (int message) {
}
bool sendMessage = false;
auto messageRepeat = conf.getChatterMessageRepeatInterval (message);
const auto messageRepeat = conf.getChatterMessageRepeatInterval (message);
auto &messageTimer = m_chatterTimes[message];
if (messageTimer < game.time () || cr::fequal (messageTimer, kMaxChatterRepeatInterval)) {
@ -910,7 +910,7 @@ void Bot::checkMsgQueue () {
}
// get message from deque
auto state = m_msgQueue.popFront ();
const auto state = m_msgQueue.popFront ();
// nothing to do?
if (state == BotMsg::None || (state == BotMsg::Radio && game.is (GameFlags::FreeForAll))) {
@ -1117,7 +1117,7 @@ bool Bot::canReplaceWeapon () {
// this function determines currently owned primary weapon, and checks if bot has
// enough money to buy more powerful weapon.
auto tab = conf.getRawWeapons ();
const auto tab = conf.getRawWeapons ();
// if bot is not rich enough or non-standard weapon mode enabled return false
if (tab[25].teamStandard != 1 || m_moneyAmount < 4000) {
@ -1142,7 +1142,7 @@ int Bot::pickBestWeapon (Array <int> &vec, int moneySave) {
if (vec.length () < 2) {
return vec.first ();
}
bool needMoreRandomWeapon = (m_personality == Personality::Careful) || (rg.chance (25) && m_personality == Personality::Normal);
const bool needMoreRandomWeapon = (m_personality == Personality::Careful) || (rg.chance (25) && m_personality == Personality::Normal);
if (needMoreRandomWeapon) {
auto buyFactor = (static_cast <float> (m_moneyAmount) - static_cast <float> (moneySave)) / (16000.0f - static_cast <float> (moneySave)) * 3.0f;
@ -1194,7 +1194,7 @@ void Bot::buyStuff () {
// select the priority tab for this personality
const int *pref = conf.getWeaponPrefs (m_personality) + kNumWeapons;
auto tab = conf.getRawWeapons ();
const auto tab = conf.getRawWeapons ();
const bool isPistolMode = tab[25].teamStandard == -1 && tab[3].teamStandard == 2;
const bool teamHasGoodEconomics = bots.checkTeamEco (m_team);
@ -1572,11 +1572,11 @@ 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)))) {
float length = pev->origin.distance2d (m_enemy->v.origin);
const float length = pev->origin.distance2d (m_enemy->v.origin);
// do nodes movement if enemy is not reachable with a knife
if (length > 250.0f && (m_states & Sense::SeeingEnemy)) {
int nearestToEnemyPoint = graph.getNearest (m_enemy->v.origin);
const int nearestToEnemyPoint = graph.getNearest (m_enemy->v.origin);
if (nearestToEnemyPoint != kInvalidNodeIndex && nearestToEnemyPoint != m_currentNodeIndex && cr::abs (graph[nearestToEnemyPoint].origin.z - m_enemy->v.origin.z) < 16.0f) {
if (getCurrentTaskId () != Task::MoveToPosition && !cr::fequal (getTask ()->desire, TaskPri::Hide)) {
@ -1634,9 +1634,9 @@ void Bot::syncUpdatePredictedIndex () {
}
ScopedUnlock <Mutex> unlock (m_predictLock);
auto lastEnemyOrigin = m_lastEnemyOrigin;
auto currentNodeIndex = m_currentNodeIndex;
auto botOrigin = pev->origin;
const auto lastEnemyOrigin = m_lastEnemyOrigin;
const auto currentNodeIndex = m_currentNodeIndex;
const auto &botOrigin = pev->origin;
if (lastEnemyOrigin.empty () || !vistab.isReady () || !util.isAlive (m_lastEnemy)) {
wipePredict ();
@ -1893,8 +1893,8 @@ void Bot::filterTasks () {
timeHeard += 10.0f;
ratio = timeHeard * 0.1f;
}
bool lowAmmo = isLowOnAmmo (m_currentWeapon, 0.18f);
bool sniping = m_sniperStopTime > game.time () && lowAmmo;
const bool lowAmmo = isLowOnAmmo (m_currentWeapon, 0.18f);
const bool sniping = m_sniperStopTime > game.time () && lowAmmo;
if (bots.isBombPlanted () || m_isStuck || usesKnife ()) {
ratio /= 3.0f; // reduce the seek cover desire if bomb is planted
@ -2026,7 +2026,7 @@ void Bot::startTask (Task id, float desire, int data, float time, bool resume) {
clearSearchNodes ();
ignoreCollision ();
int tid = getCurrentTaskId ();
const int tid = getCurrentTaskId ();
// leader bot?
if (m_isLeader && tid == Task::SeekCover) {
@ -2146,7 +2146,7 @@ bool Bot::reactOnEnemy () {
}
if (m_enemyReachableTimer < game.time ()) {
auto lineDist = m_enemy->v.origin.distance (pev->origin);
const auto lineDist = m_enemy->v.origin.distance (pev->origin);
if (isEnemyNoticeable (lineDist)) {
m_isEnemyReachable = true;
@ -2157,8 +2157,8 @@ bool Bot::reactOnEnemy () {
if (ownIndex == kInvalidNodeIndex) {
ownIndex = findNearestNode ();
}
auto enemyIndex = graph.getNearest (m_enemy->v.origin);
auto pathDist = planner.preciseDistance (ownIndex, enemyIndex);
const auto enemyIndex = graph.getNearest (m_enemy->v.origin);
const auto pathDist = planner.preciseDistance (ownIndex, enemyIndex);
if (pathDist - lineDist > 112.0f || isOnLadder ()) {
m_isEnemyReachable = false;
@ -2194,7 +2194,7 @@ void Bot::checkRadioQueue () {
m_radioOrder = 0;
return;
}
float distance = m_radioEntity->v.origin.distance (pev->origin);
float distanceSq = m_radioEntity->v.origin.distanceSq (pev->origin);
switch (m_radioOrder) {
case Radio::CoverMe:
@ -2307,7 +2307,7 @@ void Bot::checkRadioQueue () {
case Radio::NeedBackup:
case Chatter::ScaredEmotion:
case Chatter::PinnedDown:
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distance < 2048.0f || !m_moveToC4) && rg.chance (50) && m_seeEnemyTime + 4.0f < game.time ()) {
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (2048.0f) || !m_moveToC4) && rg.chance (50) && m_seeEnemyTime + 4.0f < game.time ()) {
m_fearLevel -= 0.1f;
if (m_fearLevel < 0.0f) {
@ -2343,7 +2343,7 @@ void Bot::checkRadioQueue () {
m_fearLevel = 0.0f;
}
}
else if ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distance < 2048.0f) {
else if ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (2048.0f)) {
Task taskID = getCurrentTaskId ();
if (taskID == Task::Pause || taskID == Task::Camp) {
@ -2374,7 +2374,7 @@ void Bot::checkRadioQueue () {
break;
case Radio::ShesGonnaBlow:
if (game.isNullEntity (m_enemy) && distance < 2048.0f && bots.isBombPlanted () && m_team == Team::Terrorist) {
if (game.isNullEntity (m_enemy) && distanceSq < cr::sqrf (2048.0f) && bots.isBombPlanted () && m_team == Team::Terrorist) {
pushRadioMessage (Radio::RogerThat);
if (getCurrentTaskId () == Task::Camp) {
@ -2402,7 +2402,7 @@ void Bot::checkRadioQueue () {
break;
case Radio::StormTheFront:
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distance < 1024.0f) && rg.chance (50)) {
if (((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (1024.0f)) && rg.chance (50)) {
pushRadioMessage (Radio::RogerThat);
// don't pause/camp anymore
@ -2431,7 +2431,7 @@ void Bot::checkRadioQueue () {
break;
case Radio::TeamFallback:
if ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distance < 1024.0f) {
if ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (1024.0f)) {
m_fearLevel += 0.5f;
if (m_fearLevel > 1.0f) {
@ -2457,7 +2457,7 @@ void Bot::checkRadioQueue () {
// if bot has no enemy
if (m_lastEnemyOrigin.empty ()) {
float nearestDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
// take nearest enemy to ordering player
for (const auto &client : util.getClients ()) {
@ -2466,10 +2466,10 @@ void Bot::checkRadioQueue () {
}
auto enemy = client.ent;
float curDist = m_radioEntity->v.origin.distanceSq (enemy->v.origin);
const float currentDistanceSq = m_radioEntity->v.origin.distanceSq (enemy->v.origin);
if (curDist < nearestDistance) {
nearestDistance = curDist;
if (currentDistanceSq < nearestDistanceSq) {
nearestDistanceSq = currentDistanceSq;
m_lastEnemy = enemy;
m_lastEnemyOrigin = enemy->v.origin;
@ -2563,15 +2563,15 @@ void Bot::checkRadioQueue () {
// check if it's a ct command
if (game.getTeam (m_radioEntity) == Team::CT && m_team == Team::CT && util.isFakeClient (m_radioEntity) && bots.getPlantedBombSearchTimestamp () < game.time ()) {
float minDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
int bombPoint = kInvalidNodeIndex;
// find nearest bomb node to player
for (auto &point : graph.m_goalPoints) {
distance = graph[point].origin.distanceSq (m_radioEntity->v.origin);
distanceSq = graph[point].origin.distanceSq (m_radioEntity->v.origin);
if (distance < minDistance) {
minDistance = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
bombPoint = point;
}
}
@ -2593,7 +2593,7 @@ void Bot::checkRadioQueue () {
break;
case Radio::GetInPositionAndWaitForGo:
if (!m_isCreature && ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distance < 1024.0f)) {
if (!m_isCreature && ((game.isNullEntity (m_enemy) && seesEntity (m_radioEntity->v.origin)) || distanceSq < cr::sqrf (1024.0f))) {
pushRadioMessage (Radio::RogerThat);
if (getCurrentTaskId () == Task::Camp) {
@ -2612,7 +2612,7 @@ void Bot::checkRadioQueue () {
// if bot has no enemy
if (m_lastEnemyOrigin.empty ()) {
float nearestDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
// take nearest enemy to ordering player
for (const auto &client : util.getClients ()) {
@ -2621,10 +2621,11 @@ void Bot::checkRadioQueue () {
}
auto enemy = client.ent;
float dist = m_radioEntity->v.origin.distanceSq (enemy->v.origin);
const float distanceSq = m_radioEntity->v.origin.distanceSq (enemy->v.origin);
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
if (dist < nearestDistance) {
nearestDistance = dist;
m_lastEnemy = enemy;
m_lastEnemyOrigin = enemy->v.origin;
}
@ -2650,14 +2651,14 @@ void Bot::checkRadioQueue () {
}
void Bot::tryHeadTowardRadioMessage () {
Task taskID = getCurrentTaskId ();
const int tid = getCurrentTaskId ();
if (taskID == Task::MoveToPosition || m_headedTime + 15.0f < game.time () || !util.isAlive (m_radioEntity) || m_hasC4) {
if (tid == Task::MoveToPosition || m_headedTime + 15.0f < game.time () || !util.isAlive (m_radioEntity) || m_hasC4) {
return;
}
if ((util.isFakeClient (m_radioEntity) && rg.chance (25) && m_personality == Personality::Normal) || !(m_radioEntity->v.flags & FL_FAKECLIENT)) {
if (taskID == Task::Pause || taskID == Task::Camp) {
if (tid == Task::Pause || tid == Task::Camp) {
getTask ()->time = game.time ();
}
m_headedTime = game.time ();
@ -3345,7 +3346,7 @@ void Bot::updatePracticeValue (int damage) {
if (graph.length () < 1 || graph.hasChanged () || m_chosenGoalIndex < 0 || m_prevGoalIndex < 0) {
return;
}
auto health = static_cast <int> (m_healthValue);
const auto health = static_cast <int> (m_healthValue);
// max goal value
constexpr int maxGoalValue = PracticeLimit::Goal;
@ -3364,8 +3365,8 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) {
return;
}
int attackerTeam = game.getTeam (attacker);
int victimTeam = m_team;
const int attackerTeam = game.getTeam (attacker);
const int victimTeam = m_team;
if (attackerTeam == victimTeam) {
return;
@ -3395,10 +3396,10 @@ void Bot::updatePracticeDamage (edict_t *attacker, int damage) {
practice.setDamage (victimIndex, victimIndex, victimIndex, cr::clamp (practice.getDamage (victimTeam, victimIndex, victimIndex), 0, maxDamageValue));
}
}
auto updateDamage = util.isFakeClient (attacker) ? 10 : 7;
const auto updateDamage = util.isFakeClient (attacker) ? 10 : 7;
// store away the damage done
int damageValue = cr::clamp (practice.getDamage (m_team, victimIndex, attackerIndex) + damage / updateDamage, 0, maxDamageValue);
const auto damageValue = cr::clamp (practice.getDamage (m_team, victimIndex, attackerIndex) + damage / updateDamage, 0, maxDamageValue);
if (damageValue > practice.getHighestDamageForTeam (m_team)) {
practice.setHighestDamageForTeam (m_team, damageValue);
@ -3419,7 +3420,7 @@ void Bot::dropWeaponForUser (edict_t *user, bool discardC4) {
// this function, asks bot to discard his current primary weapon (or c4) to the user that requested it with /drop*
// command, very useful, when i'm don't have money to buy anything... )
if (util.isAlive (user) && m_moneyAmount >= 2000 && hasPrimaryWeapon () && user->v.origin.distance (pev->origin) <= 450.0f) {
if (util.isAlive (user) && m_moneyAmount >= 2000 && hasPrimaryWeapon () && user->v.origin.distanceSq (pev->origin) <= cr::sqrf (450.0f)) {
m_aimFlags |= AimFlags::Entity;
m_lookAt = user->v.origin;
@ -3480,7 +3481,7 @@ void Bot::debugMsgInternal (const char *str) {
if (game.isDedicated ()) {
return;
}
int level = cv_debug.int_ ();
const int level = cv_debug.int_ ();
if (level <= 2) {
return;
@ -3517,7 +3518,7 @@ Vector Bot::isBombAudible () {
}
const Vector &bombOrigin = graph.getBombOrigin ();
float timeElapsed = ((game.time () - bots.getTimeBombPlanted ()) / mp_c4timer.float_ ()) * 100.0f;
const float timeElapsed = ((game.time () - bots.getTimeBombPlanted ()) / mp_c4timer.float_ ()) * 100.0f;
float desiredRadius = 768.0f;
// start the manual calculations
@ -3575,7 +3576,7 @@ void Bot::runMovement () {
m_frameInterval = game.time () - m_lastCommandTime;
uint8_t msecVal = computeMsec ();
const uint8_t msecVal = computeMsec ();
m_lastCommandTime = game.time ();
engfuncs.pfnRunPlayerMove (pev->pContainingEntity, m_moveAngles, m_moveSpeed, m_strafeSpeed, 0.0f, static_cast <uint16_t> (pev->button), static_cast <uint8_t> (pev->impulse), msecVal);
@ -3588,7 +3589,7 @@ float Bot::getBombTimeleft () {
if (!bots.isBombPlanted ()) {
return 0.0f;
}
float timeLeft = ((bots.getTimeBombPlanted () + mp_c4timer.float_ ()) - game.time ());
const float timeLeft = ((bots.getTimeBombPlanted () + mp_c4timer.float_ ()) - game.time ());
if (timeLeft < 0.0f) {
return 0.0f;
@ -3606,7 +3607,7 @@ bool Bot::isOutOfBombTimer () {
}
// calculate left time
float timeLeft = getBombTimeleft ();
const float timeLeft = getBombTimeleft ();
// if time left greater than 13, no need to do other checks
if (timeLeft > 13.0f) {
@ -3630,7 +3631,7 @@ bool Bot::isOutOfBombTimer () {
}
// add reach time to left time
float reachTime = graph.calculateTravelTime (pev->maxspeed, m_pathOrigin, bombOrigin);
const float reachTime = graph.calculateTravelTime (pev->maxspeed, m_pathOrigin, bombOrigin);
// for counter-terrorist check alos is we have time to reach position plus average defuse time
if ((timeLeft < reachTime + 8.0f && !m_hasDefuser && !hasTeammatesWithDefuserKit) || (timeLeft < reachTime + 4.0f && m_hasDefuser)) {
@ -3645,7 +3646,7 @@ bool Bot::isOutOfBombTimer () {
void Bot::updateHearing () {
int hearEnemyIndex = kInvalidNodeIndex;
float minDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
// setup potential visibility set from engine
auto set = game.getVisibilitySet (this, false);
@ -3661,15 +3662,15 @@ void Bot::updateHearing () {
if (!game.checkVisibility (client.ent, set)) {
continue;
}
float distance = client.noise.pos.distance (pev->origin);
const float distanceSq = client.noise.pos.distanceSq (pev->origin);
if (distance > client.noise.dist) {
if (distanceSq > cr::sqrf (client.noise.dist)) {
continue;
}
if (distance < minDistance) {
if (distanceSq < nearestDistanceSq) {
hearEnemyIndex = i;
minDistance = distance;
nearestDistanceSq = distanceSq;
}
}
edict_t *player = nullptr;
@ -3709,9 +3710,9 @@ void Bot::updateHearing () {
}
else {
// if bot had an enemy but the heard one is nearer, take it instead
float distance = m_lastEnemyOrigin.distanceSq (pev->origin);
const float distanceSq = m_lastEnemyOrigin.distanceSq (pev->origin);
if (distance > player->v.origin.distanceSq (pev->origin) && m_seeEnemyTime + 2.0f < game.time ()) {
if (distanceSq > player->v.origin.distanceSq (pev->origin) && m_seeEnemyTime + 2.0f < game.time ()) {
m_lastEnemy = player;
m_lastEnemyOrigin = player->v.origin;
}
@ -3804,7 +3805,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
}
auto bot = bots[client.ent];
auto bombDistance = client.origin.distanceSq (bombOrigin);
const auto bombDistanceSq = client.origin.distanceSq (bombOrigin);
if (bot && !bot->m_notKilled) {
if (m_team != bot->m_team || bot->getCurrentTaskId () == Task::EscapeFromBomb) {
@ -3812,7 +3813,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
}
// if close enough, mark as progressing
if (bombDistance < distanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
if (bombDistanceSq < distanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
defusingInProgress = true;
break;
}
@ -3823,7 +3824,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
if (client.team == m_team) {
// if close enough, mark as progressing
if (bombDistance < distanceToBomb && ((client.ent->v.button | client.ent->v.oldbuttons) & IN_USE)) {
if (bombDistanceSq < distanceToBomb && ((client.ent->v.button | client.ent->v.oldbuttons) & IN_USE)) {
defusingInProgress = true;
break;
}
@ -3844,7 +3845,7 @@ void Bot::refreshModelName (char *infobuffer) {
if (infobuffer == nullptr) {
infobuffer = engfuncs.pfnGetInfoKeyBuffer (ent ());
}
String modelName = engfuncs.pfnInfoKeyValue (infobuffer, "model");
StringRef modelName = engfuncs.pfnInfoKeyValue (infobuffer, "model");
// need at least two characters to test model mask
if (modelName.length () < 2) {

View file

@ -57,7 +57,7 @@ void BotSupport::addChatErrors (String &line) {
auto length = static_cast <int32_t> (line.length ());
if (length > 15) {
auto percentile = length / 2;
const auto percentile = length / 2;
// "length / 2" percent of time drop a character
if (rg.chance (percentile)) {

View file

@ -16,30 +16,32 @@ ConVar cv_stab_close_enemies ("yb_stab_close_enemies", "1", "Enables or disables
ConVar mp_friendlyfire ("mp_friendlyfire", nullptr, Var::GameRef);
ConVar sv_gravity ("sv_gravity", nullptr, Var::GameRef);
int Bot::numFriendsNear (const Vector &origin, float radius) {
int Bot::numFriendsNear (const Vector &origin, const float radius) {
int count = 0;
const float radiusSq = cr::sqrf (radius);
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team != m_team || client.ent == ent ()) {
continue;
}
if (client.origin.distanceSq (origin) < cr::sqrf (radius)) {
if (client.origin.distanceSq (origin) < radiusSq) {
count++;
}
}
return count;
}
int Bot::numEnemiesNear (const Vector &origin, float radius) {
int Bot::numEnemiesNear (const Vector &origin, const float radius) {
int count = 0;
const float radiusSq = cr::sqrf (radius);
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team == m_team) {
continue;
}
if (client.origin.distanceSq (origin) < cr::sqrf (radius)) {
if (client.origin.distanceSq (origin) < radiusSq) {
count++;
}
}
@ -52,8 +54,8 @@ bool Bot::isEnemyHidden (edict_t *enemy) {
}
entvars_t &v = enemy->v;
bool enemyHasGun = (v.weapons & kPrimaryWeaponMask) || (v.weapons & kSecondaryWeaponMask);
bool enemyGunfire = (v.button & IN_ATTACK) || (v.oldbuttons & IN_ATTACK);
const bool enemyHasGun = (v.weapons & kPrimaryWeaponMask) || (v.weapons & kSecondaryWeaponMask);
const bool enemyGunfire = (v.button & IN_ATTACK) || (v.oldbuttons & IN_ATTACK);
if ((v.renderfx == kRenderFxExplode || (v.effects & EF_NODRAW)) && (!enemyGunfire || !enemyHasGun)) {
return true;
@ -127,13 +129,13 @@ bool Bot::checkBodyParts (edict_t *target) {
}
TraceResult result {};
auto eyes = getEyesPos ();
const auto &eyes = getEyesPos ();
auto spot = target->v.origin;
auto self = pev->pContainingEntity;
// creatures can't hurt behind anything
auto ignoreFlags = m_isCreature ? TraceIgnore::None : TraceIgnore::Everything;
const auto ignoreFlags = m_isCreature ? TraceIgnore::None : TraceIgnore::Everything;
const auto hitsTarget = [&] () -> bool {
return result.flFraction >= 1.0f || result.pHit == target;
@ -238,7 +240,7 @@ bool Bot::lookupEnemies () {
return false;
}
edict_t *player, *newEnemy = nullptr;
float nearestDistance = cr::sqrf (m_viewDistance);
float nearestDistanceSq = cr::sqrf (m_viewDistance);
// clear suspected flag
if (!game.isNullEntity (m_enemy) && (m_states & Sense::SeeingEnemy)) {
@ -255,7 +257,7 @@ bool Bot::lookupEnemies () {
player = m_enemy;
// is player is alive
if (m_enemyUpdateTime > game.time () && m_enemy->v.origin.distanceSq (pev->origin) < nearestDistance && util.isAlive (player) && seesEnemy (player)) {
if (m_enemyUpdateTime > game.time () && m_enemy->v.origin.distanceSq (pev->origin) < nearestDistanceSq && util.isAlive (player) && seesEnemy (player)) {
newEnemy = player;
}
}
@ -282,11 +284,11 @@ bool Bot::lookupEnemies () {
// see if bot can see the monster...
if (seesEnemy (interesting)) {
// higher priority for big monsters
float scaleFactor = (1.0f / calculateScaleFactor (interesting));
float distance = interesting->v.origin.distanceSq (pev->origin) * scaleFactor;
const float scaleFactor = (1.0f / calculateScaleFactor (interesting));
const float distanceSq = interesting->v.origin.distanceSq (pev->origin) * scaleFactor;
if (distance < nearestDistance) {
nearestDistance = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
newEnemy = interesting;
}
}
@ -311,10 +313,10 @@ bool Bot::lookupEnemies () {
shieldEnemy = player;
continue;
}
float distance = player->v.origin.distanceSq (pev->origin);
const float distanceSq = player->v.origin.distanceSq (pev->origin);
if (distance < nearestDistance) {
nearestDistance = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
newEnemy = player;
// aim VIP first on AS maps...
@ -475,7 +477,7 @@ Vector Bot::getBodyOffsetError (float distance) {
if (!m_enemyParts) {
return m_enemyOrigin;
}
float distance = m_enemy->v.origin.distance (pev->origin);
const float distance = m_enemy->v.origin.distance (pev->origin);
// do not aim at head, at long distance (only if not using sniper weapon)
if ((m_enemyParts & Visibility::Body) && !usesSniper () && distance > (m_difficulty >= Difficulty::Normal ? 2000.0f : 1000.0f)) {
@ -525,7 +527,7 @@ Vector Bot::getBodyOffsetError (float distance) {
spot = m_enemyOrigin + getCustomHeight (distance);
}
}
Vector idealSpot = m_enemyOrigin;
auto idealSpot = m_enemyOrigin;
if (m_difficulty < Difficulty::Expert && isEnemyInSight (idealSpot)) {
spot = idealSpot + ((spot - idealSpot) * 0.01f); // gradually adjust the aiming direction
@ -597,21 +599,19 @@ bool Bot::isFriendInLineOfFire (float distance) {
return true;
}
}
const float distanceSq = cr::sqrf (distance);
// doesn't seems to be have any effect
#if 0
// search the world for players
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive) || client.team != m_team || client.ent == ent ()) {
continue;
}
auto friendDistance = client.ent->v.origin.distanceSq (pev->origin);
const auto friendDistanceSq = client.ent->v.origin.distanceSq (pev->origin);
if (friendDistance <= distance && util.getShootingCone (ent (), client.ent->v.origin) > friendDistance / (friendDistance + 1089.0f)) {
if (friendDistanceSq <= distanceSq && util.getShootingCone (ent (), client.ent->v.origin) > friendDistanceSq / (friendDistanceSq + cr::sqrf (1089.0f))) {
return true;
}
}
#endif
return false;
}
@ -619,7 +619,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
// this function returns true if enemy can be shoot through some obstacle, false otherwise.
// credits goes to Immortal_BLG
auto method = cv_shoots_thru_walls.int_ ();
const auto method = cv_shoots_thru_walls.int_ ();
if (method == 2) {
return isPenetrableObstacle2 (dest);
@ -638,7 +638,7 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
}
TraceResult tr {};
float obstacleDistance = 0.0f;
float obstacleDistanceSq = 0.0f;
game.testLine (getEyesPos (), dest, TraceIgnore::Monsters, ent (), &tr);
if (tr.fStartSolid) {
@ -653,15 +653,15 @@ bool Bot::isPenetrableObstacle (const Vector &dest) {
if (tr.vecEndPos.z >= dest.z + 200.0f) {
return false;
}
obstacleDistance = tr.vecEndPos.distanceSq (source);
obstacleDistanceSq = tr.vecEndPos.distanceSq (source);
}
}
const float distance = cr::sqrf (75.0f);
const float kMaxDistanceSq = cr::sqrf (75.0f);
if (obstacleDistance > 0.0f) {
if (obstacleDistanceSq > 0.0f) {
while (power > 0) {
if (obstacleDistance > distance) {
obstacleDistance -= distance;
if (obstacleDistanceSq > kMaxDistanceSq) {
obstacleDistanceSq -= kMaxDistanceSq;
power--;
continue;
@ -790,7 +790,7 @@ bool Bot::needToPauseFiring (float distance) {
}
void Bot::selectWeapons (float distance, int index, int id, int choosen) {
auto tab = conf.getRawWeapons ();
const auto tab = conf.getRawWeapons ();
// we want to fire weapon, don't reload now
if (!m_isReloading) {
@ -949,7 +949,7 @@ void Bot::fireWeapons () {
if (m_isUsingGrenade) {
return;
}
float distance = m_lookAt.distance (getEyesPos ()); // how far away is the enemy?
const float distance = m_lookAt.distance (getEyesPos ()); // how far away is the enemy?
// or if friend in line of fire, stop this too but do not update shoot time
if (isFriendInLineOfFire (distance)) {
@ -958,12 +958,10 @@ void Bot::fireWeapons () {
return;
}
auto tab = conf.getRawWeapons ();
auto enemy = m_enemy;
int selectId = Weapon::Knife, selectIndex = 0, choosenWeapon = 0;
int weapons = pev->weapons;
const auto tab = conf.getRawWeapons ();
const auto weapons = pev->weapons;
// if jason mode use knife only
if (isKnifeMode ()) {
@ -972,7 +970,7 @@ void Bot::fireWeapons () {
}
// use knife if near and good difficulty (l33t dude!)
if (cv_stab_close_enemies.bool_ () && m_difficulty >= Difficulty::Normal && m_healthValue > 80.0f && !game.isNullEntity (enemy) && m_healthValue >= enemy->v.health && distance < 100.0f && !isOnLadder () && !isGroupOfEnemies (pev->origin)) {
if (cv_stab_close_enemies.bool_ () && m_difficulty >= Difficulty::Normal && m_healthValue > 80.0f && !game.isNullEntity (m_enemy) && m_healthValue >= m_enemy->v.health && distance < 100.0f && !isOnLadder () && !isGroupOfEnemies (pev->origin)) {
selectWeapons (distance, selectIndex, selectId, choosenWeapon);
return;
}
@ -997,7 +995,7 @@ void Bot::fireWeapons () {
// loop through all the weapons until terminator is found...
while (tab[selectIndex].id) {
int id = tab[selectIndex].id;
const int id = tab[selectIndex].id;
// is the bot carrying this weapon?
if (weapons & cr::bit (id)) {
@ -1028,7 +1026,7 @@ bool Bot::isWeaponBadAtDistance (int weaponIndex, float distance) {
// to attack our enemy, since current weapon is not very good in this situation.
// do not switch weapons when crossing the distance line
auto &info = conf.getWeapons ();
const auto &info = conf.getWeapons ();
if (m_difficulty < Difficulty::Normal || !hasSecondaryWeapon ()) {
return false;
@ -1067,14 +1065,14 @@ void Bot::focusEnemy () {
if (m_enemySurpriseTime > game.time ()) {
return;
}
float distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
const float distanceSq = m_lookAt.distanceSq2d (getEyesPos ()); // how far away is the enemy scum?
if (distance < 128.0f && !usesSniper ()) {
if (distanceSq < cr::sqrf (128.0f) && !usesSniper ()) {
if (usesKnife ()) {
if (distance < 72.0f) {
if (distanceSq < cr::sqrf (72.0f)) {
m_wantsToFire = true;
}
else if (distance > 90.0f) {
else if (distanceSq > cr::sqrf (90.0f)) {
m_wantsToFire = false;
}
}
@ -1083,13 +1081,13 @@ void Bot::focusEnemy () {
}
}
else {
float dot = util.getShootingCone (ent (), m_enemyOrigin);
const float dot = util.getShootingCone (ent (), m_enemyOrigin);
if (dot < 0.90f) {
m_wantsToFire = false;
}
else {
float enemyDot = util.getShootingCone (m_enemy, pev->origin);
const float enemyDot = util.getShootingCone (m_enemy, pev->origin);
// enemy faces bot?
if (enemyDot >= 0.90f) {
@ -1123,7 +1121,7 @@ void Bot::attackMovement () {
}
auto approach = 0;
auto distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
const auto distance = m_lookAt.distance2d (getEyesPos ()); // how far away is the enemy scum?
if (usesKnife ()) {
approach = 100;
@ -1159,7 +1157,7 @@ void Bot::attackMovement () {
m_fightStyle = Fight::Stay;
}
else if (usesRifle () || usesSubmachine () || usesHeavy ()) {
int rand = rg.get (1, 100);
const int rand = rg.get (1, 100);
if (distance < 500.0f) {
m_fightStyle = Fight::Strafe;
@ -1215,8 +1213,8 @@ void Bot::attackMovement () {
// to start strafing, we have to first figure out if the target is on the left side or right side
if (m_strafeSetTime < game.time ()) {
const auto &dirToPoint = (pev->origin - m_enemy->v.origin).normalize2d ();
const auto &rightSide = m_enemy->v.v_angle.right ().normalize2d ();
const auto &dirToPoint = (pev->origin - m_enemy->v.origin).normalize2d_apx ();
const auto &rightSide = m_enemy->v.v_angle.right ().normalize2d_apx ();
if ((dirToPoint | rightSide) < 0.0f) {
m_combatStrafeDir = Dodge::Left;
@ -1276,7 +1274,7 @@ void Bot::attackMovement () {
m_duckTime = game.time () + m_frameInterval * 2.0f;
}
else if ((distance > kDoubleSprayDistance && hasPrimaryWeapon ()) && (m_enemyParts & (Visibility::Head | Visibility::Body)) && getCurrentTaskId () != Task::SeekCover && getCurrentTaskId () != Task::Hunt) {
int enemyNearestIndex = graph.getNearest (m_enemy->v.origin);
const int enemyNearestIndex = graph.getNearest (m_enemy->v.origin);
if (vistab.visible (m_currentNodeIndex, enemyNearestIndex, VisIndex::Crouch) && vistab.visible (enemyNearestIndex, m_currentNodeIndex, VisIndex::Crouch)) {
m_duckTime = game.time () + m_frameInterval * 2.0f;
@ -1472,7 +1470,7 @@ bool Bot::rateGroundWeapon (edict_t *ent) {
int groundIndex = 0;
const int *pref = conf.getWeaponPrefs (m_personality);
auto tab = conf.getRawWeapons ();
const auto tab = conf.getRawWeapons ();
for (int i = 0; i < kNumWeapons; ++i) {
if (ent->v.model.str (9) == tab[*pref].model) {
@ -1513,7 +1511,7 @@ void Bot::selectBestWeapon () {
if (m_isReloading) {
return;
}
auto tab = conf.getRawWeapons ();
const auto tab = conf.getRawWeapons ();
int selectIndex = 0;
int chosenWeaponIndex = 0;
@ -1526,7 +1524,7 @@ void Bot::selectBestWeapon () {
continue;
}
int id = tab[selectIndex].id;
const int id = tab[selectIndex].id;
bool ammoLeft = false;
// is the bot already holding this weapon and there is still ammo in clip?
@ -1675,10 +1673,10 @@ bool Bot::isGroupOfEnemies (const Vector &location, int numEnemies, float radius
void Bot::checkReload () {
// check the reload state
auto task = getCurrentTaskId ();
const auto task = getCurrentTaskId ();
// we're should not reload, while doing next tasks
bool uninterruptibleTask = (task == Task::PlantBomb || task == Task::DefuseBomb || task == Task::PickupItem || task == Task::ThrowExplosive || task == Task::ThrowFlashbang || task == Task::ThrowSmoke);
const bool uninterruptibleTask = (task == Task::PlantBomb || task == Task::DefuseBomb || task == Task::PickupItem || task == Task::ThrowExplosive || task == Task::ThrowFlashbang || task == Task::ThrowSmoke);
// do not check for reload
if (uninterruptibleTask || m_isUsingGrenade || usesKnife ()) {
@ -1746,10 +1744,10 @@ void Bot::checkReload () {
float Bot::calculateScaleFactor (edict_t *ent) {
Vector entSize = ent->v.maxs - ent->v.mins;
float entArea = 2 * (entSize.x * entSize.y + entSize.y * entSize.z + entSize.x * entSize.z);
float entArea = 2.0f * (entSize.x * entSize.y + entSize.y * entSize.z + entSize.x * entSize.z);
Vector botSize = pev->maxs - pev->mins;
float botArea = 2 * (botSize.x * botSize.y + botSize.y * botSize.z + botSize.x * botSize.z);
float botArea = 2.0f * (botSize.x * botSize.y + botSize.y * botSize.z + botSize.x * botSize.z);
return entArea / botArea;
}
@ -1759,7 +1757,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
// returns null vector if toss is not feasible.
TraceResult tr {};
float gravity = sv_gravity.float_ () * 0.55f;
const float gravity = sv_gravity.float_ () * 0.55f;
Vector end = stop - pev->velocity;
end.z -= 15.0f;
@ -1778,8 +1776,8 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
if (midPoint.z < start.z || midPoint.z < end.z) {
return nullptr;
}
float timeOne = cr::sqrtf ((midPoint.z - start.z) / (0.5f * gravity));
float timeTwo = cr::sqrtf ((midPoint.z - end.z) / (0.5f * gravity));
const float timeOne = cr::sqrtf ((midPoint.z - start.z) / (0.5f * gravity));
const float timeTwo = cr::sqrtf ((midPoint.z - end.z) / (0.5f * gravity));
if (timeOne < 0.1f) {
return nullptr;
@ -1798,7 +1796,7 @@ Vector Bot::calcToss (const Vector &start, const Vector &stop) {
game.testHull (end, apex, TraceIgnore::Monsters, head_hull, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0f)) {
float dot = -(tr.vecPlaneNormal | (apex - end).normalize ());
const float dot = -(tr.vecPlaneNormal | (apex - end).normalize_apx ());
if (dot > 0.75f || tr.flFraction < 0.8f) {
return nullptr;
@ -1814,7 +1812,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) {
Vector velocity = stop - start;
TraceResult tr {};
float gravity = sv_gravity.float_ () * 0.55f;
const float gravity = sv_gravity.float_ () * 0.55f;
float time = velocity.length () / 195.0f;
if (time < 0.01f) {
@ -1839,7 +1837,7 @@ Vector Bot::calcThrow (const Vector &start, const Vector &stop) {
game.testHull (stop, apex, TraceIgnore::Monsters, head_hull, ent (), &tr);
if (!cr::fequal (tr.flFraction, 1.0) || tr.fAllSolid) {
float dot = -(tr.vecPlaneNormal | (apex - stop).normalize ());
const float dot = -(tr.vecPlaneNormal | (apex - stop).normalize_apx ());
if (dot > 0.75f || tr.flFraction < 0.8f) {
return nullptr;
@ -1874,7 +1872,7 @@ edict_t *Bot::setCorrectGrenadeVelocity (const char *model) {
void Bot::checkGrenadesThrow () {
// do not check cancel if we have grenade in out hands
bool preventibleTasks = getCurrentTaskId () == Task::PlantBomb || getCurrentTaskId () == Task::DefuseBomb;
const bool preventibleTasks = getCurrentTaskId () == Task::PlantBomb || getCurrentTaskId () == Task::DefuseBomb;
auto clearThrowStates = [] (uint32_t &states) {
states &= ~(Sense::ThrowExplosive | Sense::ThrowFlashbang | Sense::ThrowSmoke);
@ -1918,20 +1916,20 @@ void Bot::checkGrenadesThrow () {
return;
}
}
float distance = m_lastEnemyOrigin.distance2d (pev->origin);
float distanceSq = m_lastEnemyOrigin.distanceSq2d (pev->origin);
// don't throw grenades at anything that isn't on the ground!
if (!(m_lastEnemy->v.flags & FL_ONGROUND) && !m_lastEnemy->v.waterlevel && m_lastEnemyOrigin.z > pev->absmax.z) {
distance = kInfiniteDistance;
distanceSq = kInfiniteDistance;
}
// too high to throw?
if (m_lastEnemy->v.origin.z > pev->origin.z + 500.0f) {
distance = kInfiniteDistance;
distanceSq = kInfiniteDistance;
}
// enemy within a good throw distance?
if (!m_lastEnemyOrigin.empty () && distance > (grenadeToThrow == Weapon::Smoke ? 200.0f : 400.0f) && distance < 1200.0f) {
if (!m_lastEnemyOrigin.empty () && distanceSq > cr::sqrf (grenadeToThrow == Weapon::Smoke ? 200.0f : 400.0f) && distanceSq < cr::sqrf (1200.0f)) {
bool allowThrowing = true;
// care about different grenades
@ -1985,7 +1983,7 @@ void Bot::checkGrenadesThrow () {
break;
case Weapon::Flashbang: {
int nearest = graph.getNearest (m_lastEnemy->v.velocity.get2d () + m_lastEnemy->v.origin);
const int nearest = graph.getNearest (m_lastEnemy->v.velocity.get2d () + m_lastEnemy->v.origin);
if (nearest != kInvalidNodeIndex) {
m_throw = graph[nearest].origin;
@ -2143,7 +2141,7 @@ bool Bot::isEnemyNoticeable (float range) {
}
}
float dispositionChance = closeChance + (farChance - closeChance) * rangeModifier; // combine posture, speed, and range chances
const float dispositionChance = closeChance + (farChance - closeChance) * rangeModifier; // combine posture, speed, and range chances
float noticeChance = dispositionChance * coverRatio / 100.0f; // determine actual chance of noticing player
noticeChance += (0.5f + 0.5f * (static_cast <float> (m_difficulty) * 25.0f));
@ -2171,8 +2169,8 @@ int Bot::getAmmo (int id) {
}
void Bot::selectWeaponByIndex (int index) {
auto tab = conf.getRawWeapons ();
issueCommand (tab[index].name);
const auto tab = conf.getRawWeapons ();
issueCommand (tab[index].name.chars ());
}
void Bot::selectWeaponById (int id) {
@ -2206,7 +2204,7 @@ void Bot::checkBurstMode (float distance) {
void Bot::checkSilencer () {
if ((m_currentWeapon == Weapon::USP || m_currentWeapon == Weapon::M4A1) && !hasShield () && game.isNullEntity (m_enemy)) {
int prob = (m_personality == Personality::Rusher ? 35 : 65);
const int prob = (m_personality == Personality::Rusher ? 35 : 65);
// aggressive bots don't like the silencer
if (rg.chance (m_currentWeapon == Weapon::USP ? prob / 2 : prob)) {

View file

@ -61,7 +61,7 @@ int BotControl::cmdKickBots () {
enum args { alias = 1, instant, team };
// check if we're need to remove bots instantly
auto kickInstant = strValue (instant) == "instant";
const auto kickInstant = strValue (instant) == "instant";
// if team is specified, kick from specified tram
if (strValue (alias).endsWith ("_ct") || intValue (team) == 2 || strValue (team) == "ct") {
@ -109,7 +109,7 @@ int BotControl::cmdVote () {
if (!hasArg (mapid)) {
return BotCommandResult::BadFormat;
}
int mapID = intValue (mapid);
const int mapID = intValue (mapid);
// loop through all players
for (const auto &bot : bots) {
@ -126,16 +126,15 @@ int BotControl::cmdWeaponMode () {
if (!hasArg (type)) {
return BotCommandResult::BadFormat;
}
HashMap <String, int> modes;
modes["knife"] = 1;
modes["pistol"] = 2;
modes["shotgun"] = 3;
modes["smg"] = 4;
modes["rifle"] = 5;
modes["sniper"] = 6;
modes["standard"] = 7;
static HashMap <String, int> modes {
{ "knife", 1 },
{ "pistol", 2 },
{ "shotgun", 3 },
{ "smg", 4 },
{ "rifle", 5 },
{ "sniper", 6 },
{ "standard", 7 }
};
auto mode = strValue (type);
// check if selected mode exists
@ -148,7 +147,7 @@ int BotControl::cmdWeaponMode () {
}
int BotControl::cmdVersion () {
auto &build = product.build;
const auto &build = product.build;
msg ("%s v%s (ID %s)", product.name, product.version, build.id);
msg (" by %s (%s)", product.author, product.email);
@ -592,7 +591,7 @@ int BotControl::cmdNodeCache () {
graph.cachePoint (kInvalidNodeIndex);
}
else {
int index = intValue (nearest);
const int index = intValue (nearest);
// check for existence
if (graph.exists (index)) {
@ -623,11 +622,11 @@ int BotControl::cmdNodeClean () {
msg ("Done. Processed node %d. %d useless paths was cleared.", graph.getEditorNearest (), removed);
}
else {
int index = intValue (option);
const int index = intValue (option);
// check for existence
if (graph.exists (index)) {
int removed = graph.clearConnections (index);
const int removed = graph.clearConnections (index);
msg ("Done. Processed node %d. %d useless paths was cleared.", index, removed);
}

View file

@ -9,7 +9,6 @@
ConVar cv_csdm_mode ("yb_csdm_mode", "0", "Enables or disables CSDM / FFA mode for bots.\nAllowed values: '0', '1', '2', '3'.\nIf '0', CSDM / FFA mode is auto-detected.\nIf '1', CSDM mode is enabled, but FFA is disabled.\nIf '2', CSDM and FFA mode is enabled.\nIf '3', CSDM and FFA mode is disabled.", true, 0.0f, 3.0f);
ConVar cv_ignore_map_prefix_game_mode ("yb_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_breakable_health_limit ("yb_breakable_health_limit", "500.0", "Specifies the maximum health of breakable object, that bot will consider to destroy.", true, 1.0f, 3000.0);
ConVar cv_threadpool_workers ("yb_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 <float> (plat.hardwareConcurrency ()));
ConVar sv_skycolor_r ("sv_skycolor_r", nullptr, Var::GameRef);
@ -138,13 +137,13 @@ void Game::levelInitialize (edict_t *entities, int max) {
m_mapFlags &= ~MapFlags::HostageRescue;
}
}
else if (classname.startsWith ("func_door")) {
else if (util.isDoorEntity (ent)) {
m_mapFlags |= MapFlags::HasDoors;
}
else if (classname.startsWith ("func_button")) {
m_mapFlags |= MapFlags::HasButtons;
}
else if (isShootableBreakable (ent)) {
else if (util.isShootableBreakable (ent)) {
m_breakables.push (ent);
}
}
@ -341,17 +340,17 @@ float Game::getWaveLen (const char *fileName) {
return 0.0f;
}
auto length = static_cast <float> (weh.read32 (header.dataChunkLength));
auto bps = static_cast <float> (weh.read16 (header.bitsPerSample)) / 8;
auto channels = static_cast <float> (weh.read16 (header.numChannels));
auto rate = static_cast <float> (weh.read32 (header.sampleRate));
const auto length = static_cast <float> (weh.read32 (header.dataChunkLength));
const auto bps = static_cast <float> (weh.read16 (header.bitsPerSample)) / 8;
const auto channels = static_cast <float> (weh.read16 (header.numChannels));
const auto rate = static_cast <float> (weh.read32 (header.sampleRate));
return length / bps / channels / rate;
}
bool Game::isDedicated () {
// return true if server is dedicated server, false otherwise
static bool dedicated = engfuncs.pfnIsDedicatedServer () > 0;
static const bool dedicated = engfuncs.pfnIsDedicatedServer () > 0;
return dedicated;
}
@ -440,7 +439,7 @@ bool Game::checkVisibility (edict_t *ent, uint8_t *set) {
if (ent->headnode < 0) {
for (int i = 0; i < ent->num_leafs; ++i) {
auto leaf = ent->leafnums[i];
const auto leaf = ent->leafnums[i];
if (set[leaf >> 3] & cr::bit (leaf & 7)) {
return true;
@ -450,7 +449,8 @@ bool Game::checkVisibility (edict_t *ent, uint8_t *set) {
}
for (int i = 0; i < 48; ++i) {
auto leaf = ent->leafnums[i];
const auto leaf = ent->leafnums[i];
if (leaf == -1) {
break;
}
@ -464,16 +464,14 @@ bool Game::checkVisibility (edict_t *ent, uint8_t *set) {
uint8_t *Game::getVisibilitySet (Bot *bot, bool pvs) {
if (is (GameFlags::Xash3D)) {
return nullptr;
return nullptr; // TODO: bug fixed in upstream xash3d, should be removed
}
auto eyes = bot->getEyesPos ();
if (bot->isDucking ()) {
eyes += VEC_HULL_MIN - VEC_DUCK_HULL_MIN;
}
float org[3] { eyes.x, eyes.y, eyes.z };
return pvs ? engfuncs.pfnSetFatPVS (org) : engfuncs.pfnSetFatPAS (org);
return pvs ? engfuncs.pfnSetFatPVS (eyes) : engfuncs.pfnSetFatPAS (eyes);
}
void Game::sendClientMessage (bool console, edict_t *ent, StringRef message) {
@ -923,7 +921,7 @@ bool Game::postload () {
}
}
else {
bool binaryLoaded = loadCSBinary ();
const bool binaryLoaded = loadCSBinary ();
if (!binaryLoaded && !is (GameFlags::Metamod)) {
logger.fatal ("Mod that you has started, not supported by this bot (gamedir: %s)", getRunningModName ());
@ -1067,26 +1065,6 @@ void Game::searchEntities (const Vector &position, float radius, EntitySearch fu
}
}
bool Game::isShootableBreakable (edict_t *ent) {
if (isNullEntity (ent)) {
return false;
}
auto limit = cv_breakable_health_limit.float_ ();
constexpr auto kFuncBreakable = StringRef::fnv1a32 ("func_breakable");
constexpr auto kFuncPushable = StringRef::fnv1a32 ("func_pushable");
constexpr auto kFuncWall = StringRef::fnv1a32 ("func_wall");
auto classnameHash = ent->v.classname.str ().hash ();
if ((classnameHash == kFuncBreakable && ent->v.health < limit) || (classnameHash == kFuncPushable && (ent->v.spawnflags & SF_PUSH_BREAKABLE) && ent->v.health < limit) || (classnameHash == kFuncWall && ent->v.health < limit)) {
if (ent->v.takedamage > 0.0f && ent->v.impulse <= 0 && !(ent->v.flags & FL_WORLDBRUSH) && !(ent->v.spawnflags & SF_BREAK_TRIGGER_ONLY)) {
return ent->v.movetype == MOVETYPE_PUSH || ent->v.movetype == MOVETYPE_PUSHSTEP;
}
}
return false;
}
void Game::printBotVersion () {
String gameVersionStr;
StringArray botRuntimeFlags;
@ -1166,7 +1144,7 @@ void LightMeasure::animateLight () {
}
// 'm' is normal light, 'a' is no light, 'z' is double bright
const int index = static_cast <int> (game.time () * 10.0f);
const auto index = static_cast <int> (game.time () * 10.0f);
for (auto j = 0; j < MAX_LIGHTSTYLES; ++j) {
if (!m_lightstyle[j].length) {
@ -1207,8 +1185,8 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
// determine which side of the node plane our points are on, fixme: optimize for axial
auto plane = node->plane;
float front = (start | plane->normal) - plane->dist;
float back = (end | plane->normal) - plane->dist;
const float front = (start | plane->normal) - plane->dist;
const float back = (end | plane->normal) - plane->dist;
int side = front < 0.0f;
@ -1218,7 +1196,7 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
}
// calculate mid point
float frac = front / (front - back);
const float frac = front / (front - back);
auto mid = start + (end - start) * frac;
// go down front side
@ -1267,9 +1245,9 @@ template <typename S, typename M> bool LightMeasure::recursiveLightPoint (const
m_point.reset (); // reset point color.
int smax = (surf->extents[0] >> 4) + 1;
int tmax = (surf->extents[1] >> 4) + 1;
int size = smax * tmax;
const int smax = (surf->extents[0] >> 4) + 1;
const int tmax = (surf->extents[1] >> 4) + 1;
const int size = smax * tmax;
auto lightmap = surf->samples + dt * smax + ds;

View file

@ -442,55 +442,56 @@ void BotGraph::addPath (int addIndex, int pathIndex, float distance) {
}
}
int BotGraph::getFarest (const Vector &origin, float maxDistance) {
int BotGraph::getFarest (const Vector &origin, const float maxRange) {
// find the farest node to that origin, and return the index to this node
int index = kInvalidNodeIndex;
maxDistance = cr::sqrf (maxDistance);
auto maxDistanceSq = cr::sqrf (maxRange);
for (const auto &path : m_paths) {
const float distance = path.origin.distanceSq (origin);
const float distanceSq = path.origin.distanceSq (origin);
if (distance > maxDistance) {
if (distanceSq > maxDistanceSq) {
index = path.number;
maxDistance = distance;
maxDistanceSq = distanceSq;
}
}
return index;
}
int BotGraph::getForAnalyzer (const Vector &origin, float maxDistance) {
int BotGraph::getForAnalyzer (const Vector &origin, const float maxRange) {
// find the farest node to that origin, and return the index to this node
int index = kInvalidNodeIndex;
float maximumDistanceSq = cr::sqrf (maxRange);
for (const auto &path : m_paths) {
const float distance = path.origin.distance (origin);
const float distanceSq = path.origin.distanceSq (origin);
if (distance < maxDistance) {
if (distanceSq < maximumDistanceSq) {
index = path.number;
maxDistance = distance;
maximumDistanceSq = distanceSq;
}
}
return index;
}
int BotGraph::getNearestNoBuckets (const Vector &origin, float minDistance, int flags) {
int BotGraph::getNearestNoBuckets (const Vector &origin, const float range, int flags) {
// find the nearest node to that origin and return the index
// fallback and go thru wall the nodes...
int index = kInvalidNodeIndex;
minDistance = cr::sqrf (minDistance);
float nearestDistanceSq = cr::sqrf (range);
for (const auto &path : m_paths) {
if (flags != -1 && !(path.flags & flags)) {
continue; // if flag not -1 and node has no this flag, skip node
}
const float distance = path.origin.distanceSq (origin);
const float distanceSq = path.origin.distanceSq (origin);
if (distance < minDistance) {
if (distanceSq < nearestDistanceSq) {
index = path.number;
minDistance = distance;
nearestDistanceSq = distanceSq;
}
}
return index;
@ -503,36 +504,36 @@ int BotGraph::getEditorNearest () {
return getNearestNoBuckets (m_editor->v.origin, 50.0f);
}
int BotGraph::getNearest (const Vector &origin, float minDistance, int flags) {
int BotGraph::getNearest (const Vector &origin, const float range, int flags) {
// find the nearest node to that origin and return the index
if (minDistance > 256.0f && !cr::fequal (minDistance, kInfiniteDistance)) {
return getNearestNoBuckets (origin, minDistance, flags);
if (range > 256.0f && !cr::fequal (range, kInfiniteDistance)) {
return getNearestNoBuckets (origin, range, flags);
}
const auto &bucket = getNodesInBucket (origin);
if (bucket.length () < kMaxNodeLinks) {
return getNearestNoBuckets (origin, minDistance, flags);
return getNearestNoBuckets (origin, range, flags);
}
int index = kInvalidNodeIndex;
auto minDistanceSq = cr::sqrf (minDistance);
auto nearestDistanceSq = cr::sqrf (range);
for (const auto &at : bucket) {
if (flags != -1 && !(m_paths[at].flags & flags)) {
continue; // if flag not -1 and node has no this flag, skip node
}
float distance = origin.distanceSq (m_paths[at].origin);
const float distanceSq = origin.distanceSq (m_paths[at].origin);
if (distance < minDistanceSq) {
if (distanceSq < nearestDistanceSq) {
index = at;
minDistanceSq = distance;
nearestDistanceSq = distanceSq;
}
}
// nothing found, try to find without buckets
if (index == kInvalidNodeIndex) {
return getNearestNoBuckets (origin, minDistance, flags);
return getNearestNoBuckets (origin, range, flags);
}
return index;
}
@ -540,7 +541,7 @@ int BotGraph::getNearest (const Vector &origin, float minDistance, int flags) {
IntArray BotGraph::getNarestInRadius (float radius, const Vector &origin, int maxCount) {
// returns all nodes within radius from position
radius = cr::sqrf (radius);
const float radiusSq = cr::sqrf (radius);
IntArray result;
const auto &bucket = getNodesInBucket (origin);
@ -551,7 +552,7 @@ IntArray BotGraph::getNarestInRadius (float radius, const Vector &origin, int ma
break;
}
if (origin.distanceSq (path.origin) < radius) {
if (origin.distanceSq (path.origin) < radiusSq) {
result.push (path.number);
}
}
@ -563,7 +564,7 @@ IntArray BotGraph::getNarestInRadius (float radius, const Vector &origin, int ma
break;
}
if (origin.distanceSq (m_paths[at].origin) < radius) {
if (origin.distanceSq (m_paths[at].origin) < radiusSq) {
result.push (at);
}
}
@ -626,9 +627,9 @@ void BotGraph::add (int type, const Vector &pos) {
index = getEditorNearest ();
if (index != kInvalidNodeIndex && m_paths[index].number >= 0) {
float distance = m_editor->v.origin.distance (m_paths[index].origin);
const float distanceSq = m_editor->v.origin.distanceSq (m_paths[index].origin);
if (distance < 50.0f) {
if (distanceSq < cr::sqrf (50.0f)) {
addNewNode = false;
path = &m_paths[index];
@ -644,9 +645,9 @@ void BotGraph::add (int type, const Vector &pos) {
index = getEditorNearest ();
if (index != kInvalidNodeIndex && m_paths[index].number >= 0) {
float distance = m_editor->v.origin.distance (m_paths[index].origin);
const float distanceSq = m_editor->v.origin.distanceSq (m_paths[index].origin);
if (distance < 50.0f) {
if (distanceSq < cr::sqrf (50.0f)) {
addNewNode = false;
path = &m_paths[index];
@ -730,7 +731,7 @@ void BotGraph::add (int type, const Vector &pos) {
m_lastJumpNode = index;
}
else if (type == NodeAddFlag::JumpEnd) {
float distance = m_paths[m_lastJumpNode].origin.distance (m_editor->v.origin);
const float distance = m_paths[m_lastJumpNode].origin.distance (m_editor->v.origin);
addPath (m_lastJumpNode, index, distance);
for (auto &link : m_paths[m_lastJumpNode].links) {
@ -796,7 +797,7 @@ void BotGraph::add (int type, const Vector &pos) {
// ladder nodes need careful connections
if (path->flags & NodeFlag::Ladder) {
float minDistance = kInfiniteDistance;
float nearestDistance = kInfiniteDistance;
int destIndex = kInvalidNodeIndex;
TraceResult tr {};
@ -813,18 +814,18 @@ void BotGraph::add (int type, const Vector &pos) {
game.testLine (newOrigin, calc.origin, TraceIgnore::Monsters, m_editor, &tr);
if (cr::fequal (tr.flFraction, 1.0f) && cr::abs (newOrigin.x - calc.origin.x) < 64.0f && cr::abs (newOrigin.y - calc.origin.y) < 64.0f && cr::abs (newOrigin.z - calc.origin.z) < m_autoPathDistance) {
float distance = newOrigin.distance2d (calc.origin);
const float distance = newOrigin.distance2d (calc.origin);
addPath (index, calc.number, distance);
addPath (calc.number, index, distance);
}
}
else {
float distance = newOrigin.distance2d (calc.origin);
const float distance = newOrigin.distance2d (calc.origin);
if (distance < minDistance) {
if (distance < nearestDistance) {
destIndex = calc.number;
minDistance = distance;
nearestDistance = distance;
}
// check if the node is reachable from the new one
@ -955,7 +956,7 @@ void BotGraph::toggleFlags (int toggleFlag) {
void BotGraph::setRadius (int index, float radius) {
// this function allow manually setting the zone radius
int node = exists (index) ? index : getEditorNearest ();
const int node = exists (index) ? index : getEditorNearest ();
if (node != kInvalidNodeIndex) {
m_paths[node].radius = radius;
@ -1050,8 +1051,7 @@ void BotGraph::pathCreate (char dir) {
msg ("Unable to connect node with itself.");
return;
}
float distance = m_paths[nodeFrom].origin.distance (m_paths[nodeTo].origin);
const float distance = m_paths[nodeFrom].origin.distance (m_paths[nodeTo].origin);
if (dir == PathConnection::Outgoing) {
addPath (nodeFrom, nodeTo, distance);
@ -1135,7 +1135,7 @@ void BotGraph::erasePath () {
}
void BotGraph::cachePoint (int index) {
int node = exists (index) ? index : getEditorNearest ();
const int node = exists (index) ? index : getEditorNearest ();
if (node == kInvalidNodeIndex) {
m_cacheNodeIndex = kInvalidNodeIndex;
@ -1211,7 +1211,7 @@ void BotGraph::showFileInfo () {
msg (" compressed_size: %dkB", m_graphHeader.compressed / 1024);
msg (" uncompressed_size: %dkB", m_graphHeader.uncompressed / 1024);
msg (" options: %d", m_graphHeader.options); // display as string ?
msg (" analyzed: %s", (m_graphHeader.options & StorageOption::Analyzed) ? "yes" : "no"); // display as string ?
msg (" analyzed: %s", isAnalyzed () ? "yes" : "no"); // display as string ?
msg ("");
@ -1274,7 +1274,7 @@ void BotGraph::calculatePathRadius (int index) {
if (tr.flFraction < 1.0f) {
game.testLine (radiusStart, radiusEnd, TraceIgnore::Monsters, nullptr, &tr);
if (tr.pHit && tr.pHit->v.classname.str ().startsWith ("func_door")) {
if (util.isDoorEntity (tr.pHit)) {
path.radius = 0.0f;
wayBlocked = true;
@ -1714,14 +1714,14 @@ float BotGraph::calculateTravelTime (float maxSpeed, const Vector &src, const Ve
bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination, const float maxHeight) {
TraceResult tr {};
float distance = destination.distance (src);
float distanceSq = destination.distanceSq (src);
if ((destination.z - src.z) >= 45.0f) {
return false;
}
// is the destination not close enough?
if (distance > m_autoPathDistance) {
if (distanceSq > cr::sqrf (m_autoPathDistance)) {
return false;
}
@ -1735,10 +1735,12 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination,
// check if this node is "visible"...
game.testLine (src, destination, TraceIgnore::Monsters, m_editor, &tr);
const bool isDoor = util.isDoorEntity (tr.pHit);
// if node is visible from current position (even behind head)...
if (tr.pHit && (tr.flFraction >= 1.0f || tr.pHit->v.classname.str ().startsWith ("func_door"))) {
if (tr.flFraction >= 1.0f || isDoor) {
// if it's a door check if nothing blocks behind
if (tr.pHit->v.classname.str ().startsWith ("func_door")) {
if (isDoor) {
game.testLine (tr.vecEndPos, destination, TraceIgnore::Monsters, tr.pHit, &tr);
if (tr.flFraction < 1.0f) {
@ -1774,9 +1776,9 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination,
game.testLine (check, down, TraceIgnore::Monsters, m_editor, &tr);
float lastHeight = tr.flFraction * 1000.0f; // height from ground
distance = destination.distance (check); // distance from goal
distanceSq = destination.distanceSq (check); // distance from goal
while (distance > 10.0f) {
while (distanceSq > cr::sqrf (10.0f)) {
// move 10 units closer to the goal...
check = check + (direction * 10.0f);
@ -1792,7 +1794,7 @@ bool BotGraph::isNodeReacheableEx (const Vector &src, const Vector &destination,
return false; // can't get there without jumping...
}
lastHeight = height;
distance = destination.distance (check); // distance from goal
distanceSq = destination.distanceSq (check); // distance from goal
}
return true;
}
@ -1820,7 +1822,7 @@ void BotGraph::frame () {
m_editor->v.movetype = MOVETYPE_NOCLIP;
}
float nearestDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
int nearestIndex = kInvalidNodeIndex;
// check if it's time to add jump node
@ -1848,22 +1850,22 @@ void BotGraph::frame () {
// check if it's a auto-add-node mode enabled
if (hasEditFlag (GraphEdit::Auto) && (m_editor->v.flags & (FL_ONGROUND | FL_PARTIALGROUND))) {
// find the distance from the last used node
float distance = m_lastNode.distanceSq (m_editor->v.origin);
float distanceSq = m_lastNode.distanceSq (m_editor->v.origin);
if (distance > cr::sqrf (128.0f)) {
if (distanceSq > cr::sqrf (128.0f)) {
// check that no other reachable nodes are nearby...
for (const auto &path : m_paths) {
if (isNodeReacheable (m_editor->v.origin, path.origin)) {
distance = path.origin.distanceSq (m_editor->v.origin);
distanceSq = path.origin.distanceSq (m_editor->v.origin);
if (distance < nearestDistance) {
nearestDistance = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
}
}
}
// make sure nearest node is far enough away...
if (nearestDistance >= cr::sqrf (128.0f)) {
if (nearestDistanceSq >= cr::sqrf (128.0f)) {
add (NodeAddFlag::Normal); // place a node here
}
}
@ -1871,18 +1873,18 @@ void BotGraph::frame () {
m_facingAtIndex = getFacingIndex ();
// reset the minimal distance changed before
nearestDistance = kInfiniteDistance;
nearestDistanceSq = kInfiniteDistance;
// now iterate through all nodes in a map, and draw required ones
for (auto &path : m_paths) {
float distance = path.origin.distance (m_editor->v.origin);
const float distanceSq = path.origin.distanceSq (m_editor->v.origin);
// check if node is whitin a distance, and is visible
if (distance < cv_graph_draw_distance.float_ () && ((util.isVisible (path.origin, m_editor) && util.isInViewCone (path.origin, m_editor)) || !util.isAlive (m_editor) || distance < 64.0f)) {
if (distanceSq < cr::sqrf (cv_graph_draw_distance.float_ ()) && ((util.isVisible (path.origin, m_editor) && util.isInViewCone (path.origin, m_editor)) || !util.isAlive (m_editor) || distanceSq < cr::sqrf (64.0f))) {
// check the distance
if (distance < nearestDistance) {
if (distanceSq < nearestDistanceSq) {
nearestIndex = path.number;
nearestDistance = distance;
nearestDistanceSq = distanceSq;
}
if (path.display + 1.0f < game.time ()) {
@ -1895,7 +1897,7 @@ void BotGraph::frame () {
else {
nodeHeight = 72.0f;
}
float nodeHalfHeight = nodeHeight * 0.5f;
const float nodeHalfHeight = nodeHeight * 0.5f;
// all nodes are by default are green
Color nodeColor { -1, -1, -1 };
@ -1993,11 +1995,11 @@ void BotGraph::frame () {
}
// draw a paths, camplines and danger directions for nearest node
if (nearestDistance <= 56.0f && m_pathDisplayTime < game.time ()) {
if (nearestDistanceSq <= 56.0f && m_pathDisplayTime < game.time ()) {
m_pathDisplayTime = game.time () + 0.96f;
// create path pointer for faster access
auto &path = m_paths[nearestIndex];
const auto &path = m_paths[nearestIndex];
// draw the camplines
if (path.flags & NodeFlag::Camp) {
@ -2046,7 +2048,7 @@ void BotGraph::frame () {
// if radius is nonzero, draw a full circle
if (path.radius > 0.0f) {
float sqr = cr::sqrtf (cr::sqrf (path.radius) * 0.5f);
const float sqr = cr::sqrtf (cr::sqrf (path.radius) * 0.5f);
game.drawLine (m_editor, origin + Vector (path.radius, 0.0f, 0.0f), origin + Vector (sqr, -sqr, 0.0f), 5, 0, radiusColor, 200, 0, 10);
game.drawLine (m_editor, origin + Vector (sqr, -sqr, 0.0f), origin + Vector (0.0f, -path.radius, 0.0f), 5, 0, radiusColor, 200, 0, 10);
@ -2061,7 +2063,7 @@ void BotGraph::frame () {
game.drawLine (m_editor, origin + Vector (sqr, sqr, 0.0f), origin + Vector (path.radius, 0.0f, 0.0f), 5, 0, radiusColor, 200, 0, 10);
}
else {
float sqr = cr::sqrtf (32.0f);
const float sqr = cr::sqrtf (32.0f);
game.drawLine (m_editor, origin + Vector (sqr, -sqr, 0.0f), origin + Vector (-sqr, sqr, 0.0f), 5, 0, radiusColor, 200, 0, 10);
game.drawLine (m_editor, origin + Vector (-sqr, -sqr, 0.0f), origin + Vector (sqr, sqr, 0.0f), 5, 0, radiusColor, 200, 0, 10);
@ -2069,8 +2071,8 @@ void BotGraph::frame () {
// draw the danger directions
if (!m_hasChanged) {
int dangerIndexT = practice.getIndex (Team::Terrorist, nearestIndex, nearestIndex);
int dangerIndexCT = practice.getIndex (Team::CT, nearestIndex, nearestIndex);
const int dangerIndexT = practice.getIndex (Team::Terrorist, nearestIndex, nearestIndex);
const int dangerIndexCT = practice.getIndex (Team::CT, nearestIndex, nearestIndex);
if (exists (dangerIndexT)) {
game.drawLine (m_editor, path.origin, m_paths[dangerIndexT].origin, 15, 0, { 255, 0, 0 }, 200, 0, 10, DrawLine::Arrow); // draw a red arrow to this index's danger point
@ -2162,8 +2164,8 @@ void BotGraph::frame () {
// if node is not changed display experience also
if (!m_hasChanged) {
int dangerIndexCT = practice.getIndex (Team::CT, nearestIndex, nearestIndex);
int dangerIndexT = practice.getIndex (Team::Terrorist, nearestIndex, nearestIndex);
const int dangerIndexCT = practice.getIndex (Team::CT, nearestIndex, nearestIndex);
const int dangerIndexT = practice.getIndex (Team::Terrorist, nearestIndex, nearestIndex);
String practiceText;
practiceText.assignf (" Node practice data (index / damage):\n"
@ -2470,6 +2472,7 @@ void BotGraph::addBasic () {
autoCreateForEntity (NodeAddFlag::Normal, "info_player_deathmatch"); // then terrortist spawnpoints
autoCreateForEntity (NodeAddFlag::Normal, "info_player_start"); // then add ct spawnpoints
autoCreateForEntity (NodeAddFlag::Normal, "info_vip_start"); // then vip spawnpoint
autoCreateForEntity (NodeAddFlag::Normal, "armoury_entity"); // weapons on the map ?
autoCreateForEntity (NodeAddFlag::Rescue, "func_hostage_rescue"); // hostage rescue zone
@ -2477,8 +2480,10 @@ void BotGraph::addBasic () {
autoCreateForEntity (NodeAddFlag::Goal, "func_bomb_target"); // bombspot zone
autoCreateForEntity (NodeAddFlag::Goal, "info_bomb_target"); // bombspot zone (same as above)
autoCreateForEntity (NodeAddFlag::Goal, "hostage_entity"); // hostage entities
autoCreateForEntity (NodeAddFlag::Goal, "monster_scientist"); // hostage entities (same as above)
autoCreateForEntity (NodeAddFlag::Goal, "func_vip_safetyzone"); // vip rescue (safety) zone
autoCreateForEntity (NodeAddFlag::Goal, "func_escapezone"); // terrorist escape zone
}
@ -2667,7 +2672,7 @@ void BotGraph::convertCampDirection (Path &path) {
if (m_paths.empty ()) {
return;
}
const Vector &offset = path.origin + Vector (0.0f, 0.0f, (path.flags & NodeFlag::Crouch) ? 15.0f : 17.0f);
const auto &offset = path.origin + Vector (0.0f, 0.0f, (path.flags & NodeFlag::Crouch) ? 15.0f : 17.0f);
path.start = (Vector (path.start.x, path.start.y, path.origin.z) - offset).angles ();
path.end = (Vector (path.end.x, path.end.y, path.origin.z) - offset).angles ();

View file

@ -115,7 +115,7 @@ CR_EXPORT int GetEntityAPI (gamefuncs_t *table, int) {
if (!game.isNullEntity (pentTouched) && pentOther != game.getStartEntity ()) {
auto bot = bots[pentTouched];
if (bot && game.isShootableBreakable (pentOther)) {
if (bot && util.isShootableBreakable (pentOther)) {
bot->checkBreakable (pentOther);
}
}

View file

@ -241,7 +241,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
return BotCreateResult::MaxPlayersReached;
}
auto object = cr::makeUnique <Bot> (bot, difficulty, personality, team, skin);
auto index = object->index ();
const auto index = object->index ();
// assign owner of bot name
if (botName != nullptr) {
@ -380,8 +380,8 @@ void BotManager::maintainQuota () {
}
cv_quota.set (cr::clamp <int> (cv_quota.int_ (), 0, game.maxClients ()));
int totalHumansInGame = getHumansCount ();
int humanPlayersInGame = getHumansCount (true);
const int totalHumansInGame = getHumansCount ();
const int humanPlayersInGame = getHumansCount (true);
if (!game.isDedicated () && !totalHumansInGame) {
return;
@ -476,14 +476,13 @@ void BotManager::maintainAutoKill () {
return;
}
int aliveBots = 0;
// do not interrupt bomb-defuse scenario
if (game.mapIs (MapFlags::Demolition) && isBombPlanted ()) {
return;
}
int totalHumans = getHumansCount (true); // we're ignore spectators intentionally
const int totalHumans = getHumansCount (true); // we're ignore spectators intentionally
// if we're have no humans in teams do not bother to proceed
if (!totalHumans) {
@ -500,7 +499,7 @@ void BotManager::maintainAutoKill () {
}
}
}
int aliveHumans = getAliveHumansCount ();
const int aliveHumans = getAliveHumansCount ();
// check if we're have no alive players and some alive bots, and start autokill timer
if (!aliveHumans && aliveBots > 0 && cr::fzero (m_autoKillCheckTime)) {
@ -570,7 +569,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int
// this function fill server with bots, with specified team & personality
// always keep one slot
int maxClients = cv_autovacate.bool_ () ? game.maxClients () - cv_autovacate_keep_slots.int_ () - (game.isDedicated () ? 0 : getHumansCount ()) : game.maxClients ();
const int maxClients = cv_autovacate.bool_ () ? game.maxClients () - cv_autovacate_keep_slots.int_ () - (game.isDedicated () ? 0 : getHumansCount ()) : game.maxClients ();
if (getBotCount () >= maxClients - getHumansCount ()) {
return;
@ -582,7 +581,7 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int
else {
selection = 5;
}
char teams[6][12] = { "", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
constexpr char teams[6][12] = { "", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
auto toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd;
for (int i = 0; i <= toAdd; ++i) {
@ -942,7 +941,7 @@ void BotManager::updateBotDifficulties () {
if (cv_difficulty_min.int_ () != Difficulty::Invalid || cv_difficulty_max.int_ () != Difficulty::Invalid || cv_difficulty_auto.bool_ ()) {
return;
}
auto difficulty = cv_difficulty.int_ ();
const auto difficulty = cv_difficulty.int_ ();
if (difficulty != m_lastDifficulty) {
@ -961,12 +960,12 @@ void BotManager::balanceBotDifficulties () {
};
if (cv_difficulty_auto.bool_ () && m_difficultyBalanceTime < game.time ()) {
auto ratioPlayer = getAverageTeamKPD (false);
auto ratioBots = getAverageTeamKPD (true);
const auto ratioPlayer = getAverageTeamKPD (false);
const auto ratioBots = getAverageTeamKPD (true);
// calculate for each the bot
for (auto &bot : m_bots) {
float score = bot->m_kpdRatio;
const float score = bot->m_kpdRatio;
// if kd ratio is going to go to low, we need to try to set higher difficulty
if (score < 0.8f || (score <= 1.2f && ratioBots < ratioPlayer)) {
@ -1138,7 +1137,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) {
}
float Bot::getConnectionTime () {
auto current = plat.seconds ();
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);
@ -1204,7 +1203,7 @@ bool BotManager::isTeamStacked (int team) {
if (team != Team::CT && team != Team::Terrorist) {
return false;
}
int limitTeams = mp_limitteams.int_ ();
const int limitTeams = mp_limitteams.int_ ();
if (!limitTeams) {
return false;
@ -1239,8 +1238,8 @@ void BotManager::erase (Bot *bot) {
}
void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
auto killerTeam = game.getTeam (killer);
auto victimTeam = game.getTeam (victim);
const auto killerTeam = game.getTeam (killer);
const auto victimTeam = game.getTeam (victim);
if (cv_radio_mode.int_ () == 2) {
// need to send congrats on well placed shot
@ -1656,7 +1655,7 @@ void Bot::updateTeamJoin () {
m_startAction = BotMsg::None; // switch back to idle
// czero has additional models
auto maxChoice = game.is (GameFlags::ConditionZero) ? 5 : 4;
const auto maxChoice = game.is (GameFlags::ConditionZero) ? 5 : 4;
auto enforcedSkin = 0;
// setup enforced skin based on selected team
@ -1697,7 +1696,7 @@ void BotManager::captureChatRadio (StringRef cmd, StringRef arg, edict_t *ent) {
}
if (cmd.startsWith ("say")) {
bool alive = util.isAlive (ent);
const bool alive = util.isAlive (ent);
int team = -1;
if (cmd == "say_team") {
@ -1989,7 +1988,7 @@ void BotThreadWorker::shutdown () {
}
void BotThreadWorker::startup (int workers) {
size_t count = m_botWorker.threadCount ();
const size_t count = m_botWorker.threadCount ();
if (count > 0) {
logger.error ("Tried to start thread pool with existing %d threads in pool.", count);
@ -1997,7 +1996,7 @@ void BotThreadWorker::startup (int workers) {
}
int requestedThreadCount = workers;
int hardwareConcurrency = plat.hardwareConcurrency ();
const int hardwareConcurrency = plat.hardwareConcurrency ();
if (requestedThreadCount == -1) {
requestedThreadCount = hardwareConcurrency / 4;

View file

@ -16,7 +16,7 @@ void MessageDispatcher::netMsgTextMsg () {
}
// lookup cached message
auto cached = m_textMsgCache[m_args[msg].chars_];
const auto cached = m_textMsgCache[m_args[msg].chars_];
// check if we're need to handle message
if (!(cached & TextMsgCache::NeedHandle)) {
@ -113,7 +113,7 @@ void MessageDispatcher::netMsgShowMenu () {
if (m_args.length () < min || !m_bot) {
return;
}
auto cached = m_showMenuCache[m_args[menu].chars_];
const auto cached = m_showMenuCache[m_args[menu].chars_];
// only assign if non-zero
if (cached > 0) {
@ -241,7 +241,7 @@ void MessageDispatcher::netMsgStatusIcon () {
return;
}
// lookup cached icon
auto cached = m_statusIconCache[m_args[icon].chars_];
const auto cached = m_statusIconCache[m_args[icon].chars_];
// check if we're need to handle message
if (!(cached & TextMsgCache::NeedHandle)) {
@ -395,7 +395,7 @@ void MessageDispatcher::netMsgItemStatus () {
if (m_args.length () < min || !m_bot) {
return;
}
auto mask = m_args[value].long_;
const auto mask = m_args[value].long_;
m_bot->m_hasNVG = !!(mask & ItemStatus::Nightvision);
m_bot->m_hasDefuser = !!(mask & ItemStatus::DefusalKit);
@ -520,7 +520,7 @@ void MessageDispatcher::start (edict_t *ent, int32_t type) {
// search if we need to handle this message
if (m_reverseMap.exists (type)) {
auto msg = m_reverseMap[type];
const auto msg = m_reverseMap[type];
m_current = m_handlers[msg] ? msg : NetMsg::None;
}

View file

@ -87,7 +87,7 @@ int Bot::findBestGoal () {
const auto &origin = game.getEntityOrigin (ent);
// too far, go to rescue point
if (origin.distanceSq2d (pev->origin) > 1024.0f) {
if (origin.distanceSq2d (pev->origin) > cr::sqrf (1024.0f)) {
continue;
}
hasMoreHostagesAround = true;
@ -96,7 +96,7 @@ int Bot::findBestGoal () {
}
return findGoalPost (hasMoreHostagesAround ? GoalTactic::Goal : GoalTactic::RescueHostage, defensiveNodes, offensiveNodes);
}
auto difficulty = static_cast <float> (m_difficulty);
const auto difficulty = static_cast <float> (m_difficulty);
offensive = m_agressionLevel * 100.0f;
defensive = m_fearLevel * 100.0f;
@ -151,10 +151,10 @@ int Bot::findBestGoal () {
}
}
float goalDesire = rg.get (0.0f, 100.0f) + offensive;
float forwardDesire = rg.get (0.0f, 100.0f) + offensive;
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;
float campDesire = rg.get (0.0f, 100.0f) + defensive;
float backoffDesire = rg.get (0.0f, 100.0f) + defensive;
if (!usesCampGun ()) {
campDesire *= 0.5f;
@ -213,8 +213,8 @@ int Bot::findBestGoalWhenBombAction () {
result = findDefendNode (bombOrigin);
const Path &path = graph[result];
float bombTimer = mp_c4timer.float_ ();
float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
const float bombTimer = mp_c4timer.float_ ();
const float timeMidBlowup = bots.getTimeBombPlanted () + (bombTimer * 0.5f + bombTimer * 0.25f) - graph.calculateTravelTime (pev->maxspeed, pev->origin, path.origin);
if (timeMidBlowup > game.time ()) {
clearTask (Task::MoveToPosition); // remove any move tasks
@ -261,22 +261,22 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
{
// force bomber to select closest goal, if round-start goal was reset by something
if (m_hasC4 && bots.getRoundStartTime () + 20.0f < game.time ()) {
float minDist = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
int count = 0;
for (auto &point : graph.m_goalPoints) {
float distance = graph[point].origin.distanceSq (pev->origin);
const float distanceSq = graph[point].origin.distanceSq (pev->origin);
if (distance > cr::sqrf (1024.0f)) {
if (distanceSq > cr::sqrf (1024.0f)) {
continue;
}
if (distance < minDist) {
if (distanceSq < nearestDistanceSq) {
goalChoices[count] = point;
if (++count > 3) {
count = 0;
}
minDist = distance;
nearestDistanceSq = distanceSq;
}
}
@ -292,19 +292,19 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
}
else if (tactic == GoalTactic::RescueHostage && !graph.m_rescuePoints.empty ()) {
// force ct with hostage(s) to select closest rescue goal
float minDist = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
int count = 0;
for (auto &point : graph.m_rescuePoints) {
float distance = graph[point].origin.distanceSq (pev->origin);
const float distanceSq = graph[point].origin.distanceSq (pev->origin);
if (distance < minDist) {
if (distanceSq < nearestDistanceSq) {
goalChoices[count] = point;
if (++count > 3) {
count = 0;
}
minDist = distance;
nearestDistanceSq = distanceSq;
}
}
@ -372,7 +372,7 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
}
for (int index = 0; index < 4; ++index) {
auto goal = goals.random ();
const auto goal = goals.random ();
if (recurseCount <= cr::max (4, goals.length <int> ()) && isRecentOrHistorical (goal)) {
if (index > 0) {
@ -386,7 +386,7 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
}
bool Bot::hasActiveGoal () {
auto goal = getTask ()->data;
const auto goal = getTask ()->data;
if (goal == kInvalidNodeIndex) { // not decided about a goal
return false;
@ -423,7 +423,7 @@ void Bot::ignoreCollision () {
void Bot::doPlayerAvoidance (const Vector &normal) {
m_hindrance = nullptr;
float distance = cr::sqrf (348.0f);
float distanceSq = cr::sqrf (348.0f);
if (getCurrentTaskId () == Task::Attack || isOnLadder () || isInNarrowPlace ()) {
return;
@ -453,11 +453,11 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
if (ownPrio > otherPrio) {
continue;
}
auto nearest = client.ent->v.origin.distanceSq (pev->origin);
const auto nearestDistanceSq = client.ent->v.origin.distanceSq (pev->origin);
if (nearest < cr::sqrf (pev->maxspeed) && nearest < distance) {
if (nearestDistanceSq < cr::sqrf (pev->maxspeed) && nearestDistanceSq < distanceSq) {
m_hindrance = client.ent;
distance = nearest;
distanceSq = nearestDistanceSq;
}
}
@ -476,11 +476,11 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
predict += right * m_strafeSpeed * interval;
predict += pev->velocity * interval;
auto movedDistance = m_hindrance->v.origin.distanceSq (predict);
auto nextFrameDistance = pev->origin.distanceSq (m_hindrance->v.origin + m_hindrance->v.velocity * interval);
const auto movedDistanceSq = m_hindrance->v.origin.distanceSq (predict);
const auto nextFrameDistanceSq = pev->origin.distanceSq (m_hindrance->v.origin + m_hindrance->v.velocity * interval);
// is player that near now or in future that we need to steer away?
if (movedDistance <= cr::sqrf (64.0f) || (distance <= cr::sqrf (72.0f) && nextFrameDistance < distance)) {
if (movedDistanceSq <= cr::sqrf (64.0f) || (distanceSq <= cr::sqrf (72.0f) && nextFrameDistanceSq < distanceSq)) {
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
@ -491,7 +491,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
setStrafeSpeed (normal, -pev->maxspeed);
}
if (distance < cr::sqrf (80.0f)) {
if (distanceSq < cr::sqrf (80.0f)) {
if ((dir | forward.normalize2d_apx ()) < 0.0f) {
m_moveSpeed = -pev->maxspeed;
}
@ -589,8 +589,8 @@ void Bot::checkTerrain (float movedDistance, const Vector &dirNormal) {
Vector right {}, forward {};
m_moveAngles.angleVectors (&forward, &right, nullptr);
const Vector &dirToPoint = (pev->origin - m_destOrigin).normalize2d ();
const Vector &rightSide = right.normalize2d ();
const Vector &dirToPoint = (pev->origin - m_destOrigin).normalize2d_apx ();
const Vector &rightSide = right.normalize2d_apx ();
bool dirRight = false;
bool dirLeft = false;
@ -947,11 +947,7 @@ bool Bot::updateNavigation () {
selectBestWeapon ();
}
}
#if 0
if (m_path->flags & NodeFlag::Ladder) {
}
#else
if ((m_pathFlags & NodeFlag::Ladder) || isOnLadder ()) {
constexpr auto kLadderOffset = Vector (0.0f, 0.0f, 16.0f);
@ -979,7 +975,7 @@ bool Bot::updateNavigation () {
int previousNode = 0;
// more than likely someone is already using our ladder...
if (client.ent->v.origin.distance (m_path->origin) < 40.0f) {
if (client.ent->v.origin.distanceSq (m_path->origin) < cr::sqrf (40.0f)) {
if ((client.team != m_team || game.is (GameFlags::FreeForAll)) && !cv_ignore_enemies.bool_ ()) {
game.testLine (getEyesPos (), client.ent->v.origin, TraceIgnore::Monsters, ent (), &tr);
@ -1039,7 +1035,6 @@ bool Bot::updateNavigation () {
}
}
#endif
// special lift handling (code merged from podbotmm)
if (m_pathFlags & NodeFlag::Lift) {
@ -1058,9 +1053,9 @@ bool Bot::updateNavigation () {
if (game.mapIs (MapFlags::HasDoors)) {
game.testLine (pev->origin, m_pathOrigin, TraceIgnore::Monsters, ent (), &tr);
if (!game.isNullEntity (tr.pHit) && game.isNullEntity (m_liftEntity) && tr.pHit->v.classname.str ().startsWith ("func_door")) {
if (!game.isNullEntity (tr.pHit) && game.isNullEntity (m_liftEntity) && util.isDoorEntity (tr.pHit)) {
// if the door is near enough...
if (pev->origin.distanceSq (game.getEntityOrigin (tr.pHit)) < 2500.0f) {
if (pev->origin.distanceSq (game.getEntityOrigin (tr.pHit)) < cr::sqrf (50.0f)) {
ignoreCollision (); // don't consider being stuck
if (rg.chance (50)) {
@ -1118,43 +1113,43 @@ bool Bot::updateNavigation () {
}
}
float desiredDistance = cr::sqrf (8.0f);
float nodeDistance = pev->origin.distanceSq (m_pathOrigin);
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
if (m_pathFlags & NodeFlag::Lift) {
desiredDistance = cr::sqrf (50.0f);
desiredDistanceSq = cr::sqrf (50.0f);
}
else if (isDucking () || (m_pathFlags & NodeFlag::Goal)) {
desiredDistance = cr::sqrf (25.0f);
desiredDistanceSq = cr::sqrf (25.0f);
}
else if (isOnLadder () || (m_pathFlags & NodeFlag::Ladder)) {
desiredDistance = cr::sqrf (24.0f);
desiredDistanceSq = cr::sqrf (24.0f);
}
else if (m_currentTravelFlags & PathFlag::Jump) {
desiredDistance = 0.0f;
desiredDistanceSq = 0.0f;
}
else if (m_path->number == cv_debug_goal.int_ ()) {
desiredDistance = 0.0f;
desiredDistanceSq = 0.0f;
}
else if (isOccupiedNode (m_path->number)) {
desiredDistance = cr::sqrf (96.0f);
desiredDistanceSq = cr::sqrf (96.0f);
}
else {
desiredDistance = cr::max (cr::sqrf (m_path->radius), desiredDistance);
desiredDistanceSq = cr::max (cr::sqrf (m_path->radius), desiredDistanceSq);
}
// check if node has a special travel flags, so they need to be reached more precisely
for (const auto &link : m_path->links) {
if (link.flags != 0) {
desiredDistance = 0.0f;
desiredDistanceSq = 0.0f;
break;
}
}
// needs precise placement - check if we get past the point
if (desiredDistance < cr::sqrf (22.0f) && nodeDistance < cr::sqrf (30.0f) && m_pathOrigin.distanceSq (pev->origin + pev->velocity * m_frameInterval) >= nodeDistance) {
desiredDistance = nodeDistance + 1.0f;
if (desiredDistanceSq < cr::sqrf (22.0f) && nodeDistanceSq < cr::sqrf (30.0f) && m_pathOrigin.distanceSq (pev->origin + pev->velocity * m_frameInterval) >= nodeDistanceSq) {
desiredDistanceSq = nodeDistanceSq + 1.0f;
}
// this allows us to prevent stupid bot behavior when he reaches almost end point of this route, but some one (other bot eg)
@ -1169,7 +1164,7 @@ bool Bot::updateNavigation () {
return false;
}
if (nodeDistance < desiredDistance) {
if (nodeDistanceSq < desiredDistanceSq) {
// did we reach a destination node?
if (getTask ()->data == m_currentNodeIndex) {
if (m_chosenGoalIndex != kInvalidNodeIndex) {
@ -1177,7 +1172,7 @@ bool Bot::updateNavigation () {
// add goal values
int goalValue = practice.getValue (m_team, m_chosenGoalIndex, m_currentNodeIndex);
int addedValue = static_cast <int> (m_healthValue * 0.5f + m_goalValue * 0.5f);
const int addedValue = static_cast <int> (m_healthValue * 0.5f + m_goalValue * 0.5f);
goalValue = cr::clamp (goalValue + addedValue, -maxGoalValue, maxGoalValue);
@ -1196,9 +1191,9 @@ bool Bot::updateNavigation () {
// bot within 'hearable' bomb tick noises?
if (!bombOrigin.empty ()) {
float distance = bombOrigin.distanceSq (graph[taskTarget].origin);
const float distanceSq = bombOrigin.distanceSq (graph[taskTarget].origin);
if (distance > cr::sqrf (512.0f)) {
if (distanceSq > cr::sqrf (512.0f)) {
if (rg.chance (50) && !graph.isVisited (taskTarget)) {
pushRadioMessage (Radio::SectorClear);
}
@ -1241,7 +1236,7 @@ bool Bot::updateLiftHandling () {
// trace line to door
game.testLine (pev->origin, m_pathOrigin, TraceIgnore::Everything, ent (), &tr);
if (tr.flFraction < 1.0f && tr.pHit && tr.pHit->v.classname.str ().startsWith ("func_door") && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
if (tr.flFraction < 1.0f && util.isDoorEntity (tr.pHit) && (m_liftState == LiftState::None || m_liftState == LiftState::WaitingFor || m_liftState == LiftState::LookingButtonOutside) && pev->groundentity != tr.pHit) {
if (m_liftState == LiftState::None) {
m_liftState = LiftState::LookingButtonOutside;
m_liftUsageTime = game.time () + 7.0f;
@ -1543,7 +1538,7 @@ int Bot::findAimingNode (const Vector &to, int &pathLength) {
// return the most distant node which is seen from the bot to the target and is within count
ensureCurrentNodeIndex ();
int destIndex = graph.getNearest (to);
const int destIndex = graph.getNearest (to);
int bestIndex = m_currentNodeIndex;
if (destIndex == kInvalidNodeIndex) {
@ -1618,27 +1613,27 @@ bool Bot::findNextBestNode () {
}
// if we're still here, find some close nodes
float distance = pev->origin.distanceSq (path.origin);
const float distanceSq = pev->origin.distanceSq (path.origin);
if (distance < lessDist[0]) {
if (distanceSq < lessDist[0]) {
lessDist[2] = lessDist[1];
lessIndex[2] = lessIndex[1];
lessDist[1] = lessDist[0];
lessIndex[1] = lessIndex[0];
lessDist[0] = distance;
lessDist[0] = distanceSq;
lessIndex[0] = path.number;
}
else if (distance < lessDist[1]) {
else if (distanceSq < lessDist[1]) {
lessDist[2] = lessDist[1];
lessIndex[2] = lessIndex[1];
lessDist[1] = distance;
lessDist[1] = distanceSq;
lessIndex[1] = path.number;
}
else if (distance < lessDist[2]) {
lessDist[2] = distance;
else if (distanceSq < lessDist[2]) {
lessDist[2] = distanceSq;
lessIndex[2] = path.number;
}
}
@ -1682,12 +1677,12 @@ float Bot::getEstimatedNodeReachTime () {
// calculate 'real' time that we need to get from one node to another
if (graph.exists (m_currentNodeIndex) && graph.exists (m_previousNodes[0])) {
float distance = graph[m_previousNodes[0]].origin.distanceSq (graph[m_currentNodeIndex].origin);
const float distanceSq = graph[m_previousNodes[0]].origin.distanceSq (graph[m_currentNodeIndex].origin);
// caclulate estimated time
estimatedTime = 5.0f * (distance / cr::sqrf (m_moveSpeed + 1.0f));
estimatedTime = 5.0f * (distanceSq / cr::sqrf (m_moveSpeed + 1.0f));
bool longTermReachability = (m_pathFlags & NodeFlag::Crouch) || (m_pathFlags & NodeFlag::Ladder) || (pev->button & IN_DUCK) || (m_oldButtons & IN_DUCK);
const bool longTermReachability = (m_pathFlags & NodeFlag::Crouch) || (m_pathFlags & NodeFlag::Ladder) || (pev->button & IN_DUCK) || (m_oldButtons & IN_DUCK);
// check for special nodes, that can slowdown our movement
if (longTermReachability) {
@ -1757,7 +1752,7 @@ int Bot::findNearestNode () {
constexpr float kMaxDistance = 1024.0f;
int index = kInvalidNodeIndex;
float minimumDistance = cr::sqrf (kMaxDistance);
float nearestDistanceSq = cr::sqrf (kMaxDistance);
const auto &origin = pev->origin + pev->velocity * m_frameInterval;
const auto &bucket = graph.getNodesInBucket (origin);
@ -1768,20 +1763,20 @@ int Bot::findNearestNode () {
if (!graph.exists (path.number)) {
continue;
}
const float distance = path.origin.distanceSq (pev->origin);
const float distanceSq = path.origin.distanceSq (pev->origin);
if (distance < minimumDistance) {
if (distanceSq < nearestDistanceSq) {
// if bot doing navigation, make sure node really visible and reacheable
if (isReachableNode (path.number)) {
index = path.number;
minimumDistance = distance;
nearestDistanceSq = distanceSq;
}
}
}
// try to search ANYTHING that can be reachaed
if (!graph.exists (index)) {
minimumDistance = cr::sqrf (kMaxDistance);
nearestDistanceSq = cr::sqrf (kMaxDistance);
const auto &nearestNodes = graph.getNarestInRadius (kMaxDistance, pev->origin);
for (const auto &i : nearestNodes) {
@ -1790,15 +1785,15 @@ int Bot::findNearestNode () {
if (!graph.exists (path.number)) {
continue;
}
const float distance = path.origin.distanceSq (pev->origin);
const float distanceSq = path.origin.distanceSq (pev->origin);
if (distance < minimumDistance) {
if (distanceSq < nearestDistanceSq) {
TraceResult tr;
game.testLine (getEyesPos (), path.origin, TraceIgnore::Monsters, ent (), &tr);
if (tr.flFraction >= 1.0f && !tr.fStartSolid) {
index = path.number;
minimumDistance = distance;
nearestDistanceSq = distanceSq;
}
}
}
@ -1820,14 +1815,14 @@ int Bot::findNearestNode () {
int Bot::findBombNode () {
// this function finds the best goal (bomb) node for CTs when searching for a planted bomb.
auto &goals = graph.m_goalPoints;
const auto &goals = graph.m_goalPoints;
const auto &bomb = graph.getBombOrigin ();
const auto &audible = isBombAudible ();
// take the nearest to bomb nodes instead of goal if close enough
if (pev->origin.distanceSq (bomb) < cr::sqrf (96.0f)) {
int node = graph.getNearest (bomb, 420.0f);
const int node = graph.getNearest (bomb, 420.0f);
m_bombSearchOverridden = true;
@ -1845,16 +1840,16 @@ int Bot::findBombNode () {
int goal = 0, count = 0;
float lastDistance = kInfiniteDistance;
float lastDistanceSq = kInfiniteDistance;
// find nearest goal node either to bomb (if "heard" or player)
for (auto &point : goals) {
float distance = bomb.distanceSq (graph[point].origin);
const float distanceSq = bomb.distanceSq (graph[point].origin);
// check if we got more close distance
if (distance < lastDistance) {
if (distanceSq < lastDistanceSq) {
goal = point;
lastDistance = distance;
lastDistanceSq = distanceSq;
}
}
@ -1876,14 +1871,14 @@ int Bot::findDefendNode (const Vector &origin) {
TraceResult tr {};
int nodeIndex[kMaxNodeLinks] {};
float minDistance[kMaxNodeLinks] {};
float nearestDistance[kMaxNodeLinks] {};
for (int i = 0; i < kMaxNodeLinks; ++i) {
nodeIndex[i] = kInvalidNodeIndex;
minDistance[i] = 128.0f;
nearestDistance[i] = 128.0f;
}
int posIndex = graph.getNearest (origin);
const int posIndex = graph.getNearest (origin);
int srcIndex = m_currentNodeIndex;
// max search distance
@ -1920,37 +1915,37 @@ int Bot::findDefendNode (const Vector &origin) {
continue;
}
if (distance > minDistance[0]) {
if (distance > nearestDistance[0]) {
nodeIndex[0] = path.number;
minDistance[0] = distance;
nearestDistance[0] = distance;
}
else if (distance > minDistance[1]) {
else if (distance > nearestDistance[1]) {
nodeIndex[1] = path.number;
minDistance[1] = distance;
nearestDistance[1] = distance;
}
else if (distance > minDistance[2]) {
else if (distance > nearestDistance[2]) {
nodeIndex[2] = path.number;
minDistance[2] = distance;
nearestDistance[2] = distance;
}
else if (distance > minDistance[3]) {
else if (distance > nearestDistance[3]) {
nodeIndex[3] = path.number;
minDistance[3] = distance;
nearestDistance[3] = distance;
}
else if (distance > minDistance[4]) {
else if (distance > nearestDistance[4]) {
nodeIndex[4] = path.number;
minDistance[4] = distance;
nearestDistance[4] = distance;
}
else if (distance > minDistance[5]) {
else if (distance > nearestDistance[5]) {
nodeIndex[5] = path.number;
minDistance[5] = distance;
nearestDistance[5] = distance;
}
else if (distance > minDistance[6]) {
else if (distance > nearestDistance[6]) {
nodeIndex[6] = path.number;
minDistance[6] = distance;
nearestDistance[6] = distance;
}
else if (distance > minDistance[7]) {
else if (distance > nearestDistance[7]) {
nodeIndex[7] = path.number;
minDistance[7] = distance;
nearestDistance[7] = distance;
}
}
@ -1960,8 +1955,8 @@ int Bot::findDefendNode (const Vector &origin) {
int practiceDamage = practice.getDamage (m_team, nodeIndex[i], nodeIndex[i]);
practiceDamage = (practiceDamage * 100) / practice.getHighestDamageForTeam (m_team);
minDistance[i] = static_cast <float> ((practiceDamage * 100) / 8192);
minDistance[i] += static_cast <float> (practiceDamage);
nearestDistance[i] = static_cast <float> ((practiceDamage * 100) / 8192);
nearestDistance[i] += static_cast <float> (practiceDamage);
}
}
bool sorting = false;
@ -1972,9 +1967,9 @@ int Bot::findDefendNode (const Vector &origin) {
// completely sort the data
for (int i = 0; i < kMaxNodeLinks - 1; ++i) {
if (nodeIndex[i] != kInvalidNodeIndex && nodeIndex[i + 1] != kInvalidNodeIndex && minDistance[i] > minDistance[i + 1]) {
if (nodeIndex[i] != kInvalidNodeIndex && nodeIndex[i + 1] != kInvalidNodeIndex && nearestDistance[i] > nearestDistance[i + 1]) {
cr::swap (nodeIndex[i], nodeIndex[i + 1]);
cr::swap (minDistance[i], minDistance[i + 1]);
cr::swap (nearestDistance[i], nearestDistance[i + 1]);
sorting = true;
}
@ -1985,7 +1980,7 @@ int Bot::findDefendNode (const Vector &origin) {
IntArray found;
for (const auto &path : graph) {
if (origin.distanceSq (path.origin) < cr::sqrf (static_cast <float> (kMaxDistance)) && vistab.visible (path.number, posIndex) && !isOccupiedNode (path.number)) {
if (origin.distanceSq (path.origin) < cr::sqrf (kMaxDistance) && vistab.visible (path.number, posIndex) && !isOccupiedNode (path.number)) {
found.push (path.number);
}
}
@ -2008,28 +2003,28 @@ int Bot::findDefendNode (const Vector &origin) {
int Bot::findCoverNode (float maxDistance) {
// this function tries to find a good cover node if bot wants to hide
const float enemyMax = m_lastEnemyOrigin.distance (pev->origin);
const float enemyMaxDistance = m_lastEnemyOrigin.distance (pev->origin);
// do not move to a position near to the enemy
if (maxDistance > enemyMax) {
maxDistance = enemyMax;
if (maxDistance > enemyMaxDistance) {
maxDistance = enemyMaxDistance;
}
if (maxDistance < 300.0f) {
maxDistance = 300.0f;
}
int srcIndex = m_currentNodeIndex;
int enemyIndex = graph.getNearest (m_lastEnemyOrigin);
const int srcIndex = m_currentNodeIndex;
const int enemyIndex = graph.getNearest (m_lastEnemyOrigin);
IntArray enemies;
int nodeIndex[kMaxNodeLinks] {};
float minDistance[kMaxNodeLinks] {};
float nearestDistance[kMaxNodeLinks] {};
for (int i = 0; i < kMaxNodeLinks; ++i) {
nodeIndex[i] = kInvalidNodeIndex;
minDistance[i] = maxDistance;
nearestDistance[i] = maxDistance;
}
if (enemyIndex == kInvalidNodeIndex) {
@ -2074,37 +2069,37 @@ int Bot::findCoverNode (float maxDistance) {
continue;
}
if (distance < minDistance[0]) {
if (distance < nearestDistance[0]) {
nodeIndex[0] = path.number;
minDistance[0] = distance;
nearestDistance[0] = distance;
}
else if (distance < minDistance[1]) {
else if (distance < nearestDistance[1]) {
nodeIndex[1] = path.number;
minDistance[1] = distance;
nearestDistance[1] = distance;
}
else if (distance < minDistance[2]) {
else if (distance < nearestDistance[2]) {
nodeIndex[2] = path.number;
minDistance[2] = distance;
nearestDistance[2] = distance;
}
else if (distance < minDistance[3]) {
else if (distance < nearestDistance[3]) {
nodeIndex[3] = path.number;
minDistance[3] = distance;
nearestDistance[3] = distance;
}
else if (distance < minDistance[4]) {
else if (distance < nearestDistance[4]) {
nodeIndex[4] = path.number;
minDistance[4] = distance;
nearestDistance[4] = distance;
}
else if (distance < minDistance[5]) {
else if (distance < nearestDistance[5]) {
nodeIndex[5] = path.number;
minDistance[5] = distance;
nearestDistance[5] = distance;
}
else if (distance < minDistance[6]) {
else if (distance < nearestDistance[6]) {
nodeIndex[6] = path.number;
minDistance[6] = distance;
nearestDistance[6] = distance;
}
else if (distance < minDistance[7]) {
else if (distance < nearestDistance[7]) {
nodeIndex[7] = path.number;
minDistance[7] = distance;
nearestDistance[7] = distance;
}
}
@ -2114,8 +2109,8 @@ int Bot::findCoverNode (float maxDistance) {
int practiceDamage = practice.getDamage (m_team, nodeIndex[i], nodeIndex[i]);
practiceDamage = (practiceDamage * 100) / practice.getHighestDamageForTeam (m_team);
minDistance[i] = static_cast <float> ((practiceDamage * 100) / 8192);
minDistance[i] += static_cast <float> (practiceDamage);
nearestDistance[i] = static_cast <float> ((practiceDamage * 100) / 8192);
nearestDistance[i] += static_cast <float> (practiceDamage);
}
}
bool sorting = false;
@ -2125,9 +2120,9 @@ int Bot::findCoverNode (float maxDistance) {
sorting = false;
for (int i = 0; i < kMaxNodeLinks - 1; ++i) {
if (nodeIndex[i] != kInvalidNodeIndex && nodeIndex[i + 1] != kInvalidNodeIndex && minDistance[i] > minDistance[i + 1]) {
if (nodeIndex[i] != kInvalidNodeIndex && nodeIndex[i + 1] != kInvalidNodeIndex && nearestDistance[i] > nearestDistance[i + 1]) {
cr::swap (nodeIndex[i], nodeIndex[i + 1]);
cr::swap (minDistance[i], minDistance[i + 1]);
cr::swap (nearestDistance[i], nearestDistance[i + 1]);
sorting = true;
}
@ -2161,9 +2156,9 @@ bool Bot::selectBestNextNode () {
assert (!m_pathWalk.empty ());
assert (m_pathWalk.hasNext ());
auto nextNodeIndex = m_pathWalk.next ();
auto currentNodeIndex = m_pathWalk.first ();
auto prevNodeIndex = m_currentNodeIndex;
const auto nextNodeIndex = m_pathWalk.next ();
const auto currentNodeIndex = m_pathWalk.first ();
const auto prevNodeIndex = m_currentNodeIndex;
if (!isOccupiedNode (currentNodeIndex)) {
return false;
@ -2314,7 +2309,7 @@ bool Bot::advanceMovement () {
// check if bot is going to jump
bool willJump = false;
float jumpDistance = 0.0f;
float jumpDistanceSq = 0.0f;
Vector src;
Vector dst;
@ -2331,7 +2326,7 @@ bool Bot::advanceMovement () {
src = path.origin;
dst = next.origin;
jumpDistance = src.distance (dst);
jumpDistanceSq = src.distanceSq (dst);
willJump = true;
break;
@ -2345,7 +2340,7 @@ bool Bot::advanceMovement () {
}
// is there a jump node right ahead and do we need to draw out the light weapon ?
if (willJump && !usesKnife () && m_currentWeapon != Weapon::Scout && !m_isReloading && !usesPistol () && (jumpDistance > 145.0f || (dst.z - 32.0f > src.z && jumpDistance > 125.0f)) && !(m_states & Sense::SeeingEnemy)) {
if (willJump && !usesKnife () && m_currentWeapon != Weapon::Scout && !m_isReloading && !usesPistol () && (jumpDistanceSq > cr::sqrf (145.0f) || (dst.z - 32.0f > src.z && jumpDistanceSq > cr::sqrf (125.0f))) && !(m_states & Sense::SeeingEnemy)) {
selectWeaponById (Weapon::Knife); // draw out the knife if we needed
}
@ -2384,14 +2379,14 @@ void Bot::setPathOrigin () {
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);
}
float closest = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
for (int i = 0; i < kMaxAlternatives; ++i) {
float distance = pev->origin.distanceSq (orgs[i]);
const float distanceSq = pev->origin.distanceSq (orgs[i]);
if (distance < closest) {
if (distanceSq < nearestDistanceSq) {
nearestIndex = i;
closest = distance;
nearestDistanceSq = distanceSq;
}
}
@ -2430,7 +2425,7 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
if (!game.mapIs (MapFlags::HasDoors)) {
return false;
}
return result->flFraction < 1.0f && result->pHit && !result->pHit->v.classname.str ().startsWith ("func_door");
return result->flFraction < 1.0f && !util.isDoorEntity (result->pHit);
};
// trace from the bot's eyes straight forward...
@ -2438,7 +2433,7 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
// check if the trace hit something...
if (tr->flFraction < 1.0f) {
if (game.mapIs (MapFlags::HasDoors) && tr->pHit && tr->pHit->v.classname.str ().startsWith ("func_door")) {
if (game.mapIs (MapFlags::HasDoors) && util.isDoorEntity (tr->pHit)) {
return false;
}
return true; // bot's head will hit something
@ -2793,7 +2788,7 @@ bool Bot::isBlockedLeft () {
game.testLine (pev->origin, forward * direction - right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && !tr.pHit->v.classname.str ().startsWith ("func_door")) {
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && !util.isDoorEntity (tr.pHit)) {
return true; // bot's body will hit something
}
return false;
@ -2813,7 +2808,7 @@ bool Bot::isBlockedRight () {
game.testLine (pev->origin, pev->origin + forward * direction + right * 48.0f, TraceIgnore::Monsters, ent (), &tr);
// check if the trace hit something...
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && tr.pHit && !tr.pHit->v.classname.str ().startsWith ("func_door")) {
if (game.mapIs (MapFlags::HasDoors) && tr.flFraction < 1.0f && !util.isDoorEntity (tr.pHit)) {
return true; // bot's body will hit something
}
return false;
@ -2859,13 +2854,13 @@ bool Bot::isDeadlyMove (const Vector &to) {
}
float lastHeight = tr.flFraction * 1000.0f; // height from ground
float distance = to.distanceSq (check); // distance from goal
float distanceSq = to.distanceSq (check); // distance from goal
if (distance <= cr::sqrf (30.0f) && lastHeight > 150.0f) {
if (distanceSq <= cr::sqrf (30.0f) && lastHeight > 150.0f) {
return true;
}
while (distance > cr::sqrf (30.0f)) {
while (distanceSq > cr::sqrf (30.0f)) {
check = check - direction * 30.0f; // move 10 units closer to the goal...
down = check;
@ -2884,7 +2879,7 @@ bool Bot::isDeadlyMove (const Vector &to) {
return true;
}
lastHeight = height;
distance = to.distanceSq (check); // distance from goal
distanceSq = to.distanceSq (check); // distance from goal
}
return false;
}
@ -2892,8 +2887,8 @@ bool Bot::isDeadlyMove (const Vector &to) {
void Bot::changePitch (float speed) {
// this function turns a bot towards its ideal_pitch
float idealPitch = cr::wrapAngle (pev->idealpitch);
float curent = cr::wrapAngle (pev->v_angle.x);
const float idealPitch = cr::wrapAngle (pev->idealpitch);
const float curent = cr::wrapAngle (pev->v_angle.x);
// turn from the current v_angle pitch to the idealpitch by selecting
// the quickest way to turn to face that direction
@ -2926,8 +2921,8 @@ void Bot::changePitch (float speed) {
void Bot::changeYaw (float speed) {
// this function turns a bot towards its ideal_yaw
float idealPitch = cr::wrapAngle (pev->ideal_yaw);
float curent = cr::wrapAngle (pev->v_angle.y);
const float idealPitch = cr::wrapAngle (pev->ideal_yaw);
const float curent = cr::wrapAngle (pev->v_angle.y);
// turn from the current v_angle yaw to the ideal_yaw by selecting
// the quickest way to turn to face that direction
@ -2973,14 +2968,14 @@ int Bot::getRandomCampDir () {
++count;
}
else {
float distance = pev->origin.distanceSq (path.origin);
const float distanceSq = pev->origin.distanceSq (path.origin);
uint16_t visBits = path.vis.crouch + path.vis.stand;
for (int j = 0; j < kMaxNodesToSearch; ++j) {
if (visBits >= visibility[j] && distance > distTab[j]) {
if (visBits >= visibility[j] && distanceSq > distTab[j]) {
indices[j] = path.number;
distTab[j] = distance;
distTab[j] = distanceSq;
visibility[j] = visBits;
break;
@ -2998,7 +2993,7 @@ int Bot::getRandomCampDir () {
void Bot::setStrafeSpeed (const Vector &moveDir, float strafeSpeed) {
const Vector &los = (moveDir - pev->origin).normalize2d_apx ();
float dot = los | pev->angles.forward ().get2d ();
const float dot = los | pev->angles.forward ().get2d ();
if (dot > 0.0f && !checkWallOnRight ()) {
m_strafeSpeed = strafeSpeed;
@ -3050,7 +3045,7 @@ bool Bot::isOccupiedNode (int index, bool needZeroVelocity) {
if (needZeroVelocity && client.ent->v.velocity.length2d () > 0.0f) {
continue;
}
auto length = client.origin.distanceSq (graph[index].origin);
const auto length = client.origin.distanceSq (graph[index].origin);
if (length < cr::clamp (cr::sqrf (graph[index].radius) * 2.0f, cr::sqrf (40.0f), cr::sqrf (90.0f))) {
return true;
@ -3072,7 +3067,7 @@ edict_t *Bot::lookupButton (const char *target) {
if (strings.isEmpty (target)) {
return nullptr;
}
float nearest = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
edict_t *result = nullptr;
// find the nearest button which can open our target
@ -3081,11 +3076,11 @@ edict_t *Bot::lookupButton (const char *target) {
// check if this place safe
if (!isDeadlyMove (pos)) {
float distance = pev->origin.distanceSq (pos);
const float distanceSq = pev->origin.distanceSq (pos);
// check if we got more close button
if (distance <= nearest) {
nearest = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
result = ent;
}
}
@ -3124,10 +3119,10 @@ bool Bot::isReachableNode (int index) {
if (pev->waterlevel == 2 || pev->waterlevel == 3) {
return true;
}
float ladderDist = dst.distance2d (src);
const float ladderDistSq = dst.distanceSq2d (src);
// check for ladder
bool nonLadder = !(graph[index].flags & NodeFlag::Ladder) || ladderDist > 16.0f;
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) {

View file

@ -197,10 +197,10 @@ bool AStarAlgo::cantSkipNode (const int a, const int b) {
if (tooNarrow) {
return true;
}
const float distance = ag.origin.distanceSq (bg.origin);
const float distanceSq = ag.origin.distanceSq (bg.origin);
const bool tooFar = distance > cr::sqrf (400.0f);
const bool tooClose = distance < cr::sqrtf (40.0f);
const bool tooFar = distanceSq > cr::sqrf (400.0f);
const bool tooClose = distanceSq < cr::sqrtf (40.0f);
if (tooFar || tooClose) {
return true;
@ -416,7 +416,7 @@ bool FloydWarshallAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNo
void DijkstraAlgo::init (const int length) {
m_length = length;
auto ulength = static_cast <size_t> (length);
const auto ulength = static_cast <size_t> (length);
m_distance.resize (ulength);
m_parent.resize (ulength);

View file

@ -109,7 +109,7 @@ void BotPractice::syncUpdate () {
if (i == j || !vistab.visible (i, j) || !exists (team, i, j)) {
continue;
}
auto actDamage = getDamage (team, i, j);
const auto actDamage = getDamage (team, i, j);
if (actDamage > maxDamage) {
maxDamage = actDamage;

View file

@ -32,7 +32,7 @@ void BotSounds::listenNoise (edict_t *ent, StringRef sample, float volume) {
if (origin.empty ()) {
return;
}
auto noise = m_noiseCache[sample.substr (0, 11)];
const auto noise = m_noiseCache[sample.substr (0, 11)];
// we're not handling theese
if (!(noise & Noise::NeedHandle)) {
@ -49,12 +49,12 @@ void BotSounds::listenNoise (edict_t *ent, StringRef sample, float volume) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive)) {
continue;
}
auto distance = client.origin.distanceSq (origin);
const auto distanceSq = client.origin.distanceSq (origin);
// now find nearest player
if (distance < nearest) {
if (distanceSq < nearest) {
result = &client;
nearest = distance;
nearest = distanceSq;
}
}
return result;

View file

@ -16,8 +16,8 @@ template <typename U> bool BotStorage::load (SmallArray <U> &data, ExtenHeader *
extern ConVar cv_debug, cv_graph_url;
// graphs can be downloaded...
auto isGraph = !!(type.option & StorageOption::Graph);
auto isDebug = cv_debug.bool_ ();
const auto isGraph = !!(type.option & StorageOption::Graph);
const auto isDebug = cv_debug.bool_ ();
MemFile file (filename); // open the file
data.clear ();
@ -127,8 +127,8 @@ template <typename U> bool BotStorage::load (SmallArray <U> &data, ExtenHeader *
if ((hdr.options & type.option) != type.option) {
return error (isGraph, isDebug, file, "Incorrect storage format for %s (filename: '%s').", type.name, filename);
}
auto compressedSize = static_cast <size_t> (hdr.compressed);
auto numberNodes = static_cast <size_t> (hdr.length);
const auto compressedSize = static_cast <size_t> (hdr.compressed);
const auto numberNodes = static_cast <size_t> (hdr.length);
SmallArray <uint8_t> compressed (compressedSize + sizeof (uint8_t) * ULZ::Excess);
@ -155,8 +155,8 @@ template <typename U> bool BotStorage::load (SmallArray <U> &data, ExtenHeader *
// author of graph.. save
if ((hdr.options & StorageOption::Exten) && exten != nullptr) {
auto extenSize = sizeof (ExtenHeader);
auto actuallyRead = file.read (exten, extenSize) * extenSize;
const auto extenSize = sizeof (ExtenHeader);
const auto actuallyRead = file.read (exten, extenSize) * extenSize;
if (isGraph) {
resetRetries ();
@ -198,7 +198,7 @@ template <typename U> bool BotStorage::save (const SmallArray <U> &data, ExtenHe
if (passOptions != 0) {
type.option |= passOptions;
}
auto isGraph = !!(type.option & StorageOption::Graph);
const auto isGraph = !!(type.option & StorageOption::Graph);
// do not allow to save graph with less than 8 nodes
if (isGraph && graph.length () < kMaxNodeLinks) {
@ -226,7 +226,7 @@ template <typename U> bool BotStorage::save (const SmallArray <U> &data, ExtenHe
logger.error ("Unable to open %s file for writing (filename: '%s').", type.name, filename);
return false;
}
auto rawLength = data.length () * sizeof (U);
const auto rawLength = data.length () * sizeof (U);
SmallArray <uint8_t> compressed (rawLength + sizeof (uint8_t) * ULZ::Excess);
// try to compress

View file

@ -9,6 +9,7 @@
ConVar cv_display_welcome_text ("yb_display_welcome_text", "1", "Enables or disables showing welcome message to host entity on game start.");
ConVar cv_enable_query_hook ("yb_enable_query_hook", "0", "Enables or disables fake server queries response, that shows bots as real players in server browser.");
ConVar cv_breakable_health_limit ("yb_breakable_health_limit", "500.0", "Specifies the maximum health of breakable object, that bot will consider to destroy.", true, 1.0f, 3000.0);
BotSupport::BotSupport () {
m_needToSendWelcome = false;
@ -226,11 +227,18 @@ bool BotSupport::isPlayerVIP (edict_t *ent) {
return *(engfuncs.pfnInfoKeyValue (engfuncs.pfnGetInfoKeyBuffer (ent), "model")) == 'v';
}
bool BotSupport::isDoorEntity (edict_t *ent) {
if (game.isNullEntity (ent)) {
return false;
}
return ent->v.classname.str ().startsWith ("func_door");;
}
bool BotSupport::isHostageEntity (edict_t *ent) {
if (game.isNullEntity (ent)) {
return false;
}
auto classHash = ent->v.classname.str ().hash ();
const auto classHash = ent->v.classname.str ().hash ();
constexpr auto kHostageEntity = StringRef::fnv1a32 ("hostage_entity");
constexpr auto kMonsterScientist = StringRef::fnv1a32 ("monster_scientist");
@ -238,6 +246,30 @@ bool BotSupport::isHostageEntity (edict_t *ent) {
return classHash == kHostageEntity || classHash == kMonsterScientist;
}
bool BotSupport::isShootableBreakable (edict_t *ent) {
if (game.isNullEntity (ent)) {
return false;
}
const auto limit = cv_breakable_health_limit.float_ ();
// not shootable
if (ent->v.health >= limit) {
return false;
}
constexpr auto kFuncBreakable = StringRef::fnv1a32 ("func_breakable");
constexpr auto kFuncPushable = StringRef::fnv1a32 ("func_pushable");
constexpr auto kFuncWall = StringRef::fnv1a32 ("func_wall");
if (ent->v.takedamage > 0.0f && ent->v.impulse <= 0 && !(ent->v.flags & FL_WORLDBRUSH) && !(ent->v.spawnflags & SF_BREAK_TRIGGER_ONLY)) {
auto classHash = ent->v.classname.str ().hash ();
if (classHash == kFuncBreakable || (classHash == kFuncPushable && (ent->v.spawnflags & SF_PUSH_BREAKABLE)) || classHash == kFuncWall) {
return ent->v.movetype == MOVETYPE_PUSH || ent->v.movetype == MOVETYPE_PUSHSTEP;
}
}
return false;
}
bool BotSupport::isFakeClient (edict_t *ent) {
if (bots[ent] != nullptr || (!game.isNullEntity (ent) && (ent->v.flags & FL_FAKECLIENT))) {
return true;
@ -254,7 +286,7 @@ void BotSupport::checkWelcome () {
m_welcomeReceiveTime = 0.0f;
bool needToSendMsg = (graph.length () > 0 ? m_needToSendWelcome : true);
const bool needToSendMsg = (graph.length () > 0 ? m_needToSendWelcome : true);
auto receiveEntity = game.getLocalEntity ();
if (isAlive (receiveEntity) && m_welcomeReceiveTime < 1.0f && needToSendMsg) {
@ -312,10 +344,12 @@ bool BotSupport::findNearestPlayer (void **pvHolder, edict_t *to, float searchDi
// team, live status, search distance etc. if needBot is true, then pvHolder, will
// be filled with bot pointer, else with edict pointer(!).
searchDistance = cr::sqrf (searchDistance);
edict_t *survive = nullptr; // pointer to temporally & survive entity
float nearestPlayer = 4096.0f; // nearest player
int toTeam = game.getTeam (to);
const int toTeam = game.getTeam (to);
for (const auto &client : m_clients) {
if (!(client.flags & ClientFlags::Used) || client.ent == to) {
@ -325,10 +359,10 @@ bool BotSupport::findNearestPlayer (void **pvHolder, edict_t *to, float searchDi
if ((sameTeam && client.team != toTeam) || (needAlive && !(client.flags & ClientFlags::Alive)) || (needBot && !bots[client.ent]) || (needDrawn && (client.ent->v.effects & EF_NODRAW)) || (needBotWithC4 && (client.ent->v.weapons & Weapon::C4))) {
continue; // filter players with parameters
}
float distance = client.ent->v.origin.distance (to->v.origin);
const float distanceSq = client.ent->v.origin.distanceSq (to->v.origin);
if (distance < nearestPlayer && distance < searchDistance) {
nearestPlayer = distance;
if (distanceSq < nearestPlayer && distanceSq < searchDistance) {
nearestPlayer = distanceSq;
survive = client.ent;
}
}
@ -437,10 +471,10 @@ void BotSupport::syncCalculatePings () {
if (!bot) {
continue;
}
int part = static_cast <int> (static_cast <float> (average.first) * 0.2f);
const int part = static_cast <int> (static_cast <float> (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);
int botLoss = rg.get (average.second / 2, average.second);
const int botLoss = rg.get (average.second / 2, average.second);
if (botPing <= 5) {
botPing = rg.get (10, 23);

View file

@ -16,7 +16,7 @@ ConVar cv_camping_time_max ("yb_camping_time_max", "45.0", "Upper bound of time
void Bot::normal_ () {
m_aimFlags |= AimFlags::Nav;
int debugGoal = cv_debug_goal.int_ ();
const int debugGoal = cv_debug_goal.int_ ();
// user forced a node as a goal?
if (debugGoal != kInvalidNodeIndex && getTask ()->data != debugGoal) {
@ -67,7 +67,7 @@ void Bot::normal_ () {
// reached node is a camp node
if ((m_pathFlags & NodeFlag::Camp) && !game.is (GameFlags::CSDM) && cv_camping_allowed.bool_ () && !isKnifeMode ()) {
const bool allowedCampWeapon = hasPrimaryWeapon () || (hasSecondaryWeapon () && !hasPrimaryWeapon () && m_numFriendsLeft > game.maxClients () / 6);
const bool allowedCampWeapon = hasPrimaryWeapon () || hasShield () || (hasSecondaryWeapon () && !hasPrimaryWeapon () && m_numFriendsLeft > game.maxClients () / 6);
// check if bot has got a primary weapon and hasn't camped before
if (allowedCampWeapon && m_timeCamping + 10.0f < game.time () && !m_hasHostage) {
@ -138,7 +138,7 @@ void Bot::normal_ () {
}
}
else if (m_team == Team::Terrorist && rg.chance (75)) {
int index = findDefendNode (m_path->origin);
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
@ -164,7 +164,7 @@ void Bot::normal_ () {
}
else if (m_team == Team::CT) {
if (!bots.isBombPlanted () && numFriendsNear (pev->origin, 210.0f) < 4) {
int index = findDefendNode (m_path->origin);
const int index = findDefendNode (m_path->origin);
float campTime = rg.get (25.0f, 40.f);
// rusher bots don't like to camp too much
@ -188,7 +188,7 @@ void Bot::normal_ () {
ignoreCollision ();
// did we already decide about a goal before?
auto currIndex = getTask ()->data;
const auto currIndex = getTask ()->data;
auto destIndex = graph.exists (currIndex) ? currIndex : findBestGoal ();
// check for existence (this is fail over, for i.e. CSDM, this should be not true with normal game play, only when spawned outside of covered area)
@ -219,7 +219,7 @@ void Bot::normal_ () {
m_moveSpeed = m_minSpeed;
}
}
float shiftSpeed = getShiftSpeed ();
const float shiftSpeed = getShiftSpeed ();
if (!m_isStuck && (!cr::fzero (m_moveSpeed) && m_moveSpeed > shiftSpeed) && (cv_walking_allowed.bool_ () && mp_footsteps.bool_ ()) && m_difficulty >= Difficulty::Normal && !(m_aimFlags & AimFlags::Enemy) && (m_heardSoundTime + 6.0f >= game.time () || (m_states & Sense::SuspectEnemy)) && numEnemiesNear (pev->origin, 768.0f) >= 1 && !isKnifeMode () && !bots.isBombPlanted ()) {
m_moveSpeed = shiftSpeed;
@ -310,7 +310,7 @@ void Bot::huntEnemy_ () {
// do we need to calculate a new path?
else if (!hasActiveGoal ()) {
int destIndex = kInvalidNodeIndex;
int goal = getTask ()->data;
const int goal = getTask ()->data;
// is there a remembered index?
if (graph.exists (goal)) {
@ -708,11 +708,10 @@ void Bot::moveToPos_ () {
m_prevGoalIndex = kInvalidNodeIndex;
m_position = nullptr;
}
// didn't choose goal node yet?
else if (!hasActiveGoal ()) {
int destIndex = kInvalidNodeIndex;
int goal = getTask ()->data;
const int goal = getTask ()->data;
if (graph.exists (goal)) {
destIndex = goal;
@ -776,8 +775,8 @@ void Bot::plantBomb_ () {
if (numFriendsNear (pev->origin, 1200.0f) != 0) {
pushRadioMessage (Radio::NeedBackup);
}
auto index = findDefendNode (pev->origin);
float guardTime = mp_c4timer.float_ () * 0.5f + mp_c4timer.float_ () * 0.25f;
const auto index = findDefendNode (pev->origin);
const auto guardTime = mp_c4timer.float_ () * 0.5f + mp_c4timer.float_ () * 0.25f;
// push camp task on to stack
startTask (Task::Camp, TaskPri::Camp, kInvalidNodeIndex, game.time () + guardTime, true);
@ -791,8 +790,9 @@ void Bot::plantBomb_ () {
}
void Bot::defuseBomb_ () {
float fullDefuseTime = m_hasDefuser ? 7.0f : 12.0f;
float timeToBlowUp = getBombTimeleft ();
const float fullDefuseTime = m_hasDefuser ? 7.0f : 12.0f;
const float timeToBlowUp = getBombTimeleft ();
float defuseRemainingTime = fullDefuseTime;
if (m_hasProgressBar /*&& isOnFloor ()*/) {
@ -834,7 +834,7 @@ void Bot::defuseBomb_ () {
defuseError = true;
}
else if (m_states & Sense::SeeingEnemy) {
int friends = numFriendsNear (pev->origin, 768.0f);
const int friends = numFriendsNear (pev->origin, 768.0f);
if (friends < 2 && defuseRemainingTime < timeToBlowUp) {
defuseError = true;
@ -872,9 +872,9 @@ void Bot::defuseBomb_ () {
m_strafeSpeed = 0.0f;
// bot is reloading and we close enough to start defusing
if (m_isReloading && bombPos.distance2d (pev->origin) < 80.0f) {
if (m_isReloading && bombPos.distanceSq2d (pev->origin) < cr::sqrf (80.0f)) {
if (m_numEnemiesLeft == 0 || timeToBlowUp < fullDefuseTime + 7.0f || ((getAmmoInClip () > 8 && m_reloadState == Reload::Primary) || (getAmmoInClip () > 5 && m_reloadState == Reload::Secondary))) {
int weaponIndex = bestWeaponCarried ();
const int weaponIndex = bestWeaponCarried ();
// just select knife and then select weapon
selectWeaponById (Weapon::Knife);
@ -911,11 +911,11 @@ void Bot::defuseBomb_ () {
botStandOrigin = pev->origin;
}
float duckLength = m_entity.distanceSq (botDuckOrigin);
float standLength = m_entity.distanceSq (botStandOrigin);
const float duckLengthSq = m_entity.distanceSq (botDuckOrigin);
const float standLengthSq = m_entity.distanceSq (botStandOrigin);
if (duckLength > 5625.0f || standLength > 5625.0f) {
if (standLength < duckLength) {
if (duckLengthSq > cr::sqrf (75.0f) || standLengthSq > cr::sqrf (75.0f)) {
if (standLengthSq < duckLengthSq) {
m_duckDefuse = false; // stand
}
else {
@ -1340,17 +1340,17 @@ void Bot::escapeFromBomb_ () {
else if (!hasActiveGoal ()) {
int bestIndex = kInvalidNodeIndex;
float safeRadius = rg.get (1513.0f, 2048.0f);
float closestDistance = kInfiniteDistance;
const float safeRadius = rg.get (1513.0f, 2048.0f);
float nearestDistanceSq = kInfiniteDistance;
for (const auto &path : graph) {
if (path.origin.distance (graph.getBombOrigin ()) < safeRadius || isOccupiedNode (path.number)) {
if (path.origin.distanceSq (graph.getBombOrigin ()) < cr::sqrf (safeRadius) || isOccupiedNode (path.number)) {
continue;
}
float distance = pev->origin.distance (path.origin);
const float distanceSq = pev->origin.distanceSq (path.origin);
if (closestDistance > distance) {
closestDistance = distance;
if (nearestDistanceSq > distanceSq) {
nearestDistanceSq = distanceSq;
bestIndex = path.number;
}
}
@ -1378,7 +1378,7 @@ void Bot::shootBreakable_ () {
m_aimFlags |= AimFlags::Override;
// breakable destroyed?
if (!game.isShootableBreakable (m_breakableEntity)) {
if (!util.isShootableBreakable (m_breakableEntity)) {
completeTask ();
return;
}
@ -1421,7 +1421,7 @@ void Bot::pickupItem_ () {
m_entity = dest;
// find the distance to the item
float itemDistance = dest.distance (pev->origin);
const float itemDistanceSq = dest.distanceSq (pev->origin);
switch (m_pickupType) {
case Pickup::DroppedC4:
@ -1434,7 +1434,7 @@ void Bot::pickupItem_ () {
m_aimFlags |= AimFlags::Nav;
// near to weapon?
if (itemDistance < 50.0f) {
if (itemDistanceSq < cr::sqrf (50.0f)) {
int index = 0;
auto &info = conf.getWeapons ();
@ -1467,9 +1467,9 @@ void Bot::pickupItem_ () {
else {
// primary weapon
int weaponIndex = bestWeaponCarried ();
bool niceWeapon = rateGroundWeapon (m_pickupItem);
auto tab = conf.getRawWeapons ();
const bool niceWeapon = rateGroundWeapon (m_pickupItem);
const auto tab = conf.getRawWeapons ();
if ((weaponIndex >= kPrimaryWeaponMinIndex || tab[weaponIndex].id == Weapon::Shield || hasShield ()) && niceWeapon) {
selectWeaponByIndex (weaponIndex);
@ -1498,7 +1498,7 @@ void Bot::pickupItem_ () {
}
// near to shield?
else if (itemDistance < 50.0f) {
else if (itemDistanceSq < cr::sqrf (50.0f)) {
// get current best weapon to check if it's a primary in need to be dropped
int weaponIndex = bestWeaponCarried ();
@ -1512,7 +1512,7 @@ void Bot::pickupItem_ () {
case Pickup::PlantedC4:
m_aimFlags |= AimFlags::Entity;
if (m_team == Team::CT && itemDistance < 80.0f) {
if (m_team == Team::CT && itemDistanceSq < cr::sqrf (80.0f)) {
pushChatterMessage (Chatter::DefusingBomb);
// notify team of defusing
@ -1540,8 +1540,8 @@ void Bot::pickupItem_ () {
break;
}
if (itemDistance < 50.0f) {
float angleToEntity = isInFOV (dest - getEyesPos ());
if (itemDistanceSq < cr::sqrf (50.0f)) {
const float angleToEntity = isInFOV (dest - getEyesPos ());
// bot faces hostage?
if (angleToEntity <= 10.0f) {
@ -1556,7 +1556,7 @@ void Bot::pickupItem_ () {
completeTask ();
float minDistance = kInfiniteDistance;
float nearestDistanceSq = kInfiniteDistance;
int nearestHostageNodeIndex = kInvalidNodeIndex;
// find the nearest 'unused' hostage within the area
@ -1588,13 +1588,13 @@ void Bot::pickupItem_ () {
return EntitySearchResult::Continue;
}
}
int hostageNodeIndex = graph.getNearest (ent->v.origin);
const int hostageNodeIndex = graph.getNearest (ent->v.origin);
if (graph.exists (hostageNodeIndex)) {
float distance = graph[hostageNodeIndex].origin.distanceSq (pev->origin);
const float distanceSq = graph[hostageNodeIndex].origin.distanceSq (pev->origin);
if (distance < minDistance) {
minDistance = distance;
if (distanceSq < nearestDistanceSq) {
nearestDistanceSq = distanceSq;
nearestHostageNodeIndex = hostageNodeIndex;
}
}
@ -1631,10 +1631,10 @@ void Bot::pickupItem_ () {
}
// find angles from bot origin to entity...
float angleToEntity = isInFOV (dest - getEyesPos ());
const float angleToEntity = isInFOV (dest - getEyesPos ());
// near to the button?
if (itemDistance < 90.0f) {
if (itemDistanceSq < cr::sqrf (90.0f)) {
m_moveSpeed = 0.0f;
m_strafeSpeed = 0.0f;
m_moveToGoal = false;

View file

@ -79,7 +79,7 @@ void Bot::updateAimDir () {
else if (flags & AimFlags::Grenade) {
m_lookAt = m_throw;
float throwDistance = m_throw.distance (pev->origin);
const float throwDistance = m_throw.distance (pev->origin);
float coordCorrection = 0.0f;
if (throwDistance > 100.0f && throwDistance < 800.0f) {
@ -200,7 +200,7 @@ void Bot::updateAimDir () {
const bool onLadder = (m_pathFlags & NodeFlag::Ladder);
if (m_canChooseAimDirection && m_seeEnemyTime + 4.0f < game.time () && m_currentNodeIndex != kInvalidNodeIndex && !onLadder) {
auto dangerIndex = practice.getIndex (m_team, m_currentNodeIndex, m_currentNodeIndex);
const auto dangerIndex = practice.getIndex (m_team, m_currentNodeIndex, m_currentNodeIndex);
if (graph.exists (dangerIndex) && vistab.visible (m_currentNodeIndex, dangerIndex) && !(graph[dangerIndex].flags & NodeFlag::Crouch)) {
if (pev->origin.distanceSq (graph[dangerIndex].origin) < cr::sqrf (512.0f)) {
@ -217,7 +217,7 @@ void Bot::updateAimDir () {
// try look at next node if on ladder
if (onLadder && m_pathWalk.hasNext ()) {
auto nextPath = graph[m_pathWalk.next ()];
const auto &nextPath = graph[m_pathWalk.next ()];
if ((nextPath.flags & NodeFlag::Ladder) && m_destOrigin.distanceSq (pev->origin) < cr::sqrf (120.0f) && nextPath.origin.z > m_pathOrigin.z + 45.0f) {
m_lookAt = nextPath.origin;
@ -247,11 +247,11 @@ void Bot::checkDarkness () {
return;
}
auto skyColor = illum.getSkyColor ();
auto flashOn = (pev->effects & EF_DIMLIGHT);
const auto skyColor = illum.getSkyColor ();
const auto flashOn = (pev->effects & EF_DIMLIGHT);
if (mp_flashlight.bool_ () && !m_hasNVG) {
auto task = getCurrentTaskId ();
const auto task = getCurrentTaskId ();
if (!flashOn && task != Task::Camp && task != Task::Attack && m_heardSoundTime + 3.0f < game.time () && m_flashLevel > 30 && ((skyColor > 50.0f && m_path->light < 10.0f) || (skyColor <= 50.0f && m_path->light < 40.0f))) {
pev->impulse = 100;

View file

@ -162,7 +162,7 @@ void GraphVistable::load () {
if (!m_length) {
return;
}
bool dataLoaded = bstor.load <VisStorage> (m_vistable);
const bool dataLoaded = bstor.load <VisStorage> (m_vistable);
// if loaded, do not recalculate visibility
if (dataLoaded) {