]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
sample implementation of QC replacement physics (already available on website, but...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 8 Aug 2003 22:19:01 +0000 (22:19 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Fri, 8 Aug 2003 22:19:01 +0000 (22:19 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3377 d7cf8633-e32d-0410-b094-e92efae38249

sv_user.qc [new file with mode: 0644]

diff --git a/sv_user.qc b/sv_user.qc
new file mode 100644 (file)
index 0000000..62f218b
--- /dev/null
@@ -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;
+       }
+}