From: Mario <mario@smbclan.net>
Date: Sat, 22 Oct 2016 01:48:51 +0000 (+1000)
Subject: Add wall jump mutator
X-Git-Tag: xonotic-v0.8.2~480
X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=b1132f7d44f9eed1b22ac36979029915616e62b2;p=xonotic%2Fxonotic-data.pk3dir.git

Add wall jump mutator
---

diff --git a/mutators.cfg b/mutators.cfg
index 8fd4d2baf6..2188f80070 100644
--- a/mutators.cfg
+++ b/mutators.cfg
@@ -427,3 +427,13 @@ seta cl_multijump 1 "allow multijump mutator"
 set g_multijump 0	"Number of multiple jumps to allow (jumping again in the air), -1 allows for infinite jumps"
 set g_multijump_add 0	"0 = make the current z velocity equal to jumpvelocity, 1 = add jumpvelocity to the current z velocity"
 set g_multijump_speed -999999	"Minimum vertical speed a player must have in order to jump again"
+
+
+// ===========
+//  wall jump
+// ===========
+set g_walljump 0 "Enable wall jumping mutator"
+set g_walljump_delay 1 "Minimum delay between wall jumps"
+set g_walljump_force 300 "How far to bounce/jump off the wall"
+set g_walljump_velocity_xy_factor 1.15 "How much to slow down along horizontal axis, higher value = higher deceleration, if factor is < 1, you accelerate by wall jumping"
+set g_walljump_velocity_z_factor 0.5 "Upwards velocity factor, multiplied by normal jump velocity"
\ No newline at end of file
diff --git a/qcsrc/common/mutators/mutator/_mod.inc b/qcsrc/common/mutators/mutator/_mod.inc
index 294047d500..0d6326fef0 100644
--- a/qcsrc/common/mutators/mutator/_mod.inc
+++ b/qcsrc/common/mutators/mutator/_mod.inc
@@ -33,5 +33,6 @@
 #include <common/mutators/mutator/touchexplode/_mod.inc>
 #include <common/mutators/mutator/vampire/_mod.inc>
 #include <common/mutators/mutator/vampirehook/_mod.inc>
+#include <common/mutators/mutator/walljump/_mod.inc>
 #include <common/mutators/mutator/waypoints/_mod.inc>
 #include <common/mutators/mutator/weaponarena_random/_mod.inc>
diff --git a/qcsrc/common/mutators/mutator/_mod.qh b/qcsrc/common/mutators/mutator/_mod.qh
index de43630bed..917dc6557c 100644
--- a/qcsrc/common/mutators/mutator/_mod.qh
+++ b/qcsrc/common/mutators/mutator/_mod.qh
@@ -33,5 +33,6 @@
 #include <common/mutators/mutator/touchexplode/_mod.qh>
 #include <common/mutators/mutator/vampire/_mod.qh>
 #include <common/mutators/mutator/vampirehook/_mod.qh>
+#include <common/mutators/mutator/walljump/_mod.qh>
 #include <common/mutators/mutator/waypoints/_mod.qh>
 #include <common/mutators/mutator/weaponarena_random/_mod.qh>
