From 113cb5e9164fb7d9242343dfffd552b47098c771 Mon Sep 17 00:00:00 2001 From: jeefo Date: Sat, 20 Dec 2025 00:44:21 +0300 Subject: [PATCH] bot: stop shoot breakable task in case enemy exists manager: fix crash due miss-swap of max and min difficulty levels on bot adding (thx @stalin_alex) --- src/botlib.cpp | 6 +++ src/control.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++------ src/engine.cpp | 2 +- src/manager.cpp | 9 ++-- src/tasks.cpp | 3 +- 5 files changed, 123 insertions(+), 20 deletions(-) diff --git a/src/botlib.cpp b/src/botlib.cpp index c0ab995..13f2bda 100644 --- a/src/botlib.cpp +++ b/src/botlib.cpp @@ -154,6 +154,12 @@ void Bot::checkBreakable (edict_t *touch) { if (!game.hasBreakables ()) { return; } + const bool hasEnemy = !game.isNullEntity (m_enemy); + + // do n ot track for breakables if has some enemies + if (hasEnemy) { + return; + } if (game.isNullEntity (touch)) { auto breakable = lookupBreakable (); diff --git a/src/control.cpp b/src/control.cpp index 62761f0..d0ea28e 100644 --- a/src/control.cpp +++ b/src/control.cpp @@ -2193,21 +2193,114 @@ BotControl::BotControl () { m_menuServerFillTeam = 5; m_printQueueFlushTimestamp = 0.0f; - m_cmds.emplace ("add/addbot/add_ct/addbot_ct/add_t/addbot_t/addhs/addhs_t/addhs_ct", "add [difficulty] [personality] [team] [model] [name]", "Adding specific bot into the game.", &BotControl::cmdAddBot); - m_cmds.emplace ("kick/kickone/kick_ct/kick_t/kickbot_ct/kickbot_t", "kick [team]", "Kicks off the random bot from the game.", &BotControl::cmdKickBot); - m_cmds.emplace ("removebots/kickbots/kickall/kickall_ct/kickall_t", "removebots [instant] [team]", "Kicks all the bots from the game.", &BotControl::cmdKickBots); - m_cmds.emplace ("kill/killbots/killall/kill_ct/kill_t", "kill [team] [silent]", "Kills the specified team / all the bots.", &BotControl::cmdKillBots); - m_cmds.emplace ("fill/fillserver", "fill [team] [count] [difficulty] [personality]", "Fill the server (add bots) with specified parameters.", &BotControl::cmdFill); - m_cmds.emplace ("vote/votemap", "vote [map_id]", "Forces all the bot to vote to specified map.", &BotControl::cmdVote); - m_cmds.emplace ("weapons/weaponmode", "weapons [knife|pistol|shotgun|smg|rifle|sniper|standard]", "Sets the bots weapon mode to use.", &BotControl::cmdWeaponMode); - m_cmds.emplace ("menu/botmenu", "menu [cmd]", "Opens the main bot menu, or command menu if specified.", &BotControl::cmdMenu); - m_cmds.emplace ("version/ver/about", "version [no arguments]", "Displays version information about bot build.", &BotControl::cmdVersion); - m_cmds.emplace ("graphmenu/wpmenu/wptmenu", "graphmenu [noarguments]", "Opens and displays bots graph editor.", &BotControl::cmdNodeMenu); - m_cmds.emplace ("list/listbots", "list [noarguments]", "Lists the bots currently playing on server.", &BotControl::cmdList); - m_cmds.emplace ("graph/g/w/wp/wpt/waypoint", "graph [help]", "Handles graph operations.", &BotControl::cmdNode); - m_cmds.emplace ("cvars", "cvars [save|save_map|cvar|defaults]", "Display all the cvars with their descriptions.", &BotControl::cmdCvars); - m_cmds.emplace ("show_custom", "show_custom [noarguments]", "Shows the current values from custom.cfg.", &BotControl::cmdShowCustom, false); - m_cmds.emplace ("exec", "exec [user_id] [command]", "Executes a client command on bot entity.", &BotControl::cmdExec); + m_cmds = { + { + "add/addbot/add_ct/addbot_ct/add_t/addbot_t/addhs/addhs_t/addhs_ct", + "add [difficulty] [personality] [team] [model] [name]", + "Adding specific bot into the game.", + + &BotControl::cmdAddBot + }, + { + "kick/kickone/kick_ct/kick_t/kickbot_ct/kickbot_t", + "kick [team]", + "Kicks off the random bot from the game.", + + &BotControl::cmdKickBot + }, + { + "removebots/kickbots/kickall/kickall_ct/kickall_t", + "removebots [instant] [team]", + "Kicks all the bots from the game.", + + &BotControl::cmdKickBots + }, + { + "kill/killbots/killall/kill_ct/kill_t", + "kill [team] [silent]", + "Kills the specified team / all the bots.", + + &BotControl::cmdKillBots + }, + { + "fill/fillserver", + "fill [team] [count] [difficulty] [personality]", + "Fill the server (add bots) with specified parameters.", + + &BotControl::cmdFill + }, + { + "vote/votemap", + "vote [map_id]", + "Forces all the bots to vote for the specified map.", + + &BotControl::cmdVote + }, + { + "weapons/weaponmode", + "weapons [knife|pistol|shotgun|smg|rifle|sniper|standard]", + "Sets the bots' weapon mode to use.", + + &BotControl::cmdWeaponMode + }, + { + "menu/botmenu", + "menu [cmd]", + "Opens the main bot menu, or command menu if specified.", + + &BotControl::cmdMenu + }, + { + "version/ver/about", + "version [no arguments]", + "Displays version information about bot build.", + + &BotControl::cmdVersion + }, + { + "graphmenu/wpmenu/wptmenu", + "graphmenu [noarguments]", + "Opens and displays bots graph editor.", + + &BotControl::cmdNodeMenu + }, + { + "list/listbots", + "list [noarguments]", + "Lists the bots currently playing on server.", + + &BotControl::cmdList + }, + { + "graph/g/w/wp/wpt/waypoint", + "graph [help]", + "Handles graph operations.", + + &BotControl::cmdNode + }, + { + "cvars", + "cvars [save|save_map|cvar|defaults]", + "Display all the cvars with their descriptions.", + + &BotControl::cmdCvars + }, + { + "show_custom", + "show_custom [noarguments]", + "Shows the current values from custom.cfg.", + + &BotControl::cmdShowCustom, + false + }, + { + "exec", + "exec [user_id] [command]", + "Executes a client command on bot entity.", + + &BotControl::cmdExec + } + }; // declare the menus createMenus (); diff --git a/src/engine.cpp b/src/engine.cpp index 0a7c480..6a6c245 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -1472,7 +1472,7 @@ bool Game::isBreakableEntity (edict_t *ent, bool initialSeed) const { const auto limit = cv_breakable_health_limit.as (); // not shoot-able - if (ent->v.health >= limit) { + if (ent->v.health < 5 || ent->v.health >= limit) { return false; } constexpr auto kFuncBreakable = StringRef::fnv1a32 ("func_breakable"); diff --git a/src/manager.cpp b/src/manager.cpp index 2529a0f..862661e 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1093,6 +1093,7 @@ void BotManager::updateBotDifficulties () { void BotManager::balanceBotDifficulties () { // difficulty changing once per round (time) auto updateDifficulty = [] (Bot *bot, int32_t offset) { + game.print ("offset = %d", offset); bot->setNewDifficulty (cr::clamp (static_cast (bot->m_difficulty + offset), Difficulty::Noob, Difficulty::Expert)); }; @@ -1203,7 +1204,7 @@ Bot::Bot (edict_t *bot, int difficulty, int personality, int team, int skin) { // if we're have min/max difficulty specified, choose value from they if (minDifficulty != Difficulty::Invalid && maxDifficulty != Difficulty::Invalid) { - if (maxDifficulty > minDifficulty) { + if (minDifficulty > maxDifficulty) { cr::swap (maxDifficulty, minDifficulty); } setNewDifficulty (rg (minDifficulty, maxDifficulty)); @@ -1830,8 +1831,10 @@ void Bot::markStale () { void Bot::setNewDifficulty (int32_t newDifficulty) { if (newDifficulty < Difficulty::Noob || newDifficulty > Difficulty::Expert) { - m_difficulty = Difficulty::Hard; - m_difficultyData = conf.getDifficultyTweaks (Difficulty::Hard); + const auto difficlutyDefault = Difficulty::Hard;; + + m_difficulty = difficlutyDefault; + m_difficultyData = conf.getDifficultyTweaks (difficlutyDefault); } m_difficulty = newDifficulty; diff --git a/src/tasks.cpp b/src/tasks.cpp index 3a8d1f8..29db80d 100644 --- a/src/tasks.cpp +++ b/src/tasks.cpp @@ -1469,9 +1469,10 @@ void Bot::escapeFromBomb_ () { } void Bot::shootBreakable_ () { + const bool hasEnemy = !game.isNullEntity (m_enemy); // breakable destroyed? - if (!game.isBreakableEntity (m_breakableEntity)) { + if (hasEnemy || !game.isBreakableEntity (m_breakableEntity)) { completeTask (); return; }