void bot_setnameandstuff(entity this)
{
string readfile, s;
- float file, tokens, prio;
-
- string bot_name, bot_model, bot_skin, bot_shirt, bot_pants;
- string name, prefix, suffix;
-
- if(autocvar_g_campaign)
- {
- prefix = "";
- suffix = "";
- }
- else
- {
- prefix = autocvar_bot_prefix;
- suffix = autocvar_bot_suffix;
- }
+ int file, tokens, prio;
file = fopen(autocvar_bot_config_file, FILE_READ);
}
else
{
+ entity balance = TeamBalance_CheckAllowedTeams(NULL);
+ TeamBalance_GetTeamCounts(balance, NULL);
+ int smallest_team = -1;
+ int smallest_count = -1;
+ if (teamplay)
+ {
+ for (int i = 1; i <= AvailableTeams(); ++i)
+ {
+ // NOTE if (autocvar_g_campaign && autocvar_g_campaign_forceteam == i)
+ // TeamBalance_GetNumberOfPlayers(balance, i); returns the number of players + 1
+ // since it keeps a spot for the real player in the desired team
+ int count = TeamBalance_GetNumberOfPlayers(balance, i);
+ if (smallest_count < 0 || count < smallest_count)
+ {
+ smallest_team = i;
+ smallest_count = count;
+ }
+ }
+ }
+ TeamBalance_Destroy(balance);
RandomSelection_Init();
while((readfile = fgets(file)))
{
continue;
if(substring(readfile, 0, 1) == "#")
continue;
+ // NOTE if the line is empty tokenizebyseparator(readfile, "\t")
+ // will create 1 empty token because there's no separator (bug?)
+ if (readfile == "")
+ continue;
tokens = tokenizebyseparator(readfile, "\t");
if(tokens == 0)
continue;
s = argv(0);
- prio = 1;
+ prio = 0;
+ bool conflict = false;
FOREACH_CLIENT(IS_BOT_CLIENT(it), {
- if(s == it.cleanname)
+ if (s == it.cleanname)
{
- prio = 0;
+ conflict = true;
break;
}
});
+ if (!conflict)
+ prio += 1;
+ if (teamplay && !(autocvar_bot_vs_human && AvailableTeams() == 2))
+ {
+ int forced_team = stof(argv(5));
+ if (!Team_IsValidIndex(forced_team))
+ forced_team = 0;
+ if (!forced_team || forced_team == smallest_team)
+ prio += 2;
+ }
RandomSelection_AddString(readfile, 1, prio);
}
readfile = RandomSelection_chosen_string;
fclose(file);
}
+ string bot_name, bot_model, bot_skin, bot_shirt, bot_pants;
+
tokens = tokenizebyseparator(readfile, "\t");
if(argv(0) != "") bot_name = argv(0);
else bot_name = "Bot";
if(argv(4) != "" && stof(argv(4)) >= 0) bot_pants = argv(4);
else bot_pants = ftos(floor(random() * 15));
- this.bot_forced_team = stof(argv(5));
+ if (teamplay && !(autocvar_bot_vs_human && AvailableTeams() == 2))
+ this.bot_forced_team = stof(argv(5));
+ else
+ this.bot_forced_team = 0;
prio = 6;
READSKILL(bot_thinkskill, 1, 0.5); // think skill
READSKILL(bot_aiskill, 2, 0); // "ai" skill
+ if (file >= 0 && argv(prio) != "")
+ LOG_INFOF("^1Warning^7: too many parameters for bot %s, please check format of %s", bot_name, autocvar_bot_config_file);
+
this.bot_config_loaded = true;
// this is really only a default, TeamBalance_JoinBestTeam is called later
setcolor(this, stof(bot_shirt) * 16 + stof(bot_pants));
this.bot_preferredcolors = this.clientcolors;
- // pick the name
- if (autocvar_bot_usemodelnames)
- name = bot_model;
- else
- name = bot_name;
+ string prefix = (autocvar_g_campaign ? "" : autocvar_bot_prefix);
+ string suffix = (autocvar_g_campaign ? "" : autocvar_bot_suffix);
+ string name = (autocvar_bot_usemodelnames ? bot_model : bot_name);
- // number bots with identical names
if (name == "")
{
name = ftos(etof(this));
}
else
{
+ // number bots with identical names
int j = 0;
FOREACH_CLIENT(IS_BOT_CLIENT(it), {
if(it.cleanname == name)
stepheightvec = autocvar_sv_stepheight * '0 0 1';
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
+ jumpheight_time = autocvar_sv_jumpvelocity / autocvar_sv_gravity;
}
bool bot_fixcount()
if(botframe_cachedwaypointlinks)
{
if(!botframe_loadedforcedlinks)
- waypoint_load_links_hardwired();
+ waypoint_load_hardwiredlinks();
}
else
{