float stepdist;
float ignorehazards;
float swimming;
- entity tw_ladder = NULL;
if(autocvar_bot_debug_tracewalk)
{
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;
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)
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");
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;
{
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)
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