diff options
| author | xolatile | 2025-08-10 00:19:46 +0200 |
|---|---|---|
| committer | xolatile | 2025-08-10 00:19:46 +0200 |
| commit | 757096e7df15c14b9b10352fa91663483f9e34f8 (patch) | |
| tree | dcad789d0abd8be76463277dc01bf32c4e6a527b /src/fpsgame/ai.cpp | |
| parent | b2c89d7060e99a36c8c7ac897b7386686c74deac (diff) | |
| download | xolatile-badassbug-757096e7df15c14b9b10352fa91663483f9e34f8.tar.xz xolatile-badassbug-757096e7df15c14b9b10352fa91663483f9e34f8.tar.zst | |
all
Diffstat (limited to 'src/fpsgame/ai.cpp')
| -rw-r--r-- | src/fpsgame/ai.cpp | 86 |
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(); |
