]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Dynamically cache submerged state for waypoints and static items
authorterencehill <piuntn@gmail.com>
Thu, 27 Jul 2017 11:15:41 +0000 (13:15 +0200)
committerterencehill <piuntn@gmail.com>
Thu, 27 Jul 2017 13:02:22 +0000 (15:02 +0200)
qcsrc/server/bot/default/navigation.qc
qcsrc/server/bot/default/navigation.qh
qcsrc/server/bot/default/waypoints.qc

index 37b1acf54306683557f7911609ce1841bcc05229..ebf2f6e16595e32be4670810e66739846700fccf 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",
index 4731e67babc016531af00b91e5592d761dad5832..c188f53ac0b108b8a504a1479d8a5fc4d52cc456 100644 (file)
@@ -125,6 +125,12 @@ void navigation_dynamicgoal_init(entity this, bool initially_static);
 void navigation_dynamicgoal_set(entity this);
 void navigation_dynamicgoal_unset(entity this);
 
+.int nav_submerged_state;
+#define SUBMERGED_UNDEFINED 0
+#define SUBMERGED_NO 1
+#define SUBMERGED_YES 2
+bool navigation_check_submerged_state(entity ent, vector pos);
+
 
 /*
  * Functions
index 9e37d825934d20231863cda1139c0ca65b3ef4ef..f08c32691683d03c8c8f4696153001683c8d6475 100644 (file)
@@ -227,11 +227,6 @@ entity waypoint_spawn(vector m1, vector m2, float f)
                        }
                }
                setsize(w, '0 0 0', '0 0 0');
-
-               // can't apply the same logic to box waypoints because often they are
-               // inside some solid and SUBMERGED check would fail even if submerged
-               if(SUBMERGED(w.origin))
-                       w.waterlevel = WATERLEVEL_SUBMERGED;
        }
 
        waypoint_clearlinks(w);
@@ -457,17 +452,8 @@ float waypoint_getlinearcost_underwater(float dist)
 
 float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent)
 {
-       bool submerged_from;
-       if((from_ent.classname == "waypoint" && !from_ent.wpisbox) || from_ent.classname == "player")
-               submerged_from = (from_ent.waterlevel == WATERLEVEL_SUBMERGED);
-       else
-               submerged_from = SUBMERGED(from);
-
-       bool submerged_to;
-       if((to_ent.classname == "waypoint" && !to_ent.wpisbox) || to_ent.classname == "player")
-               submerged_to = (to_ent.waterlevel == WATERLEVEL_SUBMERGED);
-       else
-               submerged_to = SUBMERGED(to);
+       bool submerged_from = navigation_check_submerged_state(from_ent, from);
+       bool submerged_to = navigation_check_submerged_state(to_ent, to);
 
        if (submerged_from && submerged_to)
                return waypoint_getlinearcost_underwater(vlen(to - from));