Merge branch 'master' into chatter-fixes-and-improvements

This commit is contained in:
Владислав Сухов 2024-05-17 18:33:56 +00:00
commit f049391637
26 changed files with 579 additions and 476 deletions

View file

@ -6,6 +6,8 @@
;
; Custom configuration file, allow to change some hardcoded stuff in bot code.
;
; NOTE: All changes to this file takes effect only on server restart.
;
;
; Custom name for C4 model, for servers that replacing C4 model with it's own.
@ -28,3 +30,23 @@ AMXParachuteCvar = sv_parachute
;
CustomCSDMSpawnPoint = view_spawn
;
; Primary cvar for detection if CSDM mod is activated in game.
;
CSDMDetectCvar = csdm_active
;
; Primary cvar to detect if bot is running on Zombie Mod.
;
ZMDetectCvar = zp_delay
;
; For Zombie Mod, the cvars that deals with time before any game mode starts.
;
ZMDelayCvar = zp_delay
;
; For Zombie Mod, determines the team on which infected players are on.
; Valid values: T, CT.
;
ZMInfectedTeam = T

View file

@ -10,11 +10,11 @@
[ORIGINAL]
\yMain Menu\w
1. Control Bots
1. Control bots
2. Features
3. Fill Server
4. End Round
3. Fill server
4. End round
0. Exit
@ -32,12 +32,12 @@
[ORIGINAL]
\yBots Features\w
1. Weapon Mode Menu
2. Waypoint Menu
3. Select Personality
1. Weapon mode menu
2. Graph editor
3. Select personality
4. Toggle Debug Mode
5. Command Menu
4. Toggle debug mode
5. Command menu
0. Exit
@ -56,13 +56,13 @@
[ORIGINAL]
\yBots Control Menu\w
1. Add a Bot, Quick
2. Add a Bot, Specified
1. Quick add bot
2. Add specific bot
3. Remove Random Bot
4. Remove All Bots
3. Remove random bot
4. Remove all bots
5. Remove Bot Menu
5. Bot removal menu
0. Exit
@ -85,10 +85,10 @@
1. Knives only
2. Pistols only
3. Shotguns only
4. Machine Guns only
4. Machine guns only
5. Rifles only
6. Sniper Weapons only
7. All Weapons
6. Sniper weapons only
7. All weapons
0. Exit
@ -148,7 +148,7 @@
0. Schließen
[ORIGINAL]
\ySelect a team\w
\ySelect a Team\w
1. Terrorist Force
2. Counter-Terrorist Force
@ -168,7 +168,7 @@
0. Schließen
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Phoenix Connexion
2. L337 Krew
@ -192,7 +192,7 @@
0. Schließen
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Seal Team 6 (DEVGRU)
2. German GSG-9
@ -216,16 +216,16 @@
0. Schließen
[ORIGINAL]
\yWaypoint Operations (Page 1)\w
\yGraph Editor (Page 1)\w
1. Show/Hide waypoints
2. Cache waypoint
1. Show/Hide nodes
2. Cache node
3. Create path
4. Delete path
5. Add waypoint
6. Delete waypoint
7. Set Autopath Distance
8. Set Radius
5. Add node
6. Delete node
7. Set autopath distance
8. Set radius
9. Next...
@ -248,15 +248,15 @@
0. Schließen
[ORIGINAL]
\yWaypoint Operations (Page 2)\w
\yGraph Editor (Page 2)\w
1. Waypoint stats
2. Autowaypoint on/off
1. Debug goal
2. Auto node placement on/off
3. Set flags
4. Save waypoints
4. Save graph
5. Save without checking
6. Load waypoints
7. Check waypoints
6. Load graph
7. Check graph
8. Noclip cheat on/off
9. Previous...
@ -280,17 +280,17 @@
0. Schließen
[ORIGINAL]
\yWaypoint Radius\w
\yNode Radius\w
1. SetRadius 0
2. SetRadius 8
3. SetRadius 16
4. SetRadius 32
5. SetRadius 48
6. SetRadius 64
7. SetRadius 80
8. SetRadius 96
9. SetRadius 128
1. 0 units
2. 8 units
3. 16 units
4. 32 units
5. 48 units
6. 64 units
7. 80 units
8. 96 units
9. 128 units
0. Exit
@ -310,16 +310,16 @@
0. Schließen
[ORIGINAL]
\yWaypoint Type\w
\yNode Type\w
1. Normal
\r2. Terrorist Important
3. Counter-Terrorist Important
\r2. Terrorist important
3. Counter-Terrorist important
\w4. Block with hostage / Ladder
\y5. Rescue Zone
\y5. Rescue zone
\w6. Camping
7. Camp End
\r8. Map Goal
7. Camp end
\r8. Map goal
\w9. Jump
0. Exit
@ -340,13 +340,13 @@
0. Schließen
[ORIGINAL]
\yToggle Waypoint Flags\w
\yToggle Node Flags\w
1. Block with Hostage
2. Terrorists Specific
3. CTs Specific
4. Use Elevator
5. Sniper Point (\yFor Camp Points Only!\w)
1. Block with hostage
2. Terrorists specific
3. CTs specific
4. Use elevator
5. Sniper point (\yfor camp points only!\w)
0. Exit
@ -364,11 +364,11 @@
[ORIGINAL]
\yBot Command Menu\w
1. Make Double Jump
2. Finish Double Jump
1. Make double jump
2. Finish double jump
3. Drop the C4 Bomb
4. Drop the Weapon
3. Drop the C4 bomb
4. Drop the weapon
0. Exit
@ -386,13 +386,13 @@
[ORIGINAL]
\yAutoPath Distance\w
1. Distance 0
2. Distance 100
3. Distance 130
4. Distance 160
5. Distance 190
6. Distance 220
7. Distance 250 (Default)
1. 0 units
2. 100 units
3. 130 units
4. 160 units
5. 190 units
6. 220 units
7. 250 units (Default)
0. Exit
@ -412,9 +412,9 @@
[ORIGINAL]
\yCreate Path (Choose Direction)\w
1. Outgoing Path
2. Incoming Path
3. Bidirectional (Both Ways)
1. Outgoing path
2. Incoming path
3. Bidirectional (both ways)
0. Exit
@ -548,13 +548,13 @@ Bot '%s' kicked.
Bot '%s' wurde hinausgeworfen.
[ORIGINAL]
Bots Remove Menu
Bot Removal Menu
[TRANSLATED]
Bot entfernen Menü
[ORIGINAL]
Not a Bot
Not a bot
[TRANSLATED]
Kein Bot

View file

