]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/navigation.qc
Merge branch 'master' into terencehill/bot_waypoints
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / navigation.qc
index d787cbb876224c597400c10d7934b99b9114bdcd..e450da01f369ee6e862acf77e7639348004ab59f 100644 (file)
@@ -37,6 +37,26 @@ void navigation_dynamicgoal_unset(entity this)
        this.nearestwaypointtimeout = -1;
 }
 
+bool navigation_check_submerged_state(entity ent, vector pos)
+{
+       bool submerged;
+       if(IS_PLAYER(ent))
+               submerged = (ent.waterlevel == WATERLEVEL_SUBMERGED);
+       else if(ent.nav_submerged_state != SUBMERGED_UNDEFINED)
+               submerged = (ent.nav_submerged_state == SUBMERGED_YES);
+       else
+       {
+               submerged = SUBMERGED(pos);
+               // NOTE: SUBMERGED check of box waypoint origin may fail even if origin
+               //  is actually submerged because often they are inside some solid.
+               //  That's why submerged state is saved now that we know current pos is
+               //  not stuck in solid (previous tracewalk call to this pos was successfully)
+               if(!ent.navigation_dynamicgoal)
+                       ent.nav_submerged_state = (submerged) ? SUBMERGED_YES : SUBMERGED_NO;
+       }
+       return submerged;
+}
+
 bool navigation_checkladders(entity e, vector org, vector m1, vector m2, vector end, vector end2, int movemode)
 {
        IL_EACH(g_ladders, it.classname == "func_ladder",
@@ -189,6 +209,8 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                if (flatdist <= 0)
                        break;
 
+               if (stepdist > flatdist)
+                       stepdist = flatdist;
                if(nav_action == NAV_SWIM_UNDERWATER || (nav_action == NAV_SWIM_ONWATER && org.z > end2.z))
                {
                        // can't use movement direction here to calculate move because of
@@ -196,8 +218,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                        //water_dir = normalize(water_end - org);
                        //move = org + water_dir * stepdist;
                        fixed_end.z = bound(end.z, org.z, end2.z);
-                       if (stepdist > flatdist)
-                               stepdist = flatdist;
                        if (stepdist == flatdist) {
                                move = fixed_end;
                                flatdist = 0;
@@ -208,8 +228,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                }
                else // horiz. direction
                {
-                       if (stepdist > flatdist)
-                               stepdist = flatdist;
                        flatdist -= stepdist;
                        move = org + flatdir * stepdist;
                }
@@ -323,7 +341,7 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                                                        nav_action = NAV_SWIM_ONWATER;
 
                                                // we didn't advance horiz. in this step, flatdist decrease should be reverted
-                                               // but we can do it properly right now... apply this workaround instead
+                                               // but we can't do it properly right now... apply this workaround instead
                                                if (flatdist <= 0)
                                                        flatdist = 1;
 
@@ -495,12 +513,6 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                        else
                                move = trace_endpos;
 
-                       if (flatdist <= 0)
-                       {
-                               org = move;
-                               continue;
-                       }
-
                        // trace down from stepheight as far as possible and move there,
                        // if this starts in solid we try again without the stepup, and
                        // if that also fails we assume it is a wall
@@ -524,6 +536,13 @@ bool tracewalk(entity e, vector start, vector m1, vector m2, vector end, float e
                                }
                        }
 
+                       if (flatdist <= 0)
+                       {
+                               if(move.z >= end2.z && org.z < end2.z)
+                                       org.z = end2.z;
+                               continue;
+                       }
+
                        if(org.z > move.z - 1 || !SUBMERGED(org))
                        {
                                nav_action = NAV_WALK;
@@ -797,7 +816,7 @@ float navigation_markroutes_nearestwaypoints(entity this, float maxdist)
                        if (tracewalk(this, this.origin, this.mins, this.maxs, v, v_height, bot_navigation_movemode))
                        {
                                it.wpnearestpoint = v;
-                               it.wpcost = waypoint_gettravelcost(this.origin, v, SUBMERGED(this.origin), SUBMERGED(v)) + it.dmg;
+                               it.wpcost = waypoint_gettravelcost(this.origin, v, this, it) + it.dmg;
                                it.wpfire = 1;
                                it.enemy = NULL;
                                c = c + 1;
@@ -826,7 +845,7 @@ void navigation_markroutes_checkwaypoint(entity w, entity wp, float cost, vector
        if (w.wpflags & WAYPOINTFLAG_TELEPORT)
                cost += w.wp00mincost; // assuming teleport has exactly one destination
        else
-               cost += waypoint_gettravelcost(p, v, SUBMERGED(p), SUBMERGED(v));
+               cost += waypoint_gettravelcost(p, v, w, wp);
        if (wp.wpcost > cost)
        {
                wp.wpcost = cost;
@@ -1187,7 +1206,7 @@ void navigation_routerating(entity this, entity e, float f, float rangebias)
        if (nwp.wpcost < 10000000)
        {
                //te_wizspike(nwp.wpnearestpoint);
-               float cost = nwp.wpcost + waypoint_gettravelcost(nwp.wpnearestpoint, goal_org, SUBMERGED(nwp.wpnearestpoint), SUBMERGED(goal_org));
+               float cost = nwp.wpcost + waypoint_gettravelcost(nwp.wpnearestpoint, goal_org, nwp, e);
                LOG_DEBUG(e.classname, " ", ftos(f), "/(1+", ftos(cost), "/", ftos(rangebias), ") = ");
                f = f * rangebias / (rangebias + cost);
                LOG_DEBUG("considering ", e.classname, " (with rating ", ftos(f), ")");
@@ -1412,11 +1431,13 @@ void botframe_updatedangerousobjects(float maxupdate)
        vector m1, m2, v, o;
        float c, d, danger;
        c = 0;
+       entity wp_cur;
        IL_EACH(g_waypoints, true,
        {
                danger = 0;
                m1 = it.absmin;
                m2 = it.absmax;
+               wp_cur = it;
                IL_EACH(g_bot_dodge, it.bot_dodge,
                {
                        v = it.origin;
@@ -1424,7 +1445,7 @@ void botframe_updatedangerousobjects(float maxupdate)
                        v.y = bound(m1_y, v.y, m2_y);
                        v.z = bound(m1_z, v.z, m2_z);
                        o = (it.absmin + it.absmax) * 0.5;
-                       d = waypoint_getlinearcost(it.bot_dodgerating) - waypoint_gettravelcost(o, v, SUBMERGED(o), SUBMERGED(v));
+                       d = waypoint_getlinearcost(it.bot_dodgerating) - waypoint_gettravelcost(o, v, it, wp_cur);
                        if (d > 0)
                        {
                                traceline(o, v, true, NULL);