summaryrefslogtreecommitdiff
path: root/src/fpsgame/ai.cpp
diff options
context:
space:
mode:
authorxolatile2025-08-10 00:19:46 +0200
committerxolatile2025-08-10 00:19:46 +0200
commit757096e7df15c14b9b10352fa91663483f9e34f8 (patch)
treedcad789d0abd8be76463277dc01bf32c4e6a527b /src/fpsgame/ai.cpp
parentb2c89d7060e99a36c8c7ac897b7386686c74deac (diff)
downloadxolatile-badassbug-757096e7df15c14b9b10352fa91663483f9e34f8.tar.xz
xolatile-badassbug-757096e7df15c14b9b10352fa91663483f9e34f8.tar.zst
all
Diffstat (limited to 'src/fpsgame/ai.cpp')
-rw-r--r--src/fpsgame/ai.cpp86
1 files changed, 25 insertions, 61 deletions
diff --git a/src/fpsgame/ai.cpp b/src/fpsgame/ai.cpp
index b4e631b..b59dbd3 100644
--- a/src/fpsgame/ai.cpp
+++ b/src/fpsgame/ai.cpp
@@ -29,7 +29,7 @@ namespace ai {
float weapmaxdist(int weap) {
return guns[weap].range + 4;
}
- bool weaprange(fpsent *d, int weap, float dist) {
+ bool weaprange(int weap, float dist) {
float mindist = weapmindist(weap), maxdist = weapmaxdist(weap);
return dist >= mindist*mindist && dist <= maxdist*maxdist;
}
@@ -53,16 +53,16 @@ namespace ai {
return false;
}
bool canshoot(fpsent *d, fpsent *e) {
- if(weaprange(d, d->gunselect, e->o.squaredist(d->o)) && targetable(d, e))
+ if(weaprange(d->gunselect, e->o.squaredist(d->o)) && targetable(d, e))
return d->ammo[d->gunselect] > 0 && lastmillis - d->lastaction >= d->gunwait;
return false;
}
bool canshoot(fpsent *d) {
return !d->ai->becareful && d->ammo[d->gunselect] > 0 && lastmillis - d->lastaction >= d->gunwait;
}
- bool hastarget(fpsent *d, aistate &b, fpsent *e, float yaw, float pitch, float dist) {
+ bool hastarget(fpsent *d, float yaw, float pitch, float dist) {
// add margins of error
- if(weaprange(d, d->gunselect, dist) || (d->skill <= 100 && !rnd(d->skill))) {
+ if(weaprange(d->gunselect, dist) || (d->skill <= 100 && !rnd(d->skill))) {
if(d->gunselect == GUN_FIST) return true;
float skew = clamp(float(lastmillis-d->ai->enemymillis)/float((d->skill*guns[d->gunselect].attackdelay/200.f)), 0.f, guns[d->gunselect].projspeed ? 0.25f : 1e16f),
offy = yaw-d->yaw, offp = pitch-d->pitch;
@@ -95,6 +95,7 @@ namespace ai {
if(d->ai) DELETEP(d->ai);
}
void init(fpsent *d, int at, int ocn, int sk, int bn, int pm, const char *name, const char *team) {
+ (void) bn; (void) pm;
loadwaypoints();
fpsent *o = newclient(ocn);
d->aitype = at;
@@ -194,7 +195,7 @@ namespace ai {
if(d->skill <= 100) return d->health <= (111-d->skill)/4;
return false;
}
- bool enemy(fpsent *d, aistate &b, const vec &pos, float guard = SIGHTMIN, int pursue = 0) {
+ bool enemy(fpsent *d, aistate &b, float guard = SIGHTMIN, int pursue = 0) {
fpsent *t = NULL;
vec dp = d->headpos();
float mindist = guard*guard, bestdist = 1e16f;
@@ -232,7 +233,7 @@ namespace ai {
return true;
}
bool defend(fpsent *d, aistate &b, const vec &pos, float guard, float wander, int walk) {
- bool hasenemy = enemy(d, b, pos, wander, d->gunselect == GUN_FIST ? 1 : 0);
+ bool hasenemy = enemy(d, b, wander, d->gunselect == GUN_FIST ? 1 : 0);
if(!walk) {
if(d->feetpos().squaredist(pos) <= guard*guard) {
b.idle = hasenemy ? 2 : 1;
@@ -288,19 +289,7 @@ namespace ai {
if(d->ammo[GUN_GL] > 5) return true;
return false;
}
- void assist(fpsent *d, aistate &b, vector<interest> &interests, bool all, bool force) {
- loopv(players) {
- fpsent *e = players[i];
- if(e == d || (!all && e->aitype != AI_NONE) || !isteam(d->team, e->team)) continue;
- interest &n = interests.add();
- n.state = AI_S_DEFEND;
- n.node = e->lastnode;
- n.target = e->clientnum;
- n.targtype = AI_T_PLAYER;
- n.score = e->o.squaredist(d->o)/(hasgoodammo(d) ? 1e8f : (force ? 1e4f : 1e2f));
- }
- }
- static void tryitem(fpsent *d, extentity &e, int id, aistate &b, vector<interest> &interests, bool force = false) {
+ static void tryitem(fpsent *d, extentity &e, int id, vector<interest> &interests) {
float score = 0;
switch(e.type) {
case I_HEALTH:
@@ -330,18 +319,18 @@ namespace ai {
n.node = closestwaypoint(e.o, SIGHTMIN, true);
n.target = id;
n.targtype = AI_T_ENTITY;
- n.score = d->feetpos().squaredist(e.o)/(force ? -1 : score);
+ n.score = d->feetpos().squaredist(e.o)/score;
}
}
- void items(fpsent *d, aistate &b, vector<interest> &interests, bool force = false) {
+ void items(fpsent *d, vector<interest> &interests) {
loopv(entities::ents) {
extentity &e = *(extentity *)entities::ents[i];
if(!e.spawned() || e.nopickup() || !d->canpickup(e.type)) continue;
- tryitem(d, e, i, b, interests, force);
+ tryitem(d, e, i, interests);
}
}
static vector<int> targets;
- bool parseinterests(fpsent *d, aistate &b, vector<interest> &interests, bool override, bool ignore) {
+ bool parseinterests(fpsent *d, aistate &b, vector<interest> &interests, bool ignore) {
while(!interests.empty()) {
int q = interests.length()-1;
loopi(interests.length()-1) if(interests[i].score < interests[q].score) q = i;
@@ -362,12 +351,12 @@ namespace ai {
}
return false;
}
- bool find(fpsent *d, aistate &b, bool override = false) {
+ bool find(fpsent *d, aistate &b) {
static vector<interest> interests;
interests.setsize(0);
if(!m_noitems) {
if((!m_noammo && !hasgoodammo(d)) || d->health < min(d->skill - 15, 75))
- items(d, b, interests);
+ items(d, interests);
else {
static vector<int> nearby;
nearby.setsize(0);
@@ -375,36 +364,11 @@ namespace ai {
loopv(nearby) {
int id = nearby[i];
extentity &e = *(extentity *)entities::ents[id];
- if(d->canpickup(e.type)) tryitem(d, e, id, b, interests);
- }
- }
- }
- if(m_teammode) assist(d, b, interests);
- return parseinterests(d, b, interests, override);
- }
- bool findassist(fpsent *d, aistate &b, bool override = false) {
- static vector<interest> interests;
- interests.setsize(0);
- assist(d, b, interests);
- while(!interests.empty()) {
- int q = interests.length()-1;
- loopi(interests.length()-1) if(interests[i].score < interests[q].score) q = i;
- interest n = interests.removeunordered(q);
- bool proceed = true;
- switch(n.state) {
- case AI_S_DEFEND: { // don't get into herds {
- int members = 0;
- proceed = !checkothers(targets, d, n.state, n.targtype, n.target, true, &members) && members > 1;
- break;
+ if(d->canpickup(e.type)) tryitem(d, e, id, interests);
}
- default: break;
- }
- if(proceed && makeroute(d, b, n.node)) {
- d->ai->switchstate(b, n.state, n.targtype, n.target);
- return true;
}
}
- return false;
+ return parseinterests(d, b, interests);
}
void damaged(fpsent *d, fpsent *e) {
if(d->ai && canmove(d) && targetable(d, e)) { // see if this ai is interested in a grudge {
@@ -442,7 +406,7 @@ namespace ai {
void spawned(fpsent *d) {
if(d->ai) setup(d);
}
- void killed(fpsent *d, fpsent *e) {
+ void killed(fpsent *d) {
if(d->ai) d->ai->reset();
}
void itemspawned(int ent) {
@@ -595,7 +559,7 @@ namespace ai {
}
return -1;
}
- bool anynode(fpsent *d, aistate &b, int len = NUMPREVNODES) {
+ bool anynode(fpsent *d, int len = NUMPREVNODES) {
if(iswaypoint(d->lastnode)) loopk(2) {
d->ai->clear(k ? true : false);
int n = randomlink(d, d->lastnode);
@@ -662,7 +626,7 @@ namespace ai {
}
}
b.override = false;
- return anynode(d, b);
+ return anynode(d);
}
void jumpto(fpsent *d, aistate &b, const vec &pos) {
vec off = vec(pos).sub(d->feetpos()), dir(off.x, off.y, 0);
@@ -797,7 +761,7 @@ namespace ai {
}
scaleyawpitch(d->yaw, d->pitch, yaw, pitch, frame, sskew);
if(insight || quick) {
- if(canshoot(d, e) && hastarget(d, b, e, yaw, pitch, dp.squaredist(ep))) {
+ if(canshoot(d, e) && hastarget(d, yaw, pitch, dp.squaredist(ep))) {
d->attacking = true;
d->ai->lastaction = lastmillis;
result = 3;
@@ -862,7 +826,7 @@ namespace ai {
if(targetable(d, e)) {
vec ep = getaimpos(d, e);
float dist = ep.squaredist(d->headpos());
- if(weaprange(d, weap, dist)) return true;
+ if(weaprange(weap, dist)) return true;
}
return false;
}
@@ -882,7 +846,7 @@ namespace ai {
}
return process(d, b) >= 2;
}
- void timeouts(fpsent *d, aistate &b) {
+ void timeouts(fpsent *d) {
if(d->blocked) {
d->ai->blocktime += lastmillis-d->ai->lastrun;
if(d->ai->blocktime > (d->ai->blockseq+1)*1000) {
@@ -931,7 +895,7 @@ namespace ai {
}
}
}
- void logic(fpsent *d, aistate &b, bool run) {
+ void logic(fpsent *d, aistate &b) {
bool allowmove = canmove(d) && b.type != AI_S_WAIT;
if(d->state != CS_ALIVE || !allowmove) d->stopmoving();
if(d->state == CS_ALIVE) {
@@ -942,7 +906,7 @@ namespace ai {
if(!intermission) {
if(d->ragdoll) cleanragdoll(d);
moveplayer(d, 10, true);
- if(allowmove && !b.idle) timeouts(d, b);
+ if(allowmove && !b.idle) timeouts(d);
if(d->quadmillis) entities::checkquad(curtime, d);
entities::checkitems(d);
}
@@ -1006,7 +970,7 @@ namespace ai {
}
}
}
- logic(d, c, run);
+ logic(d, c);
break;
}
if(d->ai->trywipe) d->ai->wipe();