]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/server/mutators/mutator_dodging.qc
NIX: better disabling
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / mutators / mutator_dodging.qc
1
2 .float cvar_cl_dodging_timeout;
3
4
5 // these are used to store the last key press time for each of the keys..
6 .float last_FORWARD_KEY_time;
7 .float last_BACKWARD_KEY_time;
8 .float last_LEFT_KEY_time;
9 .float last_RIGHT_KEY_time;
10
11 // these store the movement direction at the time of the dodge action happening.
12 .float dodging_direction_x;
13 .float dodging_direction_y;
14
15 // this indicates the last time a dodge was executed. used to check if another one is allowed
16 // and to ramp up the dodge acceleration in the physics hook.
17 .float last_dodging_time;
18
19 // set to 1 to indicate dodging has started.. reset by physics hook after dodge has been done..
20 .float dodging_action;
21
22 // the jump part of the dodge cannot be ramped
23 .float dodging_single_action;
24
25 void dodging_Initialize() {
26         // print("dodging_Initialize\n");
27
28         self.last_FORWARD_KEY_time = 0;
29         self.last_BACKWARD_KEY_time = 0;
30         self.last_RIGHT_KEY_time = 0;
31         self.last_LEFT_KEY_time = 0;
32         self.last_dodging_time = 0;
33         self.dodging_action = 0;
34         self.dodging_single_action = 0;
35         self.dodging_direction_x = 0;
36         self.dodging_direction_y = 0;
37 }
38
39 MUTATOR_HOOKFUNCTION(dodging_GetCvars) {
40         // print("dodging_GetCvars\n");
41
42         string s;
43         s = strcat1(argv(get_cvars_f));
44
45         GetCvars_handleFloat(s, get_cvars_f, cvar_cl_dodging_timeout, "cl_dodging_timeout");
46
47         return 0;
48 }
49
50 MUTATOR_HOOKFUNCTION(dodging_PlayerPhysics) {
51         // print("dodging_PlayerPhysics\n");
52
53         float common_factor;
54
55         // is dodging enabled at all? if not, do nothing..
56         if (g_dodging == 0)
57                 return 0;
58
59         // make sure v_up, v_right and v_forward are sane
60         makevectors(self.angles);
61
62         // if we have e.g. 0.5 sec ramptime and a frametime of 0.25, then the ramp code 
63         // will be called ramp_time/frametime times = 2 times. so, we need to 
64         // add 0.5 * the total speed each frame until the dodge action is done..
65         common_factor = sys_frametime / cvar("sv_dodging_ramp_time");
66
67         // if ramp time is smaller than frametime we get problems ;D
68         if (common_factor > 1) 
69                 common_factor = 1;
70
71
72         // ramp up dodging speed by adding some velocity each frame.. TODO: do it! :D
73         if (self.dodging_action == 1) {
74                 self.velocity = 
75                           self.velocity 
76                         + (common_factor * (self.dodging_direction_y * cvar("sv_dodging_horiz_speed")) * v_right) 
77                         + (common_factor * (self.dodging_direction_x * cvar("sv_dodging_horiz_speed")) * v_forward);
78         }
79
80         // the up part of the dodge is a single shot action
81         if (self.dodging_single_action == 1) {
82                 self.velocity = 
83                           self.velocity 
84                         + (cvar("sv_dodging_up_speed") * v_up);
85
86                 self.dodging_single_action = 0;
87         }
88
89         // are we done with the dodging ramp yet?
90         if((self.dodging_action == 1) && ((time - self.last_dodging_time) > cvar("sv_dodging_ramp_time")))
91         {
92                 // reset state so next dodge can be done correctly
93                 self.dodging_action = 0;
94                 self.dodging_direction_x = 0;
95                 self.dodging_direction_y = 0;
96         }
97
98         return 0;
99 }
100
101 MUTATOR_HOOKFUNCTION(dodging_GetPressedKeys) {
102         // print("dodging_PlayerPhysics\n");
103
104         float length;
105         float dodge_detected;
106
107         if (g_dodging == 0)
108                 return 0;
109
110         dodge_detected = 0;
111
112         // first check if the last dodge is far enough back in time so we can dodge again
113         if ((time - self.last_dodging_time) < cvar("sv_dodging_delay"))
114                 return 0;
115
116         // check if our feet are on the ground :D
117         if (!(self.lastflags & FL_ONGROUND))
118                 return 0;
119
120
121         // TODO: fix!
122         // self.cvar_cl_dodging_timeout = 0.2;
123
124         if (self.movement_x > 0) {
125                 // is this a state change?
126                 if (!(self.pressedkeys & KEY_FORWARD)) {
127                         if ((time - self.last_FORWARD_KEY_time) < self.cvar_cl_dodging_timeout) { 
128                                 dodge_detected = 1;
129                                 self.dodging_direction_x = 1.0;
130                                 self.last_dodging_time = time;
131                         }
132                         self.last_FORWARD_KEY_time = time;
133                 }
134         }
135
136         if (self.movement_x < 0) {
137                 // is this a state change?
138                 if (!(self.pressedkeys & KEY_BACKWARD)) {
139                         if ((time - self.last_BACKWARD_KEY_time) < self.cvar_cl_dodging_timeout)        { 
140                                 dodge_detected = 1;
141                                 self.dodging_direction_x = -1.0;
142                                 self.last_dodging_time = time;
143                         }
144                         self.last_BACKWARD_KEY_time = time;
145                 }
146         }
147
148         if (self.movement_y > 0) {
149                 // is this a state change?
150                 if (!(self.pressedkeys & KEY_RIGHT)) {
151                         if ((time - self.last_RIGHT_KEY_time) < self.cvar_cl_dodging_timeout)   { 
152                                 dodge_detected = 1;
153                                 self.dodging_direction_y = 1.0;
154                                 self.last_dodging_time = time;
155                         }
156                         self.last_RIGHT_KEY_time = time;
157                 }
158         }
159
160         if (self.movement_y < 0) {
161                 // is this a state change?
162                 if (!(self.pressedkeys & KEY_LEFT)) {
163                         if ((time - self.last_LEFT_KEY_time) < self.cvar_cl_dodging_timeout)    { 
164                                 dodge_detected = 1;
165                                 self.dodging_direction_y = -1.0;
166                                 self.last_dodging_time = time;
167                         }
168                         self.last_LEFT_KEY_time = time;
169                 }
170         }
171
172
173
174         if (dodge_detected == 1) {
175                 self.dodging_action = 1;
176                 self.dodging_single_action = 1;
177
178                 // normalize the dodging_direction vector.. (unlike UT99) XD
179                 length = length + self.dodging_direction_x * self.dodging_direction_x;
180                 length = length + self.dodging_direction_y * self.dodging_direction_y;
181                 length = sqrt(length);
182
183                 self.dodging_direction_x = self.dodging_direction_x * 1.0/length;
184                 self.dodging_direction_y = self.dodging_direction_y * 1.0/length;
185         }
186
187         return 0;
188 }
189
190 MUTATOR_DEFINITION(dodging)
191 {
192         // we need to be called before GetPressedKey does its thing so we can
193         // detect state changes and therefore dodging actions..
194         MUTATOR_HOOK(GetPressedKeys, dodging_GetPressedKeys, CBC_ORDER_ANY);
195
196         // in the physics hook we actually implement the dodge..
197         MUTATOR_HOOK(PlayerPhysics, dodging_PlayerPhysics, CBC_ORDER_ANY);
198
199         MUTATOR_HOOK(GetCvars, dodging_GetCvars, CBC_ORDER_ANY);
200
201         // this just turns on the cvar.
202         MUTATOR_ONADD
203         {
204                 g_dodging = 1;
205                 dodging_Initialize();
206         }
207
208         // this just turns off the cvar.
209         MUTATOR_ONREMOVE
210         {        
211                 g_dodging = 0;
212         }
213
214         return 0;
215 }