From: terencehill Date: Sun, 16 Apr 2017 18:50:08 +0000 (+0200) Subject: Improve linking of normal waypoints to ladders by autogenerating waypoints for ladders X-Git-Tag: xonotic-v0.8.5~2378^2~185 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=3a2096fd2ebf7f982e75afda194e5372339659e7;p=xonotic%2Fxonotic-data.pk3dir.git Improve linking of normal waypoints to ladders by autogenerating waypoints for ladders --- diff --git a/qcsrc/common/triggers/func/ladder.qc b/qcsrc/common/triggers/func/ladder.qc index 5ff2bdcc2..58c726360 100644 --- a/qcsrc/common/triggers/func/ladder.qc +++ b/qcsrc/common/triggers/func/ladder.qc @@ -45,6 +45,10 @@ void func_ladder_init(entity this) trigger_init(this); func_ladder_link(this); + vector top = (this.absmin + this.absmax) / 2; + top.z = this.absmax.z + 1 - PL_MIN_CONST.z; + float height = this.absmax.z - this.absmin.z; + waypoint_spawnforteleporter_boxes(this, WAYPOINTFLAG_LADDER, this.absmin, this.absmax, top, top, height); } spawnfunc(func_ladder) diff --git a/qcsrc/server/bot/api.qh b/qcsrc/server/bot/api.qh index 3cbf2d9d2..330e61961 100644 --- a/qcsrc/server/bot/api.qh +++ b/qcsrc/server/bot/api.qh @@ -10,6 +10,7 @@ const int WAYPOINTFLAG_PERSONAL = BIT(19); const int WAYPOINTFLAG_PROTECTED = BIT(18); // Useless WP detection never kills these. const int WAYPOINTFLAG_USEFUL = BIT(17); // Useless WP detection temporary flag. const int WAYPOINTFLAG_DEAD_END = BIT(16); // Useless WP detection temporary flag. +const int WAYPOINTFLAG_LADDER = BIT(15); entity kh_worldkeylist; .entity kh_worldkeynext; diff --git a/qcsrc/server/bot/default/navigation.qc b/qcsrc/server/bot/default/navigation.qc index b4503fa14..6fafa9d47 100644 --- a/qcsrc/server/bot/default/navigation.qc +++ b/qcsrc/server/bot/default/navigation.qc @@ -50,7 +50,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float m float stepdist; float ignorehazards; float swimming; - entity tw_ladder = NULL; if(autocvar_bot_debug_tracewalk) { @@ -178,17 +177,26 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float m tracebox(org + jumpstepheightvec, m1, m2, move + jumpstepheightvec, movemode, e); if (trace_fraction < 1 || trace_startsolid) { + bool ladder_found = false; + FOREACH_ENTITY_CLASS("func_ladder", boxesoverlap(trace_endpos + m1 + '-1 -1 -1', trace_endpos + m2 + '1 1 1', it.absmin, it.absmax), + { + if(boxesoverlap(end, end, it.absmin + (m1 - eZ * m1.z - '1 1 0'), it.absmax + (m2 - eZ * m2.z + '1 1 0'))) + ladder_found = true; // can't return here ("Loop mutex held by tracewalk" error) + }); + if(ladder_found) + { + if(autocvar_bot_debug_tracewalk) + debugnodestatus(org, DEBUG_NODE_SUCCESS); + + //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n"); + return true; + } + if(autocvar_bot_debug_tracewalk) debugnodestatus(trace_endpos, DEBUG_NODE_WARNING); - FOREACH_ENTITY_CLASS("func_ladder", true, - { it.solid = SOLID_BSP; }); - traceline( org, move, movemode, e); - FOREACH_ENTITY_CLASS("func_ladder", true, - { it.solid = SOLID_TRIGGER; }); - if ( trace_ent.classname == "door_rotating" || trace_ent.classname == "door") { vector nextmove; @@ -200,24 +208,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float m move = nextmove; } } - else if (trace_ent.classname == "func_ladder") - { - tw_ladder = trace_ent; - vector ladder_bottom = trace_endpos - dir * m2.x; - vector ladder_top = ladder_bottom; - ladder_top.z = trace_ent.absmax.z + (-m1.z + 1); - tracebox(ladder_bottom, m1, m2, ladder_top, movemode, e); - if (trace_fraction < 1 || trace_startsolid) - { - if(autocvar_bot_debug_tracewalk) - debugnodestatus(trace_endpos, DEBUG_NODE_FAIL); - - return false; // failed - } - org = ladder_top + dir * m2.x; - move = org + dir * stepdist; - continue; - } else { if(autocvar_bot_debug_tracewalk) @@ -257,16 +247,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float m org = trace_endpos; } - - if(tw_ladder && org.z < tw_ladder.absmax.z) - { - // stop tracewalk if destination height is lower than the top of the ladder - // otherwise bot can't easily figure out climbing direction - if(autocvar_bot_debug_tracewalk) - debugnodestatus(org, DEBUG_NODE_FAIL); - - return false; - } } //print("tracewalk: ", vtos(start), " did not arrive at ", vtos(end), " but at ", vtos(org), "\n"); diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc index a98a04a37..865cd2160 100644 --- a/qcsrc/server/bot/default/waypoints.qc +++ b/qcsrc/server/bot/default/waypoints.qc @@ -968,11 +968,11 @@ void waypoint_spawnforitem(entity e) waypoint_spawnforitem_force(e, e.origin); } -void waypoint_spawnforteleporter_boxes(entity e, vector org1, vector org2, vector destination1, vector destination2, float timetaken) +void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1, vector org2, vector destination1, vector destination2, float timetaken) { entity w; entity dw; - w = waypoint_spawn(org1, org2, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_TELEPORT | WAYPOINTFLAG_NORELINK); + w = waypoint_spawn(org1, org2, WAYPOINTFLAG_GENERATED | teleport_flag | WAYPOINTFLAG_NORELINK); dw = waypoint_spawn(destination1, destination2, WAYPOINTFLAG_GENERATED); // one way link to the destination w.wp00 = dw; @@ -987,13 +987,13 @@ void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, flo { org = waypoint_fixorigin(org); destination = waypoint_fixorigin(destination); - waypoint_spawnforteleporter_boxes(e, org, org, destination, destination, timetaken); + waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, 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); + waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, e.absmin, e.absmax, destination, destination, timetaken); } entity waypoint_spawnpersonal(entity this, vector position) @@ -1275,6 +1275,8 @@ void botframe_deleteuselesswaypoints() it.wpflags |= WAYPOINTFLAG_USEFUL; if (it.wpflags & WAYPOINTFLAG_TELEPORT) it.wpflags |= WAYPOINTFLAG_USEFUL; + if (it.wpflags & WAYPOINTFLAG_LADDER) + it.wpflags |= WAYPOINTFLAG_USEFUL; if (it.wpflags & WAYPOINTFLAG_PROTECTED) it.wpflags |= WAYPOINTFLAG_USEFUL; // b) WP is closest WP for an item/spawnpoint/other entity