X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fbot.qc;h=1f9b8625f4d6332474949d39d39b951ac85b158f;hb=5aab6120acfc624751d20a695d1b911b3e919831;hp=0e6c87b675d577fd820cdaf8612c0bd66fd5d5e0;hpb=0c6b993abfdde30411dc771643b8d25b8377cb50;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc index 0e6c87b67..1f9b8625f 100644 --- a/qcsrc/server/bot/default/bot.qc +++ b/qcsrc/server/bot/default/bot.qc @@ -21,7 +21,7 @@ #include "../../race.qh" #include -#include "../../mutators/_mod.qh" +#include #include "../../weapons/accuracy.qh" @@ -129,11 +129,14 @@ void bot_think(entity this) // if dead, just wait until we can respawn if (IS_DEAD(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) { PHYS_INPUT_BUTTON_JUMP(this) = true; // press jump to respawn - this.bot_strategytime = 0; + navigation_goalrating_timeout_force(this); } } else if(this.aistatus & AI_STATUS_STUCK) @@ -396,18 +399,10 @@ void bot_clientdisconnect(entity this) if (!IS_BOT_CLIENT(this)) return; bot_clearqueue(this); - if(this.cleanname) - strunzone(this.cleanname); - if(this.netname_freeme) - strunzone(this.netname_freeme); - if(this.playermodel_freeme) - strunzone(this.playermodel_freeme); - if(this.playerskin_freeme) - strunzone(this.playerskin_freeme); - this.cleanname = string_null; - this.netname_freeme = string_null; - this.playermodel_freeme = string_null; - this.playerskin_freeme = string_null; + strfree(this.cleanname); + strfree(this.netname_freeme); + strfree(this.playermodel_freeme); + strfree(this.playerskin_freeme); if(this.bot_cmd_current) delete(this.bot_cmd_current); if(bot_waypoint_queue_owner == this) @@ -438,7 +433,7 @@ void bot_clientconnect(entity this) else if(this.bot_forced_team==4) this.team = NUM_TEAM_4; else - JoinBestTeam(this, false, true); + JoinBestTeam(this, true); havocbot_setupbot(this); } @@ -579,9 +574,8 @@ void autoskill(float factor) void bot_calculate_stepheightvec() { stepheightvec = autocvar_sv_stepheight * '0 0 1'; - jumpstepheightvec = stepheightvec + - ((autocvar_sv_jumpvelocity * autocvar_sv_jumpvelocity) / (2 * autocvar_sv_gravity)) * '0 0 0.85'; - // 0.75 factor is for safety to make the jumps easy + jumpheight_vec = (autocvar_sv_jumpvelocity ** 2) / (2 * autocvar_sv_gravity) * '0 0 1'; + jumpstepheightvec = stepheightvec + jumpheight_vec * 0.85; // reduce it a bit to make the jumps easy } float bot_fixcount() @@ -680,11 +674,51 @@ void bot_clear(entity this) void bot_serverframe() { + if (intermission_running && currentbots > 0) + { + // after the end of the match all bots stay unless all human players disconnect + int realplayers = 0; + FOREACH_CLIENT(IS_REAL_CLIENT(it), { ++realplayers; }); + if (!realplayers) + { + FOREACH_CLIENT(IS_BOT_CLIENT(it), { dropclient(it); }); + currentbots = 0; + } + return; + } + if (game_stopped) return; - if (time < 2) + // Added 0.5 to avoid possible addition + immediate removal of bots that would make them appear as + // spectators in the scoreboard and never go away. This issue happens at time 2 if map is changed + // with the gotomap command, minplayers is > 1 and human clients join as players very soon + // either intentionally or automatically (sv_spectate 0) + if (time < 2.5) + { + currentbots = -1; return; + } + + if (currentbots == -1) + { + // count bots already in the server from the previous match + currentbots = 0; + FOREACH_CLIENT(IS_BOT_CLIENT(it), { ++currentbots; }); + } + + if(autocvar_skill != skill) + { + float wpcost_update = false; + if(skill >= autocvar_bot_ai_bunnyhop_skilloffset && autocvar_skill < autocvar_bot_ai_bunnyhop_skilloffset) + wpcost_update = true; + if(skill < autocvar_bot_ai_bunnyhop_skilloffset && autocvar_skill >= autocvar_bot_ai_bunnyhop_skilloffset) + wpcost_update = true; + + skill = autocvar_skill; + if (wpcost_update) + waypoint_updatecost_foralllinks(); + } bot_calculate_stepheightvec(); bot_navigation_movemode = ((autocvar_bot_navigation_ignoreplayers) ? MOVE_NOMONSTERS : MOVE_NORMAL); @@ -704,8 +738,6 @@ void bot_serverframe() botframe_nextthink = time + 10; } - bot_ignore_bots = autocvar_bot_ignore_bots; - if(botframe_spawnedwaypoints) { if(autocvar_waypoint_benchmark) @@ -734,8 +766,7 @@ void bot_serverframe() { botframe_spawnedwaypoints = true; waypoint_loadall(); - if(!waypoint_load_links()) - waypoint_schedulerelinkall(); + waypoint_load_links(); } if (bot_list) @@ -745,11 +776,26 @@ void bot_serverframe() // frame, which causes choppy framerates) if (bot_strategytoken_taken) { + // give goal token to the first bot without goals; if all bots don't have + // any goal (or are dead/frozen) simply give it to the next one bot_strategytoken_taken = false; - if (bot_strategytoken) - bot_strategytoken = bot_strategytoken.nextbot; - if (!bot_strategytoken) - bot_strategytoken = bot_list; + entity bot_strategytoken_save = bot_strategytoken; + while (true) + { + if (bot_strategytoken) + bot_strategytoken = bot_strategytoken.nextbot; + if (!bot_strategytoken) + bot_strategytoken = bot_list; + + if (!(IS_DEAD(bot_strategytoken) || STAT(FROZEN, bot_strategytoken)) + && !bot_strategytoken.goalcurrent) + break; + + if (!bot_strategytoken_save) // break loop if all the bots are dead or frozen + break; + if (bot_strategytoken == bot_strategytoken_save) + bot_strategytoken_save = NULL; // looped through all the bots + } } if (botframe_nextdangertime < time)