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.h147
1 files changed, 43 insertions, 104 deletions
diff --git a/src/fpsgame/aiman.h b/src/fpsgame/aiman.h
index 940f13e..f926d44 100644
--- a/src/fpsgame/aiman.h
+++ b/src/fpsgame/aiman.h
@@ -1,15 +1,11 @@
// server-side ai manager
-namespace aiman
-{
+namespace aiman {
bool dorefresh = false, botbalance = true;
VARN(serverbotlimit, botlimit, 0, 8, MAXBOTS);
VAR(serverbotbalance, 0, 1, 1);
-
- void calcteams(vector<teamscore> &teams)
- {
+ void calcteams(vector<teamscore> &teams) {
static const char * const defaults[2] = { "good", "evil" };
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
teamscore *t = NULL;
@@ -18,83 +14,64 @@ namespace aiman
else teams.add(teamscore(ci->team, 1));
}
teams.sort(teamscore::compare);
- if(teams.length() < int(sizeof(defaults)/sizeof(defaults[0])))
- {
+ 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()
- {
+ 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)
- {
+ 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))
- {
+ 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--)
- {
+ 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)
- {
+ 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()
- {
+ const char *chooseteam() {
vector<teamscore> teams;
calcteams(teams);
return teams.length() ? teams.last().team : "";
}
-
- static inline bool validaiclient(clientinfo *ci)
- {
+ 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 *findaiclient(clientinfo *exclude = NULL) {
clientinfo *least = NULL;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(!validaiclient(ci) || ci==exclude) continue;
if(!least || ci->bots.length() < least->bots.length()) least = ci;
}
return least;
}
-
- bool addai(int skill, int limit)
- {
+ bool addai(int skill, int limit) {
int numai = 0, cn = -1, maxai = limit >= 0 ? min(limit, MAXBOTS) : MAXBOTS;
- loopv(bots)
- {
+ loopv(bots) {
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))
- {
+ if(bots.inrange(cn)) {
clientinfo *ci = bots[cn];
- if(ci)
- { // reuse a slot that was going to removed
-
+ 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);
@@ -124,9 +101,7 @@ namespace aiman
dorefresh = true;
return true;
}
-
- void deleteai(clientinfo *ci)
- {
+ void deleteai(clientinfo *ci) {
int cn = ci->clientnum - MAXCLIENTS;
if(!bots.inrange(cn)) return;
sendf(-1, 1, "ri2", N_CDIS, ci->clientnum);
@@ -136,25 +111,18 @@ namespace aiman
DELETEP(bots[cn]);
dorefresh = true;
}
-
- bool deleteai()
- {
- loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0)
- {
+ bool deleteai() {
+ loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0) {
deleteai(bots[i]);
return true;
}
return false;
}
-
- void reinitai(clientinfo *ci)
- {
+ void reinitai(clientinfo *ci) {
if(ci->ownernum < 0) deleteai(ci);
- else if(ci->aireinit >= 1)
- {
+ else if(ci->aireinit >= 1) {
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)
- {
+ if(ci->aireinit == 2) {
ci->reassign();
if(ci->state.state==CS_ALIVE) sendspawn(ci);
else sendresume(ci);
@@ -162,36 +130,27 @@ namespace aiman
ci->aireinit = 0;
}
}
-
- void shiftai(clientinfo *ci, clientinfo *owner = NULL)
- {
+ void shiftai(clientinfo *ci, clientinfo *owner = NULL) {
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;
}
-
- void removeai(clientinfo *ci)
- { // either schedules a removal, or someone else to assign to
-
+ void removeai(clientinfo *ci) {
+ // either schedules a removal, or someone else to assign to
loopvrev(ci->bots) shiftai(ci->bots[i], findaiclient(ci));
}
-
- bool reassignai()
- {
+ bool reassignai() {
clientinfo *hi = NULL, *lo = NULL;
- loopv(clients)
- {
+ 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(hi && lo && hi->bots.length() - lo->bots.length() > 1)
- {
- loopvrev(hi->bots)
- {
+ if(hi && lo && hi->bots.length() - lo->bots.length() > 1) {
+ loopvrev(hi->bots) {
shiftai(hi->bots[i], lo);
return true;
}
@@ -199,53 +158,39 @@ namespace aiman
return false;
}
-
- void checksetup()
- {
+ void checksetup() {
if(m_teammode && botbalance) balanceteams();
loopvrev(bots) if(bots[i]) reinitai(bots[i]);
}
-
- void clearai()
- { // clear and remove all ai immediately
+ void clearai() {
+ // clear and remove all ai immediately
loopvrev(bots) if(bots[i]) deleteai(bots[i]);
}
-
- void checkai()
- {
+ void checkai() {
if(!dorefresh) return;
dorefresh = false;
- if(m_botmode && numclients(-1, false, true))
- {
+ if(m_botmode && numclients(-1, false, true)) {
checksetup();
while(reassignai());
}
else clearai();
}
-
- void reqadd(clientinfo *ci, int skill)
- {
+ 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");
}
-
- void reqdel(clientinfo *ci)
- {
+ void reqdel(clientinfo *ci) {
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)
- {
+ 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)
- {
+ void setbotbalance(clientinfo *ci, bool balance) {
if(ci && !ci->local && !ci->privilege) return;
botbalance = balance ? 1 : 0;
dorefresh = true;
@@ -253,21 +198,15 @@ namespace aiman
sendservmsg(msg);
}
-
- void changemap()
- {
+ 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)
- {
+ void addclient(clientinfo *ci) {
if(ci->state.aitype == AI_NONE) dorefresh = true;
}
-
- void changeteam(clientinfo *ci)
- {
+ void changeteam(clientinfo *ci) {
if(ci->state.aitype == AI_NONE) dorefresh = true;
}
}