diff --git a/qcsrc/common/mutators/mutator/walljump/_mod.inc b/qcsrc/common/mutators/mutator/walljump/_mod.inc
new file mode 100644
index 0000000000..4f879c851e
--- /dev/null
+++ b/qcsrc/common/mutators/mutator/walljump/_mod.inc
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef GAMEQC
+    #include <common/mutators/mutator/walljump/walljump.qc>
+#endif
diff --git a/qcsrc/common/mutators/mutator/walljump/_mod.qh b/qcsrc/common/mutators/mutator/walljump/_mod.qh
new file mode 100644
index 0000000000..59ab51518e
--- /dev/null
+++ b/qcsrc/common/mutators/mutator/walljump/_mod.qh
@@ -0,0 +1,4 @@
+// generated file; do not modify
+#ifdef GAMEQC
+	#include <common/mutators/mutator/walljump/walljump.qh>
+#endif
diff --git a/qcsrc/common/mutators/mutator/walljump/walljump.qc b/qcsrc/common/mutators/mutator/walljump/walljump.qc
new file mode 100644
index 0000000000..e12755ca73
--- /dev/null
+++ b/qcsrc/common/mutators/mutator/walljump/walljump.qc
@@ -0,0 +1,70 @@
+#include "walljump.qh"
+
+#ifdef CSQC
+REGISTER_MUTATOR(walljump, true);
+#elif defined(SVQC)
+REGISTER_MUTATOR(walljump, cvar("g_walljump"));
+#endif
+
+#define PHYS_WALLJUMP(s) 						STAT(WALLJUMP, s)
+#define PHYS_WALLJUMP_VELOCITY_Z_FACTOR(s) 		STAT(WALLJUMP_VELOCITY_Z_FACTOR, s)
+#define PHYS_WALLJUMP_VELOCITY_XY_FACTOR(s) 	STAT(WALLJUMP_VELOCITY_XY_FACTOR, s)
+#define PHYS_WALLJUMP_DELAY(s) 					STAT(WALLJUMP_DELAY, s)
+#define PHYS_WALLJUMP_FORCE(s) 					STAT(WALLJUMP_FORCE, s)
+
+vector PlayerTouchWall(entity this)
+{
+#define TRACE(newvec) \
+	tracebox (start, this.mins, this.maxs, (newvec), true, this); \
+	if (trace_fraction < 1 && vdist(this.origin - trace_endpos, <, dist) && trace_plane_normal_z < max_normal) \
+	if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) \
+		return trace_plane_normal;
+
+	float dist = 10, max_normal = 0.2, scaler = 100;
+	vector start = this.origin;
+	TRACE(start + v_forward * scaler)
+	TRACE(start - v_forward * scaler)
+	TRACE(start + v_right * scaler)
+	TRACE(start - v_right * scaler)
+#undef TRACE
+	return '0 0 0';
+}
+
+MUTATOR_HOOKFUNCTION(walljump, PlayerJump)
+{
+	entity player = M_ARGV(0, entity);
+
+	if(PHYS_WALLJUMP(player))
+	if(time - STAT(LASTWJ, player) > PHYS_WALLJUMP_DELAY(player)) // can't do this on client, as it's too stupid to obey counters
+	if(!IS_ONGROUND(player))
+	if(player.move_movetype != MOVETYPE_NONE && player.move_movetype != MOVETYPE_FOLLOW && player.move_movetype != MOVETYPE_FLY && player.move_movetype != MOVETYPE_NOCLIP)
+	if(!IS_JUMP_HELD(player))
+	if(!STAT(FROZEN, player))
+	if(!IS_DEAD(player))
+	{
+		vector plane_normal = PlayerTouchWall(player);
+		
+		if(plane_normal != '0 0 0')
+		{
+			STAT(LASTWJ, player) = time;
+			float wj_force = PHYS_WALLJUMP_FORCE(player);
+			float wj_xy_factor = PHYS_WALLJUMP_VELOCITY_XY_FACTOR(player);
+			float wj_z_factor = PHYS_WALLJUMP_VELOCITY_Z_FACTOR(player);
+			player.velocity_x += plane_normal_x * wj_force;
+			player.velocity_x /= wj_xy_factor;
+			player.velocity_y += plane_normal_y * wj_force;
+			player.velocity_y /= wj_xy_factor;
+			player.velocity_z = PHYS_JUMPVELOCITY(player) * wj_z_factor;
+			if(PHYS_INPUT_BUTTON_CROUCH(player)) player.velocity_z *= -1;
+
+#ifdef SVQC
+			player.oldvelocity = player.velocity;
+			Send_Effect(EFFECT_SMOKE_RING, trace_endpos, plane_normal, 5);
+			PlayerSound(player, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
+			animdecide_setaction(player, ANIMACTION_JUMP, true);
+#endif
+
+			M_ARGV(2, bool) = true; // multijump
+		}
+	}
+}
diff --git a/qcsrc/common/mutators/mutator/walljump/walljump.qh b/qcsrc/common/mutators/mutator/walljump/walljump.qh
new file mode 100644
index 0000000000..6f70f09bee
--- /dev/null
+++ b/qcsrc/common/mutators/mutator/walljump/walljump.qh
@@ -0,0 +1 @@
+#pragma once
diff --git a/qcsrc/common/stats.qh b/qcsrc/common/stats.qh
index 09921c6f86..82398aa56b 100644
--- a/qcsrc/common/stats.qh
+++ b/qcsrc/common/stats.qh
@@ -243,6 +243,20 @@ REGISTER_STAT(JETPACK_REVERSE_THRUST, float, autocvar_g_jetpack_reverse_thrust)
 
 REGISTER_STAT(MOVEVARS_HIGHSPEED, float, autocvar_g_movement_highspeed)
 
+#ifdef SVQC
+AUTOCVAR(g_walljump, bool, false, "Enable wall jumping mutator");
+AUTOCVAR(g_walljump_delay, float, 1, "Minimum delay between wall jumps");
+AUTOCVAR(g_walljump_force, float, 300, "How far to bounce/jump off the wall");
+AUTOCVAR(g_walljump_velocity_xy_factor, float, 1.15, "How much to slow down along horizontal axis, higher value = higher deceleration, if factor is < 1, you accelerate by wall jumping");
+AUTOCVAR(g_walljump_velocity_z_factor, float, 0.5, "Upwards velocity factor, multiplied by normal jump velocity");
+#endif
+REGISTER_STAT(WALLJUMP, int, autocvar_g_walljump)
+REGISTER_STAT(WALLJUMP_VELOCITY_Z_FACTOR, float, autocvar_g_walljump_velocity_z_factor)
+REGISTER_STAT(WALLJUMP_VELOCITY_XY_FACTOR, float, autocvar_g_walljump_velocity_xy_factor)
+REGISTER_STAT(WALLJUMP_DELAY, float, autocvar_g_walljump_delay)
+REGISTER_STAT(WALLJUMP_FORCE, float, autocvar_g_walljump_force)
+REGISTER_STAT(LASTWJ, float)
+
 // freeze tag, clan arena
 REGISTER_STAT(REDALIVE, int)
 REGISTER_STAT(BLUEALIVE, int)