]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/server/gamec/cl_physics.c
don't apply friction while bunnyhopping, this cures the framerate
[divverent/nexuiz.git] / data / qcsrc / server / gamec / cl_physics.c
1 float sv_accelerate;
2 float sv_maxairspeed;
3 float sv_friction;
4 float sv_maxspeed;
5 float sv_stopspeed;
6 float sv_gravity;
7 .float ladder_time;
8 .entity ladder_entity;
9 .float gravity;
10 .float swamp_slowdown;
11
12 void SV_PlayerPhysics()
13 {
14         local vector wishvel, wishdir, v;
15         local float wishspeed, f, maxspd_mod, spd, maxairspd, airaccel, swapspd_mod;
16         string temps;
17
18         // MauveBot_AI();
19         if (clienttype(self) == CLIENTTYPE_BOT)
20         {
21                 if (self.bot_type == BOT_TYPE_MAUVEBOT || self.bot_type == BOT_TYPE_AUTOMAUVE)
22                         MauveBot_AI();
23                 else if (self.bot_type == BOT_TYPE_URREBOT || self.bot_type == BOT_TYPE_AUTOURRE)
24                         UrreBotThink();
25         }
26
27         if (self.movetype == MOVETYPE_NONE)
28                 return;
29
30         if (self.punchangle != '0 0 0')
31         {
32                 f = vlen(self.punchangle) - 10 * frametime;
33                 if (f > 0)
34                         self.punchangle = normalize(self.punchangle) * f;
35                 else
36                         self.punchangle = '0 0 0';
37         }
38
39         if (self.punchvector != '0 0 0')
40         {
41                 f = vlen(self.punchvector) - 30 * frametime;
42                 if (f > 0)
43                         self.punchvector = normalize(self.punchvector) * f;
44                 else
45                         self.punchvector = '0 0 0';
46         }
47
48         maxspd_mod = 1;
49
50         if(cvar("g_runematch"))
51         {
52                 if(self.runes & RUNE_SPEED)
53                 {
54                         if(self.runes & CURSE_SLOW)
55                                 maxspd_mod = maxspd_mod * cvar("g_balance_rune_speed_combo_moverate");
56                         else
57                                 maxspd_mod = maxspd_mod * cvar("g_balance_rune_speed_moverate");
58                 }
59                 else if(self.runes & CURSE_SLOW)
60                 {
61                         maxspd_mod = maxspd_mod * cvar("g_balance_curse_slow_moverate");
62                 }
63         }
64
65         if(cvar("g_minstagib") && (self.items & IT_INVINCIBLE))
66         {
67                 maxspd_mod = maxspd_mod * cvar("g_balance_rune_speed_moverate");
68         }
69
70         swapspd_mod = 1;
71         if(self.in_swamp != 0) {
72                 swapspd_mod = self.swamp_slowdown; //cvar("g_balance_swamp_moverate");
73         }
74
75
76         spd = sv_maxspeed * maxspd_mod;
77         spd = sv_maxspeed * swapspd_mod;
78
79         if(self.speed != spd)
80         {
81                 self.speed = spd;
82                 temps = ftos(spd);
83                 stuffcmd(self, strcat("cl_forwardspeed ", temps, "\n"));
84                 stuffcmd(self, strcat("cl_backspeed ", temps, "\n"));
85                 stuffcmd(self, strcat("cl_sidespeed ", temps, "\n"));
86                 stuffcmd(self, strcat("cl_upspeed ", temps, "\n"));
87
88                 temps = ftos(sv_accelerate * maxspd_mod);
89                 stuffcmd(self, strcat("cl_movement_accelerate ", temps, "\n"));
90         }
91
92         // if dead, behave differently
93         if (self.deadflag)
94                 return;
95
96         if (!self.fixangle)
97         {
98                 self.angles_x = 0;
99                 self.angles_y = self.v_angle_y;
100                 self.angles_z = 0;
101         }
102
103         if (self.flags & FL_WATERJUMP )
104         {
105                 self.velocity_x = self.movedir_x;
106                 self.velocity_y = self.movedir_y;
107                 if (time > self.teleport_time || self.waterlevel == 0)
108                 {
109                         self.flags = self.flags - (self.flags & FL_WATERJUMP);
110                         self.teleport_time = 0;
111                 }
112         }
113         else if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
114         {
115                 // noclipping or flying
116                 self.flags = self.flags - (self.flags & FL_ONGROUND);
117
118                 self.velocity = self.velocity * (1 - frametime * sv_friction);
119                 makevectors(self.v_angle);
120                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
121                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
122                 // acceleration
123                 wishdir = normalize(wishvel);
124                 wishspeed = vlen(wishvel);
125                 if (wishspeed > sv_maxspeed*maxspd_mod)
126                         wishspeed = sv_maxspeed*maxspd_mod;
127                 if (time >= self.teleport_time)
128                 {
129                         f = wishspeed - (self.velocity * wishdir);
130                         if (f > 0)
131                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed);
132                 }
133         }
134         else if (self.waterlevel >= 2)
135         {
136                 // swimming
137                 self.flags = self.flags - (self.flags & FL_ONGROUND);
138
139                 makevectors(self.v_angle);
140                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
141                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
142                 if (wishvel == '0 0 0')
143                         wishvel = '0 0 -60'; // drift towards bottom
144
145                 wishdir = normalize(wishvel);
146                 wishspeed = vlen(wishvel);
147                 if (wishspeed > sv_maxspeed*maxspd_mod)
148                         wishspeed = sv_maxspeed*maxspd_mod;
149                 wishspeed = wishspeed * 0.7;
150
151                 // water friction
152                 self.velocity = self.velocity * (1 - frametime * sv_friction);
153
154                 // water acceleration
155                 f = wishspeed - (self.velocity * wishdir);
156                 if (f > 0)
157                         self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed);
158         }
159         else if (time < self.ladder_time)
160         {
161                 // on a func_ladder or swimming in func_water
162                 self.flags = self.flags - (self.flags & FL_ONGROUND);
163
164                 self.velocity = self.velocity * (1 - frametime * sv_friction);
165                 makevectors(self.v_angle);
166                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
167                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
168                 if (self.gravity)
169                         self.velocity_z = self.velocity_z + self.gravity * sv_gravity * frametime;
170                 else
171                         self.velocity_z = self.velocity_z + sv_gravity * frametime;
172                 if (self.ladder_entity.classname == "func_water")
173                 {
174                         f = vlen(wishvel);
175                         if (f > self.ladder_entity.speed)
176                                 wishvel = wishvel * (self.ladder_entity.speed / f);
177
178                         self.watertype = self.ladder_entity.skin;
179                         f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
180                         if ((self.origin_z + self.view_ofs_z) < f)
181                                 self.waterlevel = 3;
182                         else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
183                                 self.waterlevel = 2;
184                         else if ((self.origin_z + self.mins_z + 1) < f)
185                                 self.waterlevel = 1;
186                         else
187                         {
188                                 self.waterlevel = 0;
189                                 self.watertype = CONTENT_EMPTY;
190                         }
191                 }
192                 // acceleration
193                 wishdir = normalize(wishvel);
194                 wishspeed = vlen(wishvel);
195                 if (wishspeed > sv_maxspeed)
196                         wishspeed = sv_maxspeed;
197                 if (time >= self.teleport_time)
198                 {
199                         f = wishspeed - (self.velocity * wishdir);
200                         if (f > 0)
201                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed);
202                 }
203         }
204         else if (self.flags & FL_ONGROUND)
205         {
206                 // walking
207                 makevectors(self.v_angle_y * '0 1 0');
208                 wishvel = v_forward * self.movement_x + v_right * self.movement_y;
209                 // friction
210                 if (self.velocity_x || self.velocity_y)
211                 if (!(self.flags & FL_JUMPRELEASED) || !self.button2) // don't apply friction if bunnyhopping
212                 {
213                         v = self.velocity;
214                         v_z = 0;
215                         f = vlen(v);
216                         if (f < sv_stopspeed)
217                                 f = 1 - frametime * (sv_stopspeed / f) * sv_friction;
218                         else
219                                 f = 1 - frametime * sv_friction;
220                         if (f > 0)
221                                 self.velocity = self.velocity * f;
222                         else
223                                 self.velocity = '0 0 0';
224                 }
225                 // acceleration
226                 wishdir = normalize(wishvel);
227                 wishspeed = vlen(wishvel);
228                 if (wishspeed > sv_maxspeed*maxspd_mod)
229                         wishspeed = sv_maxspeed*maxspd_mod;
230                 if (self.crouch)
231                         wishspeed = wishspeed * 0.5;
232                 if (time >= self.teleport_time)
233                 {
234                         f = wishspeed - (self.velocity * wishdir);
235                         if (f > 0)
236                                 self.velocity = self.velocity + wishdir * min(f, sv_accelerate*maxspd_mod * frametime * wishspeed);
237                 }
238         }
239         else
240         {
241                 if(maxspd_mod < 1)
242                 {
243                         maxairspd = sv_maxairspeed*maxspd_mod;
244                         airaccel = sv_accelerate*maxspd_mod;
245                 }
246                 else
247                 {
248                         maxairspd = sv_maxairspeed;
249                         airaccel = sv_accelerate;
250                 }
251                 // airborn
252                 makevectors(self.v_angle_y * '0 1 0');
253                 wishvel = v_forward * self.movement_x + v_right * self.movement_y;
254                 // acceleration
255                 wishdir = normalize(wishvel);
256                 wishspeed = vlen(wishvel);
257                 if (wishspeed > maxairspd)
258                         wishspeed = maxairspd;
259                 if (self.crouch)
260                         wishspeed = wishspeed * 0.5;
261                 if (time >= self.teleport_time)
262                 {
263                         f = wishspeed;// - (self.velocity * wishdir);
264                         if (f > 0)
265                                 self.velocity = self.velocity + wishdir * min(f, airaccel * frametime * wishspeed);
266                 }
267         }
268 };