]> icculus.org git repositories - divverent/nexuiz.git/blob - qcsrc/sv_user.nc
Gunswitch sound removed
[divverent/nexuiz.git] / qcsrc / sv_user.nc
1 float lastclientthink, sv_maxspeed, sv_friction, sv_accelerate, sv_stopspeed;
2 float sv_edgefriction, cl_rollspeed, cl_divspeed, cl_rollangle;
3 .float ladder_time;
4 .entity ladder_entity;
5
6 // LordHavoc:
7 // Highly optimized port of SV_ClientThink from engine code to QuakeC.
8 // No behavior changes!  This code is much shorter and probably faster than
9 // the engine code :)
10
11 // note that darkplaces engine will call this function if it finds it,
12 // so modify for your own mods and enjoy...
13
14 // note also, this code uses some builtin functions from dpextensions.qc
15 // (included with darkplaces engine releases)
16
17 void SV_PlayerPhysics() {
18         local vector wishvel, wishdir, v;
19         local float wishspeed, f;
20
21         if (self.movetype == MOVETYPE_NONE)
22                 return;
23
24         if (self.punchangle != '0 0 0')
25         {
26                 f = vlen(self.punchangle) - 10 * frametime;
27                 if (f > 0)
28                         self.punchangle = normalize(self.punchangle) * f;
29                 else
30                         self.punchangle = '0 0 0';
31         }
32
33         // if dead, behave differently
34         if (self.health <= 0)
35                 return;
36
37         if (time != lastclientthink)
38         {
39                 lastclientthink = time;
40                 sv_maxspeed = cvar("sv_maxspeed");
41                 sv_maxspeed = 220;
42                 sv_friction = cvar("sv_friction");
43                 sv_accelerate = cvar("sv_accelerate");
44                 sv_stopspeed = cvar("sv_stopspeed");
45                 sv_edgefriction = cvar("edgefriction");
46                 // LordHavoc: this * 4 is an optimization
47                 cl_rollangle = cvar("cl_rollangle") * 4;
48                 // LordHavoc: this 1 / is an optimization
49                 cl_divspeed = 1 / cvar("cl_rollspeed");
50         }
51
52         // show 1/3 the pitch angle and all the roll angle
53         self.angles_z = bound(-1, self.velocity * v_right * cl_divspeed, 1) * cl_rollangle;
54 /*      if (!self.fixangle)
55         {
56                 self.angles_x = (self.v_angle_x + self.punchangle_x) * -0.333;
57                 self.angles_y = self.v_angle_y + self.punchangle_y;
58         }*/
59         
60         if (self.crouch) self.movement = self.movement * 0.5; /* Quick try by diGGer */
61
62         if (self.flags & FL_WATERJUMP )
63         {
64                 self.velocity_x = self.movedir_x;
65                 self.velocity_y = self.movedir_y;
66                 if (time > self.teleport_time || self.waterlevel == 0)
67                 {
68                         self.flags = self.flags - (self.flags & FL_WATERJUMP);
69                         self.teleport_time = 0;
70                 }
71                 return;
72         }
73
74         makevectors(self.v_angle);
75
76         // swim
77         if (self.waterlevel >= 2)
78         if (self.movetype != MOVETYPE_NOCLIP)
79         {
80                 if (self.movement == '0 0 0')
81                         wishvel = '0 0 -60'; // drift towards bottom
82                 else
83                         wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
84
85                 wishspeed = vlen(wishvel);
86                 if (wishspeed > sv_maxspeed)
87                         wishspeed = sv_maxspeed * 0.7;
88                 else
89                         wishspeed = wishspeed * 0.7;
90
91                 // water friction
92                 if (self.velocity != '0 0 0')
93                 {
94                         f = vlen(self.velocity) * (1 - frametime * sv_friction);
95                         if (f > 0)
96                                 self.velocity = normalize(self.velocity) * f;
97                         else
98                                 self.velocity = '0 0 0';
99                 }
100                 else
101                         f = 0;
102
103                 // water acceleration
104                 if (wishspeed <= f)
105                         return;
106
107                 f = min(wishspeed - f, sv_accelerate * wishspeed * frametime);
108                 self.velocity = self.velocity + normalize(wishvel) * f;
109                 return;
110         }
111
112         // hack to not let you back into teleporter
113         if (time < self.teleport_time && self.movement_x < 0)
114                 wishvel = v_right * self.movement_y;
115         else
116                 wishvel = v_forward * self.movement_x + v_right * self.movement_y;
117
118         if (self.movetype != MOVETYPE_WALK)
119                 wishvel_z = self.movement_z;
120         else
121                 wishvel_z = 0;
122
123         wishdir = normalize(wishvel);
124         wishspeed = vlen(wishvel);
125         if (wishspeed > sv_maxspeed)
126                 wishspeed = sv_maxspeed;
127         if (self.flags & FL_ONGROUND) {
128                 wishspeed=wishspeed+wishspeed*(1);
129         }
130
131         else if (time < self.ladder_time)
132         {
133                 // on a func_ladder or swimming in func_water
134                 self.velocity = self.velocity * (1 - frametime * sv_friction);
135                 makevectors(self.v_angle);
136                 //wishvel = v_forward * self.movement_x + v_right * self.movement_y + v_up * self.movement_z;
137                 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
138                 if (self.gravity)
139                         self.velocity_z = self.velocity_z + self.gravity * sv_gravity * frametime;
140                 else
141                         self.velocity_z = self.velocity_z + sv_gravity * frametime;
142                 if (self.ladder_entity.classname == "func_water")
143                 {
144                         f = vlen(wishvel);
145                         if (f > self.ladder_entity.speed)
146                                 wishvel = wishvel * (self.ladder_entity.speed / f);
147
148                         self.watertype = self.ladder_entity.skin;
149                         f = self.ladder_entity.origin_z + self.ladder_entity.maxs_z;
150                         if ((self.origin_z + self.view_ofs_z) < f)
151                                 self.waterlevel = 3;
152                         else if ((self.origin_z + (self.mins_z + self.maxs_z) * 0.5) < f)
153                                 self.waterlevel = 2;
154                         else if ((self.origin_z + self.mins_z + 1) < f)
155                                 self.waterlevel = 1;
156                         else
157                         {
158                                 self.waterlevel = 0;
159                                 self.watertype = CONTENT_EMPTY;
160                         }
161                 }
162         }
163         if (self.movetype == MOVETYPE_NOCLIP) // noclip
164                 self.velocity = wishdir * wishspeed;
165         else if (self.flags & FL_ONGROUND) // walking
166         {
167                 // friction
168                 if (self.velocity_x || self.velocity_y)
169                 {
170                         v = self.velocity;
171                         v_z = 0;
172                         f = vlen(v);
173
174                         // if the leading edge is over a dropoff, increase friction
175                         v = self.origin + normalize(v) * 16 + '0 0 1' * self.mins_z;
176
177                         traceline(v, v + '0 0 -34', TRUE, self);
178
179                         // apply friction
180                         if (trace_fraction == 1.0)
181                         {
182                                 if (f < sv_stopspeed)
183                                         f = 1 - frametime * (sv_stopspeed / f) * sv_friction * sv_edgefriction;
184                                 else
185                                         f = 1 - frametime * sv_friction * sv_edgefriction;
186                         }
187                         else
188                         {
189                                 if (f < sv_stopspeed)
190                                         f = 1 - frametime * (sv_stopspeed / f) * sv_friction;
191                                 else
192                                         f = 1 - frametime * sv_friction;
193                         }
194
195                         if (f < 0)
196                                 self.velocity = '0 0 0';
197                         else
198                                 self.velocity = self.velocity * f;
199                         
200                 }
201
202                 // acceleration
203                 f = wishspeed - (self.velocity * wishdir);
204                 if (f > 0)
205                         self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
206         }
207         else // airborne
208         {
209                 if (wishspeed < 30)
210                         f = wishspeed - (self.velocity * wishdir);
211                 else
212                         f = 30 - (self.velocity * wishdir);
213                 if (f > 0)
214                         self.velocity = self.velocity + wishdir * (min(f, sv_accelerate) * wishspeed * frametime);
215         }
216 }