From 74e4c6581b7e16b53d7b99c76a18f344c4b5988f Mon Sep 17 00:00:00 2001
From: Mario <zacjardine@y7mail.com>
Date: Sun, 16 Sep 2018 09:21:38 +1000
Subject: [PATCH] Offset jumppad push target position by the entity's height in
 VQ3 compatibility mode, and add experimental wall clipping

---
 qcsrc/common/mapobjects/trigger/jumppads.qc | 15 +++++++++++++--
 qcsrc/common/physics/movetypes/movetypes.qc |  3 +++
 qcsrc/common/physics/movetypes/movetypes.qh |  4 ++++
 qcsrc/common/physics/movetypes/walk.qc      | 10 ++++++++++
 qcsrc/common/stats.qh                       |  9 +++++++++
 qcsrc/server/autocvars.qh                   |  1 -
 6 files changed, 39 insertions(+), 3 deletions(-)

diff --git a/qcsrc/common/mapobjects/trigger/jumppads.qc b/qcsrc/common/mapobjects/trigger/jumppads.qc
index 5ffdf2d10..ca1faeaf9 100644
--- a/qcsrc/common/mapobjects/trigger/jumppads.qc
+++ b/qcsrc/common/mapobjects/trigger/jumppads.qc
@@ -133,9 +133,20 @@ bool jumppad_push(entity this, entity targ)
 	if (!isPushable(targ))
 		return false;
 
+	vector org = targ.origin;
+#ifdef SVQC
+	if(autocvar_sv_vq3compat)
+#elif defined(CSQC)
+	if(STAT(VQ3COMPAT))
+#endif
+	{
+		org.z += targ.mins_z;
+		org.z += 1; // off by 1!
+	}
+
 	if(this.enemy)
 	{
-		targ.velocity = trigger_push_calculatevelocity(targ.origin, this.enemy, this.height, targ);
+		targ.velocity = trigger_push_calculatevelocity(org, this.enemy, this.height, targ);
 	}
 	else if(this.target && this.target != "")
 	{
@@ -148,7 +159,7 @@ bool jumppad_push(entity this, entity targ)
 			else
 				RandomSelection_AddEnt(e, 1, 1);
 		}
