#include "waypoints.qh"
+#include "cvars.qh"
+
+#include "bot.qh"
+#include "navigation.qh"
+
+#include <common/state.qh>
+
+#include "../../antilag.qh"
+
+#include <common/constants.qh>
+
+#include <lib/warpzone/common.qh>
+#include <lib/warpzone/util_server.qh>
+
// create a new spawnfunc_waypoint and automatically link it to other waypoints, and link
// them back to it as well
// (suitable for spawnfunc_waypoint editor)
entity waypoint_spawn(vector m1, vector m2, float f)
{
- entity w;
- w = find(world, classname, "waypoint");
-
- if (!(f & WAYPOINTFLAG_PERSONAL))
- while (w)
+ if(!(f & WAYPOINTFLAG_PERSONAL))
{
- // if a matching spawnfunc_waypoint already exists, don't add a duplicate
- if (boxesoverlap(m1, m2, w.absmin, w.absmax))
- return w;
- w = find(w, classname, "waypoint");
+ IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax),
+ {
+ return it;
+ });
}
- w = spawn();
+ entity w = new(waypoint);
+ IL_PUSH(g_waypoints, w);
w.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
- w.classname = "waypoint";
w.wpflags = f;
+ w.solid = SOLID_TRIGGER;
setorigin(w, (m1 + m2) * 0.5);
setsize(w, m1 - w.origin, m2 - w.origin);
- if (vlen(w.size) > 0)
+ if (w.size)
w.wpisbox = true;
if(!w.wpisbox)
{
- setsize(w, PL_MIN - '1 1 0', PL_MAX + '1 1 0');
+ setsize(w, STAT(PL_MIN, NULL) - '1 1 0', STAT(PL_MAX, NULL) + '1 1 0');
if(!move_out_of_solid(w))
{
if(!(f & WAYPOINTFLAG_GENERATED))
{
- LOG_TRACE("Killed a waypoint that was stuck in solid at ", vtos(w.origin), "\n");
- remove(w);
- return world;
+ LOG_TRACE("Killed a waypoint that was stuck in solid at ", vtos(w.origin));
+ delete(w);
+ return NULL;
}
else
{
// relink this spawnfunc_waypoint
// (precompile a list of all reachable waypoints from this spawnfunc_waypoint)
// (SLOW!)
-void waypoint_think()
-{SELFPARAM();
- entity e;
+void waypoint_think(entity this)
+{
vector sv, sm1, sm2, ev, em1, em2, dv;
bot_calculate_stepheightvec();
bot_navigation_movemode = ((autocvar_bot_navigation_ignoreplayers) ? MOVE_NOMONSTERS : MOVE_NORMAL);
- //dprint("waypoint_think wpisbox = ", ftos(self.wpisbox), "\n");
- sm1 = self.origin + self.mins;
- sm2 = self.origin + self.maxs;
- for(e = world; (e = find(e, classname, "waypoint")); )
+ //dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n");
+ sm1 = this.origin + this.mins;
+ sm2 = this.origin + this.maxs;
+ IL_EACH(g_waypoints, true,
{
- if (boxesoverlap(self.absmin, self.absmax, e.absmin, e.absmax))
+ if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax))
{
- waypoint_addlink(self, e);
- waypoint_addlink(e, self);
+ waypoint_addlink(this, it);
+ waypoint_addlink(it, this);
}
else
{
++relink_total;
- if(!checkpvs(self.origin, e))
+ if(!checkpvs(this.origin, it))
{
++relink_pvsculled;
continue;
}
- sv = e.origin;
+ sv = it.origin;
sv.x = bound(sm1_x, sv.x, sm2_x);
sv.y = bound(sm1_y, sv.y, sm2_y);
sv.z = bound(sm1_z, sv.z, sm2_z);
- ev = self.origin;
- em1 = e.origin + e.mins;
- em2 = e.origin + e.maxs;
+ ev = this.origin;
+ em1 = it.origin + it.mins;
+ em2 = it.origin + it.maxs;
ev.x = bound(em1_x, ev.x, em2_x);
ev.y = bound(em1_y, ev.y, em2_y);
ev.z = bound(em1_z, ev.z, em2_z);
dv = ev - sv;
dv.z = 0;
- if (vlen(dv) >= 1050) // max search distance in XY
+ if(vdist(dv, >=, 1050)) // max search distance in XY
{
++relink_lengthculled;
continue;
}
navigation_testtracewalk = 0;
- if (!self.wpisbox)
+ if (!this.wpisbox)
{
- tracebox(sv - PL_MIN.z * '0 0 1', PL_MIN, PL_MAX, sv, false, self);
+ tracebox(sv - STAT(PL_MIN, NULL).z * '0 0 1', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), sv, false, this);
if (!trace_startsolid)
{
//dprint("sv deviation", vtos(trace_endpos - sv), "\n");
sv = trace_endpos + '0 0 1';
}
}
- if (!e.wpisbox)
+ if (!it.wpisbox)
{
- tracebox(ev - PL_MIN.z * '0 0 1', PL_MIN, PL_MAX, ev, false, e);
+ tracebox(ev - STAT(PL_MIN, NULL).z * '0 0 1', STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), ev, false, it);
if (!trace_startsolid)
{
//dprint("ev deviation", vtos(trace_endpos - ev), "\n");
ev = trace_endpos + '0 0 1';
}
}
- //traceline(self.origin, e.origin, false, world);
+ //traceline(this.origin, it.origin, false, NULL);
//if (trace_fraction == 1)
- if (!self.wpisbox && tracewalk(self, sv, PL_MIN, PL_MAX, ev, MOVE_NOMONSTERS))
- waypoint_addlink(self, e);
+ if (!this.wpisbox && tracewalk(this, sv, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), ev, MOVE_NOMONSTERS))
+ waypoint_addlink(this, it);
else
relink_walkculled += 0.5;
- if (!e.wpisbox && tracewalk(e, ev, PL_MIN, PL_MAX, sv, MOVE_NOMONSTERS))
- waypoint_addlink(e, self);
+ if (!it.wpisbox && tracewalk(it, ev, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), sv, MOVE_NOMONSTERS))
+ waypoint_addlink(it, this);
else
relink_walkculled += 0.5;
}
- }
+ });
navigation_testtracewalk = 0;
- self.wplinked = true;
+ this.wplinked = true;
}
void waypoint_clearlinks(entity wp)
// clear links to other waypoints
float f;
f = 10000000;
- wp.wp00 = wp.wp01 = wp.wp02 = wp.wp03 = wp.wp04 = wp.wp05 = wp.wp06 = wp.wp07 = world;
- wp.wp08 = wp.wp09 = wp.wp10 = wp.wp11 = wp.wp12 = wp.wp13 = wp.wp14 = wp.wp15 = world;
- wp.wp16 = wp.wp17 = wp.wp18 = wp.wp19 = wp.wp20 = wp.wp21 = wp.wp22 = wp.wp23 = world;
- wp.wp24 = wp.wp25 = wp.wp26 = wp.wp27 = wp.wp28 = wp.wp29 = wp.wp30 = wp.wp31 = world;
+ wp.wp00 = wp.wp01 = wp.wp02 = wp.wp03 = wp.wp04 = wp.wp05 = wp.wp06 = wp.wp07 = NULL;
+ wp.wp08 = wp.wp09 = wp.wp10 = wp.wp11 = wp.wp12 = wp.wp13 = wp.wp14 = wp.wp15 = NULL;
+ wp.wp16 = wp.wp17 = wp.wp18 = wp.wp19 = wp.wp20 = wp.wp21 = wp.wp22 = wp.wp23 = NULL;
+ wp.wp24 = wp.wp25 = wp.wp26 = wp.wp27 = wp.wp28 = wp.wp29 = wp.wp30 = wp.wp31 = NULL;
wp.wp00mincost = wp.wp01mincost = wp.wp02mincost = wp.wp03mincost = wp.wp04mincost = wp.wp05mincost = wp.wp06mincost = wp.wp07mincost = f;
wp.wp08mincost = wp.wp09mincost = wp.wp10mincost = wp.wp11mincost = wp.wp12mincost = wp.wp13mincost = wp.wp14mincost = wp.wp15mincost = f;
// tell a spawnfunc_waypoint to relink
void waypoint_schedulerelink(entity wp)
{
- if (wp == world)
+ if (wp == NULL)
return;
// TODO: add some sort of visible box in edit mode for box waypoints
if (autocvar_g_waypointeditor)
}
else
wp.model = "";
- wp.wpisbox = vlen(wp.size) > 0;
- wp.enemy = world;
+ wp.wpisbox = vdist(wp.size, >, 0);
+ wp.enemy = NULL;
if (!(wp.wpflags & WAYPOINTFLAG_PERSONAL))
- wp.owner = world;
+ wp.owner = NULL;
if (!(wp.wpflags & WAYPOINTFLAG_NORELINK))
waypoint_clearlinks(wp);
// schedule an actual relink on next frame
- wp.think = waypoint_think;
+ setthink(wp, waypoint_think);
wp.nextthink = time;
wp.effects = EF_LOWPRECISION;
}
// spawnfunc_waypoint map entity
spawnfunc(waypoint)
{
- setorigin(self, self.origin);
+ IL_PUSH(g_waypoints, this);
+
+ setorigin(this, this.origin);
// schedule a relink after other waypoints have had a chance to spawn
- waypoint_clearlinks(self);
- //waypoint_schedulerelink(self);
+ waypoint_clearlinks(this);
+ //waypoint_schedulerelink(this);
}
// remove a spawnfunc_waypoint, and schedule all neighbors to relink
waypoint_schedulerelink(e.wp30);
waypoint_schedulerelink(e.wp31);
// and now remove the spawnfunc_waypoint
- remove(e);
+ delete(e);
}
// empties the map of waypoints
void waypoint_removeall()
{
- entity head, next;
- head = findchain(classname, "waypoint");
- while (head)
+ IL_EACH(g_waypoints, true,
{
- next = head.chain;
- remove(head);
- head = next;
- }
+ delete(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)
+ IL_EACH(g_waypoints, true,
{
- waypoint_schedulerelink(head);
- head = head.chain;
- }
+ waypoint_schedulerelink(it);
+ });
}
// Load waypoint links from file
{
string filename, s;
float file, tokens, c = 0, found;
- entity wp_from = world, wp_to;
+ entity wp_from = NULL, wp_to;
vector wp_to_pos, wp_from_pos;
filename = strcat("maps/", mapname);
filename = strcat(filename, ".waypoints.cache");
{
LOG_TRACE("waypoint links load from ");
LOG_TRACE(filename);
- LOG_TRACE(" failed\n");
+ LOG_TRACE(" failed");
return false;
}
found = false;
while(wp_from)
{
- if(vlen(wp_from.origin-wp_from_pos)<1)
+ if(vdist(wp_from.origin - wp_from_pos, <, 1))
if(wp_from.classname == "waypoint")
{
found = true;
if(!found)
{
- LOG_TRACE("waypoint_load_links: couldn't find 'from' waypoint at ", vtos(wp_from.origin),"\n");
+ LOG_TRACE("waypoint_load_links: couldn't find 'from' waypoint at ", vtos(wp_from.origin));
continue;
}
found = false;
while(wp_to)
{
- if(vlen(wp_to.origin-wp_to_pos)<1)
+ if(vdist(wp_to.origin - wp_to_pos, <, 1))
if(wp_to.classname == "waypoint")
{
found = true;
if(!found)
{
- LOG_TRACE("waypoint_load_links: couldn't find 'to' waypoint at ", vtos(wp_to.origin),"\n");
+ LOG_TRACE("waypoint_load_links: couldn't find 'to' waypoint at ", vtos(wp_to.origin));
continue;
}
fclose(file);
- LOG_TRACE("loaded ");
- LOG_TRACE(ftos(c));
- LOG_TRACE(" waypoint links from maps/");
- LOG_TRACE(mapname);
- LOG_TRACE(".waypoints.cache\n");
+ LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.cache");
botframe_cachedwaypointlinks = true;
return true;
{
string filename, s;
float file, tokens, c = 0, found;
- entity wp_from = world, wp_to;
+ entity wp_from = NULL, wp_to;
vector wp_to_pos, wp_from_pos;
filename = strcat("maps/", mapname);
filename = strcat(filename, ".waypoints.hardwired");
if (file < 0)
{
- LOG_TRACE("waypoint links load from ");
- LOG_TRACE(filename);
- LOG_TRACE(" failed\n");
+ LOG_TRACE("waypoint links load from ", filename, " failed");
return;
}
found = false;
while(wp_from)
{
- if(vlen(wp_from.origin-wp_from_pos)<5)
+ if(vdist(wp_from.origin - wp_from_pos, <, 5))
if(wp_from.classname == "waypoint")
{
found = true;
found = false;
while(wp_to)
{
- if(vlen(wp_to.origin-wp_to_pos)<5)
+ if(vdist(wp_to.origin - wp_to_pos, <, 5))
if(wp_to.classname == "waypoint")
{
found = true;
fclose(file);
- LOG_TRACE("loaded ");
- LOG_TRACE(ftos(c));
- LOG_TRACE(" waypoint links from maps/");
- LOG_TRACE(mapname);
- LOG_TRACE(".waypoints.hardwired\n");
+ LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.hardwired");
}
entity waypoint_get_link(entity w, float i)
case 29:return w.wp29;
case 30:return w.wp30;
case 31:return w.wp31;
- default:return world;
+ default:return NULL;
}
}
// 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;
+ IL_EACH(g_waypoints, true,
{
- for(i=0;i<32;++i)
+ for(int j = 0; j < 32; ++j)
{
- // :S
- link = waypoint_get_link(w, i);
- if(link==world)
- 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;
+ IL_EACH(g_waypoints, 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
cwb = cwb + 1;
}
fclose(file);
- LOG_TRACE("loaded ");
- LOG_TRACE(ftos(cwp));
- LOG_TRACE(" waypoints and ");
- LOG_TRACE(ftos(cwb));
- LOG_TRACE(" wayboxes from maps/");
- LOG_TRACE(mapname);
- LOG_TRACE(".waypoints\n");
+ LOG_TRACE("loaded ", ftos(cwp), " waypoints and ", ftos(cwb), " wayboxes from maps/", mapname, ".waypoints");
}
else
{
- LOG_TRACE("waypoint load from ");
- LOG_TRACE(filename);
- LOG_TRACE(" failed\n");
+ LOG_TRACE("waypoint load from ", filename, " failed");
}
return cwp + cwb;
}
vector waypoint_fixorigin(vector position)
{
- tracebox(position + '0 0 1' * (1 - PL_MIN.z), PL_MIN, PL_MAX, position + '0 0 -512', MOVE_NOMONSTERS, world);
+ tracebox(position + '0 0 1' * (1 - STAT(PL_MIN, NULL).z), STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), position + '0 0 -512', MOVE_NOMONSTERS, NULL);
if(trace_fraction < 1)
position = trace_endpos;
- //traceline(position, position + '0 0 -512', MOVE_NOMONSTERS, world);
+ //traceline(position, position + '0 0 -512', MOVE_NOMONSTERS, NULL);
//print("position is ", ftos(trace_endpos_z - position_z), " above solid\n");
return position;
}
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)
+ IL_EACH(g_waypoints, 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);
}
waypoint_spawnforteleporter_boxes(e, e.absmin, e.absmax, destination, destination, timetaken);
}
-entity waypoint_spawnpersonal(vector position)
-{SELFPARAM();
+entity waypoint_spawnpersonal(entity this, vector position)
+{
entity w;
// drop the waypoint to a proper location:
position = waypoint_fixorigin(position);
w = waypoint_spawn(position, position, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_PERSONAL);
- w.nearestwaypoint = world;
+ w.nearestwaypoint = NULL;
w.nearestwaypointtimeout = 0;
- w.owner = self;
+ w.owner = this;
waypoint_schedulerelink(w);
void botframe_showwaypointlinks()
{
- entity player, head, w;
if (time < botframe_waypointeditorlightningtime)
return;
botframe_waypointeditorlightningtime = time + 0.5;
- player = find(world, classname, "player");
- while (player)
+ FOREACH_CLIENT(IS_PLAYER(it) && !it.isbot,
{
- if (!player.isbot)
- if (player.flags & FL_ONGROUND || player.waterlevel > WATERLEVEL_NONE)
+ if(IS_ONGROUND(it) || it.waterlevel > WATERLEVEL_NONE)
{
//navigation_testtracewalk = true;
- head = navigation_findnearestwaypoint(player, false);
+ entity head = navigation_findnearestwaypoint(it, false);
// print("currently selected WP is ", etos(head), "\n");
//navigation_testtracewalk = false;
if (head)
{
- w = head ;if (w) te_lightning2(world, w.origin, player.origin);
- w = head.wp00;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp01;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp02;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp03;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp04;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp05;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp06;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp07;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp08;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp09;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp10;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp11;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp12;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp13;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp14;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp15;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp16;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp17;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp18;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp19;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp20;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp21;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp22;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp23;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp24;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp25;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp26;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp27;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp28;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp29;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp30;if (w) te_lightning2(world, w.origin, head.origin);
- w = head.wp31;if (w) te_lightning2(world, w.origin, head.origin);
+ entity w;
+ w = head ;if (w) te_lightning2(NULL, w.origin, it.origin);
+ w = head.wp00;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp01;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp02;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp03;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp04;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp05;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp06;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp07;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp08;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp09;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp10;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp11;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp12;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp13;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp14;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp15;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp16;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp17;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp18;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp19;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp20;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp21;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp22;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp23;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp24;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp25;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp26;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp27;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp28;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp29;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp30;if (w) te_lightning2(NULL, w.origin, head.origin);
+ w = head.wp31;if (w) te_lightning2(NULL, w.origin, head.origin);
}
}
- player = find(player, classname, "player");
- }
+ });
}
float botframe_autowaypoints_fixdown(vector v)
{
- tracebox(v, PL_MIN, PL_MAX, v + '0 0 -64', MOVE_NOMONSTERS, world);
+ tracebox(v, STAT(PL_MIN, NULL), STAT(PL_MAX, NULL), v + '0 0 -64', MOVE_NOMONSTERS, NULL);
if(trace_fraction >= 1)
return 0;
return 1;
float botframe_autowaypoints_createwp(vector v, entity p, .entity fld, float f)
{
- entity w;
-
- w = find(world, classname, "waypoint");
- while (w)
+ IL_EACH(g_waypoints, boxesoverlap(v - '32 32 32', v + '32 32 32', it.absmin, it.absmax),
{
// if a matching spawnfunc_waypoint already exists, don't add a duplicate
- if (boxesoverlap(v - '32 32 32', v + '32 32 32', w.absmin, w.absmax))
- //if (boxesoverlap(v - '4 4 4', v + '4 4 4', w.absmin, w.absmax))
- return 0;
- w = find(w, classname, "waypoint");
- }
+ return 0;
+ });
waypoint_schedulerelink(p.(fld) = waypoint_spawn(v, v, f));
return 1;
float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .entity fld)
{
// make it possible to go from p to wp, if we can
- // if wp is world, nearest is chosen
+ // if wp is NULL, nearest is chosen
entity w;
vector porg;
maxdist = 2100;
}
- float bestdist;
- bestdist = maxdist;
- w = find(world, classname, "waypoint");
- while (w)
+ float bestdist = maxdist;
+ IL_EACH(g_waypoints, it != wp && !(it.wpflags & WAYPOINTFLAG_NORELINK),
{
- if(w != wp && !(w.wpflags & WAYPOINTFLAG_NORELINK))
+ float d = vlen(wp.origin - it.origin) + vlen(it.origin - porg);
+ if(d < bestdist)
+ if(navigation_waypoint_will_link(wp.origin, it.origin, p, walkfromwp, 1050))
+ if(navigation_waypoint_will_link(it.origin, porg, p, walkfromwp, 1050))
{
- float d;
- d = vlen(wp.origin - w.origin) + vlen(w.origin - porg);
- if(d < bestdist)
- if(navigation_waypoint_will_link(wp.origin, w.origin, p, walkfromwp, 1050))
- if(navigation_waypoint_will_link(w.origin, porg, p, walkfromwp, 1050))
- {
- bestdist = d;
- p.(fld) = w;
- }
+ bestdist = d;
+ p.(fld) = it;
}
- w = find(w, classname, "waypoint");
- }
+ });
if(bestdist < maxdist)
{
LOG_INFO("update chain to new nearest WP ", etos(p.(fld)), "\n");
}
t = (tmin + tmax) * 0.5;
- o = antilag_takebackorigin(p, time - t);
+ o = antilag_takebackorigin(p, CS(p), time - t);
if(!botframe_autowaypoints_fixdown(o))
return -2;
o = trace_endpos;
float r = botframe_autowaypoints_fix_from(p, walkfromwp, p.(fld), fld);
if(r != -1)
return;
- r = botframe_autowaypoints_fix_from(p, walkfromwp, world, fld);
+ r = botframe_autowaypoints_fix_from(p, walkfromwp, NULL, fld);
if(r != -1)
return;
void botframe_deleteuselesswaypoints()
{
- entity w, w1, w2;
- float i, j, k;
- for (w = world; (w = findfloat(w, bot_pickup, true)); )
+ IL_EACH(g_items, it.bot_pickup,
{
// NOTE: this protects waypoints if they're the ONLY nearest
// waypoint. That's the intention.
- navigation_findnearestwaypoint(w, false); // Walk TO item.
- navigation_findnearestwaypoint(w, true); // Walk FROM item.
- }
- for (w = world; (w = find(w, classname, "waypoint")); )
+ navigation_findnearestwaypoint(it, false); // Walk TO item.
+ navigation_findnearestwaypoint(it, true); // Walk FROM item.
+ });
+ IL_EACH(g_waypoints, true,
{
- w.wpflags |= WAYPOINTFLAG_DEAD_END;
- w.wpflags &= ~WAYPOINTFLAG_USEFUL;
+ it.wpflags |= WAYPOINTFLAG_DEAD_END;
+ it.wpflags &= ~WAYPOINTFLAG_USEFUL;
// WP is useful if:
- if (w.wpflags & WAYPOINTFLAG_ITEM)
- w.wpflags |= WAYPOINTFLAG_USEFUL;
- if (w.wpflags & WAYPOINTFLAG_TELEPORT)
- w.wpflags |= WAYPOINTFLAG_USEFUL;
- if (w.wpflags & WAYPOINTFLAG_PROTECTED)
- w.wpflags |= WAYPOINTFLAG_USEFUL;
+ if (it.wpflags & WAYPOINTFLAG_ITEM)
+ it.wpflags |= WAYPOINTFLAG_USEFUL;
+ if (it.wpflags & WAYPOINTFLAG_TELEPORT)
+ it.wpflags |= WAYPOINTFLAG_USEFUL;
+ if (it.wpflags & WAYPOINTFLAG_PROTECTED)
+ it.wpflags |= WAYPOINTFLAG_USEFUL;
// b) WP is closest WP for an item/spawnpoint/other entity
// This has been done above by protecting these WPs.
- }
+ });
// c) There are w1, w, w2 so that w1 -> w, w -> w2 and not w1 -> w2.
- for (w1 = world; (w1 = find(w1, classname, "waypoint")); )
+ IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_PERSONAL),
{
- if (w1.wpflags & WAYPOINTFLAG_PERSONAL)
- continue;
- for (i = 0; i < 32; ++i)
+ for (int m = 0; m < 32; ++m)
{
- w = waypoint_get_link(w1, i);
+ entity w = waypoint_get_link(it, m);
if (!w)
break;
if (w.wpflags & WAYPOINTFLAG_PERSONAL)
continue;
if (w.wpflags & WAYPOINTFLAG_USEFUL)
continue;
- for (j = 0; j < 32; ++j)
+ for (int j = 0; j < 32; ++j)
{
- w2 = waypoint_get_link(w, j);
+ entity w2 = waypoint_get_link(w, j);
if (!w2)
break;
- if (w1 == w2)
+ if (it == w2)
continue;
if (w2.wpflags & WAYPOINTFLAG_PERSONAL)
continue;
- // If we got here, w1 != w2 exist with w1 -> w
+ // If we got here, it != w2 exist with it -> w
// and w -> w2. That means the waypoint is not
// a dead end.
w.wpflags &= ~WAYPOINTFLAG_DEAD_END;
- for (k = 0; k < 32; ++k)
+ for (int k = 0; k < 32; ++k)
{
- if (waypoint_get_link(w1, k) == w2)
+ if (waypoint_get_link(it, k) == w2)
continue;
// IF WE GET HERE, w is proven useful
- // to get from w1 to w2!
+ // to get from it to w2!
w.wpflags |= WAYPOINTFLAG_USEFUL;
goto next;
}
}
-:next
+LABEL(next)
}
- }
+ });
// d) The waypoint is a dead end. Dead end waypoints must be kept as
// they are needed to complete routes while autowaypointing.
- for (w = world; (w = find(w, classname, "waypoint")); )
+ IL_EACH(g_waypoints, !(it.wpflags & (WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END)),
{
- if (!(w.wpflags & (WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END)))
- {
- LOG_INFOF("Removed a waypoint at %v. Try again for more!\n", w.origin);
- te_explosion(w.origin);
- waypoint_remove(w);
- break;
- }
- }
- for (w = world; (w = find(w, classname, "waypoint")); )
- w.wpflags &= ~(WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END); // temp flag
+ LOG_INFOF("Removed a waypoint at %v. Try again for more!\n", it.origin);
+ te_explosion(it.origin);
+ waypoint_remove(it);
+ break;
+ });
+
+ IL_EACH(g_waypoints, true,
+ {
+ it.wpflags &= ~(WAYPOINTFLAG_USEFUL | WAYPOINTFLAG_DEAD_END); // temp flag
+ });
}
void botframe_autowaypoints()
{
- entity p;
- FOR_EACH_REALPLAYER(p)
- {
- if(p.deadflag)
- continue;
+ FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && !IS_DEAD(it), LAMBDA(
// going back is broken, so only fix waypoints to walk TO the player
//botframe_autowaypoints_fix(p, false, botframe_autowaypoints_lastwp0);
- botframe_autowaypoints_fix(p, true, botframe_autowaypoints_lastwp1);
+ botframe_autowaypoints_fix(it, true, botframe_autowaypoints_lastwp1);
//te_explosion(p.botframe_autowaypoints_lastwp0.origin);
- }
+ ));
if (autocvar_g_waypointeditor_auto >= 2) {
botframe_deleteuselesswaypoints();