Fix waypoints for warpzones with oblique or horizontal warp plane
authorterencehill <piuntn@gmail.com>
Fri, 1 Sep 2017 16:31:03 +0000 (18:31 +0200)
committerterencehill <piuntn@gmail.com>
Fri, 1 Sep 2017 16:31:03 +0000 (18:31 +0200)
qcsrc/server/bot/api.qh
qcsrc/server/bot/default/waypoints.qc
qcsrc/server/bot/default/waypoints.qh
qcsrc/server/bot/null/bot_null.qc
qcsrc/server/sv_main.qc

index 5c41731..27651bf 100644 (file)
@@ -98,7 +98,7 @@ void waypoint_schedulerelink(entity wp);
 void waypoint_spawnforitem(entity e);
 void waypoint_spawnforitem_force(entity e, vector org);
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent);
 void waypoint_spawnforitem(entity e);
 void waypoint_spawnforitem_force(entity e, vector org);
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent);
-void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent);
+void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, vector down_dir, entity tracetest_ent);
 void waypoint_spawn_fromeditor(entity pl);
 entity waypoint_spawn(vector m1, vector m2, float f);
 void waypoint_unreachable(entity pl);
 void waypoint_spawn_fromeditor(entity pl);
 entity waypoint_spawn(vector m1, vector m2, float f);
 void waypoint_unreachable(entity pl);
index 4b7da64..c3b67a3 100644 (file)
@@ -1069,9 +1069,16 @@ float waypoint_loadall()
        return cwp + cwb;
 }
 
        return cwp + cwb;
 }
 
-vector waypoint_fixorigin(vector position, entity tracetest_ent)
+#define waypoint_fixorigin(position, tracetest_ent) \
+       waypoint_fixorigin_down_dir(position, tracetest_ent, '0 0 -1')
+
+vector waypoint_fixorigin_down_dir(vector position, entity tracetest_ent, vector down_dir)
 {
 {
-       tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + '0 0 -512', MOVE_NOMONSTERS, tracetest_ent);
+       tracebox(position + '0 0 1', PL_MIN_CONST, PL_MAX_CONST, position + down_dir * 3000, MOVE_NOMONSTERS, tracetest_ent);
+       if(trace_startsolid)
+               tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z / 2), PL_MIN_CONST, PL_MAX_CONST, position + down_dir * 3000, MOVE_NOMONSTERS, tracetest_ent);
+       if(trace_startsolid)
+               tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + down_dir * 3000, MOVE_NOMONSTERS, tracetest_ent);
        if(trace_fraction < 1)
                position = trace_endpos;
        return position;
        if(trace_fraction < 1)
                position = trace_endpos;
        return position;
@@ -1129,10 +1136,18 @@ void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1,
        e.nearestwaypointtimeout = -1;
 }
 
        e.nearestwaypointtimeout = -1;
 }
 
-void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent)
+void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, vector down_dir, entity tracetest_ent)
 {
 {
-       org = waypoint_fixorigin(org, tracetest_ent);
-       destination = waypoint_fixorigin(destination, 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);
 }
 
        waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, org, org, destination, destination, timetaken);
 }
 
index d3cb3a4..bea11e9 100644 (file)
@@ -57,7 +57,7 @@ void waypoint_saveall();
 void waypoint_spawnforitem_force(entity e, vector org);
 void waypoint_spawnforitem(entity e);
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent);
 void waypoint_spawnforitem_force(entity e, vector org);
 void waypoint_spawnforitem(entity e);
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent);
-void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent);
+void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, vector down_dir, entity tracetest_ent);
 void botframe_showwaypointlinks();
 
 float waypoint_loadall();
 void botframe_showwaypointlinks();
 
 float waypoint_loadall();
@@ -72,6 +72,6 @@ entity waypoint_spawnpersonal(entity this, vector position);
 
 void waypoint_unreachable(entity pl);
 
 
 void waypoint_unreachable(entity pl);
 
-vector waypoint_fixorigin(vector position, entity tracetest_ent);
+vector waypoint_fixorigin_down_dir(vector position, entity tracetest_ent, vector down_dir);
 
 void botframe_autowaypoints();
 
 void botframe_autowaypoints();
index ddf7abd..f8738f8 100644 (file)
@@ -38,7 +38,7 @@ void waypoint_schedulerelink(entity wp) { }
 void waypoint_spawnforitem(entity e) { }
 void waypoint_spawnforitem_force(entity e, vector org) { }
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent) { }
 void waypoint_spawnforitem(entity e) { }
 void waypoint_spawnforitem_force(entity e, vector org) { }
 void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent) { }
-void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent) { }
+void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, vector down_dir, entity tracetest_ent) { }
 void waypoint_spawn_fromeditor(entity pl) { }
 entity waypoint_spawn(vector m1, vector m2, float f) { return NULL; }
 #endif
 void waypoint_spawn_fromeditor(entity pl) { }
 entity waypoint_spawn(vector m1, vector m2, float f) { return NULL; }
 #endif
index 5189076..fcae79e 100644 (file)
@@ -425,7 +425,7 @@ void WarpZone_PostInitialize_Callback()
                dst = (e.enemy.absmin + e.enemy.absmax) * 0.5;
                makevectors(e.enemy.warpzone_angles);
                dst = dst + ((e.enemy.warpzone_origin - dst) * v_forward) * v_forward - 16 * v_right;
                dst = (e.enemy.absmin + e.enemy.absmax) * 0.5;
                makevectors(e.enemy.warpzone_angles);
                dst = dst + ((e.enemy.warpzone_origin - dst) * v_forward) * v_forward - 16 * v_right;
-               waypoint_spawnforteleporter_wz(e, src, dst, 0, tracetest_ent);
+               waypoint_spawnforteleporter_wz(e, src, dst, 0, -v_up, tracetest_ent);
        }
        delete(tracetest_ent);
 }
        }
        delete(tracetest_ent);
 }