Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- float lastclientthink, sv_maxspeed, sv_friction, sv_accelerate, sv_stopspeed;
- float sv_edgefriction, cl_rollangle, cl_divspeed;
- // LordHavoc:
- // Highly optimized port of SV_ClientThink from engine code to QuakeC.
- // No behavior changes! This code is much shorter and probably faster than
- // the engine code :)
- // note that darkplaces engine will call this function if it finds it,
- // so modify for your own mods and enjoy...
- // note also, this code uses some builtin functions from dpextensions.qc
- // (included with darkplaces engine releases)
- void() SV_PlayerPhysics =
- {
- local vector wishvel, wishdir, v;
- local float wishspeed, f;
- if (self.movetype == MOVETYPE_NONE)
- return;
- if (self.punchangle != '0 0 0')
- {
- f = vlen(self.punchangle) - 10 * frametime;
- if (f > 0)
- self.punchangle = normalize(self.punchangle) * f;
- else
- self.punchangle = '0 0 0';
- }
- // if dead, behave differently
- if (self.health <= 0)
- return;
- if (time != lastclientthink)
- {
- lastclientthink = time;
- sv_maxspeed = cvar("sv_maxspeed");
- sv_friction = cvar("sv_friction");
- sv_accelerate = cvar("sv_accelerate");
- sv_stopspeed = cvar("sv_stopspeed");
- sv_edgefriction = cvar("edgefriction");
- // LordHavoc: this * 4 is an optimization
- cl_rollangle = cvar("cl_rollangle") * 4;
- // LordHavoc: this 1 / is an optimization
- cl_divspeed = 1 / cvar("cl_rollspeed");
- }
- // show 1/3 the pitch angle and all the roll angle
- self.angles_z = bound(-1, self.velocity * v_right * cl_divspeed, 1) * cl_rollangle;
- if (!self.fixangle)
- {
- self.angles_x = (self.v_angle_x + self.punchangle_x) * -0.333;
- self.angles_y = self.v_angle_y + self.punchangle_y;
- }
- if (self.flags & FL_WATERJUMP )
- {
- self.velocity_x = self.movedir_x;
- self.velocity_y = self.movedir_y;
- if (time > self.teleport_time || self.waterlevel == 0)
- {
- self.flags = self.flags - (self.flags & FL_WATERJUMP);
- self.teleport_time = 0;
- }
- return;
- }
- makevectors(self.v_angle);
- // swim
- if (self.waterlevel >= 2)
- if (self.movetype != MOVETYPE_NOCLIP)
- {
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- if (self.movement == '0 0 0')
- wishvel = '0 0 -60'; // drift towards bottom
- else
- wishvel = v_forward * self.movement_x + v_right * self.movement_y + '0 0 1' * self.movement_z;
- wishspeed = vlen (wishvel);
- if (wishspeed > sv_maxspeed)
- wishspeed = sv_maxspeed;
- wishspeed = wishspeed * 0.7;
- // water friction
- if (self.velocity != '0 0 0')
- {
- f = vlen(self.velocity) * (1 - frametime * sv_friction);
- if (f > 0)
- self.velocity = normalize(self.velocity) * f;
- else
- self.velocity = '0 0 0';
- }
- else
- f = 0;
- // water acceleration
- if (wishspeed <= f)
- return;
- f = min(wishspeed - f, sv_accelerate * wishspeed * frametime);
- self.velocity = self.velocity + normalize(wishvel) * f;
- return;
- }
- // hack to not let you back into teleporter
- if (time < self.teleport_time && self.movement_x < 0)
- wishvel = v_right * self.movement_y;
- else
- {
- // LordHavoc: this NOCLIP check is a fix for the 'not moving while looking straight up/down when noclipping' bug in Quake
- if ((self.flags & FL_ONGROUND) || (self.movetype == MOVETYPE_NOCLIP))
- makevectors (self.v_angle_y * '0 1 0');
- wishvel = v_forward * self.movement_x + v_right * self.movement_y;
- }
- if (self.movetype != MOVETYPE_WALK)
- wishvel_z = self.movement_z;
- else
- wishvel_z = 0;
- wishdir = normalize(wishvel);
- wishspeed = vlen(wishvel);
- if (wishspeed > sv_maxspeed)
- wishspeed = sv_maxspeed;
- if (self.movetype == MOVETYPE_NOCLIP) // noclip
- {
- self.flags = self.flags - (self.flags & FL_ONGROUND);
- self.velocity = wishdir * wishspeed;
- }
- else if (self.flags & FL_ONGROUND) // walking
- {
- // friction
- if (self.velocity_x || self.velocity_y)
- {
- v = self.velocity;
- v_z = 0;
- f = vlen(v);
- // if the leading edge is over a dropoff, increase friction
- v = self.origin + normalize(v) * 16 + '0 0 1' * self.mins_z;
- traceline(v, v + '0 0 -34', TRUE, self);
- // apply friction
- if (trace_fraction == 1.0)
- {
- if (f < sv_stopspeed)
- f = 1 - frametime * (sv_stopspeed / f) * sv_friction * sv_edgefriction;
- else
- f = 1 - frametime * sv_friction * sv_edgefriction;
- }
- else
- {
- if (f < sv_stopspeed)
- f = 1 - frametime * (sv_stopspeed / f) * sv_friction;
- else
- f = 1 - frametime * sv_friction;
- }
- if (f < 0)
- self.velocity = '0 0 0';
- else
- self.velocity = self.velocity * f;
- }
- // acceleration
- f = wishspeed - (self.velocity * wishdir);
- if (f > 0)
- self.velocity = self.velocity + wishdir * min(f, sv_accelerate * frametime * wishspeed);
- }
- else // airborn
- {
- if (wishspeed < 30)
- f = wishspeed - (self.velocity * wishdir);
- else
- f = 30 - (self.velocity * wishdir);
- if (f > 0)
- self.velocity = self.velocity + wishdir * (min(f, sv_accelerate) * wishspeed * frametime);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement