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