Module darkplaces: Change committed

havoc at icculus.org havoc at icculus.org
Fri Aug 8 18:19:12 EDT 2003


Commiter   : havoc
CVSROOT    : /cvs/cvsroot/twilight
Module     : darkplaces
Commit time: 2003-08-08 22:19:12 UTC

Log message:

sample implementation of QC replacement physics (already available on website, but it might as well become a maintainable thing in cvs)

Added files:
     sv_user.qc

------=MIME.f110c80b499ce2ceea91330af7526918
Content-Type: text/plain; name="darkplaces.20030808.221912.havoc.diff"
Content-Disposition: attachment; filename="darkplaces.20030808.221912.havoc.diff"
Content-Transfer-Encoding: 8bit

Index: darkplaces/sv_user.qc
diff -u /dev/null darkplaces/sv_user.qc:1.1
--- /dev/null	Fri Aug  8 18:19:12 2003
+++ darkplaces/sv_user.qc	Fri Aug  8 18:19:01 2003
@@ -0,0 +1,187 @@
+float lastclientthink, sv_maxspeed, sv_friction, sv_accelerate, sv_stopspeed;
+float sv_edgefriction, cl_rollspeed, 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)
+
+// P.S. if you find something weird in this code, it's just mimicing weird
+// stuff in the original quake engine code (which was so unreadable it was
+// hard to even identify what it was doing)
+
+void() SV_PlayerPhysics =
+{
+	local vector wishvel, wishdir, v;
+	local float wishspeed, f, limit;
+
+	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;
+	}
+
+	// swim
+	if (self.waterlevel >= 2)
+	if (self.movetype != MOVETYPE_NOCLIP)
+	{
+		makevectors(self.v_angle);
+		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 * 0.7;
+		else
+			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;
+
+		limit = sv_accelerate * wishspeed * frametime;
+		f = wishspeed - f;
+		if (f > limit)
+			self.velocity = self.velocity + normalize(wishvel) * limit;
+		else
+			self.velocity = self.velocity + normalize(wishvel) * f;
+		return;
+	}
+
+	if (self.movetype == MOVETYPE_FLY)
+		makevectors(self.v_angle);
+	else
+		makevectors(self.v_angle_y * '0 1 0');
+
+	// hack to not let you back into teleporter
+	wishvel = v_right * self.movement_y;
+	if (time >= self.teleport_time || self.movement_x > 0)
+		wishvel = wishvel + v_forward * self.movement_x;
+	if (self.movetype != MOVETYPE_WALK)
+		wishvel_z = wishvel_z + self.movement_z;
+
+	wishdir = normalize(wishvel);
+	wishspeed = vlen(wishvel);
+	if (wishspeed > sv_maxspeed)
+		wishspeed = sv_maxspeed;
+
+	if (self.movetype == MOVETYPE_NOCLIP || self.movetype == MOVETYPE_FLY)
+	{
+		self.velocity = wishdir * wishspeed;
+		return;
+	}
+
+	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;
+		}
+	}
+	else // airborn
+		if (wishspeed > 30)
+			wishspeed = 30;
+
+	// acceleration
+	f = wishspeed - (self.velocity * wishdir);
+	if (f > 0)
+	{
+		limit = sv_accelerate * frametime * wishspeed;
+		if (f > limit)
+			f = limit;
+		self.velocity = self.velocity + wishdir * f;
+	}
+}


More information about the twilight-commits mailing list