X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fbot%2Fdefault%2Fwaypoints.qc;h=d56b0da44e58e914128f85a31971efaefc534fa6;hb=d46494d5;hp=93ab1efe74310349b96ba654ffe319ddee978ea8;hpb=73fa9f23bb4be30b257a4a7fa0e95622aafeb192;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc index 93ab1efe7..d56b0da44 100644 --- a/qcsrc/server/bot/default/waypoints.qc +++ b/qcsrc/server/bot/default/waypoints.qc @@ -1,5 +1,7 @@ #include "waypoints.qh" +#include +#include #include "cvars.qh" #include "bot.qh" @@ -11,6 +13,7 @@ #include #include +#include #include #include @@ -23,7 +26,14 @@ void waypoint_unreachable(entity pl) it.colormod = '0.5 0.5 0.5'; it.effects &= ~(EF_NODEPTHTEST | EF_RED | EF_BLUE); }); + entity e2 = navigation_findnearestwaypoint(pl, false); + if(!e2) + { + LOG_INFOF("Can't find any waypoint nearby\n"); + return; + } + navigation_markroutes(pl, e2); int j = 0; @@ -160,6 +170,8 @@ void waypoint_setupmodel(entity wp) wp.colormod = '1 0 0'; else if (wp.wpflags & WAYPOINTFLAG_GENERATED) wp.colormod = '1 1 0'; + else if (wp.wphardwired) + wp.colormod = '0.5 0 1'; else wp.colormod = '1 1 1'; } @@ -174,7 +186,13 @@ entity waypoint_spawn(vector m1, vector m2, float f) { if(!(f & WAYPOINTFLAG_PERSONAL)) { - IL_EACH(g_waypoints, boxesoverlap(m1, m2, it.absmin, it.absmax), + vector em1 = m1, em2 = m2; + if (!(f & WAYPOINTFLAG_GENERATED) && m1 == m2) + { + em1 = m1 - '8 8 8'; + em2 = m2 + '8 8 8'; + } + IL_EACH(g_waypoints, boxesoverlap(em1, em2, it.absmin, it.absmax), { return it; }); @@ -235,10 +253,30 @@ void waypoint_spawn_fromeditor(entity pl) ctf_flags = order; } + if(!PHYS_INPUT_BUTTON_CROUCH(pl)) + { + // snap waypoint to item's origin if close enough + IL_EACH(g_items, true, + { + vector item_org = (it.absmin + it.absmax) * 0.5; + item_org.z = it.absmin.z - PL_MIN_CONST.z; + if(vlen(item_org - org) < 30) + { + org = item_org; + break; + } + }); + } + LABEL(add_wp); e = waypoint_spawn(org, org, 0); + if(!e) + { + LOG_INFOF("Couldn't spawn waypoint at %v\n", org); + return; + } waypoint_schedulerelink(e); - bprint(strcat("Waypoint spawned at ", vtos(org), "\n")); + bprint(strcat("Waypoint spawned at ", vtos(e.origin), "\n")); if(sym) { org = waypoint_getSymmetricalOrigin(e.origin, ctf_flags); @@ -368,48 +406,113 @@ bool waypoint_islinked(entity from, entity to) return false; } -// add a new link to the spawnfunc_waypoint, replacing the furthest link it already has -void waypoint_addlink(entity from, entity to) +void waypoint_updatecost_foralllinks() { - float c; + IL_EACH(g_waypoints, !(it.wpflags & WAYPOINTFLAG_TELEPORT), + { + if(it.wp00) it.wp00mincost = waypoint_getlinkcost(it, it.wp00); + if(it.wp01) it.wp01mincost = waypoint_getlinkcost(it, it.wp01); + if(it.wp02) it.wp02mincost = waypoint_getlinkcost(it, it.wp02); + if(it.wp03) it.wp03mincost = waypoint_getlinkcost(it, it.wp03); + if(it.wp04) it.wp04mincost = waypoint_getlinkcost(it, it.wp04); + if(it.wp05) it.wp05mincost = waypoint_getlinkcost(it, it.wp05); + if(it.wp06) it.wp06mincost = waypoint_getlinkcost(it, it.wp06); + if(it.wp07) it.wp07mincost = waypoint_getlinkcost(it, it.wp07); + if(it.wp08) it.wp08mincost = waypoint_getlinkcost(it, it.wp08); + if(it.wp09) it.wp09mincost = waypoint_getlinkcost(it, it.wp09); + if(it.wp10) it.wp10mincost = waypoint_getlinkcost(it, it.wp10); + if(it.wp11) it.wp11mincost = waypoint_getlinkcost(it, it.wp11); + if(it.wp12) it.wp12mincost = waypoint_getlinkcost(it, it.wp12); + if(it.wp13) it.wp13mincost = waypoint_getlinkcost(it, it.wp13); + if(it.wp14) it.wp14mincost = waypoint_getlinkcost(it, it.wp14); + if(it.wp15) it.wp15mincost = waypoint_getlinkcost(it, it.wp15); + if(it.wp16) it.wp16mincost = waypoint_getlinkcost(it, it.wp16); + if(it.wp17) it.wp17mincost = waypoint_getlinkcost(it, it.wp17); + if(it.wp18) it.wp18mincost = waypoint_getlinkcost(it, it.wp18); + if(it.wp19) it.wp19mincost = waypoint_getlinkcost(it, it.wp19); + if(it.wp20) it.wp20mincost = waypoint_getlinkcost(it, it.wp20); + if(it.wp21) it.wp21mincost = waypoint_getlinkcost(it, it.wp21); + if(it.wp22) it.wp22mincost = waypoint_getlinkcost(it, it.wp22); + if(it.wp23) it.wp23mincost = waypoint_getlinkcost(it, it.wp23); + if(it.wp24) it.wp24mincost = waypoint_getlinkcost(it, it.wp24); + if(it.wp25) it.wp25mincost = waypoint_getlinkcost(it, it.wp25); + if(it.wp26) it.wp26mincost = waypoint_getlinkcost(it, it.wp26); + if(it.wp27) it.wp27mincost = waypoint_getlinkcost(it, it.wp27); + if(it.wp28) it.wp28mincost = waypoint_getlinkcost(it, it.wp28); + if(it.wp29) it.wp29mincost = waypoint_getlinkcost(it, it.wp29); + if(it.wp30) it.wp30mincost = waypoint_getlinkcost(it, it.wp30); + if(it.wp31) it.wp31mincost = waypoint_getlinkcost(it, it.wp31); + }); +} - if (from == to) - return; - if (from.wpflags & WAYPOINTFLAG_NORELINK) - return; +float waypoint_getlinearcost(float dist) +{ + if(skill >= autocvar_bot_ai_bunnyhop_skilloffset) + return dist / (autocvar_sv_maxspeed * 1.25); + return dist / autocvar_sv_maxspeed; +} +float waypoint_getlinearcost_underwater(float dist) +{ + // NOTE: this value is hardcoded on the engine too, see SV_WaterMove + return dist / (autocvar_sv_maxspeed * 0.7); +} - if (waypoint_islinked(from, to)) - return; +float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent) +{ + bool submerged_from = navigation_check_submerged_state(from_ent, from); + bool submerged_to = navigation_check_submerged_state(to_ent, to); + + if (submerged_from && submerged_to) + return waypoint_getlinearcost_underwater(vlen(to - from)); + + float c = waypoint_getlinearcost(vlen(to - from)); + + float height = from.z - to.z; + if(height > jumpheight_vec.z && autocvar_sv_gravity > 0) + { + float height_cost = sqrt(height / (autocvar_sv_gravity / 2)); + c = waypoint_getlinearcost(vlen(vec2(to - from))); // xy distance cost + if(height_cost > c) + c = height_cost; + } + + if (submerged_from || submerged_to) + return (c + waypoint_getlinearcost_underwater(vlen(to - from))) / 2; + return c; +} +float waypoint_getlinkcost(entity from, entity to) +{ vector v1 = from.origin; vector v2 = to.origin; - if (to.wpisbox || from.wpisbox) + if (from.wpisbox) { - // if either is a box we have to find the nearest points on them to - // calculate the distance properly - vector m1, m2; - m1 = to.absmin; - m2 = to.absmax; - v1_x = bound(m1_x, v1_x, m2_x); - v1_y = bound(m1_y, v1_y, m2_y); - v1_z = bound(m1_z, v1_z, m2_z); - m1 = from.absmin; - m2 = from.absmax; - v2_x = bound(m1_x, v2_x, m2_x); - v2_y = bound(m1_y, v2_y, m2_y); - v2_z = bound(m1_z, v2_z, m2_z); + vector m1 = from.absmin, m2 = from.absmax; + v1.x = bound(m1.x, v2.x, m2.x); + v1.y = bound(m1.y, v2.y, m2.y); + v1.z = bound(m1.z, v2.z, m2.z); } - c = vlen(v2 - v1) / autocvar_sv_maxspeed; - - float height = v1.z - v2.z; - if(height > 0 && autocvar_sv_gravity > 0) + if (to.wpisbox) { - float height_cost = sqrt(height / autocvar_sv_gravity); - float xydist = vlen((v2 - eZ * v2.z) - (v1 - eZ * v1.z)); - float xydist_cost = xydist / autocvar_sv_maxspeed; - if(max(height_cost, xydist_cost) < c) - c = max(height_cost, xydist_cost); + vector m1 = to.absmin, m2 = to.absmax; + v2.x = bound(m1.x, v1.x, m2.x); + v2.y = bound(m1.y, v1.y, m2.y); + v2.z = bound(m1.z, v1.z, m2.z); } + return waypoint_gettravelcost(v1, v2, from, to); +} + +// add a new link to the spawnfunc_waypoint, replacing the furthest link it already has +// if c == -1 automatically determine cost of the link +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)) + return; + + if(c == -1) + c = waypoint_getlinkcost(from, to); if (from.wp31mincost < c) return; if (from.wp30mincost < c) {from.wp31 = to;from.wp31mincost = c;return;} from.wp31 = from.wp30;from.wp31mincost = from.wp30mincost; @@ -446,20 +549,24 @@ void waypoint_addlink(entity from, entity to) from.wp00 = to;from.wp00mincost = c;return; } +void waypoint_addlink(entity from, entity to) +{ + waypoint_addlink_customcost(from, to, -1); +} + // relink this spawnfunc_waypoint // (precompile a list of all reachable waypoints from this spawnfunc_waypoint) // (SLOW!) void waypoint_think(entity this) { - vector sv, sm1, sm2, ev, em1, em2, dv; + vector sv = '0 0 0', sv2 = '0 0 0', ev = '0 0 0', ev2 = '0 0 0', dv; + float sv2_height = 0, ev2_height = 0; bot_calculate_stepheightvec(); bot_navigation_movemode = ((autocvar_bot_navigation_ignoreplayers) ? MOVE_NOMONSTERS : MOVE_NORMAL); //dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n"); - sm1 = this.origin + this.mins; - sm2 = this.origin + this.maxs; IL_EACH(g_waypoints, this != it, { if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax)) @@ -475,16 +582,10 @@ void waypoint_think(entity this) ++relink_pvsculled; continue; } - 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 = 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); + + SET_TRACEWALK_DESTCOORDS_2(this, it.origin, sv, sv2, sv2_height); + SET_TRACEWALK_DESTCOORDS_2(it, this.origin, ev, ev2, ev2_height); + dv = ev - sv; dv.z = 0; if(vdist(dv, >=, 1050)) // max search distance in XY @@ -492,35 +593,30 @@ void waypoint_think(entity this) ++relink_lengthculled; continue; } + navigation_testtracewalk = 0; - if (!this.wpisbox) - { - tracebox(sv - PL_MIN_CONST.z * '0 0 1', PL_MIN_CONST, PL_MAX_CONST, sv, false, this); - if (!trace_startsolid) - { - //dprint("sv deviation", vtos(trace_endpos - sv), "\n"); - sv = trace_endpos + '0 0 1'; - } - } - if (!it.wpisbox) - { - tracebox(ev - PL_MIN_CONST.z * '0 0 1', PL_MIN_CONST, PL_MAX_CONST, ev, false, it); - if (!trace_startsolid) - { - //dprint("ev deviation", vtos(trace_endpos - ev), "\n"); - ev = trace_endpos + '0 0 1'; - } - } + //traceline(this.origin, it.origin, false, NULL); //if (trace_fraction == 1) - if (!this.wpisbox && tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, ev, MOVE_NOMONSTERS)) - waypoint_addlink(this, it); - else + if (this.wpisbox) relink_walkculled += 0.5; - if (!it.wpisbox && tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, sv, MOVE_NOMONSTERS)) - waypoint_addlink(it, this); else + { + if (tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, ev2, ev2_height, MOVE_NOMONSTERS)) + waypoint_addlink(this, it); + else + relink_walkculled += 0.5; + } + + if (it.wpisbox) relink_walkculled += 0.5; + else + { + if (tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, sv2, sv2_height, MOVE_NOMONSTERS)) + waypoint_addlink(it, this); + else + relink_walkculled += 0.5; + } } }); navigation_testtracewalk = 0; @@ -605,8 +701,27 @@ bool waypoint_load_links() return false; } + bool parse_comments = true; + float ver = 0; + while ((s = fgets(file))) { + if(parse_comments) + { + if(substring(s, 0, 2) == "//") + { + if(substring(s, 2, 8) == "VERSION ") + ver = stof(substring(s, 10, -1)); + continue; + } + else + { + if(ver < WAYPOINT_VERSION) + return false; + parse_comments = false; + } + } + tokens = tokenizebyseparator(s, "*"); if (tokens!=2) @@ -765,6 +880,8 @@ void waypoint_load_or_remove_links_hardwired(bool removal_mode) waypoint_addlink(wp_from, wp_to); wp_from.wphardwired = true; wp_to.wphardwired = true; + waypoint_setupmodel(wp_from); + waypoint_setupmodel(wp_to); } fclose(file); @@ -773,9 +890,6 @@ void waypoint_load_or_remove_links_hardwired(bool removal_mode) LOG_TRACE("loaded ", ftos(c), " waypoint links from maps/", mapname, ".waypoints.hardwired"); } -void waypoint_load_links_hardwired() { waypoint_load_or_remove_links_hardwired(false); } -void waypoint_remove_links_hardwired() { waypoint_load_or_remove_links_hardwired(true); } - entity waypoint_get_link(entity w, float i) { switch(i) @@ -830,6 +944,8 @@ void waypoint_save_links() return; } + fputs(file, strcat("//", "VERSION ", ftos_decimals(WAYPOINT_VERSION, 2), "\n")); + int c = 0; IL_EACH(g_waypoints, true, { @@ -866,6 +982,12 @@ void waypoint_saveall() return; } + // add 3 comments to not break compatibility with older Xonotic versions + // (they are read as a waypoint with origin '0 0 0' and flag 0 though) + fputs(file, strcat("//", "VERSION ", ftos_decimals(WAYPOINT_VERSION, 2), "\n")); + fputs(file, strcat("//", "\n")); + fputs(file, strcat("//", "\n")); + int c = 0; IL_EACH(g_waypoints, true, { @@ -899,49 +1021,66 @@ float waypoint_loadall() filename = strcat("maps/", mapname); filename = strcat(filename, ".waypoints"); file = fopen(filename, FILE_READ); - if (file >= 0) + + bool parse_comments = true; + float ver = 0; + + if (file < 0) { - while ((s = fgets(file))) + LOG_TRACE("waypoint load from ", filename, " failed"); + return 0; + } + + while ((s = fgets(file))) + { + if(parse_comments) { - m1 = stov(s); - s = fgets(file); - if (!s) - break; - m2 = stov(s); - s = fgets(file); - if (!s) - break; - fl = stof(s); - waypoint_spawn(m1, m2, fl); - if (m1 == m2) - cwp = cwp + 1; + if(substring(s, 0, 2) == "//") + { + if(substring(s, 2, 8) == "VERSION ") + ver = stof(substring(s, 10, -1)); + continue; + } else - cwb = cwb + 1; + { + if(floor(ver) < floor(WAYPOINT_VERSION)) + LOG_TRACE("waypoints for this map are outdated"); + parse_comments = false; + } } - fclose(file); - LOG_TRACE("loaded ", ftos(cwp), " waypoints and ", ftos(cwb), " wayboxes from maps/", mapname, ".waypoints"); - } - else - { - LOG_TRACE("waypoint load from ", filename, " failed"); + m1 = stov(s); + s = fgets(file); + if (!s) + break; + m2 = stov(s); + s = fgets(file); + if (!s) + break; + fl = stof(s); + waypoint_spawn(m1, m2, fl); + if (m1 == m2) + cwp = cwp + 1; + else + cwb = cwb + 1; } + fclose(file); + LOG_TRACE("loaded ", ftos(cwp), " waypoints and ", ftos(cwb), " wayboxes from maps/", mapname, ".waypoints"); + return cwp + cwb; } -vector waypoint_fixorigin(vector position) +vector waypoint_fixorigin(vector position, entity tracetest_ent) { - tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + '0 0 -512', MOVE_NOMONSTERS, NULL); + tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + '0 0 -512', MOVE_NOMONSTERS, tracetest_ent); if(trace_fraction < 1) position = trace_endpos; - //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) { // Fix the waypoint altitude if necessary - org = waypoint_fixorigin(org); + org = waypoint_fixorigin(org, NULL); // don't spawn an item spawnfunc_waypoint if it already exists IL_EACH(g_waypoints, true, @@ -990,17 +1129,17 @@ void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1, e.nearestwaypointtimeout = -1; } -void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken) +void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent) { - org = waypoint_fixorigin(org); - destination = waypoint_fixorigin(destination); + org = waypoint_fixorigin(org, tracetest_ent); + destination = waypoint_fixorigin(destination, tracetest_ent); waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, org, org, destination, destination, timetaken); } -void waypoint_spawnforteleporter(entity e, vector destination, float timetaken) +void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent) { - destination = waypoint_fixorigin(destination); - waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, e.absmin, e.absmax, destination, destination, timetaken); + destination = waypoint_fixorigin(destination, tracetest_ent); + waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, e.absmin - PL_MAX_CONST + '1 1 1', e.absmax - PL_MIN_CONST + '-1 -1 -1', destination, destination, timetaken); } entity waypoint_spawnpersonal(entity this, vector position) @@ -1010,7 +1149,7 @@ entity waypoint_spawnpersonal(entity this, vector position) // drop the waypoint to a proper location: // first move it up by a player height // then move it down to hit the floor with player bbox size - position = waypoint_fixorigin(position); + position = waypoint_fixorigin(position, this); w = waypoint_spawn(position, position, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_PERSONAL); w.nearestwaypoint = NULL; @@ -1033,6 +1172,35 @@ void waypoint_showlink(entity wp1, entity wp2, int display_type) te_lightning2(NULL, wp1.origin, wp2.origin); } +void waypoint_showlinks_to(entity wp, int display_type) +{ + IL_EACH(g_waypoints, it != wp, + { + if (waypoint_islinked(it, wp)) + waypoint_showlink(it, wp, display_type); + }); +} + +void waypoint_showlinks_from(entity wp, int display_type) +{ + waypoint_showlink(wp.wp00, wp, display_type); waypoint_showlink(wp.wp16, wp, display_type); + waypoint_showlink(wp.wp01, wp, display_type); waypoint_showlink(wp.wp17, wp, display_type); + waypoint_showlink(wp.wp02, wp, display_type); waypoint_showlink(wp.wp18, wp, display_type); + waypoint_showlink(wp.wp03, wp, display_type); waypoint_showlink(wp.wp19, wp, display_type); + waypoint_showlink(wp.wp04, wp, display_type); waypoint_showlink(wp.wp20, wp, display_type); + waypoint_showlink(wp.wp05, wp, display_type); waypoint_showlink(wp.wp21, wp, display_type); + waypoint_showlink(wp.wp06, wp, display_type); waypoint_showlink(wp.wp22, wp, display_type); + waypoint_showlink(wp.wp07, wp, display_type); waypoint_showlink(wp.wp23, wp, display_type); + waypoint_showlink(wp.wp08, wp, display_type); waypoint_showlink(wp.wp24, wp, display_type); + waypoint_showlink(wp.wp09, wp, display_type); waypoint_showlink(wp.wp25, wp, display_type); + waypoint_showlink(wp.wp10, wp, display_type); waypoint_showlink(wp.wp26, wp, display_type); + waypoint_showlink(wp.wp11, wp, display_type); waypoint_showlink(wp.wp27, wp, display_type); + waypoint_showlink(wp.wp12, wp, display_type); waypoint_showlink(wp.wp28, wp, display_type); + waypoint_showlink(wp.wp13, wp, display_type); waypoint_showlink(wp.wp29, wp, display_type); + waypoint_showlink(wp.wp14, wp, display_type); waypoint_showlink(wp.wp30, wp, display_type); + waypoint_showlink(wp.wp15, wp, display_type); waypoint_showlink(wp.wp31, wp, display_type); +} + void botframe_showwaypointlinks() { if (time < botframe_waypointeditorlightningtime) @@ -1055,38 +1223,10 @@ void botframe_showwaypointlinks() if (head) { te_lightning2(NULL, head.origin, it.origin); - waypoint_showlink(head.wp00, head, display_type); - waypoint_showlink(head.wp01, head, display_type); - waypoint_showlink(head.wp02, head, display_type); - waypoint_showlink(head.wp03, head, display_type); - waypoint_showlink(head.wp04, head, display_type); - waypoint_showlink(head.wp05, head, display_type); - waypoint_showlink(head.wp06, head, display_type); - waypoint_showlink(head.wp07, head, display_type); - waypoint_showlink(head.wp08, head, display_type); - waypoint_showlink(head.wp09, head, display_type); - waypoint_showlink(head.wp10, head, display_type); - waypoint_showlink(head.wp11, head, display_type); - waypoint_showlink(head.wp12, head, display_type); - waypoint_showlink(head.wp13, head, display_type); - waypoint_showlink(head.wp14, head, display_type); - waypoint_showlink(head.wp15, head, display_type); - waypoint_showlink(head.wp16, head, display_type); - waypoint_showlink(head.wp17, head, display_type); - waypoint_showlink(head.wp18, head, display_type); - waypoint_showlink(head.wp19, head, display_type); - waypoint_showlink(head.wp20, head, display_type); - waypoint_showlink(head.wp21, head, display_type); - waypoint_showlink(head.wp22, head, display_type); - waypoint_showlink(head.wp23, head, display_type); - waypoint_showlink(head.wp24, head, display_type); - waypoint_showlink(head.wp25, head, display_type); - waypoint_showlink(head.wp26, head, display_type); - waypoint_showlink(head.wp27, head, display_type); - waypoint_showlink(head.wp28, head, display_type); - waypoint_showlink(head.wp29, head, display_type); - waypoint_showlink(head.wp30, head, display_type); - waypoint_showlink(head.wp31, head, display_type); + if(PHYS_INPUT_BUTTON_CROUCH(it)) + waypoint_showlinks_to(head, display_type); + else + waypoint_showlinks_from(head, display_type); } } }); @@ -1138,7 +1278,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en // if wp -> porg, then OK float maxdist; - if(navigation_waypoint_will_link(wp.origin, porg, p, walkfromwp, 1050)) + if(navigation_waypoint_will_link(wp.origin, porg, p, porg, 0, wp.origin, 0, walkfromwp, 1050)) { // we may find a better one maxdist = vlen(wp.origin - porg); @@ -1154,8 +1294,8 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en { 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)) + if(navigation_waypoint_will_link(wp.origin, it.origin, p, it.origin, 0, wp.origin, 0, walkfromwp, 1050)) + if(navigation_waypoint_will_link(it.origin, porg, p, porg, 0, it.origin, 0, walkfromwp, 1050)) { bestdist = d; p.(fld) = it; @@ -1209,7 +1349,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en if(wp) { - if(!navigation_waypoint_will_link(wp.origin, o, p, walkfromwp, 1050)) + if(!navigation_waypoint_will_link(wp.origin, o, p, o, 0, wp.origin, 0, walkfromwp, 1050)) { // we cannot walk from wp.origin to o // get closer to tmax @@ -1235,7 +1375,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en // if we get here, o is valid regarding waypoints // check if o is connected right to the player // we break if it succeeds, as that means o is a good waypoint location - if(navigation_waypoint_will_link(o, porg, p, walkfromwp, 1050)) + if(navigation_waypoint_will_link(o, porg, p, porg, 0, o, 0, walkfromwp, 1050)) break; // o is no good, we need to get closer to the player @@ -1346,12 +1486,12 @@ LABEL(next) void botframe_autowaypoints() { - FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && !IS_DEAD(it), LAMBDA( + FOREACH_CLIENT(IS_PLAYER(it) && IS_REAL_CLIENT(it) && !IS_DEAD(it), { // going back is broken, so only fix waypoints to walk TO the player //botframe_autowaypoints_fix(p, false, botframe_autowaypoints_lastwp0); botframe_autowaypoints_fix(it, true, botframe_autowaypoints_lastwp1); //te_explosion(p.botframe_autowaypoints_lastwp0.origin); - )); + }); if (autocvar_g_waypointeditor_auto >= 2) { botframe_deleteuselesswaypoints();