X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fbot.qc;h=2b427f4fbc81580d91cd4037ec960a002db40d68;hb=69eda62d02bc02ff50547bad514af3f7ce487413;hp=20af7e71984dfdac24a5895ec91b7bf128f03b8b;hpb=2d8a70399fec0a44f3671096b261c3fc9f53f2ad;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc index 20af7e719..2b427f4fb 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" @@ -74,12 +74,6 @@ void bot_think(entity this) this.bot_nextthink = max(time, this.bot_nextthink) + max(0.01, autocvar_bot_ai_thinkinterval * (0.5 ** this.bot_aiskill) * min(14 / (skill + 14), 1)); - //if (this.bot_painintensity > 0) - // this.bot_painintensity = this.bot_painintensity - (skill + 1) * 40 * frametime; - - //this.bot_painintensity = this.bot_painintensity + this.bot_oldhealth - this.health; - //this.bot_painintensity = bound(0, this.bot_painintensity, 100); - if (!IS_PLAYER(this) || (autocvar_g_campaign && !campaign_bots_may_start)) { CS(this).movement = '0 0 0'; @@ -133,7 +127,7 @@ void bot_think(entity this) 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) @@ -255,16 +249,23 @@ void bot_setnameandstuff(entity this) name = bot_name; // number bots with identical names - int j = 0; - FOREACH_CLIENT(IS_BOT_CLIENT(it), { - if(it.cleanname == name) - ++j; - }); - if (j) - this.netname = this.netname_freeme = strzone(strcat(prefix, name, "(", ftos(j), ")", suffix)); - else + if (name == "") + { + name = ftos(etof(this)); this.netname = this.netname_freeme = strzone(strcat(prefix, name, suffix)); - + } + else + { + int j = 0; + FOREACH_CLIENT(IS_BOT_CLIENT(it), { + if(it.cleanname == name) + ++j; + }); + if (j) + this.netname = this.netname_freeme = strzone(strcat(prefix, name, "(", ftos(j), ")", suffix)); + else + this.netname = this.netname_freeme = strzone(strcat(prefix, name, suffix)); + } this.cleanname = strzone(name); // pick the model and skin @@ -396,18 +397,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,15 +431,15 @@ void bot_clientconnect(entity this) else if(this.bot_forced_team==4) this.team = NUM_TEAM_4; else - JoinBestTeam(this, true); + TeamBalance_JoinBestTeam(this, true); havocbot_setupbot(this); } void bot_removefromlargestteam() { - CheckAllowedTeams(NULL); - GetTeamCounts(NULL); + entity balance = TeamBalance_CheckAllowedTeams(NULL); + TeamBalance_GetTeamCounts(balance, NULL); entity best = NULL; float besttime = 0; @@ -465,12 +458,10 @@ void bot_removefromlargestteam() int thiscount = 0; - switch(it.team) + if (Team_IsValidTeam(it.team)) { - case NUM_TEAM_1: thiscount = c1; break; - case NUM_TEAM_2: thiscount = c2; break; - case NUM_TEAM_3: thiscount = c3; break; - case NUM_TEAM_4: thiscount = c4; break; + thiscount = TeamBalance_GetNumberOfPlayers(balance, + Team_TeamToIndex(it.team)); } if(thiscount > bestcount) @@ -485,6 +476,7 @@ void bot_removefromlargestteam() best = it; } }); + TeamBalance_Destroy(balance); if(!bcount) return; // no bots to remove currentbots = currentbots - 1; @@ -597,16 +589,6 @@ float bot_fixcount() ++realplayers; }); } - if(currentbots == -1) - { - currentbots = 0; - // human players joining early may cause weird issues (bots appearing on - // the scoreboard as spectators) when switching map with the gotomap - // command, as it doesn't remove bots of the previous match, and with - // minplayers > 1, so ignore human players in the first bot frame - // TODO maybe find a cleaner solution - activerealplayers = 0; - } int bots; // add/remove bots if needed to make sure there are at least @@ -689,15 +671,39 @@ 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; @@ -729,8 +735,6 @@ void bot_serverframe() botframe_nextthink = time + 10; } - bot_ignore_bots = autocvar_bot_ignore_bots; - if(botframe_spawnedwaypoints) { if(autocvar_waypoint_benchmark) @@ -759,8 +763,7 @@ void bot_serverframe() { botframe_spawnedwaypoints = true; waypoint_loadall(); - if(!waypoint_load_links()) - waypoint_schedulerelinkall(); // link all the autogenerated waypoints (teleporters) + waypoint_load_links(); } if (bot_list) @@ -770,11 +773,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)