From 3ddf0e1e1b65492fa18ff9170866bdedf6e9b29a Mon Sep 17 00:00:00 2001 From: terencehill Date: Mon, 31 Jul 2017 12:46:41 +0200 Subject: [PATCH] Fix ladder/jumppad/teleporter destination waypoints stuck in solid if they end up on a model (jumppad near megahealth in finalrage) --- qcsrc/common/triggers/func/ladder.qc | 21 +++++++++++++-------- qcsrc/common/triggers/teleporters.qc | 8 +++++++- qcsrc/common/triggers/trigger/jumppads.qc | 8 +++++--- qcsrc/server/bot/api.qh | 4 ++-- qcsrc/server/bot/default/waypoints.qc | 20 +++++++++----------- qcsrc/server/bot/default/waypoints.qh | 6 +++--- qcsrc/server/bot/null/bot_null.qc | 4 ++-- qcsrc/server/sv_main.qc | 6 +++++- 8 files changed, 46 insertions(+), 31 deletions(-) diff --git a/qcsrc/common/triggers/func/ladder.qc b/qcsrc/common/triggers/func/ladder.qc index 9aec33b90..92f361a14 100644 --- a/qcsrc/common/triggers/func/ladder.qc +++ b/qcsrc/common/triggers/func/ladder.qc @@ -48,17 +48,21 @@ void func_ladder_init(entity this) if(min(this.absmax.x - this.absmin.x, this.absmax.y - this.absmin.y) > 100) return; + entity tracetest_ent = spawn(); + setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST); + tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; + vector top_min = (this.absmin + this.absmax) / 2; top_min.z = this.absmax.z; vector top_max = top_min; top_max.z += PL_MAX_CONST.z - PL_MIN_CONST.z; - tracebox(top_max + jumpstepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, NULL); + tracebox(top_max + jumpstepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent); if(trace_startsolid) { - tracebox(top_max + stepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, NULL); + tracebox(top_max + stepheightvec, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent); if(trace_startsolid) { - tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, NULL); + tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent); if(trace_startsolid) { if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x @@ -73,7 +77,7 @@ void func_ladder_init(entity this) // move top on one side top_max.x = top_min.x = this.absmin.x + (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75; } - tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, NULL); + tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent); if(trace_startsolid) { if(this.absmax.x - this.absmin.x > PL_MAX_CONST.x - PL_MIN_CONST.x @@ -88,15 +92,16 @@ void func_ladder_init(entity this) // alternatively on the other side top_max.x = top_min.x = this.absmax.x - (PL_MAX_CONST.x - PL_MIN_CONST.x) * 0.75; } - tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, NULL); - if(trace_startsolid) - return; + tracebox(top_max, PL_MIN_CONST, PL_MAX_CONST, top_min, MOVE_NOMONSTERS, tracetest_ent); } } } } - if(trace_endpos.z < this.absmax.z) + if(trace_startsolid || trace_endpos.z < this.absmax.z) + { + delete(tracetest_ent); return; + } this.bot_pickup = true; // allow bots to make use of this ladder float cost = waypoint_getlinearcost(trace_endpos.z - this.absmin.z); diff --git a/qcsrc/common/triggers/teleporters.qc b/qcsrc/common/triggers/teleporters.qc index 451afa95b..13a0c41d3 100644 --- a/qcsrc/common/triggers/teleporters.qc +++ b/qcsrc/common/triggers/teleporters.qc @@ -235,7 +235,13 @@ void teleport_findtarget(entity this) ++n; #ifdef SVQC if(e.move_movetype == MOVETYPE_NONE) - waypoint_spawnforteleporter(this, e.origin, 0); + { + entity tracetest_ent = spawn(); + setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST); + tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; + waypoint_spawnforteleporter(this, e.origin, 0, tracetest_ent); + delete(tracetest_ent); + } if(e.classname != "info_teleport_destination") LOG_INFO("^3MAPPER ERROR: teleporter does target an invalid teleport destination entity. Angles will not work.\n"); #endif diff --git a/qcsrc/common/triggers/trigger/jumppads.qc b/qcsrc/common/triggers/trigger/jumppads.qc index 64c15bda5..5a24bca66 100644 --- a/qcsrc/common/triggers/trigger/jumppads.qc +++ b/qcsrc/common/triggers/trigger/jumppads.qc @@ -324,6 +324,7 @@ void trigger_push_findtarget(entity this) entity e = spawn(); setsize(e, PL_MIN_CONST, PL_MAX_CONST); + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; e.velocity = trigger_push_calculatevelocity(org, t, this.height); vel = e.velocity; vector best_target = '0 0 0'; @@ -382,7 +383,7 @@ void trigger_push_findtarget(entity this) if(velxy < autocvar_sv_maxspeed) velxy = autocvar_sv_maxspeed; cost += vlen(vec2(best_target - t.origin)) / velxy; - waypoint_spawnforteleporter(this, best_target, cost); + waypoint_spawnforteleporter(this, best_target, cost, e); } } delete(e); @@ -412,12 +413,13 @@ void trigger_push_findtarget(entity this) else { entity e = spawn(); - setorigin(e, org); setsize(e, PL_MIN_CONST, PL_MAX_CONST); + e.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; + setorigin(e, org); e.velocity = this.movedir; tracetoss(e, e); if (!(boxesoverlap(this.absmin, this.absmax + eZ * 50, trace_endpos + PL_MIN_CONST, trace_endpos + PL_MAX_CONST))) - waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity)); + waypoint_spawnforteleporter(this, trace_endpos, vlen(trace_endpos - org) / vlen(e.velocity), e); delete(e); } diff --git a/qcsrc/server/bot/api.qh b/qcsrc/server/bot/api.qh index 695763fe5..cfe3e42c0 100644 --- a/qcsrc/server/bot/api.qh +++ b/qcsrc/server/bot/api.qh @@ -95,8 +95,8 @@ void waypoint_schedulerelinkall(); 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); -void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken); +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_spawn_fromeditor(entity pl); entity waypoint_spawn(vector m1, vector m2, float f); void waypoint_unreachable(entity pl); diff --git a/qcsrc/server/bot/default/waypoints.qc b/qcsrc/server/bot/default/waypoints.qc index f08c32691..824aab23f 100644 --- a/qcsrc/server/bot/default/waypoints.qc +++ b/qcsrc/server/bot/default/waypoints.qc @@ -1017,20 +1017,18 @@ float waypoint_loadall() return cwp + cwb; } -vector waypoint_fixorigin(vector position) +vector waypoint_fixorigin(vector position, entity tracetest_ent) { - tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + '0 0 -512', MOVE_NOMONSTERS, NULL); + tracebox(position + '0 0 1' * (1 - PL_MIN_CONST.z), PL_MIN_CONST, PL_MAX_CONST, position + '0 0 -512', MOVE_NOMONSTERS, tracetest_ent); if(trace_fraction < 1) position = trace_endpos; - //traceline(position, position + '0 0 -512', MOVE_NOMONSTERS, NULL); - //print("position is ", ftos(trace_endpos_z - position_z), " above solid\n"); return position; } void waypoint_spawnforitem_force(entity e, vector org) { // Fix the waypoint altitude if necessary - org = waypoint_fixorigin(org); + org = waypoint_fixorigin(org, NULL); // don't spawn an item spawnfunc_waypoint if it already exists IL_EACH(g_waypoints, true, @@ -1079,16 +1077,16 @@ void waypoint_spawnforteleporter_boxes(entity e, int teleport_flag, vector org1, e.nearestwaypointtimeout = -1; } -void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken) +void waypoint_spawnforteleporter_wz(entity e, vector org, vector destination, float timetaken, entity tracetest_ent) { - org = waypoint_fixorigin(org); - destination = waypoint_fixorigin(destination); + org = waypoint_fixorigin(org, tracetest_ent); + destination = waypoint_fixorigin(destination, tracetest_ent); waypoint_spawnforteleporter_boxes(e, WAYPOINTFLAG_TELEPORT, org, org, destination, destination, timetaken); } -void waypoint_spawnforteleporter(entity e, vector destination, float timetaken) +void waypoint_spawnforteleporter(entity e, vector destination, float timetaken, entity tracetest_ent) { - destination = waypoint_fixorigin(destination); + destination = waypoint_fixorigin(destination, tracetest_ent); 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); } @@ -1099,7 +1097,7 @@ entity waypoint_spawnpersonal(entity this, vector position) // drop the waypoint to a proper location: // first move it up by a player height // then move it down to hit the floor with player bbox size - position = waypoint_fixorigin(position); + position = waypoint_fixorigin(position, this); w = waypoint_spawn(position, position, WAYPOINTFLAG_GENERATED | WAYPOINTFLAG_PERSONAL); w.nearestwaypoint = NULL; diff --git a/qcsrc/server/bot/default/waypoints.qh b/qcsrc/server/bot/default/waypoints.qh index 02dc7b163..e78ed55cc 100644 --- a/qcsrc/server/bot/default/waypoints.qh +++ b/qcsrc/server/bot/default/waypoints.qh @@ -52,8 +52,8 @@ 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); -void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken); +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 botframe_showwaypointlinks(); float waypoint_loadall(); @@ -65,6 +65,6 @@ entity waypoint_spawnpersonal(entity this, vector position); void waypoint_unreachable(entity pl); -vector waypoint_fixorigin(vector position); +vector waypoint_fixorigin(vector position, entity tracetest_ent); void botframe_autowaypoints(); diff --git a/qcsrc/server/bot/null/bot_null.qc b/qcsrc/server/bot/null/bot_null.qc index 6c60a70e3..ddf7abd9d 100644 --- a/qcsrc/server/bot/null/bot_null.qc +++ b/qcsrc/server/bot/null/bot_null.qc @@ -37,8 +37,8 @@ void waypoint_schedulerelinkall() { } 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) { } -void waypoint_spawnforteleporter_v(entity e, vector org, vector destination, float timetaken) { } +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_spawn_fromeditor(entity pl) { } entity waypoint_spawn(vector m1, vector m2, float f) { return NULL; } #endif diff --git a/qcsrc/server/sv_main.qc b/qcsrc/server/sv_main.qc index cd316175b..986dbce15 100644 --- a/qcsrc/server/sv_main.qc +++ b/qcsrc/server/sv_main.qc @@ -411,6 +411,9 @@ LABEL(cvar_fail) void WarpZone_PostInitialize_Callback() { // create waypoint links for warpzones + entity tracetest_ent = spawn(); + setsize(tracetest_ent, PL_MIN_CONST, PL_MAX_CONST); + tracetest_ent.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP; //for(entity e = warpzone_first; e; e = e.warpzone_next) for(entity e = NULL; (e = find(e, classname, "trigger_warpzone")); ) { @@ -421,6 +424,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; - waypoint_spawnforteleporter_v(e, src, dst, 0); + waypoint_spawnforteleporter_wz(e, src, dst, 0, tracetest_ent); } + delete(tracetest_ent); } -- 2.39.2