1 float lastclientthink, sv_maxspeed, sv_friction, sv_accelerate, sv_stopspeed;
2 float sv_edgefriction, cl_rollangle, cl_divspeed;
6 // Highly optimized port of SV_ClientThink from engine code to QuakeC.
7 // No behavior changes! This code is much shorter and probably faster than
10 // note that darkplaces engine will call this function if it finds it,
11 // so modify for your own mods and enjoy...
13 // note also, this code uses some builtin functions from dpextensions.qc
14 // (included with darkplaces engine releases)
16 // P.S. if you find something weird in this code, it's just mimicing weird
17 // stuff in the original quake engine code (which was so unreadable it was
18 // hard to even identify what it was doing)
20 void() SV_PlayerPhysics =
22 local vector wishvel, wishdir, v;
23 local float wishspeed, f, limit;
25 if (self.movetype == MOVETYPE_NONE)
28 if (self.punchangle != '0 0 0')
30 f = vlen(self.punchangle) - 10 * frametime;
32 self.punchangle = normalize(self.punchangle) * f;
34 self.punchangle = '0 0 0';
37 // if dead, behave differently
41 if (time != lastclientthink)
43 lastclientthink = time;
44 sv_maxspeed = cvar("sv_maxspeed");
45 sv_friction = cvar("sv_friction");
46 sv_accelerate = cvar("sv_accelerate");
47 sv_stopspeed = cvar("sv_stopspeed");
48 sv_edgefriction = cvar("edgefriction");
49 // LordHavoc: this * 4 is an optimization
50 cl_rollangle = cvar("cl_rollangle") * 4;
51 // LordHavoc: this 1 / is an optimization
52 cl_divspeed = 1 / cvar("cl_rollspeed");
55 // show 1/3 the pitch angle and all the roll angle
56 f = (self.velocity * v_right) * cl_divspeed;
61 self.angles_z = f * cl_rollangle;
64 self.angles_x = (self.v_angle_x + self.punchangle_x) * -0.333;
65 self.angles_y = self.v_angle_y + self.punchangle_y;
68 if (self.flags & FL_WATERJUMP )
70 self.velocity_x = self.movedir_x;
71 self.velocity_y = self.movedir_y;
72 if (time > self.teleport_time || self.waterlevel == 0)
74 self.flags = self.flags - (self.flags & FL_WATERJUMP);
75 self.teleport_time = 0;
81 if (self.waterlevel >= 2)
82 if (self.movetype != MOVETYPE_NOCLIP)
84 makevectors(self.v_angle);
85 if (self.movement == '0 0 0')
86 wishvel = '0 0 -60'; // drift towards bottom
88 wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
90 wishspeed = vlen(wishvel);
91 if (wishspeed > sv_maxspeed)
92 wishspeed = sv_maxspeed * 0.7;
94 wishspeed = wishspeed * 0.7;
97 if (self.velocity != '0 0 0')
99 f = vlen(self.velocity) * (1 - frametime * sv_friction);
101 self.velocity = normalize(self.velocity) * f;
103 self.velocity = '0 0 0';
108 // water acceleration
112 limit = sv_accelerate * wishspeed * frametime;
115 self.velocity = self.velocity + normalize(wishvel) * limit;
117 self.velocity = self.velocity + normalize(wishvel) * f;
121 if (self.movetype == MOVETYPE_FLY)
122 makevectors(self.v_angle);
124 makevectors(self.v_angle_y * '0 1 0');
126 // hack to not let you back into teleporter
127 wishvel = v_right * self.movement_y;
128 if (time >= self.teleport_time || self.movement_x > 0)
129 wishvel = wishvel + v_forward * self.movement_x;
130 if (self.movetype != MOVETYPE_WALK)
131 wishvel_z = wishvel_z + self.movement_z;
133 wishdir = normalize(wishvel);
134 wishspeed = vlen(wishvel);
135 if (wishspeed > sv_maxspeed)
136 wishspeed = sv_maxspeed;
138 if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
140 self.velocity = wishdir * wishspeed;
144 if (self.flags & FL_ONGROUND) // walking
147 if (self.velocity_x || self.velocity_y)
153 // if the leading edge is over a dropoff, increase friction
154 v = self.origin + normalize(v) * 16 + '0 0 1' * self.mins_z;
156 traceline(v, v + '0 0 -34', TRUE, self);
159 if (trace_fraction == 1.0)
161 if (f < sv_stopspeed)
162 f = 1 - frametime * (sv_stopspeed / f) * sv_friction * sv_edgefriction;
164 f = 1 - frametime * sv_friction * sv_edgefriction;
168 if (f < sv_stopspeed)
169 f = 1 - frametime * (sv_stopspeed / f) * sv_friction;
171 f = 1 - frametime * sv_friction;
175 self.velocity = '0 0 0';
177 self.velocity = self.velocity * f;
185 f = wishspeed - (self.velocity * wishdir);
188 limit = sv_accelerate * frametime * wishspeed;
191 self.velocity = self.velocity + wishdir * f;