-		targ.velocity = trigger_push_calculatevelocity(targ.origin, RandomSelection_chosen_ent, this.height, targ);
+		targ.velocity = trigger_push_calculatevelocity(org, RandomSelection_chosen_ent, this.height, targ);
 	}
 	else
 	{
diff --git a/qcsrc/common/physics/movetypes/movetypes.qc b/qcsrc/common/physics/movetypes/movetypes.qc
index 9ac3e4299..e518fe210 100644
--- a/qcsrc/common/physics/movetypes/movetypes.qc
+++ b/qcsrc/common/physics/movetypes/movetypes.qc
@@ -232,6 +232,9 @@ int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnorma
 	if(GAMEPLAYFIX_EASIERWATERJUMP(this) && (this.flags & FL_WATERJUMP) && !(blocked & 8))
 		this.velocity = primal_velocity;
 
+	if(PHYS_WALLCLIP(this) && this.pm_time && !(this.flags & FL_WATERJUMP) && !(blocked & 8))
+		this.velocity = primal_velocity;
+
 	if(applygravity)
 	{
 		if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !IS_ONGROUND(this))
diff --git a/qcsrc/common/physics/movetypes/movetypes.qh b/qcsrc/common/physics/movetypes/movetypes.qh
index 85912ee1c..20f9adba1 100644
--- a/qcsrc/common/physics/movetypes/movetypes.qh
+++ b/qcsrc/common/physics/movetypes/movetypes.qh
@@ -26,6 +26,8 @@ const int WATERLEVEL_SUBMERGED = 3;
 #define PHYS_JUMPSTEP(s)                    STAT(MOVEVARS_JUMPSTEP)
 #define PHYS_WALLFRICTION(s)                STAT(MOVEVARS_WALLFRICTION)
 
+#define PHYS_WALLCLIP(s)					STAT(MOVEVARS_WALLCLIP)
+
 #ifdef CSQC
 .float bouncestop;
 .float bouncefactor;
@@ -55,6 +57,8 @@ const int WATERLEVEL_SUBMERGED = 3;
 
 void set_movetype(entity this, int mt);
 
+.float pm_time;
+
 .float move_movetype;
 .float move_time;
 //.vector move_origin;
diff --git a/qcsrc/common/physics/movetypes/walk.qc b/qcsrc/common/physics/movetypes/walk.qc
index d41802963..8ac251618 100644
--- a/qcsrc/common/physics/movetypes/walk.qc
+++ b/qcsrc/common/physics/movetypes/walk.qc
@@ -20,6 +20,14 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
 	vector start_origin = this.origin;
 	vector start_velocity = this.velocity;
 
+	if(PHYS_WALLCLIP(this) && this.pm_time)
+	{
+		if(dt >= this.pm_time || (this.flags & FL_WATERJUMP))
+			this.pm_time = 0;
+		else
+			this.pm_time -= dt;
+	}
+
 	int clip = _Movetype_FlyMove(this, dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES(this) ? PHYS_STEPHEIGHT(this) : 0);
 
 	if (GAMEPLAYFIX_DOWNTRACEONGROUND(this) && !(clip & 1))
@@ -45,6 +53,8 @@ void _Movetype_Physics_Walk(entity this, float dt)  // SV_WalkMove
 	// if the move did not hit the ground at any point, we're not on ground
 	if (!(clip & 1))
 		UNSET_ONGROUND(this);
+	else if(PHYS_WALLCLIP(this) && !this.groundentity && start_velocity.z < -200) // don't do landing time if we were just going down a slope
+		this.pm_time = 0.25;
 
 	_Movetype_CheckVelocity(this);
 	_Movetype_LinkEdict(this, true);
diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh
index 9b8f04041..91548ccdf 100644
--- a/qcsrc/common/stats.qh
+++ b/qcsrc/common/stats.qh
@@ -301,6 +301,11 @@ bool autocvar_sv_slick_applygravity;
 #endif
 REGISTER_STAT(SLICK_APPLYGRAVITY, bool, autocvar_sv_slick_applygravity)
 
+#ifdef SVQC
+bool autocvar_sv_vq3compat;
+#endif
+REGISTER_STAT(VQ3COMPAT, bool, autocvar_sv_vq3compat)
+
 #ifdef SVQC
 #include "physics/movetypes/movetypes.qh"
 float warmup_limit;
@@ -360,6 +365,10 @@ REGISTER_STAT(MOVEVARS_STEPHEIGHT, float, autocvar_sv_stepheight)
 REGISTER_STAT(MOVEVARS_AIRACCEL_QW, float)
 REGISTER_STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, float)
 REGISTER_STAT(MOVEVARS_SPECIALCOMMAND, bool)
+#ifdef SVQC
+bool autocvar_sv_wallclip;
+#endif
+REGISTER_STAT(MOVEVARS_WALLCLIP, bool, autocvar_sv_wallclip)
 
 
 #ifdef CSQC
diff --git a/qcsrc/server/autocvars.qh b/qcsrc/server/autocvars.qh
index 2d19f6f9a..4e180f731 100644
--- a/qcsrc/server/autocvars.qh
+++ b/qcsrc/server/autocvars.qh
@@ -316,7 +316,6 @@ string autocvar_sv_motd;
 bool autocvar_sv_precacheplayermodels;
 //float autocvar_sv_precacheweapons; // WEAPONTODO?
 bool autocvar_sv_q3acompat_machineshotgunswap;
-bool autocvar_sv_vq3compat;
 bool autocvar_sv_servermodelsonly;
 int autocvar_sv_spectate;
 float autocvar_sv_spectator_speed_multiplier;
-- 
2.39.5