]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/common/mutators/mutator/multijump/multijump.qc
take3: format 903 files
[xonotic/xonotic-data.pk3dir.git] / qcsrc / common / mutators / mutator / multijump / multijump.qc
1 #include "multijump.qh"
2
3 #ifdef GAMEQC
4
5 #ifdef SVQC
6 #include <server/antilag.qh>
7 #endif
8 #include <common/physics/player.qh>
9
10
11 #if defined(SVQC)
12 REGISTER_MUTATOR(multijump, autocvar_g_multijump);
13 #elif defined(CSQC)
14 REGISTER_MUTATOR(multijump, true);
15 #endif
16
17 #define PHYS_MULTIJUMP(s) STAT(MULTIJUMP, s)
18 #define PHYS_MULTIJUMP_SPEED(s) STAT(MULTIJUMP_SPEED, s)
19 #define PHYS_MULTIJUMP_ADD(s) STAT(MULTIJUMP_ADD, s)
20 #define PHYS_MULTIJUMP_MAXSPEED(s) STAT(MULTIJUMP_MAXSPEED, s)
21 #define PHYS_MULTIJUMP_DODGING(s) STAT(MULTIJUMP_DODGING, s)
22 #define PHYS_MULTIJUMP_COUNT(s) STAT(MULTIJUMP_COUNT, s)
23
24 .bool multijump_ready;
25
26 #ifdef CSQC
27 bool autocvar_cl_multijump = true;
28
29 #define PHYS_MULTIJUMP_CLIENT(s) autocvar_cl_multijump
30 #elif defined(SVQC)
31 .bool cvar_cl_multijump;
32
33 #define PHYS_MULTIJUMP_CLIENT(s) CS(s).cvar_cl_multijump
34 #endif
35
36 MUTATOR_HOOKFUNCTION(multijump, PlayerPhysics)
37 {
38         entity player = M_ARGV(0, entity);
39
40 #ifdef CSQC
41         player.multijump_count = PHYS_MULTIJUMP_COUNT(player);
42 #endif
43         if (!PHYS_MULTIJUMP(player)) { return; }
44
45         if (IS_ONGROUND(player)) {
46                 player.multijump_count = 0;
47         }
48 }
49
50 MUTATOR_HOOKFUNCTION(multijump, PlayerJump)
51 {
52         entity player = M_ARGV(0, entity);
53
54         if (!PHYS_MULTIJUMP(player)) { return; }
55
56         int client_multijump = PHYS_MULTIJUMP_CLIENT(player);
57         if (client_multijump > 1) {
58                 return;                        // nope
59         }
60         if (!IS_JUMP_HELD(player) && !IS_ONGROUND(player) && client_multijump) { // jump button pressed this frame and we are in midair
61                 player.multijump_ready = true; // this is necessary to check that we released the jump button and pressed it again
62         } else {
63                 player.multijump_ready = false;
64         }
65
66         int phys_multijump = PHYS_MULTIJUMP(player);
67
68         if (!M_ARGV(2, bool) && player.multijump_ready && (PHYS_MULTIJUMP_COUNT(player) < phys_multijump || phys_multijump == -1) && player.velocity_z > PHYS_MULTIJUMP_SPEED(player)
69                 && (!PHYS_MULTIJUMP_MAXSPEED(player) || vdist(player.velocity, <=, PHYS_MULTIJUMP_MAXSPEED(player)))) {
70                 if (PHYS_MULTIJUMP(player)) {
71                         if (!PHYS_MULTIJUMP_ADD(player)) { // in this case we make the z velocity == jumpvelocity
72                                 if (player.velocity_z < PHYS_JUMPVELOCITY(player)) {
73                                         M_ARGV(2, bool) = true;
74                                         player.velocity_z = 0;
75                                 }
76                         } else {
77                                 M_ARGV(2, bool) = true;
78                         }
79
80                         if (M_ARGV(2, bool)) {
81                                 if (PHYS_MULTIJUMP_DODGING(player)) {
82                                         if (PHYS_CS(player).movement_x != 0 || PHYS_CS(player).movement_y != 0) { // don't remove all speed if player isnt pressing any movement keys
83                                                 float curspeed;
84                                                 vector wishvel, wishdir;
85
86 /*#ifdef SVQC
87                     curspeed = max(
88                         vlen(vec2(player.velocity)), // current xy speed
89                         vlen(vec2(antilag_takebackavgvelocity(player, max(player.lastteleporttime + sys_frametime, time - 0.25), time))) // average xy topspeed over the last 0.25 secs
90                     );
91 #elif defined(CSQC)*/
92                                                 curspeed = vlen(vec2(player.velocity));
93 // #endif
94
95                                                 makevectors(player.v_angle_y * '0 1 0');
96                                                 wishvel = v_forward * PHYS_CS(player).movement_x + v_right * PHYS_CS(player).movement_y;
97                                                 wishdir = normalize(wishvel);
98
99                                                 player.velocity_x = wishdir_x * curspeed; // allow "dodging" at a multijump
100                                                 player.velocity_y = wishdir_y * curspeed;
101                                                 // keep velocity_z unchanged!
102                                         }
103                                 }
104                                 if (PHYS_MULTIJUMP(player) > 0) {
105                                         player.multijump_count += 1;
106                                 }
107                         }
108                 }
109                 player.multijump_ready = false; // require releasing and pressing the jump button again for the next jump
110         }
111 }
112
113 #ifdef SVQC
114
115 REPLICATE(cvar_cl_multijump, bool, "cl_multijump");
116
117 MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsString)
118 {
119         M_ARGV(0, string) = strcat(M_ARGV(0, string), ":multijump");
120 }
121
122 MUTATOR_HOOKFUNCTION(multijump, BuildMutatorsPrettyString)
123 {
124         M_ARGV(0, string) = strcat(M_ARGV(0, string), ", Multi jump");
125 }
126
127 #endif
128
129 #endif