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