@ -10,11 +10,11 @@
[ORIGINAL]
\yMain Menu\w
1. Control Bots
1. Control bots
2. Features
3. Fill Server
4. End Round
3. Fill server
4. End round
0. Exit
@ -32,12 +32,12 @@
[ORIGINAL]
\yBots Features\w
1. Weapon Mode Menu
2. Waypoint Menu
3. Select Personality
1. Weapon mode menu
2. Graph editor
3. Select personality
4. Toggle Debug Mode
5. Command Menu
4. Toggle debug mode
5. Command menu
0. Exit
@ -45,8 +45,8 @@
\yФункции бота\w
1. Меню выбора режима оружия
2. Меню вэйпоинтов
3. Выбрать личность бота
2. Редактор графов
3. Выбрать характер бота
4. Переключить режим отладки
5. Меню команд бота
@ -56,13 +56,13 @@
[ORIGINAL]
\yBots Control Menu\w
1. Add a Bot, Quick
2. Add a Bot, Specified
1. Quick add bot
2. Add specific bot
3. Remove Random Bot
4. Remove All Bots
3. Remove random bot
4. Remove all bots
5. Remove Bot Menu
5. Bot removal menu
0. Exit
@ -85,15 +85,15 @@
1. Knives only
2. Pistols only
3. Shotguns only
4. Machine Guns only
4. Machine guns only
5. Rifles only
6. Sniper Weapons only
7. All Weapons
6. Sniper weapons only
7. All weapons
0. Exit
[TRANSLATED]
\yВыбор режима оружия\w
\yРежим оружия ботов\w
1. Только ножи
2. Только пистолеты
@ -116,12 +116,12 @@
0. Exit
[TRANSLATED]
\yВыбор личности ботов\w
\yХарактер ботов\w
1. Случайная
2. Нормальная
3. Агрессивная
4. Осторожная
1. Случайный
2. Нормальный
3. Агрессивный
4. Осторожный
0. Выход
@ -148,7 +148,7 @@
0. Выход
[ORIGINAL]
\ySelect a team\w
\ySelect a Team\w
1. Terrorist Force
2. Counter-Terrorist Force
@ -163,12 +163,13 @@
1. Террористы
2. Контр-террористы
5. Случайно
5. Авто-выбор
0. Выход
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Phoenix Connexion
2. L337 Krew
3. Arctic Avengers
@ -191,7 +192,7 @@
0. Выход
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Seal Team 6 (DEVGRU)
2. German GSG-9
@ -215,7 +216,8 @@
0. Выход
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Phoenix Connexion
2. L337 Krew
3. Arctic Avengers
@ -240,7 +242,7 @@
0. Выход
[ORIGINAL]
\ySelect an appearance\w
\ySelect an Appearance\w
1. Seal Team 6 (DEVGRU)
2. German GSG-9
@ -266,47 +268,47 @@
0. Выход
[ORIGINAL]
\yWaypoint Operations (Page 1)\w
\yGraph Editor (Page 1)\w
1. Show/Hide waypoints
2. Cache waypoint
1. Show/Hide nodes
2. Cache node
3. Create path
4. Delete path
5. Add waypoint
6. Delete waypoint
7. Set Autopath Distance
8. Set Radius
5. Add node
6. Delete node
7. Set autopath distance
8. Set radius
9. Next...
0. Exit
[TRANSLATED]
\yОперации с вэйпоинтами (Стр. 1)\w
\yРедактор графов (Стр. 1)\w
1. Показать/Скрыть вэйпоинты
2. Запомнить вэйпоинт
1. Показать/Скрыть точки
2. Запомнить точку
3. Создать путь
4. Убрать путь
5. Добавить вэйпоинт
6. Удалить вэйпоинт
7. Установить дистанцию автопути
8. Установить радиус
5. Добавить точку
6. Удалить точку
7. Задать дистанцию автопути
8. Задать радиус
9. Далее...
0. Выход
[ORIGINAL]
\yWaypoint Operations (Page 2)\w
\yGraph Editor (Page 2)\w
1. Debug goal
2. Autowaypoint on/off
2. Auto node placement on/off
3. Set flags
4. Save waypoints
4. Save graph
5. Save without checking
6. Load waypoints
7. Check waypoints
6. Load graph
7. Check graph
8. Noclip cheat on/off
9. Previous...
@ -314,15 +316,15 @@
0. Exit
[TRANSLATED]
\yОперации с вэйпоинтами (Стр. 2)\w
\yРедактор графов (Стр. 2)\w
1. Отладка цели
2. Вкл./Выкл. автовэйпоинт
2. Вкл./Выкл. авторасстановку точек
3. Установить флаг
4. Сохранить вэйпоинты
4. Сохранить граф
5. Сохранить без проверки
6. Загрузить вэйпоинты
7. Проверить вэйпоинты
6. Загрузить граф
7. Проверить граф
8. Вкл./Выкл. режим полёта
9. Назад...
@ -330,52 +332,52 @@
0. Выход
[ORIGINAL]
\yWaypoint Radius\w
\yNode Radius\w
1. SetRadius 0
2. SetRadius 8
3. SetRadius 16
4. SetRadius 32
5. SetRadius 48
6. SetRadius 64
7. SetRadius 80
8. SetRadius 96
9. SetRadius 128
1. 0 units
2. 8 units
3. 16 units
4. 32 units
5. 48 units
6. 64 units
7. 80 units
8. 96 units
9. 128 units
0. Exit
[TRANSLATED]
\yУстановка радиуса\w
\yРадиус точки\w
1. Установить на 0
2. Установить на 8
3. Установить на 16
4. Установить на 32
5. Установить на 48
6. Установить на 64
7. Установить на 80
8. Установить на 96
9. Установить на 128
1. 0 юнитов
2. 8 юнитов
3. 16 юнитов
4. 32 юнита
5. 48 юнитов
6. 64 юнита
7. 80 юнитов
8. 96 юнитов
9. 128 юнитов
0. Выход
[ORIGINAL]
\yWaypoint Type\w
\yNode Type\w
1. Normal
\r2. Terrorist Important
3. Counter-Terrorist Important
\r2. Terrorist important
3. Counter-Terrorist important
\w4. Block with hostage / Ladder
\y5. Rescue Zone
\y5. Rescue zone
\w6. Camping
7. Camp End
\r8. Map Goal
7. Camp end
\r8. Map goal
\w9. Jump
0. Exit
[TRANSLATED]
\yТип вэйпоинта\w
\yТип точки\w
1. Обычный
\r2. Важный для Террористов
@ -390,7 +392,7 @@
\w0. Выход
[ORIGINAL]
\yDebug goal\w
\yDebug Goal\w
1. Debug nearest node
2. Debug facing node
@ -408,28 +410,28 @@
0. Выход
[ORIGINAL]
\yToggle Waypoint Flags\w
\yToggle Node Flags\w
1. Block with Hostage
2. Terrorists Specific
3. CTs Specific
4. Use Elevator
5. Sniper Point (\yFor Camp Points Only!\w)
6. Map Goal
7. Rescue Zone
8. Crouch Down
9. Camp Point
1. Block with hostage
2. Terrorists specific
3. CTs specific
4. Use elevator
5. Sniper point (\yfor camp points only!\w)
6. Map goal
7. Rescue zone
8. Crouch down
9. Camp point
0. Exit
[TRANSLATED]
\yИзменение флагов вэйпоинтов\w
\yИзменение флагов точки\w
1. Блокировать с заложником
2. Только для Террористов
3. Только для Контр-террористов
4. Использовать лифт
5. Снайперский (\yТолько для кемперских точек!\w)
5. Снайперский (\yтолько для кемперских точек!\w)
6. Цель карты
7. Зона спасения
8. Присесть
@ -438,10 +440,10 @@
0. Выход
[ORIGINAL]
\ySet Camp Point directions\w
\ySet Camp Point Directions\w
1. Camp Start
2. Camp End
1. Camp start
2. Camp end
0. Exit
@ -456,11 +458,11 @@
[ORIGINAL]
\yBot Command Menu\w
1. Make Double Jump
2. Finish Double Jump
1. Make double jump
2. Finish double jump
3. Drop the C4 Bomb
4. Drop the Weapon
3. Drop the C4 bomb
4. Drop the weapon
0. Exit
@ -478,45 +480,45 @@
[ORIGINAL]
\yAutoPath Distance\w
1. Distance 0
2. Distance 100
3. Distance 130
4. Distance 160
5. Distance 190
6. Distance 220
7. Distance 250 (Default)
1. 0 units
2. 100 units
3. 130 units
4. 160 units
5. 190 units
6. 220 units
7. 250 units (Default)
0. Exit
[TRANSLATED]
\yДистанция автопути\w
1. Дистанция 0
2. Дистанция 100
3. Дистанция 130
4. Дистанция 160
5. Дистанция 190
6. Дистанция 220
7. Дистанция 250 (По умолчанию)
1. 0 юнитов
2. 100 юнитов
3. 130 юнитов
4. 160 юнитов
5. 190 юнитов
6. 220 юнитов
7. 250 юнитов (по умолчанию)
0. Выход
[ORIGINAL]
\yCreate Path (Choose Direction)\w
1. Outgoing Path
2. Incoming Path
3. Bidirectional (Both Ways)
4. Jumping Path
1. Outgoing path
2. Incoming path
3. Bidirectional (both ways)
4. Jumping path
0. Exit
[TRANSLATED]
\yСоздание пути (выберите направление)\w
\yСоздать путь (выберите направление)\w
1. Исходящий путь
2. Входящий путь
3. Двунаправленный (Оба пути)
3. Двунаправленный (оба пути)
4. Прыговой путь
0. Выход
@ -696,13 +698,13 @@ Bot '%s' kicked.
Бот '%s' убран.
[ORIGINAL]
Bots Remove Menu
Bot Removal Menu
[TRANSLATED]
Меню убирания ботов
[ORIGINAL]
Not a Bot
Not a bot
[TRANSLATED]
Не бот
@ -2463,9 +2465,9 @@ Allowed values: 'none', 'normal', 'careful', 'rusher'.
If 'none' is specified personality chosen randomly.
[TRANSLATED]
Задаёт личность по умолчанию при создании ботов с управлением квотой.
Задаёт характер по умолчанию при создании ботов с управлением квотой.
Допустимые значения: 'none', 'normal', 'careful', 'rusher'.
Если указано 'none', личность выбирается случайным образом.
Если указано 'none', характер выбирается случайным образом.
[ORIGINAL]
Lower bound for base bot ping shown in scoreboard upon creation.
@ -2762,16 +2764,10 @@ options: %d
опции: %d
[ORIGINAL]
analyzed: yes
analyzed: %s
[TRANSLATED]
проанализировано: да
[ORIGINAL]
analyzed: no
[TRANSLATED]
проанализировано: нет
проанализировано: %s
[ORIGINAL]
extensions:
@ -2826,3 +2822,15 @@ You're launched standalone version of %s. Metamod is not installed or not enable
[TRANSLATED]
Вы запустили автономную версию %s. Metamod не установлен или не включён!
[ORIGINAL]
yes
[TRANSLATED]
да
[ORIGINAL]
no
[TRANSLATED]
нет

@ -1 +1 @@
Subproject commit c72215707a9be44eb2582b82a90a4a7f27a9f2e1
Subproject commit d35f784642aa87f8e86930442fcc4fc1087b8f15

View file

@ -47,7 +47,8 @@ CR_DECLARE_SCOPED_ENUM (GameFlags,
HasFakePings = cr::bit (10), // on that game version we can fake bots pings
HasBotVoice = cr::bit (11), // on that game version we can use chatter
AnniversaryHL25 = cr::bit (12), // half-life 25th anniversary engine
Xash3DLegacy = cr::bit (13) // old xash3d-branch
Xash3DLegacy = cr::bit (13), // old xash3d-branch
ZombieMod = cr::bit (14) // zombie mod is active
)
// defines map type

View file

@ -269,7 +269,7 @@ public:
public:
int32_t getMaxRouteLength () const {
return length () / 2;
return (length () / 2) + (kMaxNodes / 256);
}
StringRef getAuthor () const {

View file

@ -122,6 +122,7 @@ public:
void setLastWinner (int winner);
void checkBotModel (edict_t *ent, char *infobuffer);
void checkNeedsToBeKicked ();
void refreshCreatureStatus ();
bool isTeamStacked (int team);
bool kickRandom (bool decQuota = true, Team fromTeam = Team::Unassigned);

View file

@ -189,7 +189,8 @@ public:
}
void init (int32_t length) {
m_path = cr::makeUnique <int32_t[]> (length);
const auto allocSize = static_cast <uint32_t> (length);
m_path = cr::makeUnique <int32_t[]> (allocSize);
}
};
@ -305,6 +306,7 @@ private:
bool m_moveToC4 {}; // ct is moving to bomb
bool m_needToSendWelcomeChat {}; // bot needs to greet people on server?
bool m_isCreature {}; // bot is not a player, but something else ? zombie ?
bool m_isOnInfectedTeam {}; // bot is zombie (this assumes bot is a creature)
bool m_defuseNotified {}; // bot is notified about bomb defusion
bool m_jumpSequence {}; // next path link will be jump link
bool m_checkFall {}; // check bot fall
@ -464,7 +466,7 @@ private:
void updateLookAnglesNewbie (const Vector &direction, float delta);
void setIdealReactionTimers (bool actual = false);
void updateHearing ();
void postprocessGoals (const IntArray &goals, int result[]);
void postProcessGoals (const IntArray &goals, int result[]);
void updatePickups ();
void ensureEntitiesClear ();
void checkTerrain (float movedDistance, const Vector &dirNormal);
@ -499,7 +501,7 @@ private:
void selectWeaponByIndex (int index);
void syncUpdatePredictedIndex ();
void updatePredictedIndex ();
void refreshModelName (char *infobuffer);
void refreshCreatureStatus (char *infobuffer);
void updateRightRef ();
void completeTask ();

View file

