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;
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;
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), ")");
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;
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);
}
}
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);
return dist / (autocvar_sv_maxspeed * 0.7);
}
-float waypoint_gettravelcost(vector from, vector to, bool submerged_from, bool submerged_to)
+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);
+
if (submerged_from && submerged_to)
return waypoint_getlinearcost_underwater(vlen(to - from));
v2.y = bound(m1.y, v1.y, m2.y);
v2.z = bound(m1.z, v1.z, m2.z);
}
- return waypoint_gettravelcost(v1, v2, SUBMERGED(v1), SUBMERGED(v2));
+ return waypoint_gettravelcost(v1, v2, from, to);
}
// add a new link to the spawnfunc_waypoint, replacing the furthest link it already has
void waypoint_schedulerelink(entity wp);
float waypoint_getlinkcost(entity from, entity to);
-float waypoint_gettravelcost(vector v1, vector v2, bool submerged_from, bool submerged_to);
+float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent);
float waypoint_getlinearcost(float dist);
void waypoint_updatecost_foralllinks();