diff --git a/cfg/addons/yapb/conf/custom.cfg b/cfg/addons/yapb/conf/custom.cfg index 6ad83ae..89fc9ef 100644 --- a/cfg/addons/yapb/conf/custom.cfg +++ b/cfg/addons/yapb/conf/custom.cfg @@ -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 diff --git a/cfg/addons/yapb/conf/lang/de_lang.cfg b/cfg/addons/yapb/conf/lang/de_lang.cfg index 11610b5..a5a1fa6 100644 --- a/cfg/addons/yapb/conf/lang/de_lang.cfg +++ b/cfg/addons/yapb/conf/lang/de_lang.cfg @@ -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 diff --git a/cfg/addons/yapb/conf/lang/ru_lang.cfg b/cfg/addons/yapb/conf/lang/ru_lang.cfg index a4da326..7b9e051 100644 --- a/cfg/addons/yapb/conf/lang/ru_lang.cfg +++ b/cfg/addons/yapb/conf/lang/ru_lang.cfg @@ -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. @@ -2729,49 +2731,43 @@ header: magic: %d [TRANSLATED] -магическое число: %d + магическое число: %d [ORIGINAL] version: %d [TRANSLATED] -версия: %d + версия: %d [ORIGINAL] node_count: %d [TRANSLATED] -количество точек: %d + количество точек: %d [ORIGINAL] compressed_size: %dkB [TRANSLATED] -размер с сжатием: %dКБ + размер с сжатием: %dКБ [ORIGINAL] uncompressed_size: %dkB [TRANSLATED] -размер без сжатия: %dКБ + размер без сжатия: %dКБ [ORIGINAL] options: %d [TRANSLATED] -опции: %d + опции: %d [ORIGINAL] -analyzed: yes +analyzed: %s [TRANSLATED] -проанализировано: да - -[ORIGINAL] -analyzed: no - -[TRANSLATED] -проанализировано: нет + проанализировано: %s [ORIGINAL] extensions: @@ -2783,19 +2779,19 @@ extensions: author: %s [TRANSLATED] -автор: %s + автор: %s [ORIGINAL] modified_by: %s [TRANSLATED] -модифицировано: %s + модифицировано: %s [ORIGINAL] bsp_size: %d [TRANSLATED] -размер bsp: %d + размер bsp: %d [ORIGINAL] Force-enable Xash3D sv_forcesimulating cvar. @@ -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] +нет diff --git a/ext/crlib b/ext/crlib index c722157..d35f784 160000 --- a/ext/crlib +++ b/ext/crlib @@ -1 +1 @@ -Subproject commit c72215707a9be44eb2582b82a90a4a7f27a9f2e1 +Subproject commit d35f784642aa87f8e86930442fcc4fc1087b8f15 diff --git a/inc/engine.h b/inc/engine.h index 878ef10..1398541 100644 --- a/inc/engine.h +++ b/inc/engine.h @@ -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 diff --git a/inc/graph.h b/inc/graph.h index 48576f6..182afa4 100644 --- a/inc/graph.h +++ b/inc/graph.h @@ -269,7 +269,7 @@ public: public: int32_t getMaxRouteLength () const { - return length () / 2; + return (length () / 2) + (kMaxNodes / 256); } StringRef getAuthor () const { diff --git a/inc/manager.h b/inc/manager.h index 2ff470f..abcde90 100644 --- a/inc/manager.h +++ b/inc/manager.h @@ -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); diff --git a/inc/yapb.h b/inc/yapb.h index 23c8b59..b2e2bdc 100644 --- a/inc/yapb.h +++ b/inc/yapb.h @@ -189,7 +189,8 @@ public: } void init (int32_t length) { - m_path = cr::makeUnique (length); + const auto allocSize = static_cast (length); + m_path = cr::makeUnique (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 (); diff --git a/src/analyze.cpp b/src/analyze.cpp index a5d310e..5e98ddc 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -177,7 +177,7 @@ void GraphAnalyze::optimize () { cleanup (); auto smooth = [] (const Array &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 indexes; + Array 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 diff --git a/src/botlib.cpp b/src/botlib.cpp index 1f24a96..00d97db 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -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 choices; + Array 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 teammates; + static Array 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; } diff --git a/src/chatlib.cpp b/src/chatlib.cpp index 9f9a056..353b898 100644 --- a/src/chatlib.cpp +++ b/src/chatlib.cpp @@ -195,7 +195,7 @@ void Bot::prepareChatMessage (StringRef message) { auto getRoundTime = [] () -> String { auto roundTimeSecs = static_cast (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; @@ -203,12 +203,12 @@ void Bot::prepareChatMessage (StringRef message) { // get bot's victim auto getMyVictim = [&] () -> String {; - return humanizedName (game.indexOfPlayer (m_lastVictim)); + return humanizedName (game.indexOfPlayer (m_lastVictim)); }; // 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); diff --git a/src/combat.cpp b/src/combat.cpp index 706b0d4..ce9526b 100644 --- a/src/combat.cpp +++ b/src/combat.cpp @@ -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 users; + static Array 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); diff --git a/src/config.cpp b/src/config.cpp index 5b7e986..e1075da 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -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 (); } }; - 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 () == 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 lang; + String temp {}; + Twin 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)) { diff --git a/src/control.cpp b/src/control.cpp index 08b6778..a32b8eb 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -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 commands; - static StringArray descriptions; + static HashMap 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 (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); diff --git a/src/engine.cpp b/src/engine.cpp index 2f72752..2718c6b 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -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 (m_worldModel->nodes, point, endPoint); }; + return !recursiveCheck () ? kInvalidLightLevel : 100 * cr::sqrtf (cr::min (75.0f, static_cast (m_point.avg ())) / 75.0f); } diff --git a/src/graph.cpp b/src/graph.cpp index eb17ad8..cee9ba1 100644 --- a/src/graph.cpp +++ b/src/graph.cpp @@ -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 (kMaxNodes)); - PathWalk walk; + PathWalk walk {}; walk.init (length); - Array visited; + Array 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 outgoingPaths; // store incoming paths for speedup + Array 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 (axis) + width) & 0x007f80) >> shift; + return ((static_cast (axis) + kWidth) & 0x007f80) >> shift; }; return hash (pos.x, 15) + hash (pos.y, 7); } diff --git a/src/hooks.cpp b/src/hooks.cpp index 04cebc8..81b78d1 100644 --- a/src/hooks.cpp +++ b/src/hooks.cpp @@ -13,12 +13,12 @@ int32_t ServerQueryHook::sendTo (int socket, const void *message, size_t length, }; auto packet = reinterpret_cast (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 (); 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 (); // 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 (0); // zero out bot count diff --git a/src/manager.cpp b/src/manager.cpp index af7a605..af6a43f 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -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 (), 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) { diff --git a/src/navigate.cpp b/src/navigate.cpp index a8bd8e8..eb272df 100644 --- a/src/navigate.cpp +++ b/src/navigate.cpp @@ -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,7 +405,9 @@ void Bot::postprocessGoals (const IntArray &goals, int result[]) { refill (graph.m_goalPoints); } else { - resulting.insert (0, goals); + if (!goals.empty ()) { + resulting.insert (0, goals); + } } for (int index = 0; index < 4; ++index) { @@ -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... diff --git a/src/planner.cpp b/src/planner.cpp index ac4e01e..465c44f 100644 --- a/src/planner.cpp +++ b/src/planner.cpp @@ -473,7 +473,7 @@ bool DijkstraAlgo::find (int srcIndex, int destIndex, NodeAdderFn onAddedNode, i } } } - static SmallArray pathInReverse; + static SmallArray pathInReverse {}; pathInReverse.clear (); for (int i = destIndex; i != kInvalidNodeIndex; i = m_parent[i]) { diff --git a/src/practice.cpp b/src/practice.cpp index e77a8a9..81b5d58 100644 --- a/src/practice.cpp +++ b/src/practice.cpp @@ -153,7 +153,7 @@ void BotPractice::save () { if (!graph.length () || graph.hasChanged ()) { return; // no action } - SmallArray data; + SmallArray 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 data; + SmallArray data {}; m_data.clear (); const bool dataLoaded = bstor.load (data); diff --git a/src/storage.cpp b/src/storage.cpp index b02f147..e46d72a 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -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) { diff --git a/src/support.cpp b/src/support.cpp index ffe3c84..2d92e20 100644 --- a/src/support.cpp +++ b/src/support.cpp @@ -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); diff --git a/src/tasks.cpp b/src/tasks.cpp index a6d19d2..30ce905 100644 --- a/src/tasks.cpp +++ b/src/tasks.cpp @@ -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; diff --git a/src/vision.cpp b/src/vision.cpp index 934b95a..b30d68b 100644 --- a/src/vision.cpp +++ b/src/vision.cpp @@ -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 ¢er, 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 diff --git a/src/vistable.cpp b/src/vistable.cpp index 1a54174..1d67ff6 100644 --- a/src/vistable.cpp +++ b/src/vistable.cpp @@ -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;