void RubbleLimit(string cname, float limit, void(entity) deleteproc)
{
- entity e;
- entity oldest;
- float c;
- float oldesttime;
-
// remove rubble of the same type if it's at the limit
// remove multiple rubble if the limit has been decreased
while (1)
{
- e = findchain(classname, cname);
- if (e == NULL) break;
// walk the list and count the entities, find the oldest
// initialize our search with the first entity
- c = 1;
- oldest = e;
- oldesttime = e.creationtime;
- e = e.chain;
+ int c = 0;
+ entity oldest = NULL;
+ float oldesttime = 0;
// compare to all other matching entities
- while (e)
+ FOREACH_ENTITY_CLASS(cname, true,
{
- c = c + 1;
- if (oldesttime > e.creationtime)
+ ++c;
+ if(!oldest || oldesttime > it.creationtime)
{
- oldesttime = e.creationtime;
- oldest = e;
+ oldest = it;
+ oldesttime = it.creationtime;
}
- e = e.chain;
- }
+ });
// stop if there are less than the limit already
if (c <= limit) break;
}
ons_ControlPoint_UpdateSprite(l);
}
- l = findchain(classname, "ons_captureshield");
- while(l)
+ FOREACH_ENTITY_CLASS("ons_captureshield", true,
{
- l.team = l.enemy.team;
- l.colormap = l.enemy.colormap;
- l = l.chain;
- }
+ it.team = it.enemy.team;
+ it.colormap = it.enemy.colormap;
+ });
}
void havocbot_goalrating_ons_offenseitems(entity this, float ratingscale, vector org, float sradius)
{
- entity head;
- float t, c;
bool needarmor = false, needweapons = false;
// Needs armor/health?
needarmor = true;
// Needs weapons?
- c = 0;
+ int c = 0;
FOREACH(Weapons, it != WEP_Null, {
if(this.weapons & (it.m_wepset))
if(++c >= 4)
LOG_DEBUG(strcat(this.netname, " needs armor ", ftos(needarmor) , "\n"));
// See what is around
- head = findchainfloat(bot_pickup, true);
- while (head)
+ FOREACH_ENTITY_FLOAT(bot_pickup, true,
{
// gather health and armor only
- if (head.solid)
- if ( ((head.health || head.armorvalue) && needarmor) || (head.weapons && needweapons ) )
- if (vdist(head.origin - org, <, sradius))
+ if (it.solid)
+ if ( ((it.health || it.armorvalue) && needarmor) || (it.weapons && needweapons ) )
+ if (vdist(it.origin - org, <, sradius))
{
- t = head.bot_pickupevalfunc(this, head);
+ int t = it.bot_pickupevalfunc(this, it);
if (t > 0)
- navigation_routerating(this, head, t * ratingscale, 500);
+ navigation_routerating(this, it, t * ratingscale, 500);
}
- head = head.chain;
- }
+ });
}
void havocbot_role_ons_setrole(entity this, int role)
*/
entity ons_Nearest_ControlPoint(entity this, vector pos, float max_dist)
{
- entity tmp_entity, closest_target = NULL;
- tmp_entity = findchain(classname, "onslaught_controlpoint");
- while(tmp_entity)
+ entity closest_target = NULL;
+ FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
{
- if(SAME_TEAM(tmp_entity, this))
- if(tmp_entity.iscaptured)
- if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <=, max_dist))
- if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
- closest_target = tmp_entity;
- tmp_entity = tmp_entity.chain;
- }
- tmp_entity = findchain(classname, "onslaught_generator");
- while(tmp_entity)
+ if(SAME_TEAM(it, this))
+ if(it.iscaptured)
+ if(max_dist <= 0 || vdist(it.origin - pos, <=, max_dist))
+ if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+ closest_target = it;
+ });
+ FOREACH_ENTITY_CLASS("onslaught_generator", true,
{
- if(SAME_TEAM(tmp_entity, this))
- if(max_dist <= 0 || vdist(tmp_entity.origin - pos, <, max_dist))
- if(vlen2(tmp_entity.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
- closest_target = tmp_entity;
- tmp_entity = tmp_entity.chain;
- }
+ if(SAME_TEAM(it, this))
+ if(max_dist <= 0 || vdist(it.origin - pos, <, max_dist))
+ if(vlen2(it.origin - pos) <= vlen2(closest_target.origin - pos) || closest_target == NULL)
+ closest_target = it;
+ });
return closest_target;
}
*/
entity ons_Nearest_ControlPoint_2D(entity this, vector pos, float max_dist)
{
- entity tmp_entity, closest_target = NULL;
+ entity closest_target = NULL;
vector delta;
float smallest_distance = 0, distance;
- tmp_entity = findchain(classname, "onslaught_controlpoint");
- while(tmp_entity)
+ FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
{
- delta = tmp_entity.origin - pos;
+ delta = it.origin - pos;
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(tmp_entity, this))
- if(tmp_entity.iscaptured)
+ if(SAME_TEAM(it, this))
+ if(it.iscaptured)
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == NULL || distance <= smallest_distance )
{
- closest_target = tmp_entity;
+ closest_target = it;
smallest_distance = distance;
}
-
- tmp_entity = tmp_entity.chain;
- }
- tmp_entity = findchain(classname, "onslaught_generator");
- while(tmp_entity)
+ });
+ FOREACH_ENTITY_CLASS("onslaught_generator", true,
{
- delta = tmp_entity.origin - pos;
+ delta = it.origin - pos;
delta_z = 0;
distance = vlen(delta);
- if(SAME_TEAM(tmp_entity, this))
+ if(SAME_TEAM(it, this))
if(max_dist <= 0 || distance <= max_dist)
if(closest_target == NULL || distance <= smallest_distance )
{
- closest_target = tmp_entity;
+ closest_target = it;
smallest_distance = distance;
}
-
- tmp_entity = tmp_entity.chain;
- }
+ });
return closest_target;
}
*/
int ons_Count_SelfControlPoints(entity this)
{
- entity tmp_entity;
- tmp_entity = findchain(classname, "onslaught_controlpoint");
int n = 0;
- while(tmp_entity)
+ FOREACH_ENTITY_CLASS("onslaught_controlpoint", true,
{
- if(SAME_TEAM(tmp_entity, this))
- if(tmp_entity.iscaptured)
+ if(SAME_TEAM(it, this))
+ if(it.iscaptured)
n++;
- tmp_entity = tmp_entity.chain;
- }
- tmp_entity = findchain(classname, "onslaught_generator");
- while(tmp_entity)
+ });
+ FOREACH_ENTITY_CLASS("onslaught_generator", true,
{
- if(SAME_TEAM(tmp_entity, this))
+ if(SAME_TEAM(it, this))
n++;
- tmp_entity = tmp_entity.chain;
- }
+ });
return n;
}
}
- e = findchainfloat(railgunhit, 1);
- while (e) {
- e.railgunhit = 0;
- e = e.chain;
- }
-
+ FOREACH_ENTITY_FLOAT(railgunhit, 1,
+ {
+ it.railgunhit = 0;
+ });
}
}
void raptor_flare_think(entity this)
{
this.nextthink = time + 0.1;
- entity _missile = findchainentity(enemy, this.owner);
- while(_missile)
+ FOREACH_ENTITY_ENT(enemy, this.owner,
{
- if(_missile.flags & FL_PROJECTILE)
- if(vdist(this.origin - _missile.origin, <, autocvar_g_vehicle_raptor_flare_range))
+ if(it.flags & FL_PROJECTILE)
+ if(vdist(this.origin - it.origin, <, autocvar_g_vehicle_raptor_flare_range))
if(random() > autocvar_g_vehicle_raptor_flare_chase)
- _missile.enemy = this;
- _missile = _missile.chain;
- }
+ it.enemy = this;
+ });
if(this.tur_impacttime < time)
remove(this);
void spiderbot_guide_release(entity this)
{
- entity rkt;
- rkt = findchainentity(realowner, this.owner);
- if(!rkt)
- return;
-
- crosshair_trace(this.owner);
- while(rkt)
+ FOREACH_ENTITY_ENT(realowner, this.owner,
{
- if(getthink(rkt) == spiderbot_rocket_guided)
+ if(i == 0) // something exists, let's trace!
+ crosshair_trace(this.owner);
+
+ if(getthink(it) == spiderbot_rocket_guided)
{
- rkt.pos1 = trace_endpos;
- setthink(rkt, spiderbot_rocket_unguided);
+ it.pos1 = trace_endpos;
+ setthink(it, spiderbot_rocket_unguided);
}
- rkt = rkt.chain;
- }
+ });
}
float spiberbot_calcartillery_flighttime;
if(skill >= 2) // skill 0 and 1 bots won't detonate rockets!
{
// decide whether to detonate rockets
- entity targetlist, targ;
- float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+ float edgedamage, coredamage, edgeradius, recipricoledgeradius;
float selfdamage, teamdamage, enemydamage;
edgedamage = WEP_CVAR(devastator, edgedamage);
coredamage = WEP_CVAR(devastator, damage);
selfdamage = 0;
teamdamage = 0;
enemydamage = 0;
- targetlist = findchainfloat(bot_attack, true);
FOREACH_ENTITY_ENT(realowner, actor,
{
if(it.classname != "rocket") continue;
- targ = targetlist;
- while(targ)
+ entity rocket = it;
+ FOREACH_ENTITY_FLOAT(bot_attack, true,
{
- d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - it.origin);
- d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
- // count potential damage according to type of target
- if(targ == actor)
- selfdamage = selfdamage + d;
- else if(targ.team == actor.team && teamplay)
- teamdamage = teamdamage + d;
- else if(bot_shouldattack(actor, targ))
- enemydamage = enemydamage + d;
- targ = targ.chain;
- }
+ float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - rocket.origin);
+ d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+ // count potential damage according to type of target
+ if(it == actor)
+ selfdamage = selfdamage + d;
+ else if(SAME_TEAM(it, actor))
+ teamdamage = teamdamage + d;
+ else if(bot_shouldattack(actor, it))
+ enemydamage = enemydamage + d;
+ });
});
float desirabledamage;
desirabledamage = enemydamage;
if(teamplay && actor.team)
desirabledamage = desirabledamage - teamdamage;
+ makevectors(actor.v_angle);
FOREACH_ENTITY_ENT(realowner, actor,
{
if(it.classname != "rocket") continue;
- makevectors(it.v_angle);
- targ = targetlist;
if(skill > 9) // normal players only do this for the target they are tracking
{
- targ = targetlist;
- while(targ)
- {
- if(
- (v_forward * normalize(it.origin - targ.origin)< 0.1)
- && desirabledamage > 0.1*coredamage
- ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- targ = targ.chain;
- }
- }
- else
- {
- float distance; distance= bound(300,vlen(actor.origin-actor.enemy.origin),30000);
+ entity rocket = it;
+ FOREACH_ENTITY_FLOAT(bot_attack, true,
+ {
+ if((v_forward * normalize(rocket.origin - it.origin) < 0.1)
+ && desirabledamage > 0.1 * coredamage
+ ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+ });
+ }
+ else
+ {
//As the distance gets larger, a correct detonation gets near imposible
//Bots are assumed to use the rocket spawnfunc_light to see if the rocket gets near a player
- if(v_forward * normalize(it.origin - actor.enemy.origin)< 0.1)
- if(IS_PLAYER(actor.enemy))
- if(desirabledamage >= 0.1*coredamage)
- if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
- PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
- }
+ if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1)
+ && IS_PLAYER(actor.enemy)
+ && (desirabledamage >= 0.1 * coredamage)
+ )
+ {
+ float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
+ if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
+ PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+ }
+ }
});
// if we would be doing at X percent of the core damage, detonate it
// but don't fire a new shot at the same time!
if(skill >= 2) // skill 0 and 1 bots won't detonate mines!
{
// decide whether to detonate mines
- entity targetlist, targ;
- float edgedamage, coredamage, edgeradius, recipricoledgeradius, d;
+ float edgedamage, coredamage, edgeradius, recipricoledgeradius;
float selfdamage, teamdamage, enemydamage;
edgedamage = WEP_CVAR(minelayer, edgedamage);
coredamage = WEP_CVAR(minelayer, damage);
selfdamage = 0;
teamdamage = 0;
enemydamage = 0;
- targetlist = findchainfloat(bot_attack, true);
- entity mine = find(NULL, classname, "mine");
- while(mine)
+
+ FOREACH_ENTITY_ENT(realowner, actor,
{
- if(mine.realowner != actor)
- {
- mine = find(mine, classname, "mine");
- continue;
- }
- targ = targetlist;
- while(targ)
- {
- d = vlen(targ.origin + (targ.mins + targ.maxs) * 0.5 - mine.origin);
- d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
+ if(it.classname != "mine") continue;
+
+ entity mine = it;
+ FOREACH_ENTITY_FLOAT(bot_attack, true,
+ {
+ float d = vlen(it.origin + (it.mins + it.maxs) * 0.5 - mine.origin);
+ d = bound(0, edgedamage + (coredamage - edgedamage) * sqrt(1 - d * recipricoledgeradius), 10000);
// count potential damage according to type of target
- if(targ == actor)
+ if(it == actor)
selfdamage = selfdamage + d;
- else if(targ.team == actor.team && teamplay)
+ else if(SAME_TEAM(it, actor))
teamdamage = teamdamage + d;
- else if(bot_shouldattack(actor, targ))
+ else if(bot_shouldattack(actor, it))
enemydamage = enemydamage + d;
- targ = targ.chain;
- }
- mine = find(mine, classname, "mine");
- }
+ });
+ });
+
float desirabledamage;
desirabledamage = enemydamage;
if(time > actor.invincible_finished && time > actor.spawnshieldtime)
if(teamplay && actor.team)
desirabledamage = desirabledamage - teamdamage;
- mine = find(NULL, classname, "mine");
- while(mine)
+ makevectors(actor.v_angle);
+ FOREACH_ENTITY_ENT(realowner, actor,
{
- if(mine.realowner != actor)
- {
- mine = find(mine, classname, "mine");
- continue;
- }
- makevectors(mine.v_angle);
- targ = targetlist;
+ if(it.classname != "mine") continue;
+
if(skill > 9) // normal players only do this for the target they are tracking
{
- targ = targetlist;
- while(targ)
- {
- if(
- (v_forward * normalize(mine.origin - targ.origin)< 0.1)
- && desirabledamage > 0.1*coredamage
- ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- targ = targ.chain;
- }
- }else{
- float distance; distance= bound(300,vlen(actor.origin-actor.enemy.origin),30000);
+ entity mine = it;
+ FOREACH_ENTITY_FLOAT(bot_attack, true,
+ {
+ if((v_forward * normalize(mine.origin - it.origin) < 0.1)
+ && desirabledamage > 0.1 * coredamage
+ ) PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+ });
+ }
+ else
+ {
//As the distance gets larger, a correct detonation gets near imposible
//Bots are assumed to use the mine spawnfunc_light to see if the mine gets near a player
- if(v_forward * normalize(mine.origin - actor.enemy.origin)< 0.1)
- if(IS_PLAYER(actor.enemy))
- if(desirabledamage >= 0.1*coredamage)
- if(random()/distance*300 > frametime*bound(0,(10-skill)*0.2,1))
- PHYS_INPUT_BUTTON_ATCK2(actor) = true;
- // dprint(ftos(random()/distance*300),">");dprint(ftos(frametime*bound(0,(10-skill)*0.2,1)),"\n");
- }
-
- mine = find(mine, classname, "mine");
- }
+ if((v_forward * normalize(it.origin - actor.enemy.origin) < 0.1)
+ && IS_PLAYER(actor.enemy)
+ && (desirabledamage >= 0.1 * coredamage)
+ )
+ {
+ float distance = bound(300, vlen(actor.origin - actor.enemy.origin), 30000);
+ if(random() / distance * 300 > frametime * bound(0, (10 - skill) * 0.2, 1))
+ PHYS_INPUT_BUTTON_ATCK2(actor) = true;
+ }
+ }
+ });
+
// if we would be doing at X percent of the core damage, detonate it
// but don't fire a new shot at the same time!
if(desirabledamage >= 0.75 * coredamage) //this should do group damage in rare fortunate events
void bot_relinkplayerlist()
{
- entity e;
- entity prevbot;
player_count = 0;
currentbots = 0;
- player_list = e = findchainflags(flags, FL_CLIENT);
bot_list = NULL;
- prevbot = NULL;
- while (e)
+
+ entity prevbot = NULL;
+ FOREACH_CLIENT(true,
{
- player_count = player_count + 1;
- e.nextplayer = e.chain;
- if (IS_BOT_CLIENT(e))
+ ++player_count;
+
+ if(IS_BOT_CLIENT(it))
{
- if (prevbot)
- prevbot.nextbot = e;
+ if(prevbot)
+ prevbot.nextbot = it;
else
{
- bot_list = e;
+ bot_list = it;
bot_list.nextbot = NULL;
}
- prevbot = e;
- currentbots = currentbots + 1;
+ prevbot = it;
+ ++currentbots;
}
- e = e.chain;
- }
+ });
LOG_TRACE(strcat("relink: ", ftos(currentbots), " bots seen.\n"));
bot_strategytoken = bot_list;
bot_strategytoken_taken = true;
void bot_removefromlargestteam()
{
- float besttime, bestcount, thiscount;
- entity best, head;
CheckAllowedTeams(NULL);
GetTeamCounts(NULL);
- head = findchainfloat(isbot, true);
- if (!head)
- return;
- best = head;
- besttime = head.createdtime;
- bestcount = 0;
- while (head)
+
+ entity best = NULL;
+ float besttime = 0;
+ int bestcount = 0;
+
+ int bcount = 0;
+ FOREACH_ENTITY_FLOAT(isbot, true,
{
- if(head.team == NUM_TEAM_1)
- thiscount = c1;
- else if(head.team == NUM_TEAM_2)
- thiscount = c2;
- else if(head.team == NUM_TEAM_3)
- thiscount = c3;
- else if(head.team == NUM_TEAM_4)
- thiscount = c4;
- else
- thiscount = 0;
- if (thiscount > bestcount)
+ ++bcount;
+
+ if(!best)
+ {
+ best = it;
+ besttime = it.createdtime;
+ }
+
+ int thiscount = 0;
+
+ switch(it.team)
+ {
+ case NUM_TEAM_1: thiscount = c1; break;
+ case NUM_TEAM_2: thiscount = c2; break;
+ case NUM_TEAM_3: thiscount = c3; break;
+ case NUM_TEAM_4: thiscount = c4; break;
+ }
+
+ if(thiscount > bestcount)
{
bestcount = thiscount;
- besttime = head.createdtime;
- best = head;
+ besttime = it.createdtime;
+ best = it;
}
- else if (thiscount == bestcount && besttime < head.createdtime)
+ else if(thiscount == bestcount && besttime < it.createdtime)
{
- besttime = head.createdtime;
- best = head;
+ besttime = it.createdtime;
+ best = it;
}
- head = head.chain;
- }
+ });
+ if(!bcount)
+ return; // no bots to remove
currentbots = currentbots - 1;
dropclient(best);
}
void bot_removenewest()
{
- float besttime;
- entity best, head;
-
if(teamplay)
{
bot_removefromlargestteam();
return;
}
- head = findchainfloat(isbot, true);
- if (!head)
- return;
- best = head;
- besttime = head.createdtime;
- while (head)
+ float besttime = 0;
+ entity best = NULL;
+ int bcount = 0;
+
+ FOREACH_ENTITY_FLOAT(isbot, true,
{
- if (besttime < head.createdtime)
+ ++bcount;
+
+ if(!best)
{
- besttime = head.createdtime;
- best = head;
+ best = it;
+ besttime = it.createdtime;
}
- head = head.chain;
- }
+
+ if(besttime < it.createdtime)
+ {
+ besttime = it.createdtime;
+ best = it;
+ }
+ });
+
+ if(!bcount)
+ return; // no bots to remove
+
currentbots = currentbots - 1;
dropclient(best);
}
else
{
// TODO: Make this check cleaner
- entity wp = findchain(classname, "waypoint");
- if(time - wp.nextthink > 10)
+ FOREACH_ENTITY_CLASS("waypoint", time - it.nextthink > 10,
+ {
waypoint_save_links();
+ });
}
}
else
float bot_weapons_close[Weapons_MAX];
entity bot_list;
-entity player_list;
.entity nextbot;
-.entity nextplayer;
.string cleanname;
.string netname_freeme;
.string playermodel_freeme;
// TODO: tracewalk() should take care of this job (better path finding under water)
// if we don't have a goal and we're under water look for a waypoint near the "shore" and push it
if(IS_DEAD(this))
- if(this.goalcurrent==NULL)
- if(this.waterlevel==WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
+ if(!this.goalcurrent)
+ if(this.waterlevel == WATERLEVEL_SWIMMING || (this.aistatus & AI_STATUS_OUT_WATER))
{
// Look for the closest waypoint out of water
- entity newgoal, head;
- float bestdistance, distance;
-
- newgoal = NULL;
- bestdistance = 10000;
- for (head = findchain(classname, "waypoint"); head; head = head.chain)
+ entity newgoal = NULL;
+ FOREACH_ENTITY_CLASS("waypoint", vdist(it.origin - this.origin, <, 10000),
{
- distance = vlen(head.origin - this.origin);
- if(distance>10000)
- continue;
-
- if(head.origin.z < this.origin.z)
+ if(it.origin.z < this.origin.z)
continue;
- if(head.origin.z - this.origin.z - this.view_ofs.z > 100)
+ if(it.origin.z - this.origin.z - this.view_ofs.z > 100)
continue;
- if (pointcontents(head.origin + head.maxs + '0 0 1') != CONTENT_EMPTY)
+ if (pointcontents(it.origin + it.maxs + '0 0 1') != CONTENT_EMPTY)
continue;
- traceline(this.origin + this.view_ofs , head.origin, true, head);
+ traceline(this.origin + this.view_ofs, ((it.absmin + it.absmax) * 0.5), true, this);
- if(trace_fraction<1)
+ if(trace_fraction < 1)
continue;
- if(distance<bestdistance)
- {
- newgoal = head;
- bestdistance = distance;
- }
- }
+ if(!newgoal || vlen2(it.origin - this.origin) < vlen2(newgoal.origin - this.origin))
+ newgoal = it;
+ });
if(newgoal)
{
{
if(fabs(this.velocity.z)<50)
{
- entity head, newgoal = NULL;
- float distance, bestdistance = 0;
-
- for (head = findchain(classname, "waypoint"); head; head = head.chain)
+ entity newgoal = NULL;
+ FOREACH_ENTITY_CLASS("waypoint", vdist(it.origin - this.origin, <, 1000),
{
+ traceline(this.origin + this.view_ofs, ((it.absmin + it.absmax) * 0.5), true, this);
- distance = vlen(head.origin - this.origin);
- if(distance>1000)
+ if(trace_fraction < 1)
continue;
- traceline(this.origin + this.view_ofs , ( ( head.absmin + head.absmax ) * 0.5 ), true, NULL);
-
- if(trace_fraction<1)
- continue;
-
- if(distance>bestdistance)
- {
- newgoal = head;
- bestdistance = distance;
- }
- }
+ if(!newgoal || vlen2(it.origin - this.origin) > vlen2(newgoal.origin - this.origin))
+ newgoal = it;
+ });
if(newgoal)
{
void havocbot_goalrating_items(entity this, float ratingscale, vector org, float sradius)
{
- entity head;
- float rating, d, discard, distance, friend_distance, enemy_distance;
+ float rating, d, discard, friend_distance, enemy_distance;
vector o;
ratingscale = ratingscale * 0.0001; // items are rated around 10000 already
- head = findchainfloat(bot_pickup, true);
- while (head)
+ FOREACH_ENTITY_FLOAT(bot_pickup, true,
{
- o = (head.absmin + head.absmax) * 0.5;
- distance = vlen(o - org);
+ o = (it.absmin + it.absmax) * 0.5;
friend_distance = 10000; enemy_distance = 10000;
rating = 0;
- if(!head.solid || distance > sradius || (head == this.ignoregoal && time < this.ignoregoaltime) )
- {
- head = head.chain;
+ if(!it.solid || vdist(o - org, >, sradius) || (it == this.ignoregoal && time < this.ignoregoaltime) )
continue;
- }
// Check if the item can be picked up safely
- if(head.classname == "droppedweapon")
+ if(it.classname == "droppedweapon")
{
traceline(o, o + '0 0 -1500', true, NULL);
d = pointcontents(trace_endpos + '0 0 1');
if(d & CONTENT_WATER || d & CONTENT_SLIME || d & CONTENT_LAVA)
- {
- head = head.chain;
continue;
- }
- if(tracebox_hits_trigger_hurt(head.origin, head.mins, head.maxs, trace_endpos))
- {
- head = head.chain;
+ if(tracebox_hits_trigger_hurt(it.origin, it.mins, it.maxs, trace_endpos))
continue;
- }
}
else
{
// Ignore items under water
- traceline(head.origin + head.maxs, head.origin + head.maxs, MOVE_NORMAL, head);
+ traceline(it.origin + it.maxs, it.origin + it.maxs, MOVE_NORMAL, it);
if(trace_dpstartcontents & DPCONTENTS_LIQUIDSMASK)
- {
- head = head.chain;
continue;
- }
}
if(teamplay)
{
discard = false;
- FOREACH_CLIENT(IS_PLAYER(it) && it != this && !IS_DEAD(it), LAMBDA(
+ entity picker = it;
+ FOREACH_CLIENT(IS_PLAYER(it) && it != this && !IS_DEAD(it),
+ {
d = vlen(it.origin - o); // distance between player and item
if ( it.team == this.team )
discard = true;
- if( head.health && it.health > this.health )
+ if( picker.health && it.health > this.health )
continue;
- if( head.armorvalue && it.armorvalue > this.armorvalue)
+ if( picker.armorvalue && it.armorvalue > this.armorvalue)
continue;
- if( head.weapons )
- if( head.weapons & ~it.weapons )
+ if( picker.weapons )
+ if( picker.weapons & ~it.weapons )
continue;
- if (head.ammo_shells && it.ammo_shells > this.ammo_shells)
+ if (picker.ammo_shells && it.ammo_shells > this.ammo_shells)
continue;
- if (head.ammo_nails && it.ammo_nails > this.ammo_nails)
+ if (picker.ammo_nails && it.ammo_nails > this.ammo_nails)
continue;
- if (head.ammo_rockets && it.ammo_rockets > this.ammo_rockets)
+ if (picker.ammo_rockets && it.ammo_rockets > this.ammo_rockets)
continue;
- if (head.ammo_cells && it.ammo_cells > this.ammo_cells)
+ if (picker.ammo_cells && it.ammo_cells > this.ammo_cells)
continue;
- if (head.ammo_plasma && it.ammo_plasma > this.ammo_plasma)
+ if (picker.ammo_plasma && it.ammo_plasma > this.ammo_plasma)
continue;
discard = false;
if( d < enemy_distance )
enemy_distance = d;
}
- ));
+ });
// Rate the item only if no one needs it, or if an enemy is closer to it
- if ( (enemy_distance < friend_distance && distance < enemy_distance) ||
+ if ( (enemy_distance < friend_distance && vdist(o - org, <, enemy_distance)) ||
(friend_distance > autocvar_bot_ai_friends_aware_pickup_radius ) || !discard )
- rating = head.bot_pickupevalfunc(this, head);
+ rating = it.bot_pickupevalfunc(this, it);
}
else
- rating = head.bot_pickupevalfunc(this, head);
+ rating = it.bot_pickupevalfunc(this, it);
if(rating > 0)
- navigation_routerating(this, head, rating * ratingscale, 2000);
- head = head.chain;
- }
+ navigation_routerating(this, it, rating * ratingscale, 2000);
+ });
}
void havocbot_goalrating_controlpoints(entity this, float ratingscale, vector org, float sradius)
{
- entity head;
- head = findchain(classname, "dom_controlpoint");
- while (head)
+ FOREACH_ENTITY_CLASS("dom_controlpoint", vdist((((it.absmin + it.absmax) * 0.5) - org), <, sradius),
{
- if(vdist((((head.absmin + head.absmax) * 0.5) - org), <, sradius))
- {
- if(head.cnt > -1) // this is just being fought for
- navigation_routerating(this, head, ratingscale, 5000);
- else if(head.goalentity.cnt == 0) // unclaimed point
- navigation_routerating(this, head, ratingscale * 0.5, 5000);
- else if(head.goalentity.team != this.team) // other team's point
- navigation_routerating(this, head, ratingscale * 0.2, 5000);
- }
- head = head.chain;
- }
+ if(it.cnt > -1) // this is just being fought
+ navigation_routerating(this, it, ratingscale, 5000);
+ else if(it.goalentity.cnt == 0) // unclaimed
+ navigation_routerating(this, it, ratingscale * 0.5, 5000);
+ else if(it.goalentity.team != this.team) // other team's point
+ navigation_routerating(this, it, ratingscale * 0.2, 5000);
+ });
}
void havocbot_goalrating_enemyplayers(entity this, float ratingscale, vector org, float sradius)
entity w, wp, waylist;
float searching, cost, cost2;
vector p;
- w = waylist = findchain(classname, "waypoint");
+ w = waylist = findchain(classname, "waypoint"); // TODO
while (w)
{
w.wpconsidered = false;
void botframe_updatedangerousobjects(float maxupdate)
{
- entity head, bot_dodgelist;
vector m1, m2, v, o;
float c, d, danger;
c = 0;
- bot_dodgelist = findchainfloat(bot_dodge, true);
- botframe_dangerwaypoint = find(botframe_dangerwaypoint, classname, "waypoint");
- while (botframe_dangerwaypoint != NULL)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
danger = 0;
- m1 = botframe_dangerwaypoint.mins;
- m2 = botframe_dangerwaypoint.maxs;
- head = bot_dodgelist;
- while (head)
+ m1 = it.mins;
+ m2 = it.maxs;
+ FOREACH_ENTITY_FLOAT(bot_dodge, true,
{
- v = head.origin;
+ v = it.origin;
v.x = bound(m1_x, v.x, m2_x);
v.y = bound(m1_y, v.y, m2_y);
v.z = bound(m1_z, v.z, m2_z);
- o = (head.absmin + head.absmax) * 0.5;
- d = head.bot_dodgerating - vlen(o - v);
+ o = (it.absmin + it.absmax) * 0.5;
+ d = it.bot_dodgerating - vlen(o - v);
if (d > 0)
{
traceline(o, v, true, NULL);
if (trace_fraction == 1)
danger = danger + d;
}
- head = head.chain;
- }
- botframe_dangerwaypoint.dmg = danger;
+ });
+ it.dmg = danger;
c = c + 1;
if (c >= maxupdate)
break;
- botframe_dangerwaypoint = find(botframe_dangerwaypoint, classname, "waypoint");
- }
+ });
}
void navigation_unstuck(entity this)
vector jumpstepheightvec;
vector stepheightvec;
-entity botframe_dangerwaypoint;
entity navigation_bestgoal;
// stack of current goals (the last one of which may be an item or other
if(!number)
return NULL;
- bot = findchainflags(flags, FL_CLIENT);
+ bot = findchainflags(flags, FL_CLIENT); // TODO: doesn't findchainflags loop backwards through entities?
while (bot)
{
if(IS_BOT_CLIENT(bot))
{
if(!(f & WAYPOINTFLAG_PERSONAL))
{
- for(entity wp = findchain(classname, "waypoint"); wp; wp = wp.chain)
+ FOREACH_ENTITY_CLASS("waypoint", boxesoverlap(m1, m2, it.absmin, it.absmax),
{
- // if a matching spawnfunc_waypoint already exists, don't add a duplicate
- if(boxesoverlap(m1, m2, wp.absmin, wp.absmax))
- return wp;
- }
+ return it;
+ });
}
-
entity w = new(waypoint);
w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
// empties the map of waypoints
void waypoint_removeall()
{
- entity head, next;
- head = findchain(classname, "waypoint");
- while (head)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- next = head.chain;
- remove(head);
- head = next;
- }
+ remove(it);
+ });
}
// tell all waypoints to relink
// (is this useful at all?)
void waypoint_schedulerelinkall()
{
- entity head;
relink_total = relink_walkculled = relink_pvsculled = relink_lengthculled = 0;
- head = findchain(classname, "waypoint");
- while (head)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- waypoint_schedulerelink(head);
- head = head.chain;
- }
+ waypoint_schedulerelink(it);
+ });
}
// Load waypoint links from file
// Save all waypoint links to a file
void waypoint_save_links()
{
- string filename, s;
- float file, c, i;
- entity w, link;
- filename = strcat("maps/", mapname);
- filename = strcat(filename, ".waypoints.cache");
- file = fopen(filename, FILE_WRITE);
+ string filename = sprintf("maps/%s.waypoints.cache", mapname);
+ int file = fopen(filename, FILE_WRITE);
if (file < 0)
{
- LOG_INFO("waypoint links save to ");
- LOG_INFO(filename);
- LOG_INFO(" failed\n");
+ LOG_INFOF("waypoint link save to %s failed\n", filename);
+ return;
}
- c = 0;
- w = findchain(classname, "waypoint");
- while (w)
+
+ int c = 0;
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- for(i=0;i<32;++i)
+ for(int j = 0; j < 32; ++j)
{
- // :S
- link = waypoint_get_link(w, i);
- if(link==NULL)
- continue;
-
- s = strcat(vtos(w.origin), "*", vtos(link.origin), "\n");
- fputs(file, s);
- ++c;
+ entity link = waypoint_get_link(it, j);
+ if(link)
+ {
+ string s = strcat(vtos(it.origin), "*", vtos(link.origin), "\n");
+ fputs(file, s);
+ ++c;
+ }
}
- w = w.chain;
- }
+ });
fclose(file);
botframe_cachedwaypointlinks = true;
- LOG_INFO("saved ");
- LOG_INFO(ftos(c));
- LOG_INFO(" waypoints links to maps/");
- LOG_INFO(mapname);
- LOG_INFO(".waypoints.cache\n");
+ LOG_INFOF("saved %d waypoint links to maps/%s.waypoints.cache\n", c, mapname);
}
// save waypoints to gamedir/data/maps/mapname.waypoints
void waypoint_saveall()
{
- string filename, s;
- float file, c;
- entity w;
- filename = strcat("maps/", mapname);
- filename = strcat(filename, ".waypoints");
- file = fopen(filename, FILE_WRITE);
- if (file >= 0)
+ string filename = sprintf("maps/%s.waypoints", mapname);
+ int file = fopen(filename, FILE_WRITE);
+ if (file < 0)
{
- c = 0;
- w = findchain(classname, "waypoint");
- while (w)
- {
- if (!(w.wpflags & WAYPOINTFLAG_GENERATED))
- {
- s = strcat(vtos(w.origin + w.mins), "\n");
- s = strcat(s, vtos(w.origin + w.maxs));
- s = strcat(s, "\n");
- s = strcat(s, ftos(w.wpflags));
- s = strcat(s, "\n");
- fputs(file, s);
- c = c + 1;
- }
- w = w.chain;
- }
- fclose(file);
- bprint("saved ");
- bprint(ftos(c));
- bprint(" waypoints to maps/");
- bprint(mapname);
- bprint(".waypoints\n");
+ waypoint_save_links(); // save anyway?
+ botframe_loadedforcedlinks = false;
+
+ LOG_INFOF("waypoint links: save to %s failed\n", filename);
+ return;
}
- else
+
+ int c = 0;
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- bprint("waypoint save to ");
- bprint(filename);
- bprint(" failed\n");
- }
+ if(it.wpflags & WAYPOINTFLAG_GENERATED)
+ continue;
+
+ for(int j = 0; j < 32; ++j)
+ {
+ string s;
+ s = strcat(vtos(it.origin + it.mins), "\n");
+ s = strcat(s, vtos(it.origin + it.maxs));
+ s = strcat(s, "\n");
+ s = strcat(s, ftos(it.wpflags));
+ s = strcat(s, "\n");
+ fputs(file, s);
+ ++c;
+ }
+ });
+ fclose(file);
waypoint_save_links();
botframe_loadedforcedlinks = false;
+
+ LOG_INFOF("saved %d waypoints to maps/%s.waypoints\n", c, mapname);
}
// load waypoints from file
void waypoint_spawnforitem_force(entity e, vector org)
{
- entity w;
-
// Fix the waypoint altitude if necessary
org = waypoint_fixorigin(org);
// don't spawn an item spawnfunc_waypoint if it already exists
- w = findchain(classname, "waypoint");
- while (w)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- if (w.wpisbox)
+ if(it.wpisbox)
{
- if (boxesoverlap(org, org, w.absmin, w.absmax))
+ if(boxesoverlap(org, org, it.absmin, it.absmax))
{
- e.nearestwaypoint = w;
+ e.nearestwaypoint = it;
return;
}
}
else
{
- if (vlen(w.origin - org) < 16)
+ if(vdist(it.origin - org, <, 16))
{
- e.nearestwaypoint = w;
+ e.nearestwaypoint = it;
return;
}
}
- w = w.chain;
- }
+ });
+
e.nearestwaypoint = waypoint_spawn(org, org, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_ITEM);
}
IMPULSE(navwaypoint_unreachable)
{
if (!autocvar_g_waypointeditor) return;
- for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- e.colormod = '0.5 0.5 0.5';
- e.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
- }
+ it.colormod = '0.5 0.5 0.5';
+ it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
+ });
entity e2 = navigation_findnearestwaypoint(this, false);
navigation_markroutes(this, e2);
- int i, m;
+ int j, m;
- i = 0;
+ j = 0;
m = 0;
- for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+ FOREACH_ENTITY_CLASS("waypoint", it.wpcost >= 10000000,
{
- if (e.wpcost < 10000000) continue;
- LOG_INFO("unreachable: ", etos(e), " ", vtos(e.origin), "\n");
- e.colormod_z = 8;
- e.effects |= EF_NODEPTHTEST | EF_BLUE;
- ++i;
+ LOG_INFO("unreachable: ", etos(it), " ", vtos(it.origin), "\n");
+ it.colormod_z = 8;
+ it.effects |= EF_NODEPTHTEST | EF_BLUE;
+ ++j;
++m;
- }
- if (i) LOG_INFOF("%d waypoints cannot be reached from here in any way (marked with blue light)\n", i);
+ });
+ if (j) LOG_INFOF("%d waypoints cannot be reached from here in any way (marked with blue light)\n", j);
navigation_markroutes_inverted(e2);
- i = 0;
- for (entity e = findchain(classname, "waypoint"); e; e = e.chain)
+ j = 0;
+ FOREACH_ENTITY_CLASS("waypoint", it.wpcost >= 10000000,
{
- if (e.wpcost < 10000000) continue;
- LOG_INFO("cannot reach me: ", etos(e), " ", vtos(e.origin), "\n");
- e.colormod_x = 8;
- if (!(e.effects & EF_NODEPTHTEST)) // not already reported before
+ LOG_INFO("cannot reach me: ", etos(it), " ", vtos(it.origin), "\n");
+ it.colormod_x = 8;
+ if (!(it.effects & EF_NODEPTHTEST)) // not already reported before
++m;
- e.effects |= EF_NODEPTHTEST | EF_RED;
- ++i;
- }
- if (i) LOG_INFOF("%d waypoints cannot walk to here in any way (marked with red light)\n", i);
+ it.effects |= EF_NODEPTHTEST | EF_RED;
+ ++j;
+ });
+ if (j) LOG_INFOF("%d waypoints cannot walk to here in any way (marked with red light)\n", j);
if (m) LOG_INFOF("%d waypoints have been marked total\n", m);
- i = 0;
- for (entity e = findchain(classname, "info_player_deathmatch"); e; e = e.chain)
+ j = 0;
+ FOREACH_ENTITY_CLASS("info_player_deathmatch", true,
{
- vector org = e.origin;
- tracebox(e.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), e.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
- setorigin(e, trace_endpos);
- if (navigation_findnearestwaypoint(e, false))
+ vector org = it.origin;
+ tracebox(it.origin, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), it.origin - '0 0 512', MOVE_NOMONSTERS, NULL);
+ setorigin(it, trace_endpos);
+ if (navigation_findnearestwaypoint(it, false))
{
- setorigin(e, org);
- e.effects &= ~EF_NODEPTHTEST;
- e.model = "";
+ setorigin(it, org);
+ it.effects &= ~EF_NODEPTHTEST;
+ it.model = "";
}
else
{
- setorigin(e, org);
- LOG_INFO("spawn without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
- e.effects |= EF_NODEPTHTEST;
- _setmodel(e, this.model);
- e.frame = this.frame;
- e.skin = this.skin;
- e.colormod = '8 0.5 8';
- setsize(e, '0 0 0', '0 0 0');
- ++i;
+ setorigin(it, org);
+ LOG_INFO("spawn without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+ it.effects |= EF_NODEPTHTEST;
+ _setmodel(it, this.model);
+ it.frame = this.frame;
+ it.skin = this.skin;
+ it.colormod = '8 0.5 8';
+ setsize(it, '0 0 0', '0 0 0');
+ ++j;
}
- }
- if (i) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", i);
+ });
+ if (j) LOG_INFOF("%d spawnpoints have no nearest waypoint (marked by player model)\n", j);
- i = 0;
- entity start = findchainflags(flags, FL_ITEM);
- for (entity e = start; e; e = e.chain)
+ j = 0;
+ FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
{
- e.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
- e.colormod = '0.5 0.5 0.5';
- }
- for (entity e = start; e; e = e.chain)
+ it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE);
+ it.colormod = '0.5 0.5 0.5';
+ });
+ FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
{
- if (navigation_findnearestwaypoint(e, false)) continue;
- LOG_INFO("item without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
- e.effects |= EF_NODEPTHTEST | EF_RED;
- e.colormod_x = 8;
- ++i;
- }
- if (i) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", i);
+ if (navigation_findnearestwaypoint(it, false)) continue;
+ LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+ it.effects |= EF_NODEPTHTEST | EF_RED;
+ it.colormod_x = 8;
+ ++j;
+ });
+ if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked away from (marked with red light)\n", j);
- i = 0;
- for (entity e = start; e; e = e.chain)
+ j = 0;
+ FOREACH_ENTITY_FLAGS(flags, FL_ITEM,
{
- if (navigation_findnearestwaypoint(e, true)) continue;
- LOG_INFO("item without waypoint: ", etos(e), " ", vtos(e.origin), "\n");
- e.effects |= EF_NODEPTHTEST | EF_BLUE;
- e.colormod_z = 8;
- ++i;
- }
- if (i) LOG_INFOF("%d items have no nearest waypoint and cannot be walked to (marked with blue light)\n", i);
+ if (navigation_findnearestwaypoint(it, true)) continue;
+ LOG_INFO("item without waypoint: ", etos(it), " ", vtos(it.origin), "\n");
+ it.effects |= EF_NODEPTHTEST | EF_BLUE;
+ it.colormod_z = 8;
+ ++j;
+ });
+ if (j) LOG_INFOF("%d items have no nearest waypoint and cannot be walked to (marked with blue light)\n", j);
}
{
traceline_antilag(pl, pl.cursor_trace_start, pl.cursor_trace_start + normalize(pl.cursor_trace_endpos - pl.cursor_trace_start) * MAX_SHOT_DISTANCE, MOVE_NORMAL, pl, ANTILAG_LATENCY(pl));
}
+.bool ctrace_solidchanged;
void crosshair_trace_plusvisibletriggers(entity pl)
{
- entity first;
- entity e;
- first = findchainfloat(solid, SOLID_TRIGGER);
-
- for (e = first; e; e = e.chain)
- if (e.model != "")
- e.solid = SOLID_BSP;
+ FOREACH_ENTITY_FLOAT(solid, SOLID_TRIGGER,
+ {
+ if(it.model != "")
+ {
+ it.solid = SOLID_BSP;
+ it.ctrace_solidchanged = true;
+ }
+ });
crosshair_trace(pl);
- for (e = first; e; e = e.chain)
- e.solid = SOLID_TRIGGER;
+ FOREACH_ENTITY_FLOAT(ctrace_solidchanged, true,
+ {
+ it.solid = SOLID_TRIGGER;
+ it.ctrace_solidchanged = false;
+ });
}
void WarpZone_crosshair_trace(entity pl)
{
// legacy bot code
void havocbot_goalrating_ast_targets(entity this, float ratingscale)
{
- entity ad, best, wp;
- float radius, bestvalue;
- bool found;
- vector p;
-
- ad = findchain(classname, "func_assault_destructible");
-
- for (; ad; ad = ad.chain)
+ FOREACH_ENTITY_CLASS("func_assault_destructible", it.bot_attack,
{
- if (ad.target == "")
- continue;
-
- if (!ad.bot_attack)
+ if (it.target == "")
continue;
- found = false;
- FOREACH_ENTITY_STRING(targetname, ad.target,
+ bool found = false;
+ FOREACH_ENTITY_STRING(targetname, it.target,
{
- if(it.classname == "target_objective_decrease")
+ if(it.classname != "target_objective_decrease")
+ continue;
+
+ if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
{
- if(it.enemy.health > 0 && it.enemy.health < ASSAULT_VALUE_INACTIVE)
- {
- // dprint(etos(ad),"\n");
- found = true;
- break;
- }
+ found = true;
+ break;
}
});
if(!found)
- {
- /// dprint("target not found\n");
continue;
- }
- /// dprint("target #", etos(ad), " found\n");
-
- p = 0.5 * (ad.absmin + ad.absmax);
- // dprint(vtos(ad.origin), " ", vtos(ad.absmin), " ", vtos(ad.absmax),"\n");
- // te_knightspike(p);
- // te_lightning2(NULL, '0 0 0', p);
+ vector p = 0.5 * (it.absmin + it.absmax);
// Find and rate waypoints around it
found = false;
- best = NULL;
- bestvalue = 99999999999;
- for(radius=0; radius<1500 && !found; radius+=500)
+ entity best = NULL;
+ float bestvalue = 99999999999;
+ entity des = it;
+ for(float radius = 0; radius < 1500 && !found; radius += 500)
{
- for(wp=findradius(p, radius); wp; wp=wp.chain)
+ FOREACH_ENTITY_RADIUS(p, radius, it.classname == "waypoint" && !(it.wpflags & WAYPOINTFLAG_GENERATED),
{
- if(!(wp.wpflags & WAYPOINTFLAG_GENERATED))
- if(wp.classname=="waypoint")
- if(checkpvs(wp.origin, ad))
+ if(checkpvs(it.origin, des))
{
found = true;
- if(wp.cnt<bestvalue)
+ if(it.cnt < bestvalue)
{
- best = wp;
- bestvalue = wp.cnt;
+ best = it;
+ bestvalue = it.cnt;
}
}
- }
+ });
}
if(best)
this.havocbot_attack_time = 0;
- if(checkpvs(this.view_ofs,ad))
+ if(checkpvs(this.view_ofs,it))
if(checkpvs(this.view_ofs,best))
{
// dprint("increasing attack time for this target\n");
this.havocbot_attack_time = time + 2;
}
}
- }
+ });
}
void havocbot_role_ast_offense(entity this)
void havocbot_goalrating_ctf_carrieritems(entity this, float ratingscale, vector org, float sradius)
{
- entity head;
- float t;
- head = findchainfloat(bot_pickup, true);
- while (head)
+ FOREACH_ENTITY_FLOAT(bot_pickup, true,
{
// gather health and armor only
- if (head.solid)
- if (head.health || head.armorvalue)
- if (vdist(head.origin - org, <, sradius))
+ if (it.solid)
+ if (it.health || it.armorvalue)
+ if (vdist(it.origin - org, <, sradius))
{
// get the value of the item
- t = head.bot_pickupevalfunc(this, head) * 0.0001;
+ float t = it.bot_pickupevalfunc(this, it) * 0.0001;
if (t > 0)
- navigation_routerating(this, head, t * ratingscale, 500);
+ navigation_routerating(this, it, t * ratingscale, 500);
}
- head = head.chain;
- }
+ });
}
void havocbot_ctf_reset_role(entity this)
void pathlib_deletepath(entity start)
{
- entity e;
-
- e = findchainentity(owner, start);
- while(e)
+ FOREACH_ENTITY_ENT(owner, start,
{
- setthink(e, SUB_Remove);
- e.nextthink = time;
- e = e.chain;
- }
+ setthink(it, SUB_Remove);
+ it.nextthink = time;
+ });
}
//#define PATHLIB_NODEEXPIRE 0.05
entity pathlib_getbestopen()
{
- entity node;
- entity bestnode;
-
if(best_open_node)
{
++pathlib_bestcash_hits;
return best_open_node;
}
- node = findchainentity(owner,openlist);
- if(!node)
- return NULL;
-
- bestnode = node;
- while(node)
+ entity bestnode = NULL;
+ FOREACH_ENTITY_ENT(owner, openlist,
{
- ++pathlib_bestopen_seached;
- if(node.pathlib_node_f < bestnode.pathlib_node_f)
- bestnode = node;
+ ++pathlib_bestopen_searched;
- node = node.chain;
- }
+ if(!bestnode || it.pathlib_node_f < bestnode.pathlib_node_f)
+ bestnode = it;
+ });
return bestnode;
}
pathlib_made_cnt = 0;
pathlib_merge_cnt = 0;
pathlib_searched_cnt = 0;
- pathlib_bestopen_seached = 0;
+ pathlib_bestopen_searched = 0;
pathlib_bestcash_hits = 0;
pathlib_bestcash_saved = 0;
LOG_TRACE("Nodes - merged: ", ftos(pathlib_merge_cnt),"\n");
LOG_TRACE("Nodes - closed: ", ftos(pathlib_closed_cnt),"\n");
LOG_TRACE("Nodes - searched: ", ftos(pathlib_searched_cnt),"\n");
- LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_seached),"\n");
+ LOG_TRACE("Nodes bestopen searched: ", ftos(pathlib_bestopen_searched),"\n");
LOG_TRACE("Nodes bestcash - hits: ", ftos(pathlib_bestcash_hits),"\n");
LOG_TRACE("Nodes bestcash - save: ", ftos(pathlib_bestcash_saved),"\n");
LOG_TRACE("AStar done.\n");
entity pathlib_wpp_bestopen()
{
- entity n, best;
-
if(best_open_node)
return best_open_node;
- n = findchainentity(pathlib_list, openlist);
- best = n;
- while(n)
- {
- if(n.pathlib_node_f < best.pathlib_node_f)
- best = n;
+ entity best = NULL;
- n = n.chain;
- }
+ FOREACH_ENTITY_ENT(pathlib_list, openlist,
+ {
+ if(!best || it.pathlib_node_f < best.pathlib_node_f)
+ best = it;
+ });
return best;
entity pathlib_waypointpath(entity wp_from, entity wp_to, float callback)
{
- entity n;
float ptime;
ptime = gettime(GETTIME_REALTIME);
// Initialize waypoint grid
// FIXME! presisted chain for better preformance
- for(n = findchain(classname, "waypoint"); n; n = n.chain)
+ FOREACH_ENTITY_CLASS("waypoint", true,
{
- n.pathlib_list = NULL;
- n.pathlib_node_g = 0;
- n.pathlib_node_f = 0;
- n.pathlib_node_h = 0;
-
- //setmodel(n, "models/runematch/rune.mdl");
- //n.effects = EF_LOWPRECISION;
- //n.colormod = '0 0 0';
- //n.scale = 1;
-
- }
+ it.pathlib_list = NULL;
+ it.pathlib_node_g = 0;
+ it.pathlib_node_f = 0;
+ it.pathlib_node_h = 0;
+
+ //setmodel(it, "models/runematch/rune.mdl");
+ //it.effects = EF_LOWPRECISION;
+ //it.colormod = '0 0 0';
+ //it.scale = 1;
+ });
goal_node = wp_to;
start_node = wp_from;
float pathlib_made_cnt;
float pathlib_merge_cnt;
float pathlib_searched_cnt;
-float pathlib_bestopen_seached;
+float pathlib_bestopen_searched;
float pathlib_bestcash_hits;
float pathlib_bestcash_saved;
float pathlib_gridsize;
if(!this.enemy)
{
- e = findchainfloat(flock_id,this.flock_id);
- while(e)
+ FOREACH_ENTITY_FLOAT(flock_id, this.flock_id,
{
- d = vlen(this.origin - e.origin);
-
- if(e != this.owner)
- if(e != ee)
- if(d > bd)
- {
- this.enemy = e;
- bd = d;
- }
- e = e.chain;
- }
+ if(it == this.owner || it == ee)
+ continue;
+
+ if(!this.enemy || vlen2(this.origin - it.origin) < vlen2(this.origin - this.enemy.origin))
+ this.enemy = it;
+ });
}
if(this.enemy)
this.velocity = movelib_inertmove_byspeed(this, newmove,1250,0.3,0.7);
this.velocity = movelib_dragvec(this, 0.01,0.5);
-
this.angles = vectoangles(this.velocity);
this.nextthink = time + 0.1;
}