@ -177,7 +177,7 @@ void GraphAnalyze::optimize () {
cleanup ();
auto smooth = [] (const Array <int> &nodes) {
Vector result;
Vector result {};
for (const auto &node : nodes) {
result += graph[node].origin;
@ -198,7 +198,7 @@ void GraphAnalyze::optimize () {
continue;
}
const auto &path = graph[i];
Array <int> indexes;
Array <int> indexes {};
for (const auto &link : path.links) {
if (graph.exists (link.index) && !m_optimizedNodes[link.index]
@ -303,7 +303,7 @@ void GraphAnalyze::displayOverlayMessage () {
void GraphAnalyze::flood (const Vector &pos, const Vector &next, float range) {
range *= 0.75f;
TraceResult tr;
TraceResult tr {};
game.testHull (pos, { next.x, next.y, next.z + 19.0f }, TraceIgnore::Monsters, head_hull, nullptr, &tr);
// we're can't reach next point

View file

@ -887,7 +887,7 @@ void Bot::instantChatter (int type) {
if (m_isAlive) {
showChatterIcon (true);
}
MessageWriter msg;
MessageWriter msg {};
const int ownIndex = index ();
auto writeChatterSound = [&msg] (ChatterItem item) {
@ -1161,18 +1161,18 @@ bool Bot::isWeaponRestrictedAMX (int wid) {
// check for weapon restrictions
if (cr::bit (wid) & (kPrimaryWeaponMask | kSecondaryWeaponMask | Weapon::Shield)) {
constexpr int ids[] = { 4, 25, 20, -1, 8, -1, 12, 19, -1, 5, 6, 13, 23, 17, 18, 1, 2, 21, 9, 24, 7, 16, 10, 22, -1, 3, 15, 14, 0, 11 };
constexpr int kIds[] = { 4, 25, 20, -1, 8, -1, 12, 19, -1, 5, 6, 13, 23, 17, 18, 1, 2, 21, 9, 24, 7, 16, 10, 22, -1, 3, 15, 14, 0, 11 };
// verify restrictions
return checkRestriction ("amx_restrweapons", ids);
return checkRestriction ("amx_restrweapons", kIds);
}
// check for equipment restrictions
else {
constexpr int ids[] = { -1, -1, -1, 3, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 0, 1, 5 };
constexpr int kIds[] = { -1, -1, -1, 3, -1, -1, -1, -1, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 2, -1, -1, -1, -1, -1, 0, 1, 5 };
// verify restrictions
return checkRestriction ("amx_restrequipammo", ids);
return checkRestriction ("amx_restrequipammo", kIds);
}
}
@ -1253,7 +1253,7 @@ void Bot::buyStuff () {
}
int count = 0;
Array <int32_t> choices;
Array <int32_t> choices {};
// select the priority tab for this personality
const int *pref = conf.getWeaponPrefs (m_personality) + kNumWeapons;
@ -1658,10 +1658,10 @@ void Bot::overrideConditions () {
// special handling, if we have a knife in our hands
if (isKnifeMode () && (util.isPlayer (m_enemy) || (cv_attack_monsters && util.isMonster (m_enemy)))) {
const float length = pev->origin.distance2d (m_enemy->v.origin);
const float distance2d = 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)) {
if (distance2d > 250.0f && (m_states & Sense::SeeingEnemy)) {
const int nearestToEnemyPoint = graph.getNearest (m_enemy->v.origin);
if (nearestToEnemyPoint != kInvalidNodeIndex
@ -1669,18 +1669,18 @@ void Bot::overrideConditions () {
&& cr::abs (graph[nearestToEnemyPoint].origin.z - m_enemy->v.origin.z) < 16.0f) {
if (tid != Task::MoveToPosition && !cr::fequal (getTask ()->desire, TaskPri::Hide)) {
startTask (Task::MoveToPosition, TaskPri::Hide, nearestToEnemyPoint, game.time () + length / (m_moveSpeed * 2.0f), true);
startTask (Task::MoveToPosition, TaskPri::Hide, nearestToEnemyPoint, game.time () + distance2d / (m_moveSpeed * 2.0f), true);
}
else {
if (tid == Task::MoveToPosition && getTask ()->data != nearestToEnemyPoint) {
clearTask (Task::MoveToPosition);
startTask (Task::MoveToPosition, TaskPri::Hide, nearestToEnemyPoint, game.time () + length / (m_moveSpeed * 2.0f), true);
startTask (Task::MoveToPosition, TaskPri::Hide, nearestToEnemyPoint, game.time () + distance2d / (m_moveSpeed * 2.0f), true);
}
}
}
}
else {
if (length <= 250.0f && (m_states & Sense::SeeingEnemy) && tid == Task::MoveToPosition) {
if (distance2d <= 250.0f && (m_states & Sense::SeeingEnemy) && tid == Task::MoveToPosition) {
clearTask (Task::MoveToPosition); // remove any move tasks
}
}
@ -2877,7 +2877,6 @@ void Bot::frame () {
if (m_thinkDelay.time <= game.time ()) {
update ();
// delay next execution for thinking
m_thinkDelay.time = game.time () + m_thinkDelay.interval;
@ -3013,7 +3012,7 @@ void Bot::logicDuringFreezetime () {
pev->button |= IN_JUMP;
m_jumpTime = game.time ();
}
static Array <Bot *> teammates;
static Array <Bot *> teammates {};
teammates.clear ();
for (const auto &bot : bots) {
@ -3282,7 +3281,7 @@ void Bot::logic () {
}
void Bot::spawned () {
if (game.is (GameFlags::CSDM)) {
if (game.is (GameFlags::CSDM | GameFlags::ZombieMod)) {
newRound ();
clearTasks ();
}
@ -3380,7 +3379,7 @@ void Bot::showDebugOverlay () {
if (!game.isNullEntity (m_pickupItem)) {
pickup = m_pickupItem->v.classname.str ();
}
String aimFlags;
String aimFlags {};
for (uint32_t i = 0u; i < 9u; ++i) {
auto bit = cr::bit (i);
@ -3718,7 +3717,7 @@ void Bot::debugMsgInternal (StringRef str) {
if (level <= 2) {
return;
}
String printBuf;
String printBuf {};
printBuf.assignf ("%s: %s", pev->netname.str (), str);
bool playMessage = false;
@ -3777,9 +3776,9 @@ Vector Bot::isBombAudible () {
}
bool Bot::canRunHeavyWeight () {
constexpr auto interval = 1.0f / 10.0f;
constexpr auto kInterval = 1.0f / 10.0f;
if (m_heavyTimestamp + interval < game.time ()) {
if (m_heavyTimestamp + kInterval < game.time ()) {
m_heavyTimestamp = game.time ();
return true;
@ -4070,7 +4069,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
return false;
}
bool defusingInProgress = false;
constexpr auto distanceToBomb = cr::sqrf (165.0f);
constexpr auto kDistanceToBomb = cr::sqrf (165.0f);
for (const auto &client : util.getClients ()) {
if (!(client.flags & ClientFlags::Used) || !(client.flags & ClientFlags::Alive)) {
@ -4086,7 +4085,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
}
// if close enough, mark as progressing
if (bombDistanceSq < distanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
if (bombDistanceSq < kDistanceToBomb && (bot->getCurrentTaskId () == Task::DefuseBomb || bot->m_hasProgressBar)) {
defusingInProgress = true;
break;
}
@ -4097,7 +4096,7 @@ bool Bot::isBombDefusing (const Vector &bombOrigin) {
if (client.team == m_team) {
// if close enough, mark as progressing
if (bombDistanceSq < distanceToBomb && ((client.ent->v.button | client.ent->v.oldbuttons) & IN_USE)) {
if (bombDistanceSq < kDistanceToBomb && ((client.ent->v.button | client.ent->v.oldbuttons) & IN_USE)) {
defusingInProgress = true;
break;
}
@ -4127,7 +4126,27 @@ float Bot::getShiftSpeed () {
return pev->maxspeed * 0.4f;
}
void Bot::refreshModelName (char *infobuffer) {
void Bot::refreshCreatureStatus (char *infobuffer) {
// if bot is on infected team, assume he is a creature
if (game.is (GameFlags::ZombieMod)) {
static StringRef zmInfectedTeam (conf.fetchCustom ("ZMInfectedTeam"));
// by default infected team is terrorists
Team infectedTeam = Team::Terrorist;
if (zmInfectedTeam == "CT") {
infectedTeam = Team::CT;
}
// if bot is on infected team, and zombie mode is active, assume bot is a creature/zombie
m_isOnInfectedTeam = game.getRealTeam (ent ()) == infectedTeam;
// do not process next if already infected
if (m_isOnInfectedTeam) {
return;
}
}
if (infobuffer == nullptr) {
infobuffer = engfuncs.pfnGetInfoKeyBuffer (ent ());
}
@ -4150,8 +4169,8 @@ void Bot::refreshModelName (char *infobuffer) {
bool Bot::isCreature () {
// current creature models are: zombie, chicken
constexpr auto modelMaskZombie = (('o' << 8) + 'z');
constexpr auto modelMaskChicken = (('h' << 8) + 'c');
constexpr auto kModelMaskZombie = (('o' << 8) + 'z');
constexpr auto kModelMaskChicken = (('h' << 8) + 'c');
return m_modelMask == modelMaskZombie || m_modelMask == modelMaskChicken;
return m_isOnInfectedTeam || m_modelMask == kModelMaskZombie || m_modelMask == kModelMaskChicken;
}

View file

@ -195,7 +195,7 @@ void Bot::prepareChatMessage (StringRef message) {
auto getRoundTime = [] () -> String {
auto roundTimeSecs = static_cast <int> (bots.getRoundEndTime () - game.time ());
String roundTime;
String roundTime {};
roundTime.assignf ("%02d:%02d", cr::clamp (roundTimeSecs / 60, 0, 59), cr::clamp (cr::abs (roundTimeSecs % 60), 0, 59));
return roundTime;
@ -208,7 +208,7 @@ void Bot::prepareChatMessage (StringRef message) {
// get the game name alias
auto getGameName = [] () -> String {
String gameName;
String gameName {};
if (game.is (GameFlags::ConditionZero)) {
if (rg.chance (30)) {
@ -308,7 +308,7 @@ bool Bot::isReplyingToChat () {
if (m_sayTextBuffer.entityIndex != -1 && !m_sayTextBuffer.sayText.empty ()) {
// check is time to chat is good
if (m_sayTextBuffer.timeNextChat < game.time () + rg (m_sayTextBuffer.chatDelay / 2, m_sayTextBuffer.chatDelay)) {
String replyText;
String replyText {};
if (rg.chance (m_sayTextBuffer.chatProbability + rg (40, 70)) && checkChatKeywords (replyText)) {
prepareChatMessage (replyText);

View file

@ -793,7 +793,7 @@ bool Bot::isPenetrableObstacle2 (const Vector &dest, int) {
int thikness = 0;
int numHits = 0;
Vector point;
Vector point {};
TraceResult tr {};
game.testLine (source, dest, TraceIgnore::Everything, ent (), &tr);
@ -998,7 +998,11 @@ void Bot::selectWeapons (float distance, int index, int id, int choosen) {
if (distance >= 750.0f && !isShieldDrawn ()) {
pev->button |= IN_ATTACK2; // draw the shield
}
else if (isShieldDrawn () || (!game.isNullEntity (m_enemy) && ((m_enemy->v.button & IN_RELOAD) || !seesEntity (m_enemy->v.origin)))) {
else if (isShieldDrawn ()
|| m_isReloading
|| !seesEntity (m_enemy->v.origin)
|| (!game.isNullEntity (m_enemy) && (m_enemy->v.button & IN_RELOAD))) {
pev->button |= IN_ATTACK2; // draw out the shield
}
m_shieldCheckTime = game.time () + 1.0f;
@ -1316,7 +1320,7 @@ void Bot::attackMovement () {
}
const bool isFullView = !!(m_enemyParts & (Visibility::Head | Visibility::Body));
if (m_lastFightStyleCheck + 3.0f < game.time ()) {
if (m_lastFightStyleCheck < game.time ()) {
if (usesSniper ()) {
m_fightStyle = Fight::Stay;
}
@ -1368,7 +1372,7 @@ void Bot::attackMovement () {
&& isInViewCone (m_enemyOrigin))) {
m_fightStyle = Fight::Strafe;
}
m_lastFightStyleCheck = game.time ();
m_lastFightStyleCheck = game.time () + 3.0f;
}
if (distance < 96.0f && !usesKnife ()) {
@ -1490,7 +1494,7 @@ void Bot::attackMovement () {
}
if (!isInWater () && !isOnLadder () && (m_moveSpeed > 0.0f || m_strafeSpeed > 0.0f)) {
Vector right, forward;
Vector right {}, forward {};
pev->v_angle.angleVectors (&forward, &right, nullptr);
const auto &front = forward * m_moveSpeed * 0.2f;
@ -1752,7 +1756,7 @@ int Bot::bestWeaponCarried () {
void Bot::decideFollowUser () {
// this function forces bot to follow user
static Array <edict_t *> users;
static Array <edict_t *> users {};
users.clear ();
// search friends near us
@ -2311,7 +2315,8 @@ bool Bot::isEnemyNoticeable (float range) {
constexpr float kCloseRange = 300.0f;
constexpr float kFarRange = 1000.0f;
float rangeModifier;
float rangeModifier {};
if (range < kCloseRange) {
rangeModifier = 0.0f;
}
@ -2327,7 +2332,7 @@ bool Bot::isEnemyNoticeable (float range) {
// moving players are easier to spot
float playerSpeedSq = m_enemy->v.velocity.lengthSq ();
float farChance, closeChance;
float farChance {}, closeChance {};
constexpr float kRunSpeed = cr::sqrf (200.0f);
constexpr float kWalkSpeed = cr::sqrf (30.0f);

View file

@ -46,8 +46,9 @@ void BotConfig::loadMainConfig (bool isFirstLoad) {
}
return false;
};
String line;
MemFile file;
String line {};
MemFile file {};
// this is does the same as exec of engine, but not overwriting values of cvars specified in cv_ignore_cvars_on_changelevel
if (openConfig (product.nameLower, "Bot main config file is not found.", &file, false)) {
@ -121,8 +122,8 @@ void BotConfig::loadMainConfig (bool isFirstLoad) {
void BotConfig::loadNamesConfig () {
setupMemoryFiles ();
String line;
MemFile file;
String line {};
MemFile file {};
constexpr auto kMaxNameLen = 32;
@ -179,8 +180,8 @@ void BotConfig::loadWeaponsConfig () {
to[i] = data[i].as <int> ();
}
};
String line;
MemFile file;
String line {};
MemFile file {};
// weapon data initialization
if (openConfig ("weapon", "Weapon configuration file not found. Loading defaults.", &file)) {
@ -231,8 +232,8 @@ void BotConfig::loadWeaponsConfig () {
void BotConfig::loadChatterConfig () {
setupMemoryFiles ();
String line;
MemFile file;
String line {};
MemFile file {};
// chatter initialization
if (game.is (GameFlags::HasBotVoice) && cv_radio_mode.as <int> () == 2 && openConfig ("chatter", "Couldn't open chatter system configuration", &file)) {
@ -379,8 +380,8 @@ void BotConfig::loadChatterConfig () {
void BotConfig::loadChatConfig () {
setupMemoryFiles ();
String line;
MemFile file;
String line {};
MemFile file {};
// chat config initialization
if (openConfig ("chat", "Chat file not found.", &file, true)) {
@ -481,16 +482,20 @@ void BotConfig::loadLanguageConfig () {
if (game.is (GameFlags::Legacy)) {
return; // legacy versions will use only english translation
}
String line;
MemFile file;
String line {};
MemFile file {};
// localizer initialization
if (openConfig ("lang", "Specified language not found.", &file, true)) {
String temp;
Twin <String, String> lang;
String temp {};
Twin <String, String> lang {};
auto trimWithoutWs = [] (String in) -> String {
return in.trim ("\r\n");
};
auto pushTranslatedMsg = [&] () {
m_language[hashLangString (lang.first.trim ().chars ())] = lang.second.trim ();
m_language[hashLangString (trimWithoutWs (lang.first).chars ())] = trimWithoutWs (lang.second);
};
// clear all the translations before new load
@ -519,7 +524,7 @@ void BotConfig::loadLanguageConfig () {
// make sure last string is translated
if (file.eof () && !lang.first.empty ()) {
lang.second = line.trim ();
lang.second = trimWithoutWs (line);
pushTranslatedMsg ();
}
}
@ -537,8 +542,8 @@ void BotConfig::loadAvatarsConfig () {
return;
}
String line;
MemFile file;
String line {};
MemFile file {};
// avatars initialization
if (openConfig ("avatars", "Avatars config file not found. Avatars will not be displayed.", &file)) {
@ -556,8 +561,8 @@ void BotConfig::loadAvatarsConfig () {
void BotConfig::loadDifficultyConfig () {
setupMemoryFiles ();
String line;
MemFile file;
String line {};
MemFile file {};
// initialize defaults
m_difficulty[Difficulty::Noob] = {
@ -661,14 +666,19 @@ void BotConfig::loadMapSpecificConfig () {
}
void BotConfig::loadCustomConfig () {
String line;
MemFile file;
String line {};
MemFile file {};
auto setDefaults = [&] () {
m_custom["C4ModelName"] = "c4.mdl";
m_custom["AMXParachuteCvar"] = "sv_parachute";
m_custom["CustomCSDMSpawnPoint"] = "view_spawn";
m_custom["CSDMDetectCvar"] = "csdm_active";
m_custom["ZMDetectCvar"] = "zp_delay";
m_custom["ZMDelayCvar"] = "zp_delay";
m_custom["ZMInfectedTeam"] = "T";
};
setDefaults ();
// has errors ?
@ -710,8 +720,8 @@ void BotConfig::loadCustomConfig () {
void BotConfig::loadLogosConfig () {
setupMemoryFiles ();
String line;
MemFile file;
String line {};
MemFile file {};
// logos initialization
if (openConfig ("logos", "Logos config file not found. Loading defaults.", &file)) {
@ -866,7 +876,8 @@ uint32_t BotConfig::hashLangString (StringRef str) {
auto test = [] (const char ch) {
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z');
};
String res;
String res {};
for (const auto &ch : str) {
if (!test (ch)) {

View file

@ -231,7 +231,7 @@ int BotControl::cmdCvars () {
const bool isSave = isSaveMain || isSaveMap;
File cfg;
File cfg {};
// if save requested, dump cvars to main config
if (isSave) {
@ -375,8 +375,8 @@ int BotControl::cmdNode () {
}
// should be moved to class?
static HashMap <String, BotCmd> commands;
static StringArray descriptions;
static HashMap <String, BotCmd> commands {};
static StringArray descriptions {};
// fill only once
if (descriptions.empty ()) {
@ -898,7 +898,7 @@ int BotControl::cmdNodeUpload () {
msg ("\n");
}
else {
String status;
String status {};
auto code = http.getLastStatusCode ();
if (code == HttpClientResult::Forbidden) {
@ -1871,7 +1871,8 @@ bool BotControl::executeCommands () {
}
return false;
};
String cmd;
String cmd {};
// give some help
if (hasArg (1) && arg <StringRef> (1) == "help") {
@ -2012,15 +2013,16 @@ void BotControl::showMenu (int id) {
.writeByte (last ? HLFalse : HLTrue)
.writeString (text.chars ());
};
constexpr size_t maxMenuSentLength = 140;
constexpr size_t kMaxMenuSentLength = 140;
for (const auto &display : m_menus) {
if (display.ident == id) {
String text = (game.is (GameFlags::Xash3D | GameFlags::Mobility) && !cv_display_menu_text) ? " " : display.text.chars ();
// split if needed
if (text.length () > maxMenuSentLength) {
auto chunks = text.split (maxMenuSentLength);
if (text.length () > kMaxMenuSentLength) {
auto chunks = text.split (kMaxMenuSentLength);
// send in chunks
for (size_t i = 0; i < chunks.length (); ++i) {
@ -2064,12 +2066,12 @@ void BotControl::kickBotByMenu (int page) {
return;
}
static StringRef headerTitle = conf.translate ("Bots Remove Menu");
static StringRef notABot = conf.translate ("Not a Bot");
static StringRef headerTitle = conf.translate ("Bot Removal Menu");
static StringRef notABot = conf.translate ("Not a bot");
static StringRef backKey = conf.translate ("Back");
static StringRef moreKey = conf.translate ("More");
String menus;
String menus {};
menus.assignf ("\\y%s (%d/4):\\w\n\n", headerTitle, page);
int menuKeys = (page == 4) ? cr::bit (9) : (cr::bit (8) | cr::bit (9));
@ -2270,10 +2272,10 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::Main, keys (4),
"\\yMain Menu\\w\n\n"
"1. Control Bots\n"
"1. Control bots\n"
"2. Features\n\n"
"3. Fill Server\n"
"4. End Round\n\n"
"3. Fill server\n"
"4. End round\n\n"
"0. Exit",
&BotControl::menuMain);
@ -2282,11 +2284,11 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::Features, keys (5),
"\\yBots Features\\w\n\n"
"1. Weapon Mode Menu\n"
"2. Waypoint Menu\n"
"3. Select Personality\n\n"
"4. Toggle Debug Mode\n"
"5. Command Menu\n\n"
"1. Weapon mode menu\n"
"2. Graph editor\n"
"3. Select personality\n\n"
"4. Toggle debug mode\n"
"5. Command menu\n\n"
"0. Exit",
&BotControl::menuFeatures);
@ -2294,11 +2296,11 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::Control, keys (5),
"\\yBots Control Menu\\w\n\n"
"1. Add a Bot, Quick\n"
"2. Add a Bot, Specified\n\n"
"3. Remove Random Bot\n"
"4. Remove All Bots\n\n"
"5. Remove Bot Menu\n\n"
"1. Quick add bot\n"
"2. Add specific bot\n\n"
"3. Remove random bot\n"
"4. Remove all bots\n\n"
"5. Bot removal menu\n\n"
"0. Exit",
&BotControl::menuControl);
@ -2309,10 +2311,10 @@ void BotControl::createMenus () {
"1. Knives only\n"
"2. Pistols only\n"
"3. Shotguns only\n"
"4. Machine Guns only\n"
"4. Machine guns only\n"
"5. Rifles only\n"
"6. Sniper Weapons only\n"
"7. All Weapons\n\n"
"6. Sniper weapons only\n"
"7. All weapons\n\n"
"0. Exit",
&BotControl::menuWeaponMode);
@ -2342,7 +2344,7 @@ void BotControl::createMenus () {
// team select menu
m_menus.emplace (
Menu::TeamSelect, keys (5),
"\\ySelect a team\\w\n\n"
"\\ySelect a Team\\w\n\n"
"1. Terrorist Force\n"
"2. Counter-Terrorist Force\n\n"
"5. Auto-select\n\n"
@ -2352,7 +2354,7 @@ void BotControl::createMenus () {
// terrorist model select menu
m_menus.emplace (
Menu::TerroristSelect, keys (5),
"\\ySelect an appearance\\w\n\n"
"\\ySelect an Appearance\\w\n\n"
"1. Phoenix Connexion\n"
"2. L337 Krew\n"
"3. Arctic Avengers\n"
@ -2364,7 +2366,7 @@ void BotControl::createMenus () {
// counter-terrorist model select menu
m_menus.emplace (
Menu::CTSelect, keys (5),
"\\ySelect an appearance\\w\n\n"
"\\ySelect an Appearance\\w\n\n"
"1. Seal Team 6 (DEVGRU)\n"
"2. German GSG-9\n"
"3. UK SAS\n"
@ -2376,7 +2378,7 @@ void BotControl::createMenus () {
// condition zero terrorist model select menu
m_menus.emplace (
Menu::TerroristSelectCZ, keys (6),
"\\ySelect an appearance\\w\n\n"
"\\ySelect an Appearance\\w\n\n"
"1. Phoenix Connexion\n"
"2. L337 Krew\n"
"3. Arctic Avengers\n"
@ -2389,7 +2391,7 @@ void BotControl::createMenus () {
// condition zero counter-terrorist model select menu
m_menus.emplace (
Menu::CTSelectCZ, keys (6),
"\\ySelect an appearance\\w\n\n"
"\\ySelect an Appearance\\w\n\n"
"1. Seal Team 6 (DEVGRU)\n"
"2. German GSG-9\n"
"3. UK SAS\n"
@ -2403,40 +2405,40 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::Commands, keys (4),
"\\yBot Command Menu\\w\n\n"
"1. Make Double Jump\n"
"2. Finish Double Jump\n\n"
"3. Drop the C4 Bomb\n"
"4. Drop the Weapon\n\n"
"1. Make double jump\n"
"2. Finish double jump\n\n"
"3. Drop the C4 bomb\n"
"4. Drop the weapon\n\n"
"0. Exit",
&BotControl::menuCommands);
// main waypoint menu
// main node menu
m_menus.emplace (
Menu::NodeMainPage1, keys (9),
"\\yWaypoint Operations (Page 1)\\w\n\n"
"1. Show/Hide waypoints\n"
"2. Cache waypoint\n"
"\\yGraph Editor (Page 1)\\w\n\n"
"1. Show/Hide nodes\n"
"2. Cache node\n"
"3. Create path\n"
"4. Delete path\n"
"5. Add waypoint\n"
"6. Delete waypoint\n"
"7. Set Autopath Distance\n"
"8. Set Radius\n\n"
"5. Add node\n"
"6. Delete node\n"
"7. Set autopath distance\n"
"8. Set radius\n\n"
"9. Next...\n\n"
"0. Exit",
&BotControl::menuGraphPage1);
// main waypoint menu (page 2)
// main node menu (page 2)
m_menus.emplace (
Menu::NodeMainPage2, keys (9),
"\\yWaypoint Operations (Page 2)\\w\n\n"
"\\yGraph Editor (Page 2)\\w\n\n"
"1. Debug goal\n"
"2. Autowaypoint on/off\n"
"2. Auto node placement on/off\n"
"3. Set flags\n"
"4. Save waypoints\n"
"4. Save graph\n"
"5. Save without checking\n"
"6. Load waypoints\n"
"7. Check waypoints\n"
"6. Load graph\n"
"7. Check graph\n"
"8. Noclip cheat on/off\n\n"
"9. Previous...\n\n"
"0. Exit",
@ -2445,31 +2447,31 @@ void BotControl::createMenus () {
// select nodes radius menu
m_menus.emplace (
Menu::NodeRadius, keys (9),
"\\yWaypoint Radius\\w\n\n"
"1. SetRadius 0\n"
"2. SetRadius 8\n"
"3. SetRadius 16\n"
"4. SetRadius 32\n"
"5. SetRadius 48\n"
"6. SetRadius 64\n"
"7. SetRadius 80\n"
"8. SetRadius 96\n"
"9. SetRadius 128\n\n"
"\\yNode Radius\\w\n\n"
"1. 0 units\n"
"2. 8 units\n"
"3. 16 units\n"
"4. 32 units\n"
"5. 48 units\n"
"6. 64 units\n"
"7. 80 units\n"
"8. 96 units\n"
"9. 128 units\n\n"
"0. Exit",
&BotControl::menuGraphRadius);
// nodes add menu
m_menus.emplace (
Menu::NodeType, keys (9),
"\\yWaypoint Type\\w\n\n"
"\\yNode Type\\w\n\n"
"1. Normal\n"
"\\r2. Terrorist Important\n"
"3. Counter-Terrorist Important\n"
"\\r2. Terrorist important\n"
"3. Counter-Terrorist important\n"
"\\w4. Block with hostage / Ladder\n"
"\\y5. Rescue Zone\n"
"\\y5. Rescue zone\n"
"\\w6. Camping\n"
"7. Camp End\n"
"\\r8. Map Goal\n"
"7. Camp end\n"
"\\r8. Map goal\n"
"\\w9. Jump\n\n"
"0. Exit",
&BotControl::menuGraphType);
@ -2477,35 +2479,35 @@ void BotControl::createMenus () {
// debug goal menu
m_menus.emplace (
Menu::NodeDebug, keys (3),
"\\yDebug goal\\w\n\n"
"\\yDebug Goal\\w\n\n"
"1. Debug nearest node\n"
"2. Debug facing node\n"
"3. Stop debugging\n\n"
"0. Exit",
&BotControl::menuGraphDebug);
// set waypoint flag menu
// set node flag menu
m_menus.emplace (
Menu::NodeFlag, keys (9),
"\\yToggle Waypoint Flags\\w\n\n"
"1. Block with Hostage\n"
"2. Terrorists Specific\n"
"3. CTs Specific\n"
"4. Use Elevator\n"
"5. Sniper Point (\\yFor Camp Points Only!\\w)\n"
"6. Map Goal\n"
"7. Rescue Zone\n"
"8. Crouch Down\n"
"9. Camp Point\n\n"
"\\yToggle Node Flags\\w\n\n"
"1. Block with hostage\n"
"2. Terrorists specific\n"
"3. CTs specific\n"
"4. Use elevator\n"
"5. Sniper point (\\yfor camp points only!\\w)\n"
"6. Map goal\n"
"7. Rescue zone\n"
"8. Crouch down\n"
"9. Camp point\n\n"
"0. Exit",
&BotControl::menuGraphFlag);
// set camp directions menu
m_menus.emplace (
Menu::CampDirections, keys (2),
"\\ySet Camp Point directions\\w\n\n"
"1. Camp Start\n"
"2. Camp End\n\n"
"\\ySet Camp Point Directions\\w\n\n"
"1. Camp start\n"
"2. Camp end\n\n"
"0. Exit",
&BotControl::menuCampDirections);
@ -2513,13 +2515,13 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::NodeAutoPath, keys (7),
"\\yAutoPath Distance\\w\n\n"
"1. Distance 0\n"
"2. Distance 100\n"
"3. Distance 130\n"
"4. Distance 160\n"
"5. Distance 190\n"
"6. Distance 220\n"
"7. Distance 250 (Default)\n\n"
"1. 0 units\n"
"2. 100 units\n"
"3. 130 units\n"
"4. 160 units\n"
"5. 190 units\n"
"6. 220 units\n"
"7. 250 units (default)\n\n"
"0. Exit",
&BotControl::menuAutoPathDistance);
@ -2527,10 +2529,10 @@ void BotControl::createMenus () {
m_menus.emplace (
Menu::NodePath, keys (4),
"\\yCreate Path (Choose Direction)\\w\n\n"
"1. Outgoing Path\n"
"2. Incoming Path\n"
"3. Bidirectional (Both Ways)\n"
"4. Jumping Path\n\n"
"1. Outgoing path\n"
"2. Incoming path\n"
"3. Bidirectional (both ways)\n"
"4. Jumping path\n\n"
"0. Exit",
&BotControl::menuGraphPath);

View file

@ -287,13 +287,13 @@ bool Game::isDedicated () {
const char *Game::getRunningModName () {
// this function returns mod name without path
static String name;
static String name {};
if (!name.empty ()) {
return name.chars ();
}
char engineModName[256];
char engineModName[256] {};
engfuncs.pfnGetGameDir (engineModName);
name = engineModName;
@ -428,11 +428,11 @@ void Game::sendClientMessage (bool console, edict_t *ent, StringRef message) {
};
// do not excess limit
constexpr size_t maxSendLength = 125;
constexpr size_t kMaxSendLength = 125;
// split up the string into chunks if needed (maybe check if it's multibyte?)
if (buffer.length () > maxSendLength) {
auto chunks = buffer.split (maxSendLength);
if (buffer.length () > kMaxSendLength) {
auto chunks = buffer.split (kMaxSendLength);
// send in chunks
for (size_t i = 0; i < chunks.length (); ++i) {
@ -447,11 +447,11 @@ void Game::sendServerMessage (StringRef message) {
// helper to sending the client message
// do not excess limit
constexpr size_t maxSendLength = 175;
constexpr size_t kMaxSendLength = 175;
// split up the string into chunks if needed (maybe check if it's multibyte?)
if (message.length () > maxSendLength) {
auto chunks = message.split (maxSendLength);
if (message.length () > kMaxSendLength) {
auto chunks = message.split (kMaxSendLength);
// send in chunks
for (size_t i = 0; i < chunks.length (); ++i) {
@ -463,7 +463,7 @@ void Game::sendServerMessage (StringRef message) {
}
void Game::sendHudMessage (edict_t *ent, const hudtextparms_t &htp, StringRef message) {
constexpr size_t maxSendLength = 512;
constexpr size_t kMaxSendLength = 512;
if (game.isNullEntity (ent)) {
return;
@ -490,7 +490,7 @@ void Game::sendHudMessage (edict_t *ent, const hudtextparms_t &htp, StringRef me
if (htp.effect == 2) {
msg.writeShort (MessageWriter::fu16 (htp.fxTime, 8.0f));
}
msg.writeString (message.substr (0, maxSendLength).chars ());
msg.writeString (message.substr (0, kMaxSendLength).chars ());
}
void Game::prepareBotArgs (edict_t *ent, String str) {
@ -709,7 +709,7 @@ void Game::registerCvars (bool gameVars) {
self.ptr = engfuncs.pfnCVarGetPointer (reg.name);
if (!self.ptr) {
static cvar_t reg_;
static cvar_t reg_ {};
// fix metamod' memlocs not found
if (is (GameFlags::Metamod)) {
@ -951,7 +951,11 @@ void Game::applyGameModes () {
return;
}
static ConVarRef csdm_active ("csdm_active");
static StringRef csdmActiveCvarName = conf.fetchCustom ("CSDMDetectCvar");
static StringRef zmActiveCvarName = conf.fetchCustom ("ZMDetectCvar");
static StringRef zmDelayCvarName = conf.fetchCustom ("ZMDelayCvar");
static ConVarRef csdm_active (csdmActiveCvarName);
static ConVarRef csdm_version ("csdm_version");
static ConVarRef redm_active ("redm_active");
static ConVarRef mp_freeforall ("mp_freeforall");
@ -976,12 +980,21 @@ void Game::applyGameModes () {
}
}
// some little support for zombie plague
static ConVarRef zp_delay ("zp_delay");
// does zombie mod is in use
static ConVarRef zm_active (zmActiveCvarName);
// update our ignore timer if zp_elay exists
if (zp_delay.exists () && zp_delay.value () > 0.0f) {
cv_ignore_enemies_after_spawn_time.set (zp_delay.value () + 3.0f);
// do a some little support for zombie plague
if (zm_active.exists ()) {
static ConVarRef zm_delay (zmDelayCvarName);
// update our ignore timer if zp_delay exists
if (zm_delay.exists () && zm_delay.value () > 0.0f) {
cv_ignore_enemies_after_spawn_time.set (zm_delay.value () + 3.5f);
}
m_gameFlags |= GameFlags::ZombieMod;
}
else {
m_gameFlags &= ~GameFlags::ZombieMod;
}
}
@ -1033,6 +1046,9 @@ void Game::slowFrame () {
// kick failed bots
bots.checkNeedsToBeKicked ();
// refresh bot infection (creature) status
bots.refreshCreatureStatus ();
// update next update time
m_oneSecondFrame = nextUpdate + time ();
}
@ -1071,8 +1087,8 @@ bool Game::hasEntityInGame (StringRef classname) {
}
void Game::printBotVersion () {
String gameVersionStr;
StringArray botRuntimeFlags;
String gameVersionStr {};
StringArray botRuntimeFlags {};
if (is (GameFlags::Legacy)) {
gameVersionStr.assign ("Legacy");
@ -1308,6 +1324,7 @@ float LightMeasure::getLightLevel (const Vector &point) {
}
return recursiveLightPoint <msurface_t, mnode_t> (m_worldModel->nodes, point, endPoint);
};
return !recursiveCheck () ? kInvalidLightLevel : 100 * cr::sqrtf (cr::min (75.0f, static_cast <float> (m_point.avg ())) / 75.0f);
}

View file

@ -76,8 +76,8 @@ int BotGraph::clearConnections (int index) {
};
auto &path = m_paths[index];
Connection sorted[kMaxNodeLinks];
Connection top;
Connection sorted[kMaxNodeLinks] {};
Connection top {};
for (int i = 0; i < kMaxNodeLinks; ++i) {
auto &cur = sorted[i];
@ -208,7 +208,6 @@ int BotGraph::clearConnections (int index) {
return false;
};
for (int i = 2; i < kMaxNodeLinks; ++i) {
while (inspect_p0 (i)) {}
}
@ -561,7 +560,7 @@ IntArray BotGraph::getNearestInRadius (float radius, const Vector &origin, int m
const float radiusSq = cr::sqrf (radius);
IntArray result;
IntArray result {};
const auto &bucket = getNodesInBucket (origin);
if (bucket.length () < kMaxNodeLinks || radius > cr::sqrf (256.0f)) {
@ -1274,7 +1273,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", isAnalyzed () ? "yes" : "no"); // display as string ?
msg (" analyzed: %s", isAnalyzed () ? conf.translate ("yes") : conf.translate ("no")); // display as string ?
msg ("");
@ -1367,7 +1366,7 @@ void BotGraph::syncCollectOnline () {
// decode answer
if (lc.open (localFile, "rt")) {
String lines;
String lines {};
if (lc.getLine (lines)) {
wanted = lines.split (",");
@ -1429,7 +1428,7 @@ void BotGraph::calculatePathRadius (int index) {
// calculate "wayzones" for the nearest node (meaning a dynamic distance area to vary node origin)
auto &path = m_paths[index];
Vector start, direction;
Vector start {}, direction {};
if ((path.flags & (NodeFlag::Ladder | NodeFlag::Goal | NodeFlag::Camp | NodeFlag::Rescue | NodeFlag::Crouch)) || m_jumpLearnNode) {
path.radius = 0.0f;
@ -1570,7 +1569,7 @@ void BotGraph::initNarrowPlaces () {
m_narrowChecked = true;
return;
}
TraceResult tr;
TraceResult tr {};
const auto distance = 178.0f;
const auto worldspawn = game.getStartEntity ();
@ -1608,7 +1607,7 @@ void BotGraph::initNarrowPlaces () {
}
const Vector &ang = ((path.origin - m_paths[link.index].origin).normalize () * distance).angles ();
Vector forward, right, upward;
Vector forward {}, right {}, upward {};
ang.angleVectors (&forward, &right, &upward);
// helper lambda
@ -1823,7 +1822,7 @@ bool BotGraph::canDownload () {
bool BotGraph::saveGraphData () {
auto options = StorageOption::Graph | StorageOption::Exten;
String editorName;
String editorName {};
if (game.isNullEntity (m_editor) && !m_graphAuthor.empty ()) {
editorName = m_graphAuthor;
@ -1876,7 +1875,7 @@ bool BotGraph::saveGraphData () {
void BotGraph::saveOldFormat () {
PODGraphHeader header {};
String editorName;
String editorName {};
if (game.isNullEntity (m_editor) && !m_graphAuthor.empty ()) {
editorName = m_graphAuthor;
@ -1896,7 +1895,7 @@ void BotGraph::saveOldFormat () {
header.fileVersion = StorageVersion::Podbot;
header.pointNumber = length ();
File fp;
File fp {};
// file was opened
if (fp.open (bstor.buildPath (BotFile::PodbotPWF), "wb")) {
@ -2327,7 +2326,7 @@ void BotGraph::frame () {
// very helpful stuff..
auto getNodeData = [this] (StringRef type, int node) -> String {
String message, flags;
String message {}, flags {};
const auto &p = m_paths[node];
bool jumpPoint = false;
@ -2384,7 +2383,7 @@ void BotGraph::frame () {
const int dangerIndexCT = practice.getIndex (Team::CT, nearestIndex, nearestIndex);
const int dangerIndexT = practice.getIndex (Team::Terrorist, nearestIndex, nearestIndex);
String practiceText;
String practiceText {};
practiceText.assignf (" Node practice data (index / damage):\n"
" CT: %d / %d\n"
" T: %d / %d\n\n", dangerIndexCT, dangerIndexCT != kInvalidNodeIndex ? practice.getDamage (Team::CT, nearestIndex, dangerIndexCT) : 0, dangerIndexT, dangerIndexT != kInvalidNodeIndex ? practice.getDamage (Team::Terrorist, nearestIndex, dangerIndexT) : 0);
@ -2514,10 +2513,10 @@ bool BotGraph::checkNodes (bool teleportPlayer) {
// ensure valid capacity
assert (length > 8 && length < static_cast <size_t> (kMaxNodes));
PathWalk walk;
PathWalk walk {};
walk.init (length);
Array <bool> visited;
Array <bool> visited {};
visited.resize (length);
// first check incoming connectivity, initialize the "visited" table
@ -2554,7 +2553,7 @@ bool BotGraph::checkNodes (bool teleportPlayer) {
}
// then check outgoing connectivity
Array <IntArray> outgoingPaths; // store incoming paths for speedup
Array <IntArray> outgoingPaths {}; // store incoming paths for speedup
outgoingPaths.resize (length);
for (const auto &path : m_paths) {
@ -2630,7 +2629,7 @@ void BotGraph::addBasic () {
ladderLeft.z = ladderRight.z;
TraceResult tr {};
Vector up, down, front, back;
Vector up {}, down {}, front {}, back {};
Vector diff = ((ladderLeft - ladderRight) ^ nullptr) * 15.0f;
front = back = game.getEntityOrigin (ent);
@ -2675,7 +2674,7 @@ void BotGraph::addBasic () {
game.searchEntities ("classname", classname, [&] (edict_t *ent) {
Vector pos = game.getEntityOrigin (ent);
TraceResult tr;
TraceResult tr {};
game.testLine (pos, pos - Vector (0.0f, 0.0f, 999.0f), TraceIgnore::Monsters, nullptr, &tr);
tr.vecEndPos.z += 36.0f;
@ -2815,10 +2814,10 @@ void BotGraph::eraseFromBucket (const Vector &pos, int index) {
}
int BotGraph::locateBucket (const Vector &pos) {
constexpr auto width = 8192;
constexpr auto kWidth = 8192;
auto hash = [&] (float axis, int32_t shift) {
return ((static_cast <int> (axis) + width) & 0x007f80) >> shift;
return ((static_cast <int> (axis) + kWidth) & 0x007f80) >> shift;
};
return hash (pos.x, 15) + hash (pos.y, 7);
}

View file

@ -13,12 +13,12 @@ int32_t ServerQueryHook::sendTo (int socket, const void *message, size_t length,
};
auto packet = reinterpret_cast <const uint8_t *> (message);
constexpr int32_t packetLength = 5;
constexpr int32_t kPacketLength = 5;
// player replies response
if (length > packetLength && memcmp (packet, "\xff\xff\xff\xff", packetLength - 1) == 0) {
if (length > kPacketLength && memcmp (packet, "\xff\xff\xff\xff", kPacketLength - 1) == 0) {
if (packet[4] == 'D') {
QueryBuffer buffer { packet, length, packetLength };
QueryBuffer buffer { packet, length, kPacketLength };
auto count = buffer.read <uint8_t> ();
for (uint8_t i = 0; i < count; ++i) {
@ -32,7 +32,7 @@ int32_t ServerQueryHook::sendTo (int socket, const void *message, size_t length,
return send (buffer.data ());
}
else if (packet[4] == 'I') {
QueryBuffer buffer { packet, length, packetLength };
QueryBuffer buffer { packet, length, kPacketLength };
buffer.skip <uint8_t> (); // protocol
// skip server name, folder, map game
@ -48,7 +48,7 @@ int32_t ServerQueryHook::sendTo (int socket, const void *message, size_t length,
return send (buffer.data ());
}
else if (packet[4] == 'm') {
QueryBuffer buffer { packet, length, packetLength };
QueryBuffer buffer { packet, length, kPacketLength };
buffer.shiftToEnd (); // shift to the end of buffer
buffer.write <uint8_t> (0); // zero out bot count

View file

@ -174,7 +174,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
// then sends result to bot constructor
edict_t *bot = nullptr;
String resultName;
String resultName {};
// do not allow create bots when there is no graph
if (!graph.length ()) {
@ -254,7 +254,7 @@ BotCreateResult BotManager::create (StringRef name, int difficulty, int personal
}
if (hasNamePrefix) {
String prefixed; // temp buffer for storing modified name
String prefixed {}; // temp buffer for storing modified name
prefixed.assignf ("%s %s", cv_name_prefix.as <StringRef> (), resultName);
// buffer has been modified, copy to real name
@ -624,13 +624,13 @@ void BotManager::serverFill (int selection, int personality, int difficulty, int
else {
selection = 5;
}
constexpr char teams[6][12] = { "", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
constexpr char kTeams[6][12] = { "", {"Terrorists"}, {"CTs"}, "", "", {"Random"}, };
const auto toAdd = numToAdd == -1 ? maxClients - (getHumansCount () + getBotCount ()) : numToAdd;
for (int i = 0; i <= toAdd; ++i) {
addbot ("", difficulty, personality, selection, -1, true);
}
ctrl.msg ("Fill server with %s bots...", &teams[selection][0]);
ctrl.msg ("Fill server with %s bots...", &kTeams[selection][0]);
}
void BotManager::kickEveryone (bool instant, bool zeroQuota) {
@ -814,7 +814,7 @@ void BotManager::setLastWinner (int winner) {
void BotManager::checkBotModel (edict_t *ent, char *infobuffer) {
for (const auto &bot : bots) {
if (bot->ent () == ent) {
bot->refreshModelName (infobuffer);
bot->refreshCreatureStatus (infobuffer);
break;
}
}
@ -829,12 +829,24 @@ void BotManager::checkNeedsToBeKicked () {
}
}
void BotManager::refreshCreatureStatus () {
if (!game.is (GameFlags::ZombieMod)) {
return;
}
for (const auto &bot : bots) {
if (bot->m_isAlive) {
bot->refreshCreatureStatus (nullptr);
}
}
}
void BotManager::setWeaponMode (int selection) {
// this function sets bots weapon mode
selection--;
constexpr int std[7][kNumWeapons] = {
constexpr int kStd[7][kNumWeapons] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Knife only
{-1, -1, -1, 2, 2, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Pistols only
{-1, -1, -1, -1, -1, -1, -1, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Shotgun only
@ -844,7 +856,7 @@ void BotManager::setWeaponMode (int selection) {
{-1, -1, -1, 2, 2, 0, 1, 2, 2, 2, 1, 2, 0, 2, 0, 0, 1, 0, 1, 1, 2, 2, 0, 1, 2, 1} // Standard
};
constexpr int as[7][kNumWeapons] = {
constexpr int kAs[7][kNumWeapons] = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Knife only
{-1, -1, -1, 2, 2, 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Pistols only
{-1, -1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}, // Shotgun only
@ -853,19 +865,19 @@ void BotManager::setWeaponMode (int selection) {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 1, -1, -1}, // Snipers only
{-1, -1, -1, 2, 2, 0, 1, 1, 1, 1, 1, 1, 0, 2, 0, -1, 1, 0, 1, 1, 0, 0, -1, 1, 1, 1} // Standard
};
constexpr char modes[7][12] = { {"Knife"}, {"Pistol"}, {"Shotgun"}, {"Machine Gun"}, {"Rifle"}, {"Sniper"}, {"Standard"} };
constexpr char kModes[7][12] = { {"Knife"}, {"Pistol"}, {"Shotgun"}, {"Machine Gun"}, {"Rifle"}, {"Sniper"}, {"Standard"} };
// get the raw weapons array
auto tab = conf.getRawWeapons ();
// set the correct weapon mode
for (int i = 0; i < kNumWeapons; ++i) {
tab[i].teamStandard = std[selection][i];
tab[i].teamAS = as[selection][i];
tab[i].teamStandard = kStd[selection][i];
tab[i].teamAS = kAs[selection][i];
}
cv_jasonmode.set (selection == 0 ? 1 : 0);
ctrl.msg ("%s weapon mode selected.", &modes[selection][0]);
ctrl.msg ("%s weapon mode selected.", &kModes[selection][0]);
}
void BotManager::listBots () {
@ -1370,7 +1382,7 @@ void BotManager::handleDeath (edict_t *killer, edict_t *victim) {
}
}
// mark bot as "spawned", and reset it to new-round state when it dead (for csdm only)
// mark bot as "spawned", and reset it to new-round state when it dead (for csdm/zombie only)
if (victimBot != nullptr) {
victimBot->spawned ();
}
@ -1519,7 +1531,7 @@ void Bot::newRound () {
for (auto &timer : m_chatterTimes) {
timer = kMaxChatterRepeatInterval;
}
refreshModelName (nullptr);
refreshCreatureStatus (nullptr);
m_isReloading = false;
m_reloadState = Reload::None;
@ -2195,7 +2207,7 @@ bool BotManager::isLineBlockedBySmoke (const Vector &from, const Vector &to, flo
float alongDist = toGrenade | sightDir;
// compute closest point to grenade along line of sight ray
Vector close;
Vector close {};
// constrain closest point to line segment
if (alongDist < 0.0f) {

View file

@ -255,19 +255,19 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
int goalChoices[4] = { kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex, kInvalidNodeIndex };
if (tactic == GoalTactic::Defensive && !(*defensive).empty ()) { // careful goal
postprocessGoals (*defensive, goalChoices);
postProcessGoals (*defensive, goalChoices);
}
else if (tactic == GoalTactic::Camp && !graph.m_campPoints.empty ()) { // camp node goal
// pickup sniper points if possible for sniping bots
if (!graph.m_sniperPoints.empty () && usesSniper ()) {
postprocessGoals (graph.m_sniperPoints, goalChoices);
postProcessGoals (graph.m_sniperPoints, goalChoices);
}
else {
postprocessGoals (graph.m_campPoints, goalChoices);
postProcessGoals (graph.m_campPoints, goalChoices);
}
}
else if (tactic == GoalTactic::Offensive && !(*offensive).empty ()) { // offensive goal
postprocessGoals (*offensive, goalChoices);
postProcessGoals (*offensive, goalChoices);
}
else if (tactic == GoalTactic::Goal && !graph.m_goalPoints.empty ()) // map goal node
{
@ -299,7 +299,7 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
}
}
else {
postprocessGoals (graph.m_goalPoints, goalChoices);
postProcessGoals (graph.m_goalPoints, goalChoices);
}
}
else if (tactic == GoalTactic::RescueHostage && !graph.m_rescuePoints.empty ()) {
@ -359,7 +359,7 @@ int Bot::findGoalPost (int tactic, IntArray *defensive, IntArray *offensive) {
return m_chosenGoalIndex = goalChoices[0]; // return and store goal
}
void Bot::postprocessGoals (const IntArray &goals, int result[]) {
void Bot::postProcessGoals (const IntArray &goals, int result[]) {
// this function filters the goals, so new goal is not bot's old goal, and array of goals doesn't contains duplicate goals
int recurseCount = 0;
@ -369,6 +369,10 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
return true;
}
if (!isOccupiedNode (index)) {
return true;
}
// check if historical goal
for (const auto &hg : m_goalHist) {
if (hg == index) {
@ -381,8 +385,9 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
return true;
}
}
return isOccupiedNode (index);
return false;
};
static IntArray resulting {};
resulting.clear ();
@ -400,8 +405,10 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) {
refill (graph.m_goalPoints);
}
else {
if (!goals.empty ()) {
resulting.insert (0, goals);
}
}
for (int index = 0; index < 4; ++index) {
const auto goal = resulting.random ();
@ -514,7 +521,7 @@ void Bot::doPlayerAvoidance (const Vector &normal) {
const float interval = m_frameInterval * (pev->velocity.lengthSq2d () > 0.0f ? 7.5f : 2.0f);
// use our movement angles, try to predict where we should be next frame
Vector right, forward;
Vector right {}, forward {};
m_moveAngles.angleVectors (&forward, &right, nullptr);
Vector predict = pev->origin + forward * pev->maxspeed * interval;
@ -865,8 +872,7 @@ void Bot::checkFall () {
else if (pev->origin.z + 128.0f < m_checkFallPoint[1].z && pev->origin.z + 128.0f < m_checkFallPoint[0].z) {
fixFall = true;
}
if (m_currentNodeIndex != kInvalidNodeIndex) {
else if (m_currentNodeIndex != kInvalidNodeIndex) {
if (pev->origin.distanceSq (m_checkFallPoint[1]) <= cr::sqrf (32.0f) && pev->origin.z + 16.0f < m_checkFallPoint[1].z) {
fixFall = true;
}
@ -1938,7 +1944,7 @@ int Bot::findNearestNode () {
const float distanceSq = path.origin.distanceSq (pev->origin);
if (distanceSq < nearestDistanceSq) {
TraceResult tr;
TraceResult tr {};
game.testLine (getEyesPos (), path.origin, TraceIgnore::Monsters, ent (), &tr);
if (tr.flFraction >= 1.0f && !tr.fStartSolid) {
@ -2125,7 +2131,7 @@ int Bot::findDefendNode (const Vector &origin) {
} while (sorting);
if (nodeIndex[0] == kInvalidNodeIndex) {
IntArray found;
IntArray found {};
for (const auto &path : graph) {
if (origin.distanceSq (path.origin) < cr::sqrf (kMaxDistance)
@ -2168,7 +2174,7 @@ int Bot::findCoverNode (float maxDistance) {
const int srcIndex = m_currentNodeIndex;
const int enemyIndex = graph.getNearest (m_lastEnemyOrigin);
IntArray enemies;
IntArray enemies {};
int nodeIndex[kMaxNodeLinks] {};
float nearestDistance[kMaxNodeLinks] {};
@ -2467,8 +2473,8 @@ bool Bot::advanceMovement () {
bool willJump = false;
float jumpDistanceSq = 0.0f;
Vector src;
Vector dst;
Vector src {};
Vector dst {};
// try to find out about future connection flags
if (m_pathWalk.hasNext ()) {
@ -2685,7 +2691,7 @@ bool Bot::isBlockedForward (const Vector &normal, TraceResult *tr) {
bool Bot::canStrafeLeft (TraceResult *tr) {
// this function checks if bot can move sideways
Vector right, forward;
Vector right {}, forward {};
pev->v_angle.angleVectors (&forward, &right, nullptr);
Vector src = pev->origin;
@ -2698,7 +2704,6 @@ bool Bot::canStrafeLeft (TraceResult *tr) {
if (tr->flFraction < 1.0f) {
return false; // bot's body will hit something
}
src = dest;
dest = dest + forward * 40.0f;
@ -2715,7 +2720,7 @@ bool Bot::canStrafeLeft (TraceResult *tr) {
bool Bot::canStrafeRight (TraceResult *tr) {
// this function checks if bot can move sideways
Vector right, forward;
Vector right {}, forward {};
pev->v_angle.angleVectors (&forward, &right, nullptr);
Vector src = pev->origin;
@ -2894,7 +2899,7 @@ bool Bot::canDuckUnder (const Vector &normal) {
// this function check if bot can duck under obstacle
TraceResult tr {};
Vector baseHeight;
Vector baseHeight {};
// use center of the body first...
if (isDucking ()) {
@ -2946,7 +2951,7 @@ bool Bot::isBlockedLeft () {
if (m_moveSpeed < 0.0f) {
direction = -48.0f;
}
Vector right, forward;
Vector right {}, forward {};
pev->angles.angleVectors (&forward, &right, nullptr);
// do a trace to the left...
@ -2966,7 +2971,7 @@ bool Bot::isBlockedRight () {
if (m_moveSpeed < 0.0f) {
direction = -48.0f;
}
Vector right, forward;
Vector right {}, forward {};
pev->angles.angleVectors (&forward, &right, nullptr);
// do a trace to the right...

View file

@ -473,7 +473,7 @@ bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, i
}
}
}
static SmallArray <int> pathInReverse;
static SmallArray <int> pathInReverse {};
pathInReverse.clear ();
for (int i = destIndex; i != kInvalidNodeIndex; i = m_parent[i]) {

View file

@ -153,7 +153,7 @@ void BotPractice::save () {
if (!graph.length () || graph.hasChanged ()) {
return; // no action
}
SmallArray <DangerSaveRestore> data;
SmallArray <DangerSaveRestore> data {};
data.reserve (m_data.length ());
// copy hash-map data to our vector
@ -167,7 +167,7 @@ void BotPractice::load () {
if (!graph.length ()) {
return; // no action
}
SmallArray <DangerSaveRestore> data;
SmallArray <DangerSaveRestore> data {};
m_data.clear ();
const bool dataLoaded = bstor.load <DangerSaveRestore> (data);

View file

@ -331,7 +331,7 @@ String BotStorage::buildPath (int32_t file, bool isMemoryLoad, bool withoutMapNa
{ BotFile::EbotEWP, FilePath (folders.ebot, "ewp")},
};
static StringArray path;
static StringArray path {};
path.clear ();
// if not memory file we're don't need game dir
@ -389,7 +389,7 @@ int32_t BotStorage::storageToBotFile (int32_t options) {
void BotStorage::unlinkFromDisk () {
// this function removes graph file from the hard disk
StringArray unlinkable;
StringArray unlinkable {};
bots.kickEveryone (true);
// if we're delete graph, delete all corresponding to it files
@ -413,7 +413,7 @@ void BotStorage::unlinkFromDisk () {
StringRef BotStorage::getRunningPath () {
// this function get's relative path against bot library (bot library should reside in bin dir)
static String path;
static String path {};
// we're do not do relative (against bot's library) paths on android
if (plat.android) {
@ -441,7 +441,7 @@ StringRef BotStorage::getRunningPath () {
}
StringRef BotStorage::getRunningPathVFS () {
static String path;
static String path {};
// we're do not do relative (against bot's library) paths on android
if (plat.android) {

View file

@ -149,7 +149,7 @@ void BotSupport::decalTrace (entvars_t *pev, TraceResult *trace, int logotypeInd
.writeByte (decalIndex);
}
else {
MessageWriter msg;
MessageWriter msg {};
msg.start (MSG_BROADCAST, SVC_TEMPENTITY)
.writeByte (message)
@ -282,7 +282,7 @@ void BotSupport::checkWelcome () {
auto graphModified = graph.getModifiedBy ();
// legacy welcome message, to respect the original code
constexpr StringRef legacyWelcomeMessage = "Welcome to POD-Bot V2.5 by Count Floyd\n"
constexpr StringRef kLegacyWelcomeMessage = "Welcome to POD-Bot V2.5 by Count Floyd\n"
"Visit http://www.nuclearbox.com/podbot/ or\n"
" http://www.botepidemic.com/podbot for Updates\n";
@ -328,7 +328,7 @@ void BotSupport::checkWelcome () {
// send the hud message
game.sendHudMessage (receiveEnt, textParams,
sendLegacyWelcome ? legacyWelcomeMessage.chars () : modernWelcomeMessage.chars ());
sendLegacyWelcome ? kLegacyWelcomeMessage.chars () : modernWelcomeMessage.chars ());
m_welcomeReceiveTime = 0.0f;
m_needToSendWelcome = false;
@ -440,7 +440,7 @@ void BotSupport::syncCalculatePings () {
if (!(client.flags & ClientFlags::Used) || isFakeClient (client.ent)) {
continue;
}
int ping, loss;
int ping {}, loss {};
engfuncs.pfnGetPlayerStats (client.ent, &ping, &loss);
// @note: for those who asking on a email, we CAN call pfnGetPlayerStats hl-engine function in a separate thread
@ -502,7 +502,7 @@ void BotSupport::syncCalculatePings () {
}
void BotSupport::emitPings (edict_t *to) {
static MessageWriter msg;
static MessageWriter msg {};
auto isThirdpartyBot = [] (edict_t *ent) {
return !bots[ent] && (ent->v.flags & FL_FAKECLIENT);
@ -530,7 +530,7 @@ void BotSupport::emitPings (edict_t *to) {
}
void BotSupport::resetPings (edict_t *to) {
static MessageWriter msg;
static MessageWriter msg {};
// no reset if game isn't support them
if (!game.is (GameFlags::HasFakePings)) {
@ -636,7 +636,7 @@ float BotSupport::getWaveLength (StringRef filename) {
uint32_t dataChunkLength;
} header {};
static WaveEndianessHelper weh;
static WaveEndianessHelper weh {};
if (fp.read (&header, sizeof (WavHeader)) == 0) {
logger.error ("Wave File %s - has wrong or unsupported format", filePath);

View file

@ -972,7 +972,7 @@ void Bot::defuseBomb_ () {
// if defusing is not already started, maybe crouch before
if (!m_hasProgressBar && m_duckDefuseCheckTime < game.time ()) {
Vector botDuckOrigin, botStandOrigin;
Vector botDuckOrigin {}, botStandOrigin {};
if (pev->button & IN_DUCK) {
botDuckOrigin = pev->origin;

View file

@ -285,8 +285,8 @@ void Bot::updateLookAnglesNewbie (const Vector &direction, float delta) {
const float noTargetRatio = 0.3f;
const float offsetDelay = 1.2f;
Vector stiffness;
Vector randomize;
Vector stiffness {};
Vector randomize {};
m_idealAngles = direction.get2d ();
m_idealAngles.clampAngles ();
@ -368,7 +368,7 @@ bool Frustum::isObjectInsidePlane (const Plane &plane, const Vector &center, flo
}
void Frustum::calculate (Planes &planes, const Vector &viewAngle, const Vector &viewOffset) {
Vector forward, right, up;
Vector forward {}, right {}, up {};
viewAngle.angleVectors (&forward, &right, &up);
auto fc = viewOffset + forward * kMaxViewDistance;
@ -541,7 +541,6 @@ void Bot::setAimDirection () {
const auto &destOrigin = m_destOrigin + pev->view_ofs;
m_lookAt = destOrigin;
if (m_moveToGoal && m_seeEnemyTime + 4.0f < game.time ()
&& !m_isStuck && !(pev->button & IN_DUCK)
&& m_currentNodeIndex != kInvalidNodeIndex

View file

@ -19,7 +19,7 @@ void GraphVistable::rebuild () {
return;
}
TraceResult tr {};
uint8_t res, shift;
uint8_t res {}, shift {};
if (!graph.exists (m_sliceIndex)) {
m_sliceIndex = 0;