]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/walljump/walljump.qc
take3: format 903 files
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / walljump / walljump.qc
1 #include "walljump.qh"
2
3 #ifdef GAMEQC
4 #ifdef CSQC
5 REGISTER_MUTATOR(walljump, true);
6 #elif defined(SVQC)
7 REGISTER_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
16 vector PlayerTouchWall(entity this)
17 {
18 #define TRACE(newvec) \
19         tracebox(start, this.mins, this.maxs, (newvec), true, this); \
20         if (trace_fraction < 1 && vdist(this.origin - trace_endpos, <, dist) && trace_plane_normal_z < max_normal) { \
21                 if (!(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)) { \
22                         return trace_plane_normal; \
23                 } \
24         }
25
26         float dist = 10, max_normal = 0.2, scaler = 100;
27         vector start = this.origin;
28         TRACE(start + v_forward * scaler)
29         TRACE(start - v_forward * scaler)
30         TRACE(start + v_right * scaler)
31         TRACE(start - v_right * scaler)
32 #undef TRACE
33         return '0 0 0';
34 }
35
36 MUTATOR_HOOKFUNCTION(walljump, PlayerJump)
37 {
38         entity player = M_ARGV(0, entity);
39
40         if (PHYS_WALLJUMP(player)) {
41                 if (time - STAT(LASTWJ, player) > PHYS_WALLJUMP_DELAY(player)) { // can't do this on client, as it's too stupid to obey counters
42                         if (!IS_ONGROUND(player)) {
43                                 if (player.move_movetype != MOVETYPE_NONE && player.move_movetype != MOVETYPE_FOLLOW && player.move_movetype != MOVETYPE_FLY && player.move_movetype != MOVETYPE_NOCLIP) {
44                                         if (!IS_JUMP_HELD(player)) {
45                                                 if (!STAT(FROZEN, player)) {
46                                                         if (!IS_DEAD(player)) {
47                                                                 vector plane_normal = PlayerTouchWall(player);
48
49                                                                 if (plane_normal != '0 0 0') {
50                                                                         float wj_force = PHYS_WALLJUMP_FORCE(player);
51                                                                         float wj_xy_factor = PHYS_WALLJUMP_VELOCITY_XY_FACTOR(player);
52                                                                         float wj_z_factor = PHYS_WALLJUMP_VELOCITY_Z_FACTOR(player);
53                                                                         player.velocity_x += plane_normal_x * wj_force;
54                                                                         player.velocity_x /= wj_xy_factor;
55                                                                         player.velocity_y += plane_normal_y * wj_force;
56                                                                         player.velocity_y /= wj_xy_factor;
57                                                                         player.velocity_z = PHYS_JUMPVELOCITY(player) * wj_z_factor;
58                                                                         if (PHYS_INPUT_BUTTON_CROUCH(player)) { player.velocity_z *= -1; }
59
60 #ifdef SVQC
61                                                                         STAT(LASTWJ, player) = time;
62                                                                         player.oldvelocity = player.velocity;
63                                                                         Send_Effect(EFFECT_SMOKE_RING, trace_endpos, plane_normal, 5);
64                                                                         PlayerSound(player, playersound_jump, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
65                                                                         animdecide_setaction(player, ANIMACTION_JUMP, true);
66 #endif
67
68                                                                         M_ARGV(2, bool) = true; // multijump
69                                                                 }
70                                                         }
71                                                 }
72                                         }
73                                 }
74                         }
75                 }
76         }
77 }
78
79 #endif