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