summaryrefslogtreecommitdiff
path: root/src/fpsgame/aiman.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/fpsgame/aiman.h')
-rw-r--r--src/fpsgame/aiman.h300
1 files changed, 150 insertions, 150 deletions
diff --git a/src/fpsgame/aiman.h b/src/fpsgame/aiman.h
index 9c1598c..940f13e 100644
--- a/src/fpsgame/aiman.h
+++ b/src/fpsgame/aiman.h
@@ -1,146 +1,146 @@
// server-side ai manager
namespace aiman
{
- bool dorefresh = false, botbalance = true;
- VARN(serverbotlimit, botlimit, 0, 8, MAXBOTS);
- VAR(serverbotbalance, 0, 1, 1);
+ bool dorefresh = false, botbalance = true;
+ VARN(serverbotlimit, botlimit, 0, 8, MAXBOTS);
+ VAR(serverbotbalance, 0, 1, 1);
- void calcteams(vector<teamscore> &teams)
- {
- static const char * const defaults[2] = { "good", "evil" };
- loopv(clients)
- {
- clientinfo *ci = clients[i];
- if(ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
- teamscore *t = NULL;
- loopvj(teams) if(!strcmp(teams[j].team, ci->team)) { t = &teams[j]; break; }
- if(t) t->score++;
- else teams.add(teamscore(ci->team, 1));
- }
- teams.sort(teamscore::compare);
- if(teams.length() < int(sizeof(defaults)/sizeof(defaults[0])))
- {
- loopi(sizeof(defaults)/sizeof(defaults[0])) if(teams.htfind(defaults[i]) < 0) teams.add(teamscore(defaults[i], 0));
- }
- }
+ void calcteams(vector<teamscore> &teams)
+ {
+ static const char * const defaults[2] = { "good", "evil" };
+ loopv(clients)
+ {
+ clientinfo *ci = clients[i];
+ if(ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
+ teamscore *t = NULL;
+ loopvj(teams) if(!strcmp(teams[j].team, ci->team)) { t = &teams[j]; break; }
+ if(t) t->score++;
+ else teams.add(teamscore(ci->team, 1));
+ }
+ teams.sort(teamscore::compare);
+ if(teams.length() < int(sizeof(defaults)/sizeof(defaults[0])))
+ {
+ loopi(sizeof(defaults)/sizeof(defaults[0])) if(teams.htfind(defaults[i]) < 0) teams.add(teamscore(defaults[i], 0));
+ }
+ }
- void balanceteams()
- {
- vector<teamscore> teams;
- calcteams(teams);
- vector<clientinfo *> reassign;
- loopv(bots) if(bots[i]) reassign.add(bots[i]);
- while(reassign.length() && teams.length() && teams[0].score > teams.last().score + 1)
- {
- teamscore &t = teams.last();
- clientinfo *bot = NULL;
- loopv(reassign) if(reassign[i] && !strcmp(reassign[i]->team, teams[0].team))
- {
- bot = reassign.removeunordered(i);
- teams[0].score--;
- t.score++;
- for(int j = teams.length() - 2; j >= 0; j--)
- {
- if(teams[j].score >= teams[j+1].score) break;
- swap(teams[j], teams[j+1]);
- }
- break;
- }
- if(bot)
- {
- copystring(bot->team, t.team, MAXTEAMLEN+1);
- sendf(-1, 1, "riisi", N_SETTEAM, bot->clientnum, bot->team, 0);
- }
- else teams.remove(0, 1);
- }
- }
+ void balanceteams()
+ {
+ vector<teamscore> teams;
+ calcteams(teams);
+ vector<clientinfo *> reassign;
+ loopv(bots) if(bots[i]) reassign.add(bots[i]);
+ while(reassign.length() && teams.length() && teams[0].score > teams.last().score + 1)
+ {
+ teamscore &t = teams.last();
+ clientinfo *bot = NULL;
+ loopv(reassign) if(reassign[i] && !strcmp(reassign[i]->team, teams[0].team))
+ {
+ bot = reassign.removeunordered(i);
+ teams[0].score--;
+ t.score++;
+ for(int j = teams.length() - 2; j >= 0; j--)
+ {
+ if(teams[j].score >= teams[j+1].score) break;
+ swap(teams[j], teams[j+1]);
+ }
+ break;
+ }
+ if(bot)
+ {
+ copystring(bot->team, t.team, MAXTEAMLEN+1);
+ sendf(-1, 1, "riisi", N_SETTEAM, bot->clientnum, bot->team, 0);
+ }
+ else teams.remove(0, 1);
+ }
+ }
- const char *chooseteam()
- {
- vector<teamscore> teams;
- calcteams(teams);
- return teams.length() ? teams.last().team : "";
- }
+ const char *chooseteam()
+ {
+ vector<teamscore> teams;
+ calcteams(teams);
+ return teams.length() ? teams.last().team : "";
+ }
- static inline bool validaiclient(clientinfo *ci)
- {
- return ci->clientnum >= 0 && ci->state.aitype == AI_NONE && (ci->state.state!=CS_SPECTATOR || ci->local || (ci->privilege && !ci->warned));
- }
+ static inline bool validaiclient(clientinfo *ci)
+ {
+ return ci->clientnum >= 0 && ci->state.aitype == AI_NONE && (ci->state.state!=CS_SPECTATOR || ci->local || (ci->privilege && !ci->warned));
+ }
clientinfo *findaiclient(clientinfo *exclude = NULL)
{
- clientinfo *least = NULL;
+ clientinfo *least = NULL;
loopv(clients)
{
clientinfo *ci = clients[i];
if(!validaiclient(ci) || ci==exclude) continue;
- if(!least || ci->bots.length() < least->bots.length()) least = ci;
+ if(!least || ci->bots.length() < least->bots.length()) least = ci;
}
- return least;
+ return least;
}
bool addai(int skill, int limit)
{
int numai = 0, cn = -1, maxai = limit >= 0 ? min(limit, MAXBOTS) : MAXBOTS;
loopv(bots)
- {
- clientinfo *ci = bots[i];
- if(!ci || ci->ownernum < 0) { if(cn < 0) cn = i; continue; }
+ {
+ clientinfo *ci = bots[i];
+ if(!ci || ci->ownernum < 0) { if(cn < 0) cn = i; continue; }
numai++;
}
if(numai >= maxai) return false;
- if(bots.inrange(cn))
- {
- clientinfo *ci = bots[cn];
- if(ci)
- { // reuse a slot that was going to removed
+ if(bots.inrange(cn))
+ {
+ clientinfo *ci = bots[cn];
+ if(ci)
+ { // reuse a slot that was going to removed
- clientinfo *owner = findaiclient();
- ci->ownernum = owner ? owner->clientnum : -1;
- if(owner) owner->bots.add(ci);
- ci->aireinit = 2;
- dorefresh = true;
- return true;
- }
- }
- else { cn = bots.length(); bots.add(NULL); }
- const char *team = m_teammode ? chooseteam() : "";
- if(!bots[cn]) bots[cn] = new clientinfo;
- clientinfo *ci = bots[cn];
+ clientinfo *owner = findaiclient();
+ ci->ownernum = owner ? owner->clientnum : -1;
+ if(owner) owner->bots.add(ci);
+ ci->aireinit = 2;
+ dorefresh = true;
+ return true;
+ }
+ }
+ else { cn = bots.length(); bots.add(NULL); }
+ const char *team = m_teammode ? chooseteam() : "";
+ if(!bots[cn]) bots[cn] = new clientinfo;
+ clientinfo *ci = bots[cn];
ci->clientnum = MAXCLIENTS + cn;
ci->state.aitype = AI_BOT;
- clientinfo *owner = findaiclient();
+ clientinfo *owner = findaiclient();
ci->ownernum = owner ? owner->clientnum : -1;
- if(owner) owner->bots.add(ci);
- ci->state.skill = skill <= 0 ? rnd(50) + 51 : clamp(skill, 1, 101);
- clients.add(ci);
+ if(owner) owner->bots.add(ci);
+ ci->state.skill = skill <= 0 ? rnd(50) + 51 : clamp(skill, 1, 101);
+ clients.add(ci);
ci->state.lasttimeplayed = lastmillis;
copystring(ci->name, "bot", MAXNAMELEN+1);
ci->state.state = CS_DEAD;
- copystring(ci->team, team, MAXTEAMLEN+1);
- ci->playermodel = 0;
+ copystring(ci->team, team, MAXTEAMLEN+1);
+ ci->playermodel = 0;
ci->aireinit = 2;
ci->connected = true;
- dorefresh = true;
+ dorefresh = true;
return true;
}
void deleteai(clientinfo *ci)
{
- int cn = ci->clientnum - MAXCLIENTS;
- if(!bots.inrange(cn)) return;
- sendf(-1, 1, "ri2", N_CDIS, ci->clientnum);
- clientinfo *owner = (clientinfo *)getclientinfo(ci->ownernum);
- if(owner) owner->bots.removeobj(ci);
- clients.removeobj(ci);
- DELETEP(bots[cn]);
+ int cn = ci->clientnum - MAXCLIENTS;
+ if(!bots.inrange(cn)) return;
+ sendf(-1, 1, "ri2", N_CDIS, ci->clientnum);
+ clientinfo *owner = (clientinfo *)getclientinfo(ci->ownernum);
+ if(owner) owner->bots.removeobj(ci);
+ clients.removeobj(ci);
+ DELETEP(bots[cn]);
dorefresh = true;
}
bool deleteai()
{
- loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0)
- {
+ loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0)
+ {
deleteai(bots[i]);
return true;
}
@@ -154,22 +154,22 @@ namespace aiman
{
sendf(-1, 1, "ri6ss", N_INITAI, ci->clientnum, ci->ownernum, ci->state.aitype, ci->state.skill, ci->playermodel, ci->name, ci->team);
if(ci->aireinit == 2)
- {
- ci->reassign();
- if(ci->state.state==CS_ALIVE) sendspawn(ci);
- else sendresume(ci);
- }
+ {
+ ci->reassign();
+ if(ci->state.state==CS_ALIVE) sendspawn(ci);
+ else sendresume(ci);
+ }
ci->aireinit = 0;
}
}
void shiftai(clientinfo *ci, clientinfo *owner = NULL)
{
- clientinfo *prevowner = (clientinfo *)getclientinfo(ci->ownernum);
- if(prevowner) prevowner->bots.removeobj(ci);
+ clientinfo *prevowner = (clientinfo *)getclientinfo(ci->ownernum);
+ if(prevowner) prevowner->bots.removeobj(ci);
if(!owner) { ci->aireinit = 0; ci->ownernum = -1; }
else if(ci->ownernum != owner->clientnum) { ci->aireinit = 2; ci->ownernum = owner->clientnum; owner->bots.add(ci); }
- dorefresh = true;
+ dorefresh = true;
}
void removeai(clientinfo *ci)
@@ -180,13 +180,13 @@ namespace aiman
bool reassignai()
{
- clientinfo *hi = NULL, *lo = NULL;
+ clientinfo *hi = NULL, *lo = NULL;
loopv(clients)
{
clientinfo *ci = clients[i];
if(!validaiclient(ci)) continue;
- if(!lo || ci->bots.length() < lo->bots.length()) lo = ci;
- if(!hi || ci->bots.length() > hi->bots.length()) hi = ci;
+ if(!lo || ci->bots.length() < lo->bots.length()) lo = ci;
+ if(!hi || ci->bots.length() > hi->bots.length()) hi = ci;
}
if(hi && lo && hi->bots.length() - lo->bots.length() > 1)
{
@@ -202,20 +202,20 @@ namespace aiman
void checksetup()
{
- if(m_teammode && botbalance) balanceteams();
+ if(m_teammode && botbalance) balanceteams();
loopvrev(bots) if(bots[i]) reinitai(bots[i]);
}
void clearai()
{ // clear and remove all ai immediately
- loopvrev(bots) if(bots[i]) deleteai(bots[i]);
+ loopvrev(bots) if(bots[i]) deleteai(bots[i]);
}
void checkai()
{
- if(!dorefresh) return;
- dorefresh = false;
- if(m_botmode && numclients(-1, false, true))
+ if(!dorefresh) return;
+ dorefresh = false;
+ if(m_botmode && numclients(-1, false, true))
{
checksetup();
while(reassignai());
@@ -225,49 +225,49 @@ namespace aiman
void reqadd(clientinfo *ci, int skill)
{
- if(!ci->local && !ci->privilege) return;
- if(!addai(skill, !ci->local && ci->privilege < PRIV_ADMIN ? botlimit : -1)) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to create or assign bot");
+ if(!ci->local && !ci->privilege) return;
+ if(!addai(skill, !ci->local && ci->privilege < PRIV_ADMIN ? botlimit : -1)) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to create or assign bot");
}
void reqdel(clientinfo *ci)
{
- if(!ci->local && !ci->privilege) return;
- if(!deleteai()) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to remove any bots");
+ if(!ci->local && !ci->privilege) return;
+ if(!deleteai()) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to remove any bots");
}
- void setbotlimit(clientinfo *ci, int limit)
- {
- if(ci && !ci->local && ci->privilege < PRIV_ADMIN) return;
- botlimit = clamp(limit, 0, MAXBOTS);
- dorefresh = true;
- defformatstring(msg, "bot limit is now %d", botlimit);
- sendservmsg(msg);
- }
+ void setbotlimit(clientinfo *ci, int limit)
+ {
+ if(ci && !ci->local && ci->privilege < PRIV_ADMIN) return;
+ botlimit = clamp(limit, 0, MAXBOTS);
+ dorefresh = true;
+ defformatstring(msg, "bot limit is now %d", botlimit);
+ sendservmsg(msg);
+ }
- void setbotbalance(clientinfo *ci, bool balance)
- {
- if(ci && !ci->local && !ci->privilege) return;
- botbalance = balance ? 1 : 0;
- dorefresh = true;
- defformatstring(msg, "bot team balancing is now %s", botbalance ? "enabled" : "disabled");
- sendservmsg(msg);
- }
+ void setbotbalance(clientinfo *ci, bool balance)
+ {
+ if(ci && !ci->local && !ci->privilege) return;
+ botbalance = balance ? 1 : 0;
+ dorefresh = true;
+ defformatstring(msg, "bot team balancing is now %s", botbalance ? "enabled" : "disabled");
+ sendservmsg(msg);
+ }
- void changemap()
- {
- dorefresh = true;
- loopv(clients) if(clients[i]->local || clients[i]->privilege) return;
- if(botbalance != (serverbotbalance != 0)) setbotbalance(NULL, serverbotbalance != 0);
- }
+ void changemap()
+ {
+ dorefresh = true;
+ loopv(clients) if(clients[i]->local || clients[i]->privilege) return;
+ if(botbalance != (serverbotbalance != 0)) setbotbalance(NULL, serverbotbalance != 0);
+ }
- void addclient(clientinfo *ci)
- {
- if(ci->state.aitype == AI_NONE) dorefresh = true;
- }
+ void addclient(clientinfo *ci)
+ {
+ if(ci->state.aitype == AI_NONE) dorefresh = true;
+ }
- void changeteam(clientinfo *ci)
- {
- if(ci->state.aitype == AI_NONE) dorefresh = true;
- }
+ void changeteam(clientinfo *ci)
+ {
+ if(ci->state.aitype == AI_NONE) dorefresh = true;
+ }
}