Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
walljump.qc
Go to the documentation of this file.
1#include "walljump.qh"
2
3#ifdef GAMEQC
4#ifdef CSQC
5REGISTER_MUTATOR(walljump, true);
6#elif defined(SVQC)
7REGISTER_MUTATOR(walljump, autocvar_g_walljump);
8#endif
9
10#define PHYS_WALLJUMP(s) STAT(WALLJUMP, s)
11#define PHYS_WALLJUMP_VELOCITY_Z_FACTOR(s) STAT(WALLJUMP_VELOCITY_Z_FACTOR, s)
12#define PHYS_WALLJUMP_VELOCITY_XY_FACTOR(s) STAT(WALLJUMP_VELOCITY_XY_FACTOR, s)
13#define PHYS_WALLJUMP_DELAY(s) STAT(WALLJUMP_DELAY, s)
14#define PHYS_WALLJUMP_FORCE(s) STAT(WALLJUMP_FORCE, s)
15
17{
18#define TRACE(newvec) \
19 WarpZone_TraceBox(start, this.mins, this.maxs, (newvec), true, this); \
20 trans_plane_norm = WarpZone_UnTransformVelocity(WarpZone_trace_transform, trace_plane_normal); \
21 if (trace_fraction < 1 && trans_plane_norm.z < max_normal \
22 && vdist(this.origin - WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos), <, dist) \
23 && !(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) \
24 return trans_plane_norm;
25
26 float dist = 10, max_normal = 0.2, scaler = 100;
27 vector start = this.origin;
28 vector forward, right, _up, trans_plane_norm;
29 MAKE_VECTORS(this.angles, forward, right, _up);
30 TRACE(start + forward * scaler)
31 TRACE(start - forward * scaler)
32 TRACE(start + right * scaler)
33 TRACE(start - right * scaler)
34#undef TRACE
35 return '0 0 0';
36}
37
39{
40 entity player = M_ARGV(0, entity);
41
42 if(PHYS_WALLJUMP(player))
43 if(time - STAT(LASTWJ, player) > PHYS_WALLJUMP_DELAY(player)) // can't do this on client, as it's too stupid to obey counters
44 if(!IS_ONGROUND(player))
45 if(player.move_movetype != MOVETYPE_NONE && player.move_movetype != MOVETYPE_FOLLOW && player.move_movetype != MOVETYPE_FLY && player.move_movetype != MOVETYPE_NOCLIP)
46 if(!IS_JUMP_HELD(player))
47 if(!STAT(FROZEN, player) && !StatusEffects_active(STATUSEFFECT_Frozen, player))
48 if(!IS_DEAD(player))
49 {
50 vector plane_normal = PlayerTouchWall(player);
51
52 if(plane_normal != '0 0 0')
53 {
54 float wj_force = PHYS_WALLJUMP_FORCE(player);
55 float wj_xy_factor = PHYS_WALLJUMP_VELOCITY_XY_FACTOR(player);
56 float wj_z_factor = PHYS_WALLJUMP_VELOCITY_Z_FACTOR(player);
57 player.velocity_x += plane_normal_x * wj_force;
58 player.velocity_x /= wj_xy_factor;
59 player.velocity_y += plane_normal_y * wj_force;
60 player.velocity_y /= wj_xy_factor;
61 player.velocity_z = PHYS_JUMPVELOCITY(player) * wj_z_factor;
62 if(PHYS_INPUT_BUTTON_CROUCH(player)) player.velocity_z *= -1;
63
64#ifdef SVQC
65 STAT(LASTWJ, player) = time;
66 player.oldvelocity = player.velocity;
67 Send_Effect(EFFECT_SMOKE_RING, trace_endpos, plane_normal, 5);
68 PlayerSound(player, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND, 1);
70#endif
71
72 M_ARGV(2, bool) = true; // multijump
73 }
74 }
75}
76
77#endif
78#ifdef MENUQC
79METHOD(MutatorWallJump, describe, string(MutatorWallJump this))
80{
81 TC(MutatorWallJump, this);
83 PAR(_("%s is a mutator that enables jumping off walls for added mobility. "
84 "To do a wall jump, tap %s when against a wall."), COLORED_NAME(this), strcat("^3", _("jump"), "^7"));
85 PAR(_("This mutator adds a bit of versatility, allowing for more dynamic and unpredictable movement."));
86 return PAGE_TEXT;
87}
88#endif
void animdecide_setaction(entity e, float action, float restart)
const int ANIMACTION_JUMP
#define REGISTER_MUTATOR(...)
Definition base.qh:295
#define MUTATOR_HOOKFUNCTION(...)
Definition base.qh:335
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
#define COLORED_NAME(this)
Definition color.qh:189
#define M_ARGV(x, type)
Definition events.qh:17
bool PlayerJump(entity this)
Definition player.qc:386
#define PHYS_INPUT_BUTTON_CROUCH(s)
Definition player.qh:156
#define IS_DEAD(s)
Definition player.qh:244
#define PHYS_JUMPVELOCITY(s)
Definition player.qh:133
#define IS_JUMP_HELD(s)
Definition player.qh:205
float time
vector trace_endpos
vector origin
#define MAKE_VECTORS(angles, forward, right, up)
Same as the makevectors builtin but uses the provided locals instead of the v_* globals.
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:155
ent angles
Definition ent_cs.qc:146
const int VOICETYPE_PLAYERSOUND
#define PlayerSound(this, def, chan, vol, voicetype, pitchscale)
#define TC(T, sym)
Definition _all.inc:82
#define STAT(...)
Definition stats.qh:94
const int MOVETYPE_NONE
Definition movetypes.qh:133
const int MOVETYPE_FOLLOW
Definition movetypes.qh:145
const int MOVETYPE_NOCLIP
Definition movetypes.qh:141
const int MOVETYPE_FLY
Definition movetypes.qh:138
#define IS_ONGROUND(s)
Definition movetypes.qh:16
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define METHOD(cname, name, prototype)
Definition oo.qh:274
vector
Definition self.qh:96
const float VOL_BASE
Definition sound.qh:36
const int CH_PLAYER
Definition sound.qh:20
bool StatusEffects_active(StatusEffect this, entity actor)
#define PAGE_TEXT
Definition string.qh:651
#define PAR(...)
Adds an individually translatable paragraph to PAGE_TEXT without having to deal with strcat and sprin...
Definition string.qh:657
#define PAGE_TEXT_INIT()
Definition string.qh:650
#define PHYS_WALLJUMP(s)
Definition walljump.qc:10
#define PHYS_WALLJUMP_FORCE(s)
Definition walljump.qc:14
vector PlayerTouchWall(entity this)
Definition walljump.qc:16
#define PHYS_WALLJUMP_VELOCITY_Z_FACTOR(s)
Definition walljump.qc:11
#define PHYS_WALLJUMP_DELAY(s)
Definition walljump.qc:13
#define TRACE(newvec)
#define PHYS_WALLJUMP_VELOCITY_XY_FACTOR(s)
Definition walljump.qc:12