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",
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
}
}
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);
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));