]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bot navigation: don't try to climb ladders up if they are obstructed (in particular...
authorterencehill <piuntn@gmail.com>
Tue, 23 May 2017 13:09:06 +0000 (15:09 +0200)
committerterencehill <piuntn@gmail.com>
Tue, 23 May 2017 13:09:06 +0000 (15:09 +0200)
qcsrc/server/bot/default/navigation.qc

index 345ebd39503448c188a7a8ad45cb1ec2f17a0700..52752b8d5bf52ec60b04eb54affde32213a4c0f8 100644 (file)
@@ -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);