From 90a10aae8ef695a76a56874ac91c3f3aaedb581a Mon Sep 17 00:00:00 2001 From: terencehill Date: Tue, 23 May 2017 15:09:06 +0200 Subject: [PATCH] Bot navigation: don't try to climb ladders up if they are obstructed (in particular it detects the wrong side of ladders); implement detection of ladders underwater --- qcsrc/server/bot/default/navigation.qc | 45 +++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 5 deletions(-) diff --git a/qcsrc/server/bot/default/navigation.qc b/qcsrc/server/bot/default/navigation.qc index 345ebd395..52752b8d5 100644 --- a/qcsrc/server/bot/default/navigation.qc +++ b/qcsrc/server/bot/default/navigation.qc @@ -119,7 +119,10 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e } if (trace_dpstartcontents & DPCONTENTS_LIQUIDSMASK) { - vector move = org + normalize(end - org) * stepdist; + vector water_end = end; + water_end.z = bound(end.z, org.z, end2.z); + vector water_dir = normalize(water_end - org); + vector move = org + water_dir * stepdist; tracebox(org, m1, m2, move, movemode, e); if(autocvar_bot_debug_tracewalk) @@ -128,8 +131,8 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e if (trace_fraction < 1) { swimming = true; - org = trace_endpos + normalize(org - trace_endpos) * stepdist; - for (; org.z < end.z + e.maxs.z; org.z += stepdist) + org = trace_endpos - water_dir * (stepdist / 2); + for (; org.z < end2.z + e.maxs.z; org.z += stepdist) { if(autocvar_bot_debug_tracewalk) debugnode(e, org); @@ -146,6 +149,29 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e return false; //print("tracewalk: ", vtos(start), " failed under water\n"); } + + bool ladder_found = false; + IL_EACH(g_ladders, it.classname == "func_ladder", + { + if(it.bot_pickup) + if(boxesoverlap(move + m1 + '-1 -1 -1', move + m2 + '1 1 1', it.absmin, it.absmax)) + if(boxesoverlap(end, end2, it.absmin + (m1 - eZ * m1.z - '1 1 0'), it.absmax + (m2 - eZ * m2.z + '1 1 0'))) + { + vector top = org; + top.z = it.absmax.z + (PL_MAX_CONST.z - PL_MIN_CONST.z); + tracebox(org, m1, m2, top, movemode, e); + if(trace_fraction == 1) + ladder_found = true; // can't return here ("Loop mutex held by tracewalk" error) + } + }); + if(ladder_found) + { + if(autocvar_bot_debug_tracewalk) + debugnodestatus(trace_endpos, DEBUG_NODE_SUCCESS); + + //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n"); + return true; + } continue; } @@ -170,22 +196,31 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e tracebox(org + jumpstepheightvec, m1, m2, move + jumpstepheightvec, movemode, e); if (trace_fraction < 1 || trace_startsolid) { + vector org_save = org; + vector org = trace_endpos - dir * (stepdist / 2); bool ladder_found = false; IL_EACH(g_ladders, it.classname == "func_ladder", { if(it.bot_pickup) if(boxesoverlap(move + jumpheight_vec + m1 + '-1 -1 -1', move + jumpheight_vec + m2 + '1 1 1', it.absmin, it.absmax)) if(boxesoverlap(end, end2, 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) + { + vector top = org; + top.z = it.absmax.z + (PL_MAX_CONST.z - PL_MIN_CONST.z); + tracebox(org, m1, m2, top, movemode, e); + if(trace_fraction == 1) + ladder_found = true; // can't return here ("Loop mutex held by tracewalk" error) + } }); if(ladder_found) { if(autocvar_bot_debug_tracewalk) - debugnodestatus(end, DEBUG_NODE_SUCCESS); + debugnodestatus(trace_endpos, DEBUG_NODE_SUCCESS); //print("tracewalk: ", vtos(start), " can reach ", vtos(end), "\n"); return true; } + org = org_save; if(autocvar_bot_debug_tracewalk) debugnodestatus(trace_endpos, DEBUG_NODE_WARNING); -- 2.39.2