X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fwaypoints.qc;h=65da3b94c5eac95d7a1c6fcf275cf3cf314798c8;hb=67610c5b92e218cc245c040209c1a79ab6b02758;hp=2399da8ab38a5b0ce34fecf5b5438c63b4b55ae8;hpb=38e30977c8a64a89eae680587bcbd05074cdb26c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc index 2399da8ab..65da3b94c 100644 --- a/qcsrc/server/bot/default/waypoints.qc +++ b/qcsrc/server/bot/default/waypoints.qc @@ -1,7 +1,10 @@ #include "waypoints.qh" -#include -#include +#include +#include +#include +#include +#include #include "cvars.qh" #include "bot.qh" @@ -13,6 +16,7 @@ #include #include +#include #include #include #include @@ -260,6 +264,13 @@ vector waypoint_getSymmetricalPoint(vector org, int ctf_flags) return new_org; } +void crosshair_trace_waypoints(entity pl); +void waypoint_lock(entity pl) +{ + crosshair_trace_waypoints(pl); + pl.wp_locked = trace_ent; +} + bool waypoint_has_hardwiredlinks(entity wp) { if (!wp) @@ -334,6 +345,18 @@ void waypoint_unmark_hardwiredlink(entity wp_from, entity wp_to) return; } +void waypoint_restore_hardwiredlinks(entity wp) +{ + if (wp.wphw00) waypoint_addlink(wp, wp.wphw00); + if (wp.wphw01) waypoint_addlink(wp, wp.wphw01); + if (wp.wphw02) waypoint_addlink(wp, wp.wphw02); + if (wp.wphw03) waypoint_addlink(wp, wp.wphw03); + if (wp.wphw04) waypoint_addlink(wp, wp.wphw04); + if (wp.wphw05) waypoint_addlink(wp, wp.wphw05); + if (wp.wphw06) waypoint_addlink(wp, wp.wphw06); + if (wp.wphw07) waypoint_addlink(wp, wp.wphw07); +} + void waypoint_setupmodel(entity wp) { if (autocvar_g_waypointeditor) @@ -350,7 +373,13 @@ void waypoint_setupmodel(entity wp) wp.colormod = '1 1 0'; // yellow else if (wp.wpflags & WAYPOINTFLAG_SUPPORT) wp.colormod = '0 1 0'; // green - else if (wp.wpflags & WAYPOINTFLAG_NORELINK) + else if (wp.wpflags & WAYPOINTFLAG_CUSTOM_JP) + wp.colormod = '1 0.5 0'; // orange + else if (wp.wpflags & WAYPOINTFLAG_TELEPORT) + wp.colormod = '1 0.5 0'; // orange + else if (wp.wpflags & WAYPOINTFLAG_LADDER) + wp.colormod = '1 0.5 0'; // orange + else if (wp.wpflags & WAYPOINTFLAG_JUMP) wp.colormod = '1 0.5 0'; // orange else if (wp.wpflags & WAYPOINTFLAG_CROUCH) wp.colormod = '0 1 1'; // cyan @@ -410,7 +439,7 @@ entity waypoint_spawn(vector m1, vector m2, float f) // spawn only one destination waypoint for teleports teleporting player to the exact same spot // otherwise links loaded from file would be applied only to the first destination // waypoint since link format doesn't specify waypoint entities but just positions - if((f & WAYPOINTFLAG_GENERATED) && !(f & (WAYPOINTFLAG_NORELINK | WAYPOINTFLAG_PERSONAL)) && m1 == m2) + if((f & WAYPOINTFLAG_GENERATED) && !(f & (WPFLAGMASK_NORELINK | WAYPOINTFLAG_PERSONAL)) && m1 == m2) { IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax), { @@ -445,7 +474,7 @@ entity waypoint_spawn(vector m1, vector m2, float f) } else { - if(autocvar_developer) + if(autocvar_developer > 0) { LOG_INFO("A generated waypoint is stuck in solid at ", vtos(w.origin)); backtrace("Waypoint stuck"); @@ -498,19 +527,40 @@ void waypoint_clear_start_wp_globals(entity pl, bool warn) LOG_INFO("^xf80Start waypoint has been cleared.\n"); } -void waypoint_start_hardwiredlink(entity pl) +void waypoint_start_hardwiredlink(entity pl, bool at_crosshair) { entity wp = pl.nearestwaypoint; - if ((!start_wp_is_spawned || start_wp_is_hardwired) && wp && !(wp.wpflags & WAYPOINTFLAG_NORELINK)) + if (at_crosshair) + { + crosshair_trace_waypoints(pl); + wp = trace_ent; + } + string err = ""; + if (start_wp_is_spawned && !start_wp_is_hardwired) + err = "can't hardwire while in the process of creating a special link"; + else if (!wp) + { + if (at_crosshair) + err = "couldn't find any waypoint at crosshair"; + else + err = "couldn't find any waypoint nearby"; + } + else if (wp.wpflags & WPFLAGMASK_NORELINK) + err = "can't hardwire a waypoint with special links"; + + if (err == "") { start_wp_is_hardwired = true; start_wp_is_spawned = true; start_wp_origin = wp.origin; pl.wp_locked = wp; - LOG_INFOF("^x80fNearest waypoint %s marked as hardwired link origin.\n", vtos(wp.origin)); + LOG_INFOF("^x80fWaypoint %s marked as hardwired link origin.\n", vtos(wp.origin)); } else + { start_wp_is_hardwired = false; + LOG_INFO("Error: ", err, "\n"); + } } void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bool is_crouch_wp, bool is_support_wp) @@ -526,14 +576,23 @@ void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bo vector org = pl.origin; if (at_crosshair) { - crosshair_trace(pl); - org = trace_endpos - eZ * PL_MIN_CONST.z; + crosshair_trace_waypoints(pl); + org = trace_endpos; + if (!trace_ent) + org.z -= PL_MIN_CONST.z; if (!(start_wp_is_hardwired || start_wp_is_support)) IL_EACH(g_jumppads, boxesoverlap(org + PL_MIN_CONST, org + PL_MAX_CONST, it.absmin, it.absmax), { jp = it; break; }); + if (!jp && !start_wp_is_spawned && trace_ent) + { + if (trace_ent.wpflags & (WAYPOINTFLAG_JUMP)) + is_jump_wp = true; + else if (trace_ent.wpflags & (WAYPOINTFLAG_SUPPORT)) + is_support_wp = true; + } } if (jp || is_jump_wp || is_support_wp) { @@ -582,13 +641,13 @@ void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bo if (jp) { e = NULL; - IL_EACH(g_waypoints, it.wpflags & WAYPOINTFLAG_NORELINK + IL_EACH(g_waypoints, (it.wpflags & WPFLAGMASK_NORELINK) && boxesoverlap(org + PL_MIN_CONST, org + PL_MAX_CONST, it.absmin, it.absmax), { e = it; break; }); if (!e) - e = waypoint_spawn(jp.absmin - PL_MAX_CONST + '1 1 1', jp.absmax - PL_MIN_CONST + '-1 -1 -1', WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_NORELINK); + e = waypoint_spawn(jp.absmin - PL_MAX_CONST + '1 1 1', jp.absmax - PL_MIN_CONST + '-1 -1 -1', WAYPOINTFLAG_TELEPORT); if (!pl.wp_locked) pl.wp_locked = e; } @@ -602,7 +661,7 @@ void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bo LOG_INFOF("Error: can't spawn a %s waypoint over an existent waypoint of a different type\n", (is_jump_wp) ? "Jump" : "Support"); return; } - e = waypoint_spawn(org, org, type_flag | WAYPOINTFLAG_NORELINK); + e = waypoint_spawn(org, org, type_flag); if (!pl.wp_locked) pl.wp_locked = e; } @@ -625,7 +684,7 @@ void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bo entity start_wp = NULL; if (start_wp_is_spawned) { - IL_EACH(g_waypoints, (start_wp_is_hardwired || it.wpflags & WAYPOINTFLAG_NORELINK) + IL_EACH(g_waypoints, (start_wp_is_hardwired || (it.wpflags & WPFLAGMASK_NORELINK)) && boxesoverlap(start_org, start_org, it.absmin, it.absmax), { start_wp = it; break; @@ -757,9 +816,6 @@ void waypoint_spawn_fromeditor(entity pl, bool at_crosshair, bool is_jump_wp, bo void waypoint_remove(entity wp) { - if (wp.SUPPORT_WP) - waypoint_remove(wp.SUPPORT_WP); // remove support waypoint too - IL_EACH(g_waypoints, it != wp, { if (it.SUPPORT_WP == wp) @@ -809,7 +865,7 @@ void waypoint_remove_fromeditor(entity pl) if (waypoint_has_hardwiredlinks(e)) { - LOG_INFO("Can't remove a waypoint with hardwired links, remove them with \"wpeditor hardwire\" first\n"); + LOG_INFO("Can't remove a waypoint with hardwired links, remove links with \"wpeditor hardwire\" first\n"); return; } @@ -827,6 +883,7 @@ void waypoint_remove_fromeditor(entity pl) } bprint(strcat("Waypoint removed at ", vtos(e.origin), "\n")); + te_explosion(e.origin); waypoint_remove(e); if (sym && wp_sym) @@ -845,7 +902,7 @@ void waypoint_remove_fromeditor(entity pl) void waypoint_removelink(entity from, entity to) { - if (from == to || (from.wpflags & WAYPOINTFLAG_NORELINK && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT)))) + if (from == to || ((from.wpflags & WPFLAGMASK_NORELINK) && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT)))) return; entity fromwp31_prev = from.wp31; @@ -974,7 +1031,7 @@ float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ if (submerged_from && submerged_to) return waypoint_getlinearcost_underwater(vlen(to - from)); - if (from_ent.wpflags & WAYPOINTFLAG_CROUCH && to_ent.wpflags & WAYPOINTFLAG_CROUCH) + if ((from_ent.wpflags & WAYPOINTFLAG_CROUCH) && (to_ent.wpflags & WAYPOINTFLAG_CROUCH)) return waypoint_getlinearcost_crouched(vlen(to - from)); float c = waypoint_getlinearcost(vlen(to - from)); @@ -983,7 +1040,7 @@ float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ if(height > jumpheight_vec.z && autocvar_sv_gravity > 0) { float height_cost; // fall cost - if (boolean(from_ent.wpflags & WAYPOINTFLAG_JUMP)) + if (from_ent.wpflags & WAYPOINTFLAG_JUMP) height_cost = jumpheight_time + sqrt((height + jumpheight_vec.z) / (autocvar_sv_gravity / 2)); else height_cost = sqrt(height / (autocvar_sv_gravity / 2)); @@ -997,7 +1054,7 @@ float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ return (c + waypoint_getlinearcost_underwater(vlen(to - from))) / 2; // consider half path crouched - if (from_ent.wpflags & WAYPOINTFLAG_CROUCH || to_ent.wpflags & WAYPOINTFLAG_CROUCH) + if ((from_ent.wpflags & WAYPOINTFLAG_CROUCH) || (to_ent.wpflags & WAYPOINTFLAG_CROUCH)) return (c + waypoint_getlinearcost_crouched(vlen(to - from))) / 2; return c; @@ -1030,7 +1087,7 @@ void waypoint_addlink_customcost(entity from, entity to, float c) { if (from == to || waypoint_islinked(from, to)) return; - if (c == -1 && (from.wpflags & WAYPOINTFLAG_NORELINK) && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT))) + if (c == -1 && (from.wpflags & WPFLAGMASK_NORELINK) && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT))) return; if(c == -1) @@ -1073,7 +1130,7 @@ void waypoint_addlink_customcost(entity from, entity to, float c) void waypoint_addlink(entity from, entity to) { - if ((from.wpflags & WAYPOINTFLAG_NORELINK) && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT))) + if ((from.wpflags & WPFLAGMASK_NORELINK) && !(from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT))) waypoint_addlink_for_custom_jumppad(from, to); else waypoint_addlink_customcost(from, to, -1); @@ -1102,9 +1159,9 @@ void waypoint_think(entity this) { if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax)) { - if (!(this.wpflags & WAYPOINTFLAG_NORELINK)) + if (!(this.wpflags & WPFLAGMASK_NORELINK)) waypoint_addlink(this, it); - if (!(it.wpflags & WAYPOINTFLAG_NORELINK)) + if (!(it.wpflags & WPFLAGMASK_NORELINK)) waypoint_addlink(it, this); } else @@ -1129,14 +1186,14 @@ void waypoint_think(entity this) vector m1 = PL_MIN_CONST; vector m2 = PL_MAX_CONST; - if (this.wpflags & WAYPOINTFLAG_CROUCH || it.wpflags & WAYPOINTFLAG_CROUCH) + if ((this.wpflags & WAYPOINTFLAG_CROUCH) || (it.wpflags & WAYPOINTFLAG_CROUCH)) { m1 = PL_CROUCH_MIN_CONST; m2 = PL_CROUCH_MAX_CONST; // links from crouch wp to normal wp (and viceversa) are very short to avoid creating many links // that would be wasted due to rough travel cost calculation (the longer link is, the higher cost is) // links from crouch wp to crouch wp can be as long as normal links - if (!(this.wpflags & WAYPOINTFLAG_CROUCH && it.wpflags & WAYPOINTFLAG_CROUCH)) + if (!((this.wpflags & WAYPOINTFLAG_CROUCH) && (it.wpflags & WAYPOINTFLAG_CROUCH))) maxdist = 100; } @@ -1150,7 +1207,7 @@ void waypoint_think(entity this) //traceline(this.origin, it.origin, false, NULL); //if (trace_fraction == 1) - if (this.wpisbox || this.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT) // forbid outgoing links + if (this.wpisbox || (this.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT)) // forbid outgoing links || it.SUPPORT_WP) // forbid incoming links { relink_walkculled += 0.5; @@ -1164,7 +1221,7 @@ void waypoint_think(entity this) } // reverse direction - if (it.wpisbox || it.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT) // forbid incoming links + if (it.wpisbox || (it.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT)) // forbid incoming links || this.SUPPORT_WP) // forbid outgoing links { relink_walkculled += 0.5; @@ -1178,6 +1235,11 @@ void waypoint_think(entity this) } } }); + + // waypoint_clearlinks preserves references to old hardwired links (.wphwXX links) + // so they can be restored here when a wp is spawned over an existing one + waypoint_restore_hardwiredlinks(this); + navigation_testtracewalk = 0; this.wplinked = true; this.dphitcontentsmask = dphitcontentsmask_save; @@ -1200,6 +1262,8 @@ void waypoint_clearlinks(entity wp) wp.wp16mincost = wp.wp17mincost = wp.wp18mincost = wp.wp19mincost = wp.wp20mincost = wp.wp21mincost = wp.wp22mincost = wp.wp23mincost = f; wp.wp24mincost = wp.wp25mincost = wp.wp26mincost = wp.wp27mincost = wp.wp28mincost = wp.wp29mincost = wp.wp30mincost = wp.wp31mincost = f; + // don't remove references to hardwired links (.wphwXX fields) + wp.wplinked = false; } @@ -1214,7 +1278,7 @@ void waypoint_schedulerelink(entity wp) wp.enemy = NULL; if (!(wp.wpflags & WAYPOINTFLAG_PERSONAL)) wp.owner = NULL; - if (!(wp.wpflags & WAYPOINTFLAG_NORELINK)) + if (!(wp.wpflags & WPFLAGMASK_NORELINK)) waypoint_clearlinks(wp); // schedule an actual relink on next frame setthink(wp, waypoint_think); @@ -1466,7 +1530,8 @@ void waypoint_load_hardwiredlinks() if(!found) { - LOG_INFO("NOTICE: Can not find origin waypoint for the hardwired link ", s, ". Path skipped"); + s = strcat(((is_special) ? "special link " : "hardwired link "), s); + LOG_INFO("NOTICE: Can not find origin waypoint of the ", s, ". Path skipped"); continue; } } @@ -1487,7 +1552,8 @@ void waypoint_load_hardwiredlinks() if(!found) { - LOG_INFO("NOTICE: Can not find destination waypoint for the hardwired link ", s, ". Path skipped"); + s = strcat(((is_special) ? "special link " : "hardwired link "), s); + LOG_INFO("NOTICE: Can not find destination waypoint of the ", s, ". Path skipped"); continue; } @@ -1497,8 +1563,8 @@ void waypoint_load_hardwiredlinks() { waypoint_addlink(wp_from, wp_to); waypoint_mark_hardwiredlink(wp_from, wp_to); - } else if (wp_from.wpflags & WAYPOINTFLAG_NORELINK - && (wp_from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT) + } else if (wp_from.wpflags & WPFLAGMASK_NORELINK + && ((wp_from.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT)) || (wp_from.wpisbox && wp_from.wpflags & WAYPOINTFLAG_TELEPORT))) { waypoint_addlink(wp_from, wp_to); @@ -1510,6 +1576,46 @@ void waypoint_load_hardwiredlinks() LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.hardwired"); } +float waypoint_get_assigned_link_cost(entity w, float i) +{ + switch(i) + { + case 0: return w.wp00mincost; + case 1: return w.wp01mincost; + case 2: return w.wp02mincost; + case 3: return w.wp03mincost; + case 4: return w.wp04mincost; + case 5: return w.wp05mincost; + case 6: return w.wp06mincost; + case 7: return w.wp07mincost; + case 8: return w.wp08mincost; + case 9: return w.wp09mincost; + case 10: return w.wp10mincost; + case 11: return w.wp11mincost; + case 12: return w.wp12mincost; + case 13: return w.wp13mincost; + case 14: return w.wp14mincost; + case 15: return w.wp15mincost; + case 16: return w.wp16mincost; + case 17: return w.wp17mincost; + case 18: return w.wp18mincost; + case 19: return w.wp19mincost; + case 20: return w.wp20mincost; + case 21: return w.wp21mincost; + case 22: return w.wp22mincost; + case 23: return w.wp23mincost; + case 24: return w.wp24mincost; + case 25: return w.wp25mincost; + case 26: return w.wp26mincost; + case 27: return w.wp27mincost; + case 28: return w.wp28mincost; + case 29: return w.wp29mincost; + case 30: return w.wp30mincost; + case 31: return w.wp31mincost; + default: return -1; + } +} + entity waypoint_get_link(entity w, float i) { switch(i) @@ -1729,7 +1835,7 @@ void waypoint_saveall() float waypoint_loadall() { string s; - float file, cwp, cwb, fl; + int file, cwp, cwb, fl; vector m1, m2; cwp = 0; cwb = 0; @@ -1796,6 +1902,7 @@ float waypoint_loadall() if (!s) break; fl = stof(s); + fl &= ~WAYPOINTFLAG_NORELINK__DEPRECATED; waypoint_spawn(m1, m2, fl); if (m1 == m2) cwp = cwp + 1; @@ -1808,6 +1915,7 @@ float waypoint_loadall() if (autocvar_g_waypointeditor && autocvar_g_waypointeditor_symmetrical_allowload) { + string sym_str = ""; cvar_set("g_waypointeditor_symmetrical", ftos(sym)); if (sym == 1 && sym_param3 < 2) cvar_set("g_waypointeditor_symmetrical_order", "0"); // make sure this is reset if not loaded @@ -1822,16 +1930,18 @@ float waypoint_loadall() cvar_set("g_waypointeditor_symmetrical_origin", params); } cvar_set("g_waypointeditor_symmetrical_order", ftos(sym_param3)); - LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym), " with origin ", params, " and order ", ftos(sym_param3)); + sym_str = strcat(ftos(sym), " with origin ", params, " and order ", ftos(sym_param3)); } else if (sym == -2) { string params = strcat(ftos(sym_param1), " ", ftos(sym_param2)); cvar_set("g_waypointeditor_symmetrical_axis", params); - LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym), " with axis ", params); + sym_str = strcat(ftos(sym), " with axis ", params); } else - LOG_INFO("Waypoint editor: loaded symmetry ", ftos(sym)); + sym_str = ftos(sym); + if (sym_str != "") + LOG_INFO("Waypoint editor: loaded symmetry ", sym_str); LOG_INFO(strcat("g_waypointeditor_symmetrical", " has been set to ", cvar_string("g_waypointeditor_symmetrical"))); } @@ -1899,7 +2009,7 @@ void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1, { entity w; entity dw; - w = waypoint_spawn(org1, org2, WAYPOINTFLAG_GENERATED | teleport_flag | WAYPOINTFLAG_NORELINK); + w = waypoint_spawn(org1, org2, WAYPOINTFLAG_GENERATED | teleport_flag); dw = waypoint_spawn(destination1, destination2, WAYPOINTFLAG_GENERATED); // one way link to the destination w.wp00_original = dw; @@ -1979,7 +2089,7 @@ void waypoint_showlink(entity wp1, entity wp2, int display_type) if (!(wp1 && wp2)) return; - if (waypoint_is_hardwiredlink(wp1, wp2) || wp1.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT | WAYPOINTFLAG_CUSTOM_JP)) + if (waypoint_is_hardwiredlink(wp1, wp2) || (wp1.wpflags & (WAYPOINTFLAG_JUMP | WAYPOINTFLAG_SUPPORT | WAYPOINTFLAG_CUSTOM_JP))) te_beam(NULL, wp1.origin, wp2.origin); else if (display_type == 1) te_lightning2(NULL, wp1.origin, wp2.origin); @@ -2022,15 +2132,18 @@ void crosshair_trace_waypoints(entity pl) setsize(it, '-16 -16 -16', '16 16 16'); }); - crosshair_trace(pl); + WarpZone_crosshair_trace(pl); IL_EACH(g_waypoints, true, { it.solid = SOLID_TRIGGER; if (!it.wpisbox) setsize(it, '0 0 0', '0 0 0'); }); + if (trace_ent.classname != "waypoint") trace_ent = NULL; + else if (!trace_ent.wpisbox) + trace_endpos = trace_ent.origin; } void botframe_showwaypointlinks() @@ -2045,8 +2158,6 @@ void botframe_showwaypointlinks() it.wp_aimed = NULL; if (wasfreed(it.wp_locked)) it.wp_locked = NULL; - if (PHYS_INPUT_BUTTON_USE(it)) - it.wp_locked = it.wp_aimed; entity head = it.wp_locked; if (!head) head = navigation_findnearestwaypoint(it, false); @@ -2156,7 +2267,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en } float bestdist = maxdist; - IL_EACH(g_waypoints, it != wp && !(it.wpflags & WAYPOINTFLAG_NORELINK), + IL_EACH(g_waypoints, it != wp && !(it.wpflags & WPFLAGMASK_NORELINK), { float d = vlen(wp.origin - it.origin) + vlen(it.origin - porg); if(d < bestdist) @@ -2254,7 +2365,6 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en } // automatically create missing waypoints -.entity botframe_autowaypoints_lastwp0, botframe_autowaypoints_lastwp1; void botframe_autowaypoints_fix(entity p, float walkfromwp, .entity fld) { float r = botframe_autowaypoints_fix_from(p, walkfromwp, p.(fld), fld); @@ -2350,6 +2460,8 @@ LABEL(next) }); } +//.entity botframe_autowaypoints_lastwp0; +.entity botframe_autowaypoints_lastwp1; void botframe_autowaypoints() { FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && !IS_DEAD(it), {