From bee54f50a9b23fa73a00c4cf4945bff53ce9176c Mon Sep 17 00:00:00 2001 From: terencehill Date: Thu, 25 Mar 2021 16:48:36 +0100 Subject: [PATCH] Fix bots standing still after one of them is forced to observe with movetospec or bot_cmd X pause; this change also removes the special handling of bots when they are forced to spectate in modes like LMS and CA --- .../gamemode/clanarena/sv_clanarena.qc | 5 -- qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc | 4 -- qcsrc/server/bot/api.qh | 1 - qcsrc/server/bot/default/bot.qc | 56 +++++-------------- qcsrc/server/bot/default/bot.qh | 1 - qcsrc/server/bot/default/havocbot/havocbot.qc | 4 ++ qcsrc/server/bot/default/scripting.qc | 9 ++- qcsrc/server/bot/default/scripting.qh | 2 + qcsrc/server/client.qc | 5 ++ 9 files changed, 32 insertions(+), 55 deletions(-) diff --git a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc index bb23f51c80..a5367322f0 100644 --- a/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc +++ b/qcsrc/common/gamemodes/gamemode/clanarena/sv_clanarena.qc @@ -224,7 +224,6 @@ MUTATOR_HOOKFUNCTION(ca, reset_map_players) PutClientInServer(it); } }); - bot_relinkplayerlist(); return true; } @@ -286,11 +285,7 @@ MUTATOR_HOOKFUNCTION(ca, PlayerDies) } frag_target.respawn_flags |= RESPAWN_FORCE; if (!warmup_stage) - { eliminatedPlayers.SendFlags |= 1; - if (IS_BOT_CLIENT(frag_target)) - bot_clear(frag_target); - } return true; } diff --git a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc index d35da51869..dc18b7c907 100644 --- a/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc +++ b/qcsrc/common/gamemodes/gamemode/lms/sv_lms.qc @@ -192,8 +192,6 @@ void lms_RemovePlayer(entity player) { if (player.lms_spectate_warning < 2) { - if(IS_BOT_CLIENT(player)) - bot_clear(player); player.frags = FRAGS_PLAYER_OUT_OF_GAME; int pl_cnt = 0; FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { @@ -314,8 +312,6 @@ MUTATOR_HOOKFUNCTION(lms, GiveFragsForKill) FOREACH_CLIENT(IS_PLAYER(it) && it.frags != FRAGS_PLAYER_OUT_OF_GAME, { pl_cnt++; }); - if(IS_BOT_CLIENT(frag_target)) - bot_clear(frag_target); frag_target.frags = FRAGS_PLAYER_OUT_OF_GAME; GameRules_scoring_add(frag_target, LMS_RANK, pl_cnt); } diff --git a/qcsrc/server/bot/api.qh b/qcsrc/server/bot/api.qh index 44ed3b8db6..0759d46365 100644 --- a/qcsrc/server/bot/api.qh +++ b/qcsrc/server/bot/api.qh @@ -73,7 +73,6 @@ void bot_endgame(); bool bot_fixcount(); void bot_list_commands(); void bot_queuecommand(entity bot, string cmdstring); -void bot_clear(entity this); void bot_relinkplayerlist(); void bot_resetqueues(); void bot_serverframe(); diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc index 59bf07a7a9..b9d468fbf1 100644 --- a/qcsrc/server/bot/default/bot.qc +++ b/qcsrc/server/bot/default/bot.qc @@ -113,16 +113,19 @@ void bot_think(entity this) } // if dead, just wait until we can respawn - if (IS_DEAD(this)) + if (IS_DEAD(this) || IS_OBSERVER(this)) { if (bot_waypoint_queue_owner == this) bot_waypoint_queue_owner = NULL; this.aistatus = 0; CS(this).movement = '0 0 0'; - if (this.deadflag == DEAD_DEAD) + if (IS_OBSERVER(this)) + return; + if (IS_DEAD(this)) { PHYS_INPUT_BUTTON_JUMP(this) = true; // press jump to respawn - navigation_goalrating_timeout_force(this); + if (!navigation_goalrating_timeout(this)) + navigation_goalrating_timeout_force(this); } } else if(this.aistatus & AI_STATUS_STUCK) @@ -383,17 +386,19 @@ void bot_relinkplayerlist() if(IS_BOT_CLIENT(it)) { - if(prevbot) - prevbot.nextbot = it; - else - bot_list = it; - prevbot = it; + if (!IS_OBSERVER(it) && !bot_ispaused(it)) + { + if(prevbot) + prevbot.nextbot = it; + else + bot_list = it; + prevbot = it; + } ++currentbots; } }); if(prevbot) prevbot.nextbot = NULL; - LOG_TRACE("relink: ", ftos(currentbots), " bots seen."); bot_strategytoken = bot_list; bot_strategytoken_taken = true; } @@ -644,39 +649,6 @@ bool bot_fixcount() return true; } -void bot_remove_from_bot_list(entity this) -{ - entity e = bot_list; - entity prev_bot = NULL; - while (e) - { - if(e == this) - { - if(!prev_bot) - bot_list = this.nextbot; - else - prev_bot.nextbot = this.nextbot; - if(bot_strategytoken == this) - { - bot_strategytoken = this.nextbot; - bot_strategytoken_taken = true; - } - this.nextbot = NULL; - break; - } - prev_bot = e; - e = e.nextbot; - } -} - -void bot_clear(entity this) -{ - bot_remove_from_bot_list(this); - if(bot_waypoint_queue_owner == this) - bot_waypoint_queue_owner = NULL; - this.aistatus &= ~AI_STATUS_STUCK; // otherwise bot_waypoint_queue_owner will be set again to this by navigation_unstuck -} - void bot_serverframe() { if (intermission_running && currentbots > 0) diff --git a/qcsrc/server/bot/default/bot.qh b/qcsrc/server/bot/default/bot.qh index 88dba449d5..f94d282aab 100644 --- a/qcsrc/server/bot/default/bot.qh +++ b/qcsrc/server/bot/default/bot.qh @@ -95,7 +95,6 @@ void bot_setnameandstuff(entity this); void bot_custom_weapon_priority_setup(); void bot_endgame(); void bot_relinkplayerlist(); -void bot_clear(entity this); void bot_clientdisconnect(entity this); void bot_clientconnect(entity this); void bot_removefromlargestteam(); diff --git a/qcsrc/server/bot/default/havocbot/havocbot.qc b/qcsrc/server/bot/default/havocbot/havocbot.qc index 64d3c91539..41851afc00 100644 --- a/qcsrc/server/bot/default/havocbot/havocbot.qc +++ b/qcsrc/server/bot/default/havocbot/havocbot.qc @@ -43,6 +43,10 @@ void havocbot_ai(entity this) if(bot_execute_commands(this)) return; + // after bot_execute_commands otherwise bots can't be unpaused + if (bot_ispaused(this)) + return; + if (bot_strategytoken == this && !bot_strategytoken_taken) { if(this.havocbot_blockhead) diff --git a/qcsrc/server/bot/default/scripting.qc b/qcsrc/server/bot/default/scripting.qc index c904c5db49..5a13330652 100644 --- a/qcsrc/server/bot/default/scripting.qc +++ b/qcsrc/server/bot/default/scripting.qc @@ -493,8 +493,8 @@ float bot_cmd_impulse(entity this) float bot_cmd_continue(entity this) { - bot_relinkplayerlist(); this.bot_exec_status &= ~BOT_EXEC_STATUS_PAUSED; + bot_relinkplayerlist(); return CMD_STATUS_FINISHED; } @@ -1000,6 +1000,11 @@ float bot_cmd_releasekey(entity this) return bot_cmd_keypress_handler(this, key,false); } +bool bot_ispaused(entity this) +{ + return(this.bot_exec_status & BOT_EXEC_STATUS_PAUSED); +} + float bot_cmd_pause(entity this) { PHYS_INPUT_BUTTON_DRAG(this) = false; @@ -1014,8 +1019,8 @@ float bot_cmd_pause(entity this) CS(this).movement = '0 0 0'; this.bot_cmd_keys = BOT_CMD_KEY_NONE; - bot_clear(this); this.bot_exec_status |= BOT_EXEC_STATUS_PAUSED; + bot_relinkplayerlist(); return CMD_STATUS_FINISHED; } diff --git a/qcsrc/server/bot/default/scripting.qh b/qcsrc/server/bot/default/scripting.qh index cb5bf625f6..58c1fe8bd7 100644 --- a/qcsrc/server/bot/default/scripting.qh +++ b/qcsrc/server/bot/default/scripting.qh @@ -71,6 +71,8 @@ float bot_barriertime; .float bot_cmd_execution_index; // Position in the queue of the command to be executed +bool bot_ispaused(entity this); + void bot_resetqueues(); void bot_queuecommand(entity bot, string cmdstring); void bot_cmdhelp(string scmd); diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index bdfc3c1fdf..2a31be2a05 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -395,6 +395,9 @@ void PutObserverInServer(entity this) SetPlayerTeam(this, -1, TEAM_CHANGE_SPECTATOR); this.frags = FRAGS_SPECTATOR; } + + bot_relinkplayerlist(); + if (CS(this).just_joined) CS(this).just_joined = false; } @@ -825,6 +828,8 @@ void PutClientInServer(entity this) } else if (IS_PLAYER(this)) { PutPlayerInServer(this); } + + bot_relinkplayerlist(); } // TODO do we need all these fields, or should we stop autodetecting runtime -- 2.39.2