dprint(".waypoints.hardwired\n");
}
+entity waypoint_get_link(entity w, float i)
+{
+ switch(i)
+ {
+ case 0:return w.wp00;
+ case 1:return w.wp01;
+ case 2:return w.wp02;
+ case 3:return w.wp03;
+ case 4:return w.wp04;
+ case 5:return w.wp05;
+ case 6:return w.wp06;
+ case 7:return w.wp07;
+ case 8:return w.wp08;
+ case 9:return w.wp09;
+ case 10:return w.wp10;
+ case 11:return w.wp11;
+ case 12:return w.wp12;
+ case 13:return w.wp13;
+ case 14:return w.wp14;
+ case 15:return w.wp15;
+ case 16:return w.wp16;
+ case 17:return w.wp17;
+ case 18:return w.wp18;
+ case 19:return w.wp19;
+ case 20:return w.wp20;
+ case 21:return w.wp21;
+ case 22:return w.wp22;
+ case 23:return w.wp23;
+ case 24:return w.wp24;
+ case 25:return w.wp25;
+ case 26:return w.wp26;
+ case 27:return w.wp27;
+ case 28:return w.wp28;
+ case 29:return w.wp29;
+ case 30:return w.wp30;
+ case 31:return w.wp31;
+ default:return world;
+ }
+}
+
// Save all waypoint links to a file
void waypoint_save_links()
{
for(i=0;i<32;++i)
{
// :S
- link = world;
- switch(i)
- {
- // for i in $(seq -w 0 31); do echo "case $i:link = w.wp$i; break;"; done;
- case 0:link = w.wp00; break;
- case 1:link = w.wp01; break;
- case 2:link = w.wp02; break;
- case 3:link = w.wp03; break;
- case 4:link = w.wp04; break;
- case 5:link = w.wp05; break;
- case 6:link = w.wp06; break;
- case 7:link = w.wp07; break;
- case 8:link = w.wp08; break;
- case 9:link = w.wp09; break;
- case 10:link = w.wp10; break;
- case 11:link = w.wp11; break;
- case 12:link = w.wp12; break;
- case 13:link = w.wp13; break;
- case 14:link = w.wp14; break;
- case 15:link = w.wp15; break;
- case 16:link = w.wp16; break;
- case 17:link = w.wp17; break;
- case 18:link = w.wp18; break;
- case 19:link = w.wp19; break;
- case 20:link = w.wp20; break;
- case 21:link = w.wp21; break;
- case 22:link = w.wp22; break;
- case 23:link = w.wp23; break;
- case 24:link = w.wp24; break;
- case 25:link = w.wp25; break;
- case 26:link = w.wp26; break;
- case 27:link = w.wp27; break;
- case 28:link = w.wp28; break;
- case 29:link = w.wp29; break;
- case 30:link = w.wp30; break;
- case 31:link = w.wp31; break;
- }
-
+ link = waypoint_get_link(w, i);
if(link==world)
continue;
return 1;
}
-float botframe_autowaypoints_createwp(vector v, entity p, .entity fld)
+float botframe_autowaypoints_createwp(vector v, entity p, .entity fld, float f)
{
entity w;
w = find(w, classname, "waypoint");
}
- waypoint_schedulerelink(p.fld = waypoint_spawn(v, v, 0));
+ waypoint_schedulerelink(p.fld = waypoint_spawn(v, v, f));
return 1;
}
if(wp)
{
- // if any WP w fulfills wp -> w -> porg, then switch from wp to w
+ // if any WP w fulfills wp -> w -> porg and w is closer than wp, then switch from wp to w
// if wp -> porg, then OK
float maxdist;
t = (tmin + tmax) * 0.5;
o = antilag_takebackorigin(p, time - t);
if(!botframe_autowaypoints_fixdown(o))
- return -1;
+ return -2;
o = trace_endpos;
if(wp)
}
print("spawning a waypoint for connecting to ", etos(wp), "\n");
- botframe_autowaypoints_createwp(o, p, fld);
+ botframe_autowaypoints_createwp(o, p, fld, 0);
return 1;
}
print("emergency: got no good nearby WP to build a link from, starting a new chain\n");
if(!botframe_autowaypoints_fixdown(p.origin))
return; // shouldn't happen, caught above
- botframe_autowaypoints_createwp(trace_endpos, p, fld);
+ botframe_autowaypoints_createwp(trace_endpos, p, fld, WAYPOINTFLAG_PROTECTED);
+}
+
+void botframe_deleteuselesswaypoints()
+{
+ entity w, w1, w2;
+ float i, j, k;
+ for (w = world; (w = findfloat(w, bot_pickup, TRUE)); )
+ {
+ // 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")); )
+ {
+ w.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;
+ // 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")); )
+ {
+ if (w1.wpflags & WAYPOINTFLAG_PERSONAL)
+ continue;
+ for (i = 0; i < 32; ++i)
+ {
+ w = waypoint_get_link(w1, i);
+ if (!w)
+ break;
+ if (w.wpflags & WAYPOINTFLAG_PERSONAL)
+ continue;
+ if (w.wpflags & WAYPOINTFLAG_USEFUL)
+ continue;
+ for (j = 0; j < 32; ++j)
+ {
+ w2 = waypoint_get_link(w1, i);
+ if (!w2)
+ break;
+ if (w2.wpflags & WAYPOINTFLAG_PERSONAL)
+ continue;
+ for (k = 0; k < 32; ++k)
+ {
+ if (waypoint_get_link(w1, k) == w2)
+ continue;
+ // IF WE GET HERE, w is proven useful
+ // to get from w1 to w2!
+ w.wpflags |= WAYPOINTFLAG_USEFUL;
+ continue;
+ }
+ }
+ }
+ }
+ for (w = world; (w = find(w, classname, "waypoint")); )
+ {
+ if (!(w.wpflags & WAYPOINTFLAG_USEFUL))
+ {
+ printf("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; // temp flag
}
void botframe_autowaypoints()
botframe_autowaypoints_fix(p, TRUE, botframe_autowaypoints_lastwp1);
//te_explosion(p.botframe_autowaypoints_lastwp0.origin);
}
+
+ botframe_deleteuselesswaypoints();
}