From b1132f7d44f9eed1b22ac36979029915616e62b2 Mon Sep 17 00:00:00 2001 From: Mario Date: Sat, 22 Oct 2016 11:48:51 +1000 Subject: [PATCH] Add wall jump mutator --- mutators.cfg | 10 +++ qcsrc/common/mutators/mutator/_mod.inc | 1 + qcsrc/common/mutators/mutator/_mod.qh | 1 + .../common/mutators/mutator/walljump/_mod.inc | 4 ++ .../common/mutators/mutator/walljump/_mod.qh | 4 ++ .../mutators/mutator/walljump/walljump.qc | 70 +++++++++++++++++++ .../mutators/mutator/walljump/walljump.qh | 1 + qcsrc/common/stats.qh | 14 ++++ 8 files changed, 105 insertions(+) create mode 100644 qcsrc/common/mutators/mutator/walljump/_mod.inc create mode 100644 qcsrc/common/mutators/mutator/walljump/_mod.qh create mode 100644 qcsrc/common/mutators/mutator/walljump/walljump.qc create mode 100644 qcsrc/common/mutators/mutator/walljump/walljump.qh diff --git a/mutators.cfg b/mutators.cfg index 8fd4d2baf..2188f8007 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 294047d50..0d6326fef 100644 --- a/qcsrc/common/mutators/mutator/_mod.inc +++ b/qcsrc/common/mutators/mutator/_mod.inc @@ -33,5 +33,6 @@ #include #include #include +#include #include #include diff --git a/qcsrc/common/mutators/mutator/_mod.qh b/qcsrc/common/mutators/mutator/_mod.qh index de43630be..917dc6557 100644 --- a/qcsrc/common/mutators/mutator/_mod.qh +++ b/qcsrc/common/mutators/mutator/_mod.qh @@ -33,5 +33,6 @@ #include #include #include +#include #include #include diff --git a/qcsrc/common/mutators/mutator/walljump/_mod.inc b/qcsrc/common/mutators/mutator/walljump/_mod.inc new file mode 100644 index 000000000..4f879c851 --- /dev/null +++ b/qcsrc/common/mutators/mutator/walljump/_mod.inc @@ -0,0 +1,4 @@ +// generated file; do not modify +#ifdef GAMEQC + #include +#endif diff --git a/qcsrc/common/mutators/mutator/walljump/_mod.qh b/qcsrc/common/mutators/mutator/walljump/_mod.qh new file mode 100644 index 000000000..59ab51518 --- /dev/null +++ b/qcsrc/common/mutators/mutator/walljump/_mod.qh @@ -0,0 +1,4 @@ +// generated file; do not modify +#ifdef GAMEQC + #include +#endif diff --git a/qcsrc/common/mutators/mutator/walljump/walljump.qc b/qcsrc/common/mutators/mutator/walljump/walljump.qc new file mode 100644 index 000000000..e12755ca7 --- /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 000000000..6f70f09be --- /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 09921c6f8..82398aa56 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) -- 2.39.2