]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/waypoints.qc
Merge branch 'master' into terencehill/bot_waypoints
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / waypoints.qc
index f801052931068723de996146058a160e8cbf936b..f08c32691683d03c8c8f4696153001683c8d6475 100644 (file)
@@ -168,6 +168,8 @@ void waypoint_setupmodel(entity wp)
                        wp.colormod = '1 0 0';
                else if (wp.wpflags & WAYPOINTFLAG_GENERATED)
                        wp.colormod = '1 1 0';
+               else if (wp.wphardwired)
+                       wp.colormod = '0.5 0 1';
                else
                        wp.colormod = '1 1 1';
        }
@@ -182,9 +184,8 @@ entity waypoint_spawn(vector m1, vector m2, float f)
 {
        if(!(f & WAYPOINTFLAG_PERSONAL))
        {
-               vector em1 = m1;
-               vector em2 = m2;
-               if (m1 == m2)
+               vector em1 = m1, em2 = m2;
+               if (!(f & WAYPOINTFLAG_GENERATED) && m1 == m2)
                {
                        em1 = m1 - '8 8 8';
                        em2 = m2 + '8 8 8';
@@ -268,7 +269,7 @@ void waypoint_spawn_fromeditor(entity pl)
        LABEL(add_wp);
        e = waypoint_spawn(org, org, 0);
        waypoint_schedulerelink(e);
-       bprint(strcat("Waypoint spawned at ", vtos(org), "\n"));
+       bprint(strcat("Waypoint spawned at ", vtos(e.origin), "\n"));
        if(sym)
        {
                org = waypoint_getSymmetricalOrigin(e.origin, ctf_flags);
@@ -443,9 +444,20 @@ float waypoint_getlinearcost(float dist)
                return dist / (autocvar_sv_maxspeed * 1.25);
        return dist / autocvar_sv_maxspeed;
 }
+float waypoint_getlinearcost_underwater(float dist)
+{
+       // NOTE: this value is hardcoded on the engine too, see SV_WaterMove
+       return dist / (autocvar_sv_maxspeed * 0.7);
+}
 
-float waypoint_gettravelcost(vector from, vector to)
+float waypoint_gettravelcost(vector from, vector to, entity from_ent, entity to_ent)
 {
+       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));
+
        float c = waypoint_getlinearcost(vlen(to - from));
 
        float height = from.z - to.z;
@@ -456,6 +468,9 @@ float waypoint_gettravelcost(vector from, vector to)
                if(height_cost > c)
                        c = height_cost;
        }
+
+       if (submerged_from || submerged_to)
+               return (c + waypoint_getlinearcost_underwater(vlen(to - from))) / 2;
        return c;
 }
 
@@ -465,19 +480,19 @@ float waypoint_getlinkcost(entity from, entity to)
        vector v2 = to.origin;
        if (from.wpisbox)
        {
-               vector m1 = to.absmin, m2 = to.absmax;
-               v1_x = bound(m1_x, v1_x, m2_x);
-               v1_y = bound(m1_y, v1_y, m2_y);
-               v1_z = bound(m1_z, v1_z, m2_z);
+               vector m1 = from.absmin, m2 = from.absmax;
+               v1.x = bound(m1.x, v2.x, m2.x);
+               v1.y = bound(m1.y, v2.y, m2.y);
+               v1.z = bound(m1.z, v2.z, m2.z);
        }
        if (to.wpisbox)
        {
-               vector m1 = from.absmin, m2 = from.absmax;
-               v2_x = bound(m1_x, v2_x, m2_x);
-               v2_y = bound(m1_y, v2_y, m2_y);
-               v2_z = bound(m1_z, v2_z, m2_z);
+               vector m1 = to.absmin, m2 = to.absmax;
+               v2.x = bound(m1.x, v1.x, m2.x);
+               v2.y = bound(m1.y, v1.y, m2.y);
+               v2.z = bound(m1.z, v1.z, m2.z);
        }
-       return waypoint_gettravelcost(v1, v2);
+       return waypoint_gettravelcost(v1, v2, from, to);
 }
 
 // add a new link to the spawnfunc_waypoint, replacing the furthest link it already has
@@ -537,15 +552,14 @@ void waypoint_addlink(entity from, entity to)
 // (SLOW!)
 void waypoint_think(entity this)
 {
-       vector sv, sm1, sm2, ev, em1, em2, dv;
+       vector sv, sv2, ev, ev2, dv;
+       float sv2_height, ev2_height;
 
        bot_calculate_stepheightvec();
 
        bot_navigation_movemode = ((autocvar_bot_navigation_ignoreplayers) ? MOVE_NOMONSTERS : MOVE_NORMAL);
 
        //dprint("waypoint_think wpisbox = ", ftos(this.wpisbox), "\n");
-       sm1 = this.origin + this.mins;
-       sm2 = this.origin + this.maxs;
        IL_EACH(g_waypoints, this != it,
        {
                if (boxesoverlap(this.absmin, this.absmax, it.absmin, it.absmax))
@@ -561,16 +575,10 @@ void waypoint_think(entity this)
                                ++relink_pvsculled;
                                continue;
                        }
-                       sv = it.origin;
-                       sv.x = bound(sm1_x, sv.x, sm2_x);
-                       sv.y = bound(sm1_y, sv.y, sm2_y);
-                       sv.z = bound(sm1_z, sv.z, sm2_z);
-                       ev = this.origin;
-                       em1 = it.origin + it.mins;
-                       em2 = it.origin + it.maxs;
-                       ev.x = bound(em1_x, ev.x, em2_x);
-                       ev.y = bound(em1_y, ev.y, em2_y);
-                       ev.z = bound(em1_z, ev.z, em2_z);
+
+                       SET_TRACEWALK_DESTCOORDS_2(this, it.origin, sv, sv2, sv2_height);
+                       SET_TRACEWALK_DESTCOORDS_2(it, this.origin, ev, ev2, ev2_height);
+
                        dv = ev - sv;
                        dv.z = 0;
                        if(vdist(dv, >=, 1050)) // max search distance in XY
@@ -578,39 +586,16 @@ void waypoint_think(entity this)
                                ++relink_lengthculled;
                                continue;
                        }
-                       float sv_deviation = 0;
-                       float ev_deviation = 0;
+
                        navigation_testtracewalk = 0;
-                       if (!this.wpisbox)
-                       {
-                               tracebox(sv - PL_MIN_CONST.z * '0 0 1', PL_MIN_CONST, PL_MAX_CONST, sv, false, this);
-                               if (!trace_startsolid)
-                               {
-                                       //dprint("sv deviation", vtos(trace_endpos - sv), "\n");
-                                       sv_deviation = trace_endpos.z + 1 - sv.z;
-                                       sv = trace_endpos + '0 0 1';
-                               }
-                       }
-                       if (!it.wpisbox)
-                       {
-                               tracebox(ev - PL_MIN_CONST.z * '0 0 1', PL_MIN_CONST, PL_MAX_CONST, ev, false, it);
-                               if (!trace_startsolid)
-                               {
-                                       //dprint("ev deviation", vtos(trace_endpos - ev), "\n");
-                                       ev_deviation = trace_endpos.z + 1 - ev.z;
-                                       ev = trace_endpos + '0 0 1';
-                               }
-                       }
+
                        //traceline(this.origin, it.origin, false, NULL);
                        //if (trace_fraction == 1)
                        if (this.wpisbox)
                                relink_walkculled += 0.5;
                        else
                        {
-                               vector dest = ev;
-                               dest.z = em1.z + ev_deviation;
-                               float dest_height = em2.z - em1.z;
-                               if(tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, dest, dest_height, MOVE_NOMONSTERS))
+                               if (tracewalk(this, sv, PL_MIN_CONST, PL_MAX_CONST, ev2, ev2_height, MOVE_NOMONSTERS))
                                        waypoint_addlink(this, it);
                                else
                                        relink_walkculled += 0.5;
@@ -620,10 +605,7 @@ void waypoint_think(entity this)
                                relink_walkculled += 0.5;
                        else
                        {
-                               vector dest = sv;
-                               dest.z = sm1.z + sv_deviation;
-                               float dest_height = sm2.z - sm1.z;
-                               if(tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, dest, dest_height, MOVE_NOMONSTERS))
+                               if (tracewalk(it, ev, PL_MIN_CONST, PL_MAX_CONST, sv2, sv2_height, MOVE_NOMONSTERS))
                                        waypoint_addlink(it, this);
                                else
                                        relink_walkculled += 0.5;
@@ -1107,7 +1089,7 @@ void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, flo
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken)
 {
        destination = waypoint_fixorigin(destination);
-       waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, e.absmin, e.absmax, destination, destination, timetaken);
+       waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, e.absmin - PL_MAX_CONST + '1 1 1', e.absmax - PL_MIN_CONST + '-1 -1 -1', destination, destination, timetaken);
 }
 
 entity waypoint_spawnpersonal(entity this, vector position)
@@ -1246,7 +1228,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en
 
                // if wp -> porg, then OK
                float maxdist;
-               if(navigation_waypoint_will_link(wp.origin, porg, p, walkfromwp, 1050))
+               if(navigation_waypoint_will_link(wp.origin, porg, p, wp.origin, 0, walkfromwp, 1050))
                {
                        // we may find a better one
                        maxdist = vlen(wp.origin - porg);
@@ -1262,8 +1244,8 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en
                {
                        float d = vlen(wp.origin - it.origin) + vlen(it.origin - porg);
                        if(d < bestdist)
-                       if(navigation_waypoint_will_link(wp.origin, it.origin, p, walkfromwp, 1050))
-                       if(navigation_waypoint_will_link(it.origin, porg, p, walkfromwp, 1050))
+                       if(navigation_waypoint_will_link(wp.origin, it.origin, p, wp.origin, 0, walkfromwp, 1050))
+                       if(navigation_waypoint_will_link(it.origin, porg, p, it.origin, 0, walkfromwp, 1050))
                        {
                                bestdist = d;
                                p.(fld) = it;
@@ -1317,7 +1299,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en
 
                if(wp)
                {
-                       if(!navigation_waypoint_will_link(wp.origin, o, p, walkfromwp, 1050))
+                       if(!navigation_waypoint_will_link(wp.origin, o, p, wp.origin, 0, walkfromwp, 1050))
                        {
                                // we cannot walk from wp.origin to o
                                // get closer to tmax
@@ -1343,7 +1325,7 @@ float botframe_autowaypoints_fix_from(entity p, float walkfromwp, entity wp, .en
                // if we get here, o is valid regarding waypoints
                // check if o is connected right to the player
                // we break if it succeeds, as that means o is a good waypoint location
-               if(navigation_waypoint_will_link(o, porg, p, walkfromwp, 1050))
+               if(navigation_waypoint_will_link(o, porg, p, o, 0, walkfromwp, 1050))
                        break;
 
                // o is no good, we need to get closer to the player