]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/bot/default/waypoints.qc
Bot waypoints: improve generation of waypoints for warpzones pointing downwards;...
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / bot / default / waypoints.qc
index 6991ff00f556225079dfa27ced38714963a231bb..8ce5d2d38b38228eebc3b4ad549687f07e420d4a 100644 (file)
@@ -358,52 +358,65 @@ void waypoint_removelink(entity from, entity to)
        if (from == to || (from.wpflags & WAYPOINTFLAG_NORELINK))
                return;
 
-       bool found = false;
-       if (!found && from.wp00 == to) found = true; if (found) {from.wp00 = from.wp01; from.wp00mincost = from.wp01mincost;}
-       if (!found && from.wp01 == to) found = true; if (found) {from.wp01 = from.wp02; from.wp01mincost = from.wp02mincost;}
-       if (!found && from.wp02 == to) found = true; if (found) {from.wp02 = from.wp03; from.wp02mincost = from.wp03mincost;}
-       if (!found && from.wp03 == to) found = true; if (found) {from.wp03 = from.wp04; from.wp03mincost = from.wp04mincost;}
-       if (!found && from.wp04 == to) found = true; if (found) {from.wp04 = from.wp05; from.wp04mincost = from.wp05mincost;}
-       if (!found && from.wp05 == to) found = true; if (found) {from.wp05 = from.wp06; from.wp05mincost = from.wp06mincost;}
-       if (!found && from.wp06 == to) found = true; if (found) {from.wp06 = from.wp07; from.wp06mincost = from.wp07mincost;}
-       if (!found && from.wp07 == to) found = true; if (found) {from.wp07 = from.wp08; from.wp07mincost = from.wp08mincost;}
-       if (!found && from.wp08 == to) found = true; if (found) {from.wp08 = from.wp09; from.wp08mincost = from.wp09mincost;}
-       if (!found && from.wp09 == to) found = true; if (found) {from.wp09 = from.wp10; from.wp09mincost = from.wp10mincost;}
-       if (!found && from.wp10 == to) found = true; if (found) {from.wp10 = from.wp11; from.wp10mincost = from.wp11mincost;}
-       if (!found && from.wp11 == to) found = true; if (found) {from.wp11 = from.wp12; from.wp11mincost = from.wp12mincost;}
-       if (!found && from.wp12 == to) found = true; if (found) {from.wp12 = from.wp13; from.wp12mincost = from.wp13mincost;}
-       if (!found && from.wp13 == to) found = true; if (found) {from.wp13 = from.wp14; from.wp13mincost = from.wp14mincost;}
-       if (!found && from.wp14 == to) found = true; if (found) {from.wp14 = from.wp15; from.wp14mincost = from.wp15mincost;}
-       if (!found && from.wp15 == to) found = true; if (found) {from.wp15 = from.wp16; from.wp15mincost = from.wp16mincost;}
-       if (!found && from.wp16 == to) found = true; if (found) {from.wp16 = from.wp17; from.wp16mincost = from.wp17mincost;}
-       if (!found && from.wp17 == to) found = true; if (found) {from.wp17 = from.wp18; from.wp17mincost = from.wp18mincost;}
-       if (!found && from.wp18 == to) found = true; if (found) {from.wp18 = from.wp19; from.wp18mincost = from.wp19mincost;}
-       if (!found && from.wp19 == to) found = true; if (found) {from.wp19 = from.wp20; from.wp19mincost = from.wp20mincost;}
-       if (!found && from.wp20 == to) found = true; if (found) {from.wp20 = from.wp21; from.wp20mincost = from.wp21mincost;}
-       if (!found && from.wp21 == to) found = true; if (found) {from.wp21 = from.wp22; from.wp21mincost = from.wp22mincost;}
-       if (!found && from.wp22 == to) found = true; if (found) {from.wp22 = from.wp23; from.wp22mincost = from.wp23mincost;}
-       if (!found && from.wp23 == to) found = true; if (found) {from.wp23 = from.wp24; from.wp23mincost = from.wp24mincost;}
-       if (!found && from.wp24 == to) found = true; if (found) {from.wp24 = from.wp25; from.wp24mincost = from.wp25mincost;}
-       if (!found && from.wp25 == to) found = true; if (found) {from.wp25 = from.wp26; from.wp25mincost = from.wp26mincost;}
-       if (!found && from.wp26 == to) found = true; if (found) {from.wp26 = from.wp27; from.wp26mincost = from.wp27mincost;}
-       if (!found && from.wp27 == to) found = true; if (found) {from.wp27 = from.wp28; from.wp27mincost = from.wp28mincost;}
-       if (!found && from.wp28 == to) found = true; if (found) {from.wp28 = from.wp29; from.wp28mincost = from.wp29mincost;}
-       if (!found && from.wp29 == to) found = true; if (found) {from.wp29 = from.wp30; from.wp29mincost = from.wp30mincost;}
-       if (!found && from.wp30 == to) found = true; if (found) {from.wp30 = from.wp31; from.wp30mincost = from.wp31mincost;}
-       if (found) {from.wp31 = NULL; from.wp31mincost = 10000000;}
+       entity fromwp31_prev = from.wp31;
+
+       switch (waypoint_getlinknum(from, to))
+       {
+               // fallthrough all the way
+               case 00: from.wp00 = from.wp01; from.wp00mincost = from.wp01mincost;
+               case 01: from.wp01 = from.wp02; from.wp01mincost = from.wp02mincost;
+               case 02: from.wp02 = from.wp03; from.wp02mincost = from.wp03mincost;
+               case 03: from.wp03 = from.wp04; from.wp03mincost = from.wp04mincost;
+               case 04: from.wp04 = from.wp05; from.wp04mincost = from.wp05mincost;
+               case 05: from.wp05 = from.wp06; from.wp05mincost = from.wp06mincost;
+               case 06: from.wp06 = from.wp07; from.wp06mincost = from.wp07mincost;
+               case 07: from.wp07 = from.wp08; from.wp07mincost = from.wp08mincost;
+               case 08: from.wp08 = from.wp09; from.wp08mincost = from.wp09mincost;
+               case 09: from.wp09 = from.wp10; from.wp09mincost = from.wp10mincost;
+               case 10: from.wp10 = from.wp11; from.wp10mincost = from.wp11mincost;
+               case 11: from.wp11 = from.wp12; from.wp11mincost = from.wp12mincost;
+               case 12: from.wp12 = from.wp13; from.wp12mincost = from.wp13mincost;
+               case 13: from.wp13 = from.wp14; from.wp13mincost = from.wp14mincost;
+               case 14: from.wp14 = from.wp15; from.wp14mincost = from.wp15mincost;
+               case 15: from.wp15 = from.wp16; from.wp15mincost = from.wp16mincost;
+               case 16: from.wp16 = from.wp17; from.wp16mincost = from.wp17mincost;
+               case 17: from.wp17 = from.wp18; from.wp17mincost = from.wp18mincost;
+               case 18: from.wp18 = from.wp19; from.wp18mincost = from.wp19mincost;
+               case 19: from.wp19 = from.wp20; from.wp19mincost = from.wp20mincost;
+               case 20: from.wp20 = from.wp21; from.wp20mincost = from.wp21mincost;
+               case 21: from.wp21 = from.wp22; from.wp21mincost = from.wp22mincost;
+               case 22: from.wp22 = from.wp23; from.wp22mincost = from.wp23mincost;
+               case 23: from.wp23 = from.wp24; from.wp23mincost = from.wp24mincost;
+               case 24: from.wp24 = from.wp25; from.wp24mincost = from.wp25mincost;
+               case 25: from.wp25 = from.wp26; from.wp25mincost = from.wp26mincost;
+               case 26: from.wp26 = from.wp27; from.wp26mincost = from.wp27mincost;
+               case 27: from.wp27 = from.wp28; from.wp27mincost = from.wp28mincost;
+               case 28: from.wp28 = from.wp29; from.wp28mincost = from.wp29mincost;
+               case 29: from.wp29 = from.wp30; from.wp29mincost = from.wp30mincost;
+               case 30: from.wp30 = from.wp31; from.wp30mincost = from.wp31mincost;
+               case 31: from.wp31 = NULL; from.wp31mincost = 10000000;
+       }
+
+       if (fromwp31_prev && !from.wp31)
+               waypoint_schedulerelink(from);
+}
+
+int waypoint_getlinknum(entity from, entity to)
+{
+       if (from.wp00 == to) return 00; if (from.wp01 == to) return 01; if (from.wp02 == to) return 02; if (from.wp03 == to) return 03;
+       if (from.wp04 == to) return 04; if (from.wp05 == to) return 05; if (from.wp06 == to) return 06; if (from.wp07 == to) return 07;
+       if (from.wp08 == to) return 08; if (from.wp09 == to) return 09; if (from.wp10 == to) return 10; if (from.wp11 == to) return 11;
+       if (from.wp12 == to) return 12; if (from.wp13 == to) return 13; if (from.wp14 == to) return 14; if (from.wp15 == to) return 15;
+       if (from.wp16 == to) return 16; if (from.wp17 == to) return 17; if (from.wp18 == to) return 18; if (from.wp19 == to) return 19;
+       if (from.wp20 == to) return 20; if (from.wp21 == to) return 21; if (from.wp22 == to) return 22; if (from.wp23 == to) return 23;
+       if (from.wp24 == to) return 24; if (from.wp25 == to) return 25; if (from.wp26 == to) return 26; if (from.wp27 == to) return 27;
+       if (from.wp28 == to) return 28; if (from.wp29 == to) return 29; if (from.wp30 == to) return 30; if (from.wp31 == to) return 31;
+       return -1;
 }
 
 bool waypoint_islinked(entity from, entity to)
 {
-       if (from.wp00 == to) return true;if (from.wp01 == to) return true;if (from.wp02 == to) return true;if (from.wp03 == to) return true;
-       if (from.wp04 == to) return true;if (from.wp05 == to) return true;if (from.wp06 == to) return true;if (from.wp07 == to) return true;
-       if (from.wp08 == to) return true;if (from.wp09 == to) return true;if (from.wp10 == to) return true;if (from.wp11 == to) return true;
-       if (from.wp12 == to) return true;if (from.wp13 == to) return true;if (from.wp14 == to) return true;if (from.wp15 == to) return true;
-       if (from.wp16 == to) return true;if (from.wp17 == to) return true;if (from.wp18 == to) return true;if (from.wp19 == to) return true;
-       if (from.wp20 == to) return true;if (from.wp21 == to) return true;if (from.wp22 == to) return true;if (from.wp23 == to) return true;
-       if (from.wp24 == to) return true;if (from.wp25 == to) return true;if (from.wp26 == to) return true;if (from.wp27 == to) return true;
-       if (from.wp28 == to) return true;if (from.wp29 == to) return true;if (from.wp30 == to) return true;if (from.wp31 == to) return true;
-       return false;
+       return (waypoint_getlinknum(from, to) >= 0);
 }
 
 void waypoint_updatecost_foralllinks()
@@ -1284,19 +1297,38 @@ void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1,
        e.nearestwaypointtimeout = -1;
 }
 
-void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, vector down_dir, entity tracetest_ent)
+void waypoint_spawnforteleporter_wz(entity e, entity tracetest_ent)
 {
-       // warpzones with oblique warp plane rely on down_dir to snap waypoints
-       // to the ground without leaving the warp plane
-       // warpzones with horizontal warp plane (down_dir.x == -1) generate
-       // destination waypoint snapped to the ground (leaving warpzone), source
-       // waypoint in the center of the warp plane
-       if(down_dir.x != -1)
-               org = waypoint_fixorigin_down_dir(org, tracetest_ent, down_dir);
-       if(down_dir.x == -1)
-               down_dir = '0 0 -1';
-       destination = waypoint_fixorigin_down_dir(destination, tracetest_ent, down_dir);
-       waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, org, org, destination, destination, timetaken);
+       float src_angle = e.warpzone_angles.x;
+       while (src_angle < -180) src_angle += 360;
+       while (src_angle > 180) src_angle -= 360;
+
+       float dest_angle = e.enemy.warpzone_angles.x;
+       while (dest_angle < -180) dest_angle += 360;
+       while (dest_angle > 180) dest_angle -= 360;
+
+       // no waypoints for warpzones pointing upwards, they can't be used by the bots
+       if (src_angle == -90 || dest_angle == -90)
+               return;
+
+       makevectors(e.warpzone_angles);
+       vector src = (e.absmin + e.absmax) * 0.5;
+       src += ((e.warpzone_origin - src) * v_forward) * v_forward + 16 * v_right;
+       vector down_dir_src = -v_up;
+
+       makevectors(e.enemy.warpzone_angles);
+       vector dest = (e.enemy.absmin + e.enemy.absmax) * 0.5;
+       dest += ((e.enemy.warpzone_origin - dest) * v_forward) * v_forward - 16 * v_right;
+       vector down_dir_dest = -v_up;
+
+       // don't snap to the ground waypoints for source warpzones pointing downwards
+       if (src_angle != 90)
+       {
+               src = waypoint_fixorigin_down_dir(src, tracetest_ent, down_dir_src);
+               dest = waypoint_fixorigin_down_dir(dest, tracetest_ent, down_dir_dest);
+       }
+
+       waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, src, src, dest, dest, 0);
 }
 
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent)