X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fwaypoints.qc;h=0766ab0466dbe24fc9ae2bed9ecb2ce529eeef5d;hb=84376a31e0d4478dc04dd179c7e61355ddaa1dc8;hp=c661b23ed0f6d33374f5bc87a0aedbc3a9684bcc;hpb=2910c874a8a032d2ba0504ca4bc48d837030268a;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/waypoints.qc b/qcsrc/server/bot/waypoints.qc index c661b23ed..0766ab046 100644 --- a/qcsrc/server/bot/waypoints.qc +++ b/qcsrc/server/bot/waypoints.qc @@ -3,7 +3,7 @@ // (suitable for spawnfunc_waypoint editor) entity waypoint_spawn(vector m1, vector m2, float f) { - local entity w; + entity w; w = find(world, classname, "waypoint"); if not(f & WAYPOINTFLAG_PERSONAL) @@ -67,12 +67,12 @@ entity waypoint_spawn(vector m1, vector m2, float f) w.model = ""; return w; -}; +} // add a new link to the spawnfunc_waypoint, replacing the furthest link it already has void waypoint_addlink(entity from, entity to) { - local float c; + float c; if (from == to) return; @@ -92,7 +92,7 @@ void waypoint_addlink(entity from, entity to) { // if either is a box we have to find the nearest points on them to // calculate the distance properly - local vector v1, v2, m1, m2; + vector v1, v2, m1, m2; v1 = from.origin; m1 = to.absmin; m2 = to.absmax; @@ -144,15 +144,15 @@ void waypoint_addlink(entity from, entity to) if (from.wp01mincost < c) {from.wp02 = to;from.wp02mincost = c;return;} from.wp02 = from.wp01;from.wp02mincost = from.wp01mincost; if (from.wp00mincost < c) {from.wp01 = to;from.wp01mincost = c;return;} from.wp01 = from.wp00;from.wp01mincost = from.wp00mincost; from.wp00 = to;from.wp00mincost = c;return; -}; +} // relink this spawnfunc_waypoint // (precompile a list of all reachable waypoints from this spawnfunc_waypoint) // (SLOW!) void waypoint_think() { - local entity e; - local vector sv, sm1, sm2, ev, em1, em2, dv; + entity e; + vector sv, sm1, sm2, ev, em1, em2, dv; bot_calculate_stepheightvec(); @@ -226,12 +226,12 @@ void waypoint_think() } navigation_testtracewalk = 0; self.wplinked = TRUE; -}; +} void waypoint_clearlinks(entity wp) { // clear links to other waypoints - local float f; + 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; @@ -244,7 +244,7 @@ void waypoint_clearlinks(entity wp) wp.wp24mincost = wp.wp25mincost = wp.wp26mincost = wp.wp27mincost = wp.wp28mincost = wp.wp29mincost = wp.wp30mincost = wp.wp31mincost = f; wp.wplinked = FALSE; -}; +} // tell a spawnfunc_waypoint to relink void waypoint_schedulerelink(entity wp) @@ -254,7 +254,7 @@ void waypoint_schedulerelink(entity wp) // TODO: add some sort of visible box in edit mode for box waypoints if (autocvar_g_waypointeditor) { - local vector m1, m2; + vector m1, m2; m1 = wp.mins; m2 = wp.maxs; setmodel(wp, "models/runematch/rune.mdl"); wp.effects = EF_LOWPRECISION; @@ -287,7 +287,7 @@ void spawnfunc_waypoint() // schedule a relink after other waypoints have had a chance to spawn waypoint_clearlinks(self); //waypoint_schedulerelink(self); -}; +} // remove a spawnfunc_waypoint, and schedule all neighbors to relink void waypoint_remove(entity e) @@ -327,12 +327,12 @@ void waypoint_remove(entity e) waypoint_schedulerelink(e.wp31); // and now remove the spawnfunc_waypoint remove(e); -}; +} // empties the map of waypoints void waypoint_removeall() { - local entity head, next; + entity head, next; head = findchain(classname, "waypoint"); while (head) { @@ -340,13 +340,13 @@ void waypoint_removeall() remove(head); head = next; } -}; +} // tell all waypoints to relink // (is this useful at all?) void waypoint_schedulerelinkall() { - local entity head; + entity head; relink_total = relink_walkculled = relink_pvsculled = relink_lengthculled = 0; head = findchain(classname, "waypoint"); while (head) @@ -354,15 +354,15 @@ void waypoint_schedulerelinkall() waypoint_schedulerelink(head); head = head.chain; } -}; +} // Load waypoint links from file float waypoint_load_links() { - local string filename, s; - local float file, tokens, c, found; - local entity wp_from, wp_to; - local vector wp_to_pos, wp_from_pos; + string filename, s; + float file, tokens, c = 0, found; + entity wp_from = world, wp_to; + vector wp_to_pos, wp_from_pos; filename = strcat("maps/", mapname); filename = strcat(filename, ".waypoints.cache"); file = fopen(filename, FILE_READ); @@ -375,12 +375,8 @@ float waypoint_load_links() return FALSE; } - while (1) + while ((s = fgets(file))) { - s = fgets(file); - if (!s) - break; - tokens = tokenizebyseparator(s, "*"); if (tokens!=2) @@ -394,7 +390,7 @@ float waypoint_load_links() wp_to_pos = stov(argv(1)); // Search "from" waypoint - if(wp_from.origin!=wp_from_pos) + if(wp_from && wp_from.origin!=wp_from_pos) { wp_from = findradius(wp_from_pos, 1); found = FALSE; @@ -411,10 +407,10 @@ float waypoint_load_links() if(!found) { - // can't find that waypoint - fclose(file); - return FALSE; + dprint("waypoint_load_links: couldn't find 'from' waypoint at ", vtos(wp_from.origin),"\n"); + continue; } + } // Search "to" waypoint @@ -433,9 +429,8 @@ float waypoint_load_links() if(!found) { - // can't find that waypoint - fclose(file); - return FALSE; + dprint("waypoint_load_links: couldn't find 'to' waypoint at ", vtos(wp_to.origin),"\n"); + continue; } ++c; @@ -452,14 +447,14 @@ float waypoint_load_links() botframe_cachedwaypointlinks = TRUE; return TRUE; -}; +} void waypoint_load_links_hardwired() { - local string filename, s; - local float file, tokens, c, found; - local entity wp_from, wp_to; - local vector wp_to_pos, wp_from_pos; + string filename, s; + float file, tokens, c = 0, found; + entity wp_from = world, wp_to; + vector wp_to_pos, wp_from_pos; filename = strcat("maps/", mapname); filename = strcat(filename, ".waypoints.hardwired"); file = fopen(filename, FILE_READ); @@ -474,12 +469,8 @@ void waypoint_load_links_hardwired() return; } - for (;;) + while ((s = fgets(file))) { - s = fgets(file); - if (!s) - break; - if(substring(s, 0, 2)=="//") continue; @@ -495,7 +486,7 @@ void waypoint_load_links_hardwired() wp_to_pos = stov(argv(1)); // Search "from" waypoint - if(wp_from.origin!=wp_from_pos) + if(wp_from && wp_from.origin!=wp_from_pos) { wp_from = findradius(wp_from_pos, 5); found = FALSE; @@ -539,6 +530,8 @@ void waypoint_load_links_hardwired() ++c; waypoint_addlink(wp_from, wp_to); + wp_from.wphardwired = TRUE; + wp_to.wphardwired = TRUE; } fclose(file); @@ -548,14 +541,14 @@ void waypoint_load_links_hardwired() dprint(" waypoint links from maps/"); dprint(mapname); dprint(".waypoints.hardwired\n"); -}; +} // Save all waypoint links to a file void waypoint_save_links() { - local string filename, s; - local float file, c, i; - local entity w, link; + string filename, s; + float file, c, i; + entity w, link; filename = strcat("maps/", mapname); filename = strcat(filename, ".waypoints.cache"); file = fopen(filename, FILE_WRITE); @@ -572,19 +565,20 @@ 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 00:link = w.wp00; break; - case 01:link = w.wp01; break; - case 02:link = w.wp02; break; - case 03:link = w.wp03; break; - case 04:link = w.wp04; break; - case 05:link = w.wp05; break; - case 06:link = w.wp06; break; - case 07:link = w.wp07; break; - case 08:link = w.wp08; break; - case 09:link = w.wp09; break; + 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; @@ -626,14 +620,14 @@ void waypoint_save_links() print(" waypoints links to maps/"); print(mapname); print(".waypoints.cache\n"); -}; +} // save waypoints to gamedir/data/maps/mapname.waypoints void waypoint_saveall() { - local string filename, s; - local float file, c; - local entity w; + string filename, s; + float file, c; + entity w; filename = strcat("maps/", mapname); filename = strcat(filename, ".waypoints"); file = fopen(filename, FILE_WRITE); @@ -670,14 +664,14 @@ void waypoint_saveall() } waypoint_save_links(); botframe_loadedforcedlinks = FALSE; -}; +} // load waypoints from file float waypoint_loadall() { - local string filename, s; - local float file, cwp, cwb, fl; - local vector m1, m2; + string filename, s; + float file, cwp, cwb, fl; + vector m1, m2; cwp = 0; cwb = 0; filename = strcat("maps/", mapname); @@ -685,18 +679,15 @@ float waypoint_loadall() file = fopen(filename, FILE_READ); if (file >= 0) { - while (1) + while ((s = fgets(file))) { - s = fgets(file); - if (!s) - break; m1 = stov(s); s = fgets(file); - if (!s) + if not(s) break; m2 = stov(s); s = fgets(file); - if (!s) + if not(s) break; fl = stof(s); waypoint_spawn(m1, m2, fl); @@ -721,7 +712,7 @@ float waypoint_loadall() dprint(" failed\n"); } return cwp + cwb; -}; +} vector waypoint_fixorigin(vector position) { @@ -735,7 +726,7 @@ vector waypoint_fixorigin(vector position) void waypoint_spawnforitem_force(entity e, vector org) { - local entity w; + entity w; // Fix the waypoint altitude if necessary org = waypoint_fixorigin(org); @@ -771,12 +762,12 @@ void waypoint_spawnforitem(entity e) return; waypoint_spawnforitem_force(e, e.origin); -}; +} void waypoint_spawnforteleporter_boxes(entity e, vector org1, vector org2, vector destination1, vector destination2, float timetaken) { - local entity w; - local entity dw; + entity w; + entity dw; w = waypoint_spawn(org1, org2, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_NORELINK); dw = waypoint_spawn(destination1, destination2, WAYPOINTFLAG_GENERATED); // one way link to the destination @@ -786,20 +777,20 @@ void waypoint_spawnforteleporter_boxes(entity e, vector org1, vector org2, vecto // (teleporters are not goals, so this is probably useless) e.nearestwaypoint = w; e.nearestwaypointtimeout = time + 1000000000; -}; +} void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken) { org = waypoint_fixorigin(org); destination = waypoint_fixorigin(destination); waypoint_spawnforteleporter_boxes(e, org, org, destination, destination, timetaken); -}; +} void waypoint_spawnforteleporter(entity e, vector destination, float timetaken) { destination = waypoint_fixorigin(destination); waypoint_spawnforteleporter_boxes(e, e.absmin, e.absmax, destination, destination, timetaken); -}; +} entity waypoint_spawnpersonal(vector position) { @@ -818,11 +809,11 @@ entity waypoint_spawnpersonal(vector position) waypoint_schedulerelink(w); return w; -}; +} void botframe_showwaypointlinks() { - local entity player, head, w; + entity player, head, w; if (time < botframe_waypointeditorlightningtime) return; botframe_waypointeditorlightningtime = time + 0.5; @@ -875,7 +866,7 @@ void botframe_showwaypointlinks() } player = find(player, classname, "player"); } -}; +} float botframe_autowaypoints_fixdown(vector v) { @@ -925,24 +916,56 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en if(wp) { - // if nearest WP from here is linked to wp, everything is fine - // FIXME consider ALl waypoints for this, not just the nearest! - // i.e. all waypoints w for which wp -> w -> p works - w = navigation_findnearestwaypoint(p, walkfromwp); - if(w && w != wp) + // if any WP w fulfills wp -> w -> porg, then switch from wp to w + + // if wp -> porg, then OK + float maxdist; + if(navigation_waypoint_will_link(wp.origin, porg, p, walkfromwp, 1050)) + { + // we may find a better one + maxdist = vlen(wp.origin - porg); + } + else { - if(navigation_waypoint_will_link(w.origin, wp.origin, p, walkfromwp, 1050)) + // accept any "good" + maxdist = 2100; + } + + float bestdist; + bestdist = maxdist; + w = find(world, classname, "waypoint"); + while (w) + { + if(w != wp && !(w.wpflags & WAYPOINTFLAG_NORELINK)) { - print("update chain from ", etos(p.fld), " to new nearest WP ", etos(w), "\n"); - p.fld = w; - return 0; + 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; + } } + w = find(w, classname, "waypoint"); } - if(navigation_waypoint_will_link(wp.origin, porg, p, walkfromwp, 1050)) + if(bestdist < maxdist) { + print("update chain to new nearest WP ", etos(p.fld), "\n"); + return 0; + } + + if(bestdist < 2100) + { + // we know maxdist < 2100 + // so wp -> porg is still valid + // all is good p.fld = wp; return 0; } + + // otherwise, no existing WP can fix our issues } else { @@ -1030,10 +1053,10 @@ void botframe_autowaypoints_fix(entity p, float walkfromwp, .entity fld) return; // shouldn't happen, caught above botframe_autowaypoints_createwp(trace_endpos, p, fld); } + void botframe_autowaypoints() { entity p; - entity wp0, wp1; FOR_EACH_REALPLAYER(p) { if(p.deadflag) @@ -1044,3 +1067,4 @@ void botframe_autowaypoints() //te_explosion(p.botframe_autowaypoints_lastwp0.origin); } } +