]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Add movetype updates from QC physics branch
authorMario <zacjardine@y7mail.com>
Mon, 16 Mar 2015 15:29:22 +0000 (02:29 +1100)
committerMario <zacjardine@y7mail.com>
Mon, 16 Mar 2015 15:29:22 +0000 (02:29 +1100)
12 files changed:
qcsrc/common/movetypes/include.qc
qcsrc/common/movetypes/include.qh
qcsrc/common/movetypes/movetypes.qc
qcsrc/common/movetypes/movetypes.qh
qcsrc/common/movetypes/push.qc
qcsrc/common/movetypes/toss.qc
qcsrc/common/movetypes/walk.qc [new file with mode: 0644]
qcsrc/common/movetypes/walk.qh [new file with mode: 0644]
qcsrc/common/physics.qc
qcsrc/common/physics.qh
qcsrc/common/stats.qh
qcsrc/common/triggers/trigger/impulse.qc

index e4d6f39dba47202e811e3a35d007dee9103c298a..64d92d4a99fc7fc59c7bd506837b11612a04cda9 100644 (file)
@@ -1,4 +1,5 @@
 #include "push.qc"
 #include "toss.qc"
+#include "walk.qc"
 
 #include "movetypes.qc"
index 126d3b6af647cf5fdf51250bb0e0907cecb3dd91..a96e5957a9e5c021da00eca407bd8e21458b029a 100644 (file)
@@ -3,5 +3,6 @@
 
 #include "push.qh"
 #include "toss.qh"
+#include "walk.qh"
 
-#endif
\ No newline at end of file
+#endif
index 5a45e986621b54eaeee5c9d53cf12dec3ea21b95..a7351ac6625327739596f6cd4954557b7b7b9164 100644 (file)
        #include "../../server/autocvars.qh"
 #endif
 
-void _Movetype_CheckVelocity() // SV_CheckVelocity
+void _Movetype_WallFriction(vector stepnormal)  // SV_WallFriction
 {
+       /*float d, i;
+       vector into, side;
+       makevectors(self.v_angle);
+       d = (stepnormal * v_forward) + 0.5;
+
+       if(d < 0)
+       {
+           i = (stepnormal * self.move_velocity);
+           into = i * stepnormal;
+           side = self.move_velocity - into;
+           self.move_velocity_x = side.x * (1 * d);
+           self.move_velocity_y = side.y * (1 * d);
+       }*/
+}
+
+vector planes[MAX_CLIP_PLANES];
+int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight) // SV_FlyMove
+{
+       int blocked = 0, bumpcount;
+       int i, j, numplanes = 0;
+       float time_left = dt, grav = 0;
+       vector push;
+       vector primal_velocity, original_velocity, new_velocity = '0 0 0', restore_velocity;
+
+       for(i = 0; i <= MAX_CLIP_PLANES; ++i)
+               planes[i] = '0 0 0';
+       
+       grav = 0;
+
+       restore_velocity = self.move_velocity;
+
+       if(applygravity)
+       {
+               self.move_didgravity = 1;
+               grav = dt * (PHYS_ENTGRAVITY(self) ? PHYS_ENTGRAVITY(self) : 1) * PHYS_GRAVITY;
+
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND))
+               {
+                       if(GRAVITY_UNAFFECTED_BY_TICRATE)
+                               self.move_velocity_z -= grav * 0.5;
+                       else
+                               self.move_velocity_z -= grav;
+               }
+       }
+
+       original_velocity = primal_velocity = self.move_velocity;
+
+       for(bumpcount = 0;bumpcount < MAX_CLIP_PLANES;bumpcount++)
+       {
+               if(!self.move_velocity_x && !self.move_velocity_y && !self.move_velocity_z)
+                       break;
+
+               push = self.move_velocity * time_left;
+               if(!_Movetype_PushEntity(push, false))
+               {
+                       // we got teleported by a touch function
+                       // let's abort the move
+                       blocked |= 8;
+                       break;
+               }
+
+               // this code is used by MOVETYPE_WALK and MOVETYPE_STEP and SV_UnstickEntity
+               // abort move if we're stuck in the world (and didn't make it out)
+               if(trace_startsolid && trace_allsolid)
+               {
+                       self.move_velocity = restore_velocity;
+                       return 3;
+               }
+
+               if(trace_fraction == 1)
+                       break;
+               if(trace_plane_normal_z)
+               {
+                       if(trace_plane_normal_z > 0.7)
+                       {
+                               // floor
+                               blocked |= 1;
+
+                               if(!trace_ent)
+                               {
+                                       //dprint("_Movetype_FlyMove: !trace_ent\n");
+                                       trace_ent = world;
+                               }
+
+                               self.move_flags |= FL_ONGROUND;
+                               self.move_groundentity = trace_ent;
+                       }
+               }
+               else if(stepheight)
+               {
+                       // step - handle it immediately
+                       vector org;
+                       vector steppush;
+                       //Con_Printf("step %f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
+                       steppush = '0 0 1' * stepheight;
+                       org = self.move_origin;
+                       if(!_Movetype_PushEntity(steppush, false))
+                       {
+                               blocked |= 8;
+                               break;
+                       }
+                       //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
+                       if(!_Movetype_PushEntity(push, false))
+                       {
+                               blocked |= 8;
+                               break;
+                       }
+                       float trace2_fraction = trace_fraction;
+                       //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
+                       steppush = '0 0 1' * (org_z - self.move_origin_z);
+                       if(!_Movetype_PushEntity(steppush, false))
+                       {
+                               blocked |= 8;
+                               break;
+                       }
+                       //Con_Printf("%f %f %f : ", self.move_origin_x, PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
+                       // accept the new position if it made some progress...
+                       if(fabs(self.move_origin_x - org_x) >= 0.03125 || fabs(self.move_origin_y - org_y) >= 0.03125)
+                       {
+                               //Con_Printf("accepted (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]);
+                               trace_endpos = self.move_origin;
+                               time_left *= 1 - trace2_fraction;
+                               numplanes = 0;
+                               continue;
+                       }
+                       else
+                       {
+                               //Con_Printf("REJECTED (delta %f %f %f)\n", self.move_origin_x - org_x, PRVM_serveredictvector(ent, origin)[1] - org[1], PRVM_serveredictvector(ent, origin)[2] - org[2]);
+                               self.move_origin = org;
+                       }
+               }
+               else
+               {
+                       // step - return it to caller
+                       blocked |= 2;
+                       // save the trace for player extrafriction
+                       if(stepnormal)
+                               stepnormal = trace_plane_normal;
+               }
+               if(trace_fraction >= 0.001)
+               {
+                       // actually covered some distance
+                       original_velocity = self.move_velocity;
+                       numplanes = 0;
+               }
+
+               time_left *= 1 - trace_fraction;
+
+               // clipped to another plane
+               if(numplanes >= MAX_CLIP_PLANES)
+               {
+                       // this shouldn't really happen
+                       self.move_velocity = '0 0 0';
+                       blocked = 3;
+                       break;
+               }
+
+               planes[numplanes] = trace_plane_normal;
+               numplanes++;
+
+               // modify original_velocity so it parallels all of the clip planes
+               for (i = 0;i < numplanes;i++)
+               {
+                       new_velocity = _Movetype_ClipVelocity(original_velocity, planes[i], 1);
+                       for (j = 0;j < numplanes;j++)
+                       {
+                               if(j != i)
+                               {
+                                       // not ok
+                                       if((new_velocity * planes[j]) < 0)
+                                               break;
+                               }
+                       }
+                       if(j == numplanes)
+                               break;
+               }
+
+               if(i != numplanes)
+               {
+                       // go along this plane
+                       self.move_velocity = new_velocity;
+               }
+               else
+               {
+                       // go along the crease
+                       if(numplanes != 2)
+                       {
+                               self.move_velocity = '0 0 0';
+                               blocked = 7;
+                               break;
+                       }
+                       vector dir;
+                       dir.x = planes[0].y * planes[1].z - planes[0].z * planes[1].y;
+                       dir.y = planes[0].z * planes[1].x - planes[0].x * planes[1].z;
+                       dir.z = planes[0].x * planes[1].y - planes[0].y * planes[1].x;
+                       // LordHavoc: thanks to taniwha of QuakeForge for pointing out this fix for slowed falling in corners
+                       float ilength = sqrt((dir * dir));
+                       if(ilength)
+                               ilength = 1.0 / ilength;
+                       dir.x *= ilength;
+                       dir.y *= ilength;
+                       dir.z *= ilength;
+                       float d = (dir * self.move_velocity);
+                       self.move_velocity = dir * d;
+               }
+
+               // if current velocity is against the original velocity,
+               // stop dead to avoid tiny occilations in sloping corners
+               if((self.move_velocity * primal_velocity) <= 0)
+               {
+                       self.move_velocity = '0 0 0';
+                       break;
+               }
+       }
+
+       // LordHavoc: this came from QW and allows you to get out of water more easily
+       if(GAMEPLAYFIX_EASIERWATERJUMP && (self.move_flags & FL_WATERJUMP) && !(blocked & 8))
+               self.move_velocity = primal_velocity;
+
+       if(applygravity)
+       {
+               if(!GAMEPLAYFIX_NOGRAVITYONGROUND || !(self.move_flags & FL_ONGROUND))
+               {
+                       if(GRAVITY_UNAFFECTED_BY_TICRATE)
+                               self.move_velocity_z -= grav * 0.5f;
+               }
+       }
+
+       return blocked;
 }
 
-float _Movetype_CheckWater(entity ent) // SV_CheckWater
+void _Movetype_CheckVelocity()  // SV_CheckVelocity
+{
+       // if(vlen(self.move_velocity) < 0.0001)
+       // self.move_velocity = '0 0 0';
+}
+
+bool _Movetype_CheckWater(entity ent)  // SV_CheckWater
 {
        vector point = ent.move_origin;
-       point_z += (ent.mins_z + 1);
+       point.z += (ent.mins.z + 1);
 
        int nativecontents = pointcontents(point);
-
-       if(ent.move_watertype)
-       if(ent.move_watertype != nativecontents)
+       if(ent.move_watertype && ent.move_watertype != nativecontents)
        {
-               //dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents);
+               // dprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents);
                if(ent.contentstransition)
                        ent.contentstransition(ent.move_watertype, nativecontents);
        }
@@ -41,22 +274,22 @@ float _Movetype_CheckWater(entity ent) // SV_CheckWater
        {
                ent.move_watertype = nativecontents;
                ent.move_waterlevel = 1;
-               point_y = (ent.origin_y + ((ent.mins_z + ent.maxs_y) * 0.5));
+               point.y = (ent.origin.y + ((ent.mins.z + ent.maxs.y) * 0.5));
                if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
                {
                        ent.move_waterlevel = 2;
-                       point_y = ent.origin_y + ent.view_ofs_y;
+                       point.y = ent.origin.y + ent.view_ofs.y;
                        if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
                                ent.move_waterlevel = 3;
                }
        }
 
-       return (ent.move_waterlevel > 1);
+       return ent.move_waterlevel > 1;
 }
 
-void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
+void _Movetype_CheckWaterTransition(entity ent)  // SV_CheckWaterTransition
 {
-       float contents = pointcontents(ent.move_origin);
+       int contents = pointcontents(ent.move_origin);
 
        if(!ent.move_watertype)
        {
@@ -70,7 +303,7 @@ void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
        }
        else if(ent.move_watertype != contents)
        {
-               //dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents);
+               // dprintf("_Movetype_CheckWaterTransition(): Origin: %s, Direct: '%d', Original: '%d', New: '%d'\n", vtos(ent.move_origin), pointcontents(ent.move_origin), ent.move_watertype, contents);
                if(ent.contentstransition)
                        ent.contentstransition(ent.move_watertype, contents);
        }
@@ -87,12 +320,10 @@ void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
        }
 }
 
-void _Movetype_Impact(entity oth) // SV_Impact
+void _Movetype_Impact(entity oth)  // SV_Impact
 {
-       entity oldother, oldself;
-
-       oldself = self;
-       oldother = other;
+       entity oldself = self;
+       entity oldother = other;
 
        if(self.move_touch)
        {
@@ -115,17 +346,14 @@ void _Movetype_Impact(entity oth) // SV_Impact
        }
 }
 
-void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
+void _Movetype_LinkEdict_TouchAreaGrid()  // SV_LinkEdict_TouchAreaGrid
 {
-       entity e, oldself, oldother;
-
-       oldself = self;
-       oldother = other;
+       entity oldself = self;
+       entity oldother = other;
 
-       for(e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain)
+       for (entity e = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); e; e = e.chain)
        {
-               if(e.move_touch)
-               if(boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax))
+               if(e.move_touch && boxesoverlap(e.absmin, e.absmax, oldself.absmin, oldself.absmax))
                {
                        self = e;
                        other = oldself;
@@ -148,7 +376,7 @@ void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
        self = oldself;
 }
 
-void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
+void _Movetype_LinkEdict(bool touch_triggers)  // SV_LinkEdict
 {
        vector mi, ma;
        if(self.solid == SOLID_BSP)
@@ -162,26 +390,26 @@ void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
                mi = self.mins;
                ma = self.maxs;
        }
-       mi = mi + self.origin;
-       ma = ma + self.origin;
+       mi += self.move_origin;
+       ma += self.move_origin;
 
        if(self.move_flags & FL_ITEM)
        {
-               mi_x -= 15;
-               mi_y -= 15;
-               mi_z -= 1;
-               ma_x += 15;
-               ma_y += 15;
-               ma_z += 1;
+               mi.x -= 15;
+               mi.y -= 15;
+               mi.z -= 1;
+               ma.x += 15;
+               ma.y += 15;
+               ma.z += 1;
        }
        else
        {
-               mi_x -= 1;
-               mi_y -= 1;
-               mi_z -= 1;
-               ma_x += 1;
-               ma_y += 1;
-               ma_z += 1;
+               mi.x -= 1;
+               mi.y -= 1;
+               mi.z -= 1;
+               ma.x += 1;
+               ma.y += 1;
+               ma.z += 1;
        }
 
        self.absmin = mi;
@@ -191,10 +419,9 @@ void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
                _Movetype_LinkEdict_TouchAreaGrid();
 }
 
-float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
+bool _Movetype_TestEntityPosition(vector ofs)  // SV_TestEntityPosition
 {
-       vector org;
-       org = self.move_origin + ofs;
+//     vector org = self.move_origin + ofs;
 
        int cont = self.dphitcontentsmask;
        self.dphitcontentsmask = DPCONTENTS_SOLID;
@@ -209,10 +436,9 @@ float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
        return false;
 }
 
-float _Movetype_UnstickEntity() // SV_UnstickEntity
+bool _Movetype_UnstickEntity()  // SV_UnstickEntity
 {
-       if(!_Movetype_TestEntityPosition('0 0 0'))
-               return true;
+       if(!_Movetype_TestEntityPosition('0 0 0')) return true;
        if(!_Movetype_TestEntityPosition('-1 0 0')) goto success;
        if(!_Movetype_TestEntityPosition('1 0 0')) goto success;
        if(!_Movetype_TestEntityPosition('0 -1 0')) goto success;
@@ -221,38 +447,36 @@ float _Movetype_UnstickEntity() // SV_UnstickEntity
        if(!_Movetype_TestEntityPosition('1 -1 0')) goto success;
        if(!_Movetype_TestEntityPosition('-1 1 0')) goto success;
        if(!_Movetype_TestEntityPosition('1 1 0')) goto success;
-       float i;
-       for(i = 1; i <= 17; ++i)
+       for (int i = 1; i <= 17; ++i)
        {
                if(!_Movetype_TestEntityPosition('0 0 -1' * i)) goto success;
                if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success;
        }
-       dprintf("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n", num_for_edict(self), self.classname, vtos(self.move_origin));
+       dprintf("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n",
+               num_for_edict(self), self.classname, vtos(self.move_origin));
        return false;
-:success
-       dprintf("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n", num_for_edict(self), self.classname, vtos(self.move_origin));
+       : success;
+       dprintf("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)\n",
+               num_for_edict(self), self.classname, vtos(self.move_origin));
        _Movetype_LinkEdict(true);
        return true;
 }
 
-vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
+vector _Movetype_ClipVelocity(vector vel, vector norm, float f)  // SV_ClipVelocity
 {
-       vel = vel - ((vel * norm) * norm) * f;
+       vel -= ((vel * norm) * norm) * f;
 
-       if(vel_x > -0.1 && vel_x < 0.1) vel_x = 0;
-       if(vel_y > -0.1 && vel_y < 0.1) vel_y = 0;
-       if(vel_z > -0.1 && vel_z < 0.1) vel_z = 0;
+       if(vel.x > -0.1 && vel.x < 0.1) vel.x = 0;
+       if(vel.y > -0.1 && vel.y < 0.1) vel.y = 0;
+       if(vel.z > -0.1 && vel.z < 0.1) vel.z = 0;
 
        return vel;
 }
 
 void _Movetype_PushEntityTrace(vector push)
 {
-       vector end;
-       float type;
-
-       end = self.move_origin + push;
-
+       vector end = self.move_origin + push;
+       int type;
        if(self.move_nomonsters)
                type = max(0, self.move_nomonsters);
        else if(self.move_movetype == MOVETYPE_FLYMISSILE)
@@ -265,7 +489,7 @@ void _Movetype_PushEntityTrace(vector push)
        tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
 }
 
-float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
+float _Movetype_PushEntity(vector push, bool failonstartsolid)  // SV_PushEntity
 {
        _Movetype_PushEntityTrace(push);
 
@@ -285,57 +509,55 @@ float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
 .float ltime;
 .void() blocked;
 // matrix version of makevectors, sets v_forward, v_right and v_up
-void makevectors_matrix(vector myangles) // AngleVectorsFLU
+void makevectors_matrix(vector myangles)  // AngleVectorsFLU
 {
-       float angle, sr, sp, sy, cr, cp, cy;
-
        v_forward = v_right = v_up = '0 0 0';
 
-       angle = myangles_y * (M_PI*2 / 360);
-       sy = sin(angle);
-       cy = cos(angle);
-       angle = myangles_x * (M_PI*2 / 360);
-       sp = sin(angle);
-       cp = cos(angle);
+       float y = myangles.y * (M_PI * 2 / 360);
+       float sy = sin(y);
+       float cy = cos(y);
+       float p = myangles.x * (M_PI * 2 / 360);
+       float sp = sin(p);
+       float cp = cos(p);
        if(v_forward)
        {
-               v_forward_x = cp*cy;
-               v_forward_y = cp*sy;
-               v_forward_z = -sp;
+               v_forward.x = cp * cy;
+               v_forward.y = cp * sy;
+               v_forward.z = -sp;
        }
        if(v_right || v_up)
        {
-               if(myangles_z)
+               if(myangles.z)
                {
-                       angle = myangles_z * (M_PI*2 / 360);
-                       sr = sin(angle);
-                       cr = cos(angle);
+                       float r = myangles.z * (M_PI * 2 / 360);
+                       float sr = sin(r);
+                       float cr = cos(r);
                        if(v_right)
                        {
-                               v_right_x = sr*sp*cy+cr*-sy;
-                               v_right_y = sr*sp*sy+cr*cy;
-                               v_right_z = sr*cp;
+                               v_right.x = sr * sp * cy + cr * -sy;
+                               v_right.y = sr * sp * sy + cr * cy;
+                               v_right.z = sr * cp;
                        }
                        if(v_up)
                        {
-                               v_up_x = cr*sp*cy+-sr*-sy;
-                               v_up_y = cr*sp*sy+-sr*cy;
-                               v_up_z = cr*cp;
+                               v_up.x = cr * sp * cy + -sr * -sy;
+                               v_up.y = cr * sp * sy + -sr * cy;
+                               v_up.z = cr * cp;
                        }
                }
                else
                {
                        if(v_right)
                        {
-                               v_right_x = -sy;
-                               v_right_y = cy;
-                               v_right_z = 0;
+                               v_right.x = -sy;
+                               v_right.y = cy;
+                               v_right.z = 0;
                        }
                        if(v_up)
                        {
-                               v_up_x = sp*cy;
-                               v_up_y = sp*sy;
-                               v_up_z = cp;
+                               v_up.x = sp * cy;
+                               v_up.y = sp * sy;
+                               v_up.z = cp;
                        }
                }
        }
@@ -344,7 +566,7 @@ void makevectors_matrix(vector myangles) // AngleVectorsFLU
 void _Movetype_Physics_Frame(float movedt)
 {
        self.move_didgravity = -1;
-       switch(self.move_movetype)
+       switch (self.move_movetype)
        {
                case MOVETYPE_PUSH:
                case MOVETYPE_FAKEPUSH:
@@ -365,7 +587,7 @@ void _Movetype_Physics_Frame(float movedt)
                        error("SV_Physics_Step not implemented");
                        break;
                case MOVETYPE_WALK:
-                       error("SV_Physics_Walk not implemented");
+                       _Movetype_Physics_Walk(movedt);
                        break;
                case MOVETYPE_TOSS:
                case MOVETYPE_BOUNCE:
@@ -377,11 +599,9 @@ void _Movetype_Physics_Frame(float movedt)
        }
 }
 
-void Movetype_Physics_NoMatchServer() // optimized
+void Movetype_Physics_NoMatchServer()  // optimized
 {
-       float movedt;
-
-       movedt = time - self.move_time;
+       float movedt = time - self.move_time;
        self.move_time = time;
 
        _Movetype_Physics_Frame(movedt);
@@ -399,29 +619,26 @@ void Movetype_Physics_MatchServer(bool sloppy)
        Movetype_Physics_MatchTicrate(TICRATE, sloppy);
 }
 
-void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
+void Movetype_Physics_MatchTicrate(float tr, bool sloppy)  // SV_Physics_Entity
 {
-       float n, i, dt, movedt;
-
        if(tr <= 0)
        {
                Movetype_Physics_NoMatchServer();
                return;
        }
 
-       dt = time - self.move_time;
+       float dt = time - self.move_time;
 
-       movedt = tr;
-       n = max(0, floor(dt / tr));
+       int n = max(0, floor(dt / tr));
        dt -= n * tr;
        self.move_time += n * tr;
 
        if(!self.move_didgravity)
                self.move_didgravity = ((self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS) && !(self.move_flags & FL_ONGROUND));
 
-       for(i = 0; i < n; ++i)
+       for (int i = 0; i < n; ++i)
        {
-               _Movetype_Physics_Frame(movedt);
+               _Movetype_Physics_Frame(tr);
                if(wasfreed(self))
                        return;
        }
@@ -435,25 +652,15 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
 
                if(self.move_didgravity > 0)
                {
-                       if(GRAVITY_UNAFFECTED_BY_TICRATE)
-                       {
-                               if(self.gravity)
-                                       self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
-                               else
-                                       self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
-                       }
-                       else
-                       {
-                               if(self.gravity)
-                                       self.velocity_z -= dt * self.gravity * PHYS_GRAVITY;
-                               else
-                                       self.velocity_z -= dt * PHYS_GRAVITY;
-                       }
+                       self.velocity_z -= (GRAVITY_UNAFFECTED_BY_TICRATE ? 0.5 : 1)
+                           * dt
+                           * (self.gravity ? self.gravity : 1)
+                           * PHYS_GRAVITY;
                }
 
                self.angles = self.move_angles + dt * self.avelocity;
 
-               if(sloppy || self.movetype == MOVETYPE_NOCLIP)
+               if(sloppy || self.move_movetype == MOVETYPE_NOCLIP)
                {
                        setorigin(self, self.move_origin + dt * self.velocity);
                }
@@ -464,16 +671,8 @@ void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
                                setorigin(self, trace_endpos);
                }
 
-               if(self.move_didgravity > 0)
-               {
-                       if(GRAVITY_UNAFFECTED_BY_TICRATE)
-                       {
-                               if(self.gravity)
-                                       self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
-                               else
-                                       self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
-                       }
-               }
+               if(self.move_didgravity > 0 && GRAVITY_UNAFFECTED_BY_TICRATE)
+                       self.velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY;
        }
        else
        {
index 85c07fce64222d5ed65837bc4d4a9c8f48f14c11..88b545fe110bb0d76a5f90bd865518838a442805 100644 (file)
@@ -2,9 +2,9 @@
 #define MOVETYPES_H
 
 .float move_ltime;
-.void(void) move_think;
+.void(void)move_think;
 .float move_nextthink;
-.void(void) move_blocked;
+.void(void)move_blocked;
 
 .float move_movetype;
 .float move_time;
 .int move_flags;
 .int move_watertype;
 .int move_waterlevel;
-.void(void) move_touch;
-.void(float, float) contentstransition;
+.void(void)move_touch;
+.void(float, float)contentstransition;
 .float move_bounce_factor;
 .float move_bounce_stopspeed;
-.float move_nomonsters; // -1 for MOVE_NORMAL, otherwise a MOVE_ constant
+.float move_nomonsters;  // -1 for MOVE_NORMAL, otherwise a MOVE_ constant
 
 // should match sv_gameplayfix_fixedcheckwatertransition
 float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
@@ -34,12 +34,15 @@ float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
 #define TICRATE ticrate
 #endif
 
-.entity move_groundentity; // FIXME add move_groundnetworkentity?
+.entity move_groundentity;  // FIXME add move_groundnetworkentity?
 .float move_suspendedinair;
 .float move_didgravity;
 
+void _Movetype_WallFriction(vector stepnormal);
+int _Movetype_FlyMove(float dt, bool applygravity, vector stepnormal, float stepheight);
 void _Movetype_CheckVelocity();
 void _Movetype_CheckWaterTransition(entity ent);
+float _Movetype_CheckWater(entity ent);
 void _Movetype_LinkEdict_TouchAreaGrid();
 void _Movetype_LinkEdict(float touch_triggers);
 float _Movetype_TestEntityPosition(vector ofs);
@@ -60,18 +63,18 @@ float _Movetype_UnstickEntity();
 const int MAX_CLIP_PLANES = 5;
 
 #ifdef CSQC
-const int MOVETYPE_NONE                                = 0;
-const int MOVETYPE_ANGLENOCLIP     = 1;
-const int MOVETYPE_ANGLECLIP       = 2;
-const int MOVETYPE_WALK                                = 3;
-const int MOVETYPE_STEP                                = 4;
-const int MOVETYPE_FLY                         = 5;
-const int MOVETYPE_TOSS                                = 6;
-const int MOVETYPE_PUSH                                = 7;
-const int MOVETYPE_NOCLIP                  = 8;
-const int MOVETYPE_FLYMISSILE      = 9;
-const int MOVETYPE_BOUNCE                  = 10;
-const int MOVETYPE_BOUNCEMISSILE       = 11;   // Like bounce but doesn't lose speed on bouncing
+const int MOVETYPE_NONE             = 0;
+const int MOVETYPE_ANGLENOCLIP      = 1;
+const int MOVETYPE_ANGLECLIP        = 2;
+const int MOVETYPE_WALK             = 3;
+const int MOVETYPE_STEP             = 4;
+const int MOVETYPE_FLY              = 5;
+const int MOVETYPE_TOSS             = 6;
+const int MOVETYPE_PUSH             = 7;
+const int MOVETYPE_NOCLIP           = 8;
+const int MOVETYPE_FLYMISSILE       = 9;
+const int MOVETYPE_BOUNCE           = 10;
+const int MOVETYPE_BOUNCEMISSILE    = 11;  // Like bounce but doesn't lose speed on bouncing
 const int MOVETYPE_FOLLOW           = 12;
 const int MOVETYPE_FLY_WORLDONLY    = 33;
 
index 7ae5e2eb551fbe890917f1497f59303fb5b70952..1f563f58ddcf51a813dbf2e08e4c197b9ccb1fdd 100644 (file)
-void _Movetype_PushMove(float dt) // SV_PushMove
+void _Movetype_PushMove(float dt)  // SV_PushMove
 {
-       bool rotated;
-       int savesolid;
-       float movetime2, pushltime;
-       vector move, move1, moveangle, pushorig, pushang;
-       vector a;
-       vector pivot;
-       entity oldself;
-       entity check;
-
-       if(self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
+       if (self.move_velocity == '0 0 0' && self.move_avelocity == '0 0 0')
        {
                self.move_ltime += dt;
                return;
        }
 
-       switch(self.solid)
+       switch (self.solid)
        {
-       // LordHavoc: valid pusher types
-       case SOLID_BSP:
-       case SOLID_BBOX:
-       case SOLID_SLIDEBOX:
-       case SOLID_CORPSE: // LordHavoc: this would be weird...
-               break;
-       // LordHavoc: no collisions
-       case SOLID_NOT:
-       case SOLID_TRIGGER:
-               self.move_origin = self.move_origin + dt * self.move_velocity;
-               self.move_angles = self.move_angles + dt * self.move_avelocity;
-               self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0));
-               self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0));
-               self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0));
-               self.move_ltime += dt;
-               _Movetype_LinkEdict(true);
-               return;
-       default:
-               dprintf("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
-               return;
+               // LordHavoc: valid pusher types
+               case SOLID_BSP:
+               case SOLID_BBOX:
+               case SOLID_SLIDEBOX:
+               case SOLID_CORPSE:  // LordHavoc: this would be weird...
+                       break;
+               // LordHavoc: no collisions
+               case SOLID_NOT:
+               case SOLID_TRIGGER:
+                       self.move_origin = self.move_origin + dt * self.move_velocity;
+                       self.move_angles = self.move_angles + dt * self.move_avelocity;
+                       self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
+                       self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
+                       self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
+                       self.move_ltime += dt;
+                       _Movetype_LinkEdict(true);
+                       return;
+               default:
+                       dprintf("_Movetype_PushMove: entity %e, unrecognized solid type %d\n", self, self.solid);
+                       return;
        }
 
-       rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0;
+       bool rotated = (self.move_angles * self.move_angles) + (self.move_avelocity * self.move_avelocity) > 0;
 
-       movetime2 = dt;
+       vector move1 = self.move_velocity * dt;
+       vector moveangle = self.move_avelocity * dt;
 
-       move1 = self.move_velocity * movetime2;
-       moveangle = self.move_avelocity * movetime2;
+       makevectors_matrix(-moveangle);
 
-       a = -moveangle;
-       makevectors_matrix(a);
-
-       pushorig = self.move_origin;
-       pushang = self.move_angles;
-       pushltime = self.move_ltime;
+//     vector pushorig = self.move_origin;
+//     vector pushang = self.move_angles;
+//     float pushltime = self.move_ltime;
 
 // move the pusher to its final position
 
        self.move_origin = self.move_origin + dt * self.move_velocity;
        self.move_angles = self.move_angles + dt * self.move_avelocity;
-       
+
        self.move_ltime += dt;
        _Movetype_LinkEdict(true);
 
-       savesolid = self.solid;
+       int savesolid = self.solid;
 
-       if(self.move_movetype != MOVETYPE_FAKEPUSH)
-       for(check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
+       if (self.move_movetype != MOVETYPE_FAKEPUSH)
        {
-               switch(check.move_movetype)
+               for (entity check = findradius(0.5 * (self.absmin + self.absmax), 0.5 * vlen(self.absmax - self.absmin)); check; check = check.chain)
                {
-               case MOVETYPE_NONE:
-               case MOVETYPE_PUSH:
-               case MOVETYPE_FOLLOW:
-               case MOVETYPE_NOCLIP:
-               case MOVETYPE_FLY_WORLDONLY:
-                       continue;
-               default:
-                       break;
-               }
-
-               if(check.owner == self)
-                       continue;
-
-               if(self.owner == check)
-                       continue;
-
-               pivot = check.mins + 0.5 * (check.maxs - check.mins);
-
-               if (rotated)
-               {
-                       vector org2;
-                       vector org = check.move_origin - self.move_origin;
-                       org = org + pivot;
-                       org2_x = dotproduct(org, v_forward);
-                       org2_y = dotproduct(org, v_right);
-                       org2_z = dotproduct(org, v_up);
-                       move = org2 - org;
-                       move = move + move1;
-               }
-               else
-                       move = move1;
-
-               // physics objects need better collisions than this code can do
-               if(check.move_movetype == 32) // MOVETYPE_PHYSICS
-               {
-                       check.move_origin = check.move_origin + move;
-                       oldself = self;
+                       switch (check.move_movetype)
+                       {
+                               case MOVETYPE_NONE:
+                               case MOVETYPE_PUSH:
+                               case MOVETYPE_FOLLOW:
+                               case MOVETYPE_NOCLIP:
+                               case MOVETYPE_FLY_WORLDONLY:
+                                       continue;
+                               default:
+                                       break;
+                       }
+
+                       if (check.owner == self)
+                               continue;
+
+                       if (self.owner == check)
+                               continue;
+
+                       vector pivot = check.mins + 0.5 * (check.maxs - check.mins);
+                       vector move;
+                       if (rotated)
+                       {
+                               vector org = (check.move_origin - self.move_origin) + pivot;
+                               vector org2;
+                               org2.x = org * v_forward;
+                               org2.y = org * v_right;
+                               org2.z = org * v_up;
+                               move = (org2 - org) + move1;
+                       }
+                       else
+                       {
+                               move = move1;
+                       }
+
+                       // physics objects need better collisions than this code can do
+                       if (check.move_movetype == 32)  // MOVETYPE_PHYSICS
+                       {
+                               check.move_origin = check.move_origin + move;
+                               entity oldself = self;
+                               self = check;
+                               _Movetype_LinkEdict(true);
+                               self = oldself;
+                               continue;
+                       }
+
+                       // try moving the contacted entity
+                       self.solid = SOLID_NOT;
+                       entity oldself = self;
                        self = check;
-                       _Movetype_LinkEdict(true);
-                       self = oldself;
-                       continue;
-               }
-
-               // try moving the contacted entity
-               self.solid = SOLID_NOT;
-               oldself = self;
-               self = check;
-               if(!_Movetype_PushEntity(move, true))
-               {
+                       if (!_Movetype_PushEntity(move, true))
+                       {
+                               self = oldself;
+                               // entity "check" got teleported
+                               check.move_angles_y += trace_fraction * moveangle.y;
+                               self.solid = savesolid;
+                               continue;  // pushed enough
+                       }
                        self = oldself;
-                       // entity "check" got teleported
-                       check.move_angles_y += trace_fraction * moveangle_y;
+                       // FIXME: turn players specially
+                       check.move_angles_y += trace_fraction * moveangle.y;
                        self.solid = savesolid;
-                       continue; // pushed enough
+
+                       // this trace.fraction < 1 check causes items to fall off of pushers
+                       // if they pass under or through a wall
+                       // the groundentity check causes items to fall off of ledges
+                       if (check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self))
+                               check.move_flags &= ~FL_ONGROUND;
                }
-               self = oldself;
-               // FIXME: turn players specially
-               check.move_angles_y += trace_fraction * moveangle_y;
-               self.solid = savesolid;
-
-               // this trace.fraction < 1 check causes items to fall off of pushers
-               // if they pass under or through a wall
-               // the groundentity check causes items to fall off of ledges
-               if(check.move_movetype != MOVETYPE_WALK && (trace_fraction < 1 || check.move_groundentity != self))
-                       check.move_flags &= ~FL_ONGROUND;
        }
 
-       self.move_angles_x -= 360.0 * floor(self.move_angles_x * (1.0 / 360.0));
-       self.move_angles_y -= 360.0 * floor(self.move_angles_y * (1.0 / 360.0));
-       self.move_angles_z -= 360.0 * floor(self.move_angles_z * (1.0 / 360.0));
+       self.move_angles_x -= 360.0 * floor(self.move_angles.x * (1.0 / 360.0));
+       self.move_angles_y -= 360.0 * floor(self.move_angles.y * (1.0 / 360.0));
+       self.move_angles_z -= 360.0 * floor(self.move_angles.z * (1.0 / 360.0));
 }
 
-void _Movetype_Physics_Pusher(float dt) // SV_Physics_Pusher
+void _Movetype_Physics_Pusher(float dt)  // SV_Physics_Pusher
 {
-       float thinktime, oldltime, movetime;
-
-       oldltime = self.move_ltime;
-
-       thinktime = self.move_nextthink;
-       if(thinktime < self.move_ltime + dt)
+       float oldltime = self.move_ltime;
+       float thinktime = self.move_nextthink;
+       float movetime;
+       if (thinktime < self.move_ltime + dt)
        {
                movetime = thinktime - self.move_ltime;
-               if(movetime < 0)
+               if (movetime < 0)
                        movetime = 0;
        }
        else
+       {
                movetime = dt;
+       }
 
-       if(movetime)
+       if (movetime)
                // advances self.move_ltime if not blocked
                _Movetype_PushMove(movetime);
 
-       if(thinktime > oldltime && thinktime <= self.move_ltime)
+       if (thinktime > oldltime && thinktime <= self.move_ltime)
        {
                self.move_nextthink = 0;
                self.move_time = time;
                other = world;
-               if(self.move_think)
+               if (self.move_think)
                        self.move_think();
        }
 }
index df9c9b8e30de0068c1fbdc2104c58c2268bcf45f..6ed0407eb30f80c2776e34551191d636efe37da3 100644 (file)
@@ -1,14 +1,18 @@
 #include "../physics.qh"
 
-void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
+void _Movetype_Physics_Toss(float dt)  // SV_Physics_Toss
 {
-       if(self.move_flags & FL_ONGROUND)
+       if (self.move_flags & FL_ONGROUND)
        {
-               if(self.move_velocity_z >= 1/32)
+               if (self.move_velocity.z >= 1 / 32)
+               {
                        self.move_flags &= ~FL_ONGROUND;
-               else if(!self.move_groundentity)
+               }
+               else if (!self.move_groundentity)
+               {
                        return;
-               else if(self.move_suspendedinair && wasfreed(self.move_groundentity))
+               }
+               else if (self.move_suspendedinair && wasfreed(self.move_groundentity))
                {
                        self.move_groundentity = world;
                        return;
@@ -19,70 +23,53 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
 
        _Movetype_CheckVelocity();
 
-       if(self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
+       if (self.move_movetype == MOVETYPE_BOUNCE || self.move_movetype == MOVETYPE_TOSS)
        {
                self.move_didgravity = 1;
-               if(GRAVITY_UNAFFECTED_BY_TICRATE)
-               {
-                       if(self.gravity)
-                               self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
-                       else
-                               self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
-               }
-               else
-               {
-                       if(self.gravity)
-                               self.move_velocity_z -= dt * self.gravity * PHYS_GRAVITY;
-                       else
-                               self.move_velocity_z -= dt * PHYS_GRAVITY;
-               }
+               self.move_velocity_z -= (GRAVITY_UNAFFECTED_BY_TICRATE ? 0.5 : 1)
+                   * dt
+                   * (self.gravity ? self.gravity : 1)
+                   * PHYS_GRAVITY;
        }
 
        self.move_angles = self.move_angles + self.move_avelocity * dt;
 
-       float movetime, bump;
-       movetime = dt;
-       for(bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
+       float movetime = dt;
+       for (int bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
        {
-               vector move;
-               move = self.move_velocity * movetime;
+               vector move = self.move_velocity * movetime;
                _Movetype_PushEntity(move, true);
-               if(wasfreed(self))
+               if (wasfreed(self))
                        return;
 
-               if(trace_startsolid)
+               if (trace_startsolid)
                {
                        _Movetype_UnstickEntity();
                        _Movetype_PushEntity(move, false);
-                       if(wasfreed(self))
+                       if (wasfreed(self))
                                return;
                }
 
-               if(trace_fraction == 1)
+               if (trace_fraction == 1)
                        break;
 
                movetime *= 1 - min(1, trace_fraction);
 
-               if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+               if (self.move_movetype == MOVETYPE_BOUNCEMISSILE)
                {
                        self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 2.0);
                        self.move_flags &= ~FL_ONGROUND;
                }
-               else if(self.move_movetype == MOVETYPE_BOUNCE)
+               else if (self.move_movetype == MOVETYPE_BOUNCE)
                {
-                       float d, bouncefac, bouncestop;
-
-                       bouncefac = self.move_bounce_factor;     if(!bouncefac)  bouncefac = 0.5;
-                       bouncestop = self.move_bounce_stopspeed; if(!bouncestop) bouncestop = 60 / 800;
-                       if(self.gravity)
-                               bouncestop *= self.gravity * PHYS_GRAVITY;
-                       else
-                               bouncestop *= PHYS_GRAVITY;
+                       float bouncefac = self.move_bounce_factor;     if (!bouncefac)  bouncefac = 0.5;
+                       float bouncestop = self.move_bounce_stopspeed; if (!bouncestop) bouncestop = 60 / 800;
+                       bouncestop *= (self.gravity ? self.gravity : 1) * PHYS_GRAVITY;
 
                        self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac);
 
-                       d = trace_plane_normal * self.move_velocity;
-                       if(trace_plane_normal_z > 0.7 && d < bouncestop && d > -bouncestop)
+                       float d = trace_plane_normal * self.move_velocity;
+                       if (trace_plane_normal.z > 0.7 && d < bouncestop && d > -bouncestop)
                        {
                                self.move_flags |= FL_ONGROUND;
                                self.move_groundentity = trace_ent;
@@ -90,42 +77,39 @@ void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
                                self.move_avelocity = '0 0 0';
                        }
                        else
+                       {
                                self.move_flags &= ~FL_ONGROUND;
+                       }
                }
                else
                {
                        self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1.0);
-                       if(trace_plane_normal_z > 0.7)
+                       if (trace_plane_normal.z > 0.7)
                        {
                                self.move_flags |= FL_ONGROUND;
                                self.move_groundentity = trace_ent;
-                               if(trace_ent.solid == SOLID_BSP)
+                               if (trace_ent.solid == SOLID_BSP)
                                        self.move_suspendedinair = true;
                                self.move_velocity = '0 0 0';
                                self.move_avelocity = '0 0 0';
                        }
                        else
+                       {
                                self.move_flags &= ~FL_ONGROUND;
+                       }
                }
 
                // DP revision 8905 (just, WHY...)
-               if(self.move_movetype == MOVETYPE_BOUNCEMISSILE)
+               if (self.move_movetype == MOVETYPE_BOUNCEMISSILE)
                        break;
 
                // DP revision 8918 (WHY...)
-               if(self.move_flags & FL_ONGROUND)
+               if (self.move_flags & FL_ONGROUND)
                        break;
        }
 
-       if(GRAVITY_UNAFFECTED_BY_TICRATE)
-       if(self.move_didgravity > 0)
-       if(!(self.move_flags & FL_ONGROUND))
-       {
-               if(self.gravity)
-                       self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
-               else
-                       self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
-       }
+       if (GRAVITY_UNAFFECTED_BY_TICRATE && self.move_didgravity > 0 && !(self.move_flags & FL_ONGROUND))
+               self.move_velocity_z -= 0.5 * dt * (self.gravity ? self.gravity : 1) * PHYS_GRAVITY;
 
        _Movetype_CheckWaterTransition(self);
 }
diff --git a/qcsrc/common/movetypes/walk.qc b/qcsrc/common/movetypes/walk.qc
new file mode 100644 (file)
index 0000000..cbcfc5b
--- /dev/null
@@ -0,0 +1,167 @@
+void _Movetype_Physics_Walk(float dt)  // SV_WalkMove
+{
+       vector stepnormal = '0 0 0';
+
+       // if frametime is 0 (due to client sending the same timestamp twice), don't move
+       if (dt <= 0)
+               return;
+
+       if (GAMEPLAYFIX_UNSTICKPLAYERS)
+               _Movetype_UnstickEntity();
+
+       bool applygravity = (!_Movetype_CheckWater(self) && self.move_movetype == MOVETYPE_WALK && !(self.move_flags & FL_WATERJUMP));
+
+       _Movetype_CheckVelocity();
+
+       // do a regular slide move unless it looks like you ran into a step
+       bool oldonground = (self.move_flags & FL_ONGROUND);
+
+       vector start_origin = self.move_origin;
+       vector start_velocity = self.move_velocity;
+
+       int clip = _Movetype_FlyMove(dt, applygravity, stepnormal, GAMEPLAYFIX_STEPMULTIPLETIMES ? PHYS_STEPHEIGHT : 0);
+
+       if (GAMEPLAYFIX_DOWNTRACEONGROUND && !(clip & 1))
+       {
+               // only try this if there was no floor in the way in the trace (no,
+               // this check seems to be not REALLY necessary, because if clip & 1,
+               // our trace will hit that thing too)
+               vector upmove = self.move_origin + '0 0 1';
+               vector downmove = self.move_origin - '0 0 1';
+               int type;
+               if (self.move_movetype == MOVETYPE_FLYMISSILE) type = MOVE_MISSILE; else if (self.move_movetype == MOVETYPE_FLY_WORLDONLY)
+                       type = MOVE_WORLDONLY;
+               else if (self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
+                       type = MOVE_NOMONSTERS;
+               else   type = MOVE_NORMAL;
+               tracebox(upmove, self.mins, self.maxs, downmove, type, self);
+               if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
+                       clip |= 1;  // but we HAVE found a floor
+       }
+
+       // if the move did not hit the ground at any point, we're not on ground
+       if (!(clip & 1))
+               self.move_flags &= ~FL_ONGROUND;
+
+       _Movetype_CheckVelocity();
+       _Movetype_LinkEdict(true);
+
+       if (clip & 8)  // teleport
+               return;
+
+       if (self.move_flags & FL_WATERJUMP)
+               return;
+
+       if (PHYS_NOSTEP)
+               return;
+
+       vector originalmove_origin = self.move_origin;
+       vector originalmove_velocity = self.move_velocity;
+       // originalmove_clip = clip;
+       int originalmove_flags = self.move_flags;
+       entity originalmove_groundentity = self.move_groundentity;
+
+       // if move didn't block on a step, return
+       if (clip & 2)
+       {
+               // if move was not trying to move into the step, return
+               if (fabs(start_velocity.x) < 0.03125 && fabs(start_velocity.y) < 0.03125)
+                       return;
+
+               if (self.move_movetype != MOVETYPE_FLY)
+               {
+                       // return if gibbed by a trigger
+                       if (self.move_movetype != MOVETYPE_WALK)
+                               return;
+
+                       // return if attempting to jump while airborn (unless sv_jumpstep)
+                       if (!PHYS_JUMPSTEP)
+                               if (!oldonground && self.move_waterlevel == 0)
+                                       return;
+               }
+
+               // try moving up and forward to go up a step
+               // back to start pos
+               self.move_origin = start_origin;
+               self.move_velocity = start_velocity;
+
+               // move up
+               vector upmove = '0 0 1' * PHYS_STEPHEIGHT;
+               if (!_Movetype_PushEntity(upmove, true))
+               {
+                       // we got teleported when upstepping... must abort the move
+                       return;
+               }
+
+               // move forward
+               self.move_velocity_z = 0;
+               clip = _Movetype_FlyMove(dt, applygravity, stepnormal, 0);
+               self.move_velocity_z += start_velocity.z;
+               if (clip & 8)
+               {
+                       // we got teleported when upstepping... must abort the move
+                       // note that z velocity handling may not be what QC expects here, but we cannot help it
+                       return;
+               }
+
+               _Movetype_CheckVelocity();
+               _Movetype_LinkEdict(true);
+
+               // check for stuckness, possibly due to the limited precision of floats
+               // in the clipping hulls
+               if (clip
+                   && fabs(originalmove_origin.y - self.move_origin.y) < 0.03125
+                   && fabs(originalmove_origin.x - self.move_origin.x) < 0.03125)
+               {
+                       // Con_Printf("wall\n");
+                       // stepping up didn't make any progress, revert to original move
+                       self.move_origin = originalmove_origin;
+                       self.move_velocity = originalmove_velocity;
+                       // clip = originalmove_clip;
+                       self.move_flags = originalmove_flags;
+                       self.move_groundentity = originalmove_groundentity;
+                       // now try to unstick if needed
+                       // clip = SV_TryUnstick (ent, oldvel);
+                       return;
+               }
+
+               // Con_Printf("step - ");
+
+               // extra friction based on view angle
+               if (clip & 2 && PHYS_WALLFRICTION)
+                       _Movetype_WallFriction(stepnormal);
+       }
+       // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
+       else if (!GAMEPLAYFIX_STEPDOWN || self.move_waterlevel >= 3 || start_velocity.z >= (1.0 / 32.0) || !oldonground || (self.move_flags & FL_ONGROUND))
+       {
+               return;
+       }
+
+       // move down
+       vector downmove = '0 0 1' * (-PHYS_STEPHEIGHT + start_velocity.z * dt);
+       if (!_Movetype_PushEntity(downmove, true))
+       {
+               // we got teleported when downstepping... must abort the move
+               return;
+       }
+
+       if (trace_fraction < 1 && trace_plane_normal.z > 0.7)
+       {
+               // this has been disabled so that you can't jump when you are stepping
+               // up while already jumping (also known as the Quake2 double jump bug)
+       }
+       else
+       {
+               // Con_Printf("slope\n");
+               // if the push down didn't end up on good ground, use the move without
+               // the step up.  This happens near wall / slope combinations, and can
+               // cause the player to hop up higher on a slope too steep to climb
+               self.move_origin = originalmove_origin;
+               self.move_velocity = originalmove_velocity;
+               self.move_flags = originalmove_flags;
+               self.move_groundentity = originalmove_groundentity;
+       }
+
+       _Movetype_CheckVelocity();
+       _Movetype_LinkEdict(true);
+}
diff --git a/qcsrc/common/movetypes/walk.qh b/qcsrc/common/movetypes/walk.qh
new file mode 100644 (file)
index 0000000..10493c9
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef MOVETYPE_WALK_H
+#define MOVETYPE_WALK_H
+
+void _Movetype_Physics_Walk(float dt);
+
+#endif
index 728863ad44b22b7cafd102442a96c3f4b03aa67a..01b9755b1b237608cbd76cf192533920fa9fa391 100644 (file)
@@ -1751,6 +1751,9 @@ void CSQC_ClientMovement_PlayerMove_Frame(void)
        PM_Main();
 
 #ifdef CSQC
-       self.pmove_flags = self.flags; // TODO
+       self.pmove_flags = 
+                       ((self.flags & FL_DUCKED) ? PMF_DUCKED : 0) |
+                       (!(self.flags & FL_JUMPRELEASED) ? 0 : PMF_JUMP_HELD) |
+                       ((self.flags & FL_ONGROUND) ? PMF_ONGROUND : 0);
 #endif
 }
index 52a8e9a56959d67f683ccf238bb0455ca1c26329..d5b8f14acc66c8e0332118c03ac8f39800da52b7 100644 (file)
@@ -72,6 +72,10 @@ bool IsFlying(entity a);
        #define GAMEPLAYFIX_NOGRAVITYONGROUND                   cvar("sv_gameplayfix_nogravityonground")
        #define GAMEPLAYFIX_Q2AIRACCELERATE                             cvar("sv_gameplayfix_q2airaccelerate")
        #define GAMEPLAYFIX_EASIERWATERJUMP                     getstati(STAT_GAMEPLAYFIX_EASIERWATERJUMP)
+       #define GAMEPLAYFIX_DOWNTRACEONGROUND                   getstati(STAT_GAMEPLAYFIX_DOWNTRACEONGROUND)
+       #define GAMEPLAYFIX_STEPMULTIPLETIMES                   getstati(STAT_GAMEPLAYFIX_STEPMULTIPLETIMES)
+       #define GAMEPLAYFIX_UNSTICKPLAYERS                              getstati(STAT_GAMEPLAYFIX_UNSTICKPLAYERS)
+       #define GAMEPLAYFIX_STEPDOWN                                    getstati(STAT_GAMEPLAYFIX_STEPDOWN)
 
        #define IS_DUCKED(s)                                            !!(s.flags & FL_DUCKED)
        #define SET_DUCKED(s)                                           s.flags |= FL_DUCKED
@@ -95,6 +99,22 @@ bool IsFlying(entity a);
 
        #define PHYS_DOUBLEJUMP                                         getstati(STAT_DOUBLEJUMP)
 
+       #define PHYS_BUGRIGS                                            getstati(STAT_BUGRIGS)
+       #define PHYS_BUGRIGS_ANGLE_SMOOTHING            getstati(STAT_BUGRIGS_ANGLE_SMOOTHING)
+       #define PHYS_BUGRIGS_PLANAR_MOVEMENT            getstati(STAT_BUGRIGS_PLANAR_MOVEMENT)
+       #define PHYS_BUGRIGS_REVERSE_SPEEDING           getstati(STAT_BUGRIGS_REVERSE_SPEEDING)
+       #define PHYS_BUGRIGS_FRICTION_FLOOR             getstatf(STAT_BUGRIGS_FRICTION_FLOOR)
+       #define PHYS_BUGRIGS_AIR_STEERING                       getstati(STAT_BUGRIGS_AIR_STEERING)
+       #define PHYS_BUGRIGS_FRICTION_BRAKE             getstatf(STAT_BUGRIGS_FRICTION_BRAKE)
+       #define PHYS_BUGRIGS_ACCEL                                      getstatf(STAT_BUGRIGS_ACCEL)
+       #define PHYS_BUGRIGS_SPEED_REF                          getstatf(STAT_BUGRIGS_SPEED_REF)
+       #define PHYS_BUGRIGS_SPEED_POW                          getstatf(STAT_BUGRIGS_SPEED_POW)
+       #define PHYS_BUGRIGS_STEER                                      getstatf(STAT_BUGRIGS_STEER)
+       #define PHYS_BUGRIGS_FRICTION_AIR                       getstatf(STAT_BUGRIGS_FRICTION_AIR)
+       #define PHYS_BUGRIGS_CAR_JUMPING                        getstatf(STAT_BUGRIGS_CAR_JUMPING)
+       #define PHYS_BUGRIGS_REVERSE_SPINNING           getstatf(STAT_BUGRIGS_REVERSE_SPINNING)
+       #define PHYS_BUGRIGS_REVERSE_STOPPING           getstatf(STAT_BUGRIGS_REVERSE_STOPPING)
+
        #define PHYS_JUMPSPEEDCAP_MIN                           getstatf(STAT_MOVEVARS_JUMPSPEEDCAP_MIN)
        #define PHYS_JUMPSPEEDCAP_MAX                           getstatf(STAT_MOVEVARS_JUMPSPEEDCAP_MAX)
        #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS       getstati(STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS)
@@ -130,6 +150,8 @@ bool IsFlying(entity a);
        #define PHYS_WARSOWBUNNY_TOPSPEED                       getstatf(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED)
        #define PHYS_WARSOWBUNNY_TURNACCEL                      getstatf(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL)
 
+       #define PHYS_WALLFRICTION                                       getstati(STAT_MOVEVARS_WALLFRICTION)
+
        #define PHYS_JETPACK_ACCEL_UP                           getstatf(STAT_JETPACK_ACCEL_UP)
        #define PHYS_JETPACK_ACCEL_SIDE                         getstatf(STAT_JETPACK_ACCEL_SIDE)
        #define PHYS_JETPACK_ANTIGRAVITY                        getstatf(STAT_JETPACK_ANTIGRAVITY)
@@ -139,6 +161,9 @@ bool IsFlying(entity a);
 
        #define PHYS_DODGING_FROZEN                                     getstati(STAT_DODGING_FROZEN)
 
+       #define PHYS_NOSTEP                                                     getstati(STAT_NOSTEP)
+       #define PHYS_JUMPSTEP                                           getstati(STAT_MOVEVARS_JUMPSTEP)
+
 #elif defined(SVQC)
 
        .float stat_sv_airaccel_qw;
@@ -163,6 +188,29 @@ bool IsFlying(entity a);
        .float stat_jetpack_maxspeed_up;
        .float stat_jetpack_maxspeed_side;
        .float stat_gameplayfix_easierwaterjump;
+       .float stat_gameplayfix_downtracesupportsongroundflag;
+       .float stat_gameplayfix_stepmultipletimes;
+       .float stat_gameplayfix_unstickplayers;
+       .float stat_gameplayfix_stepdown;
+
+       .float stat_bugrigs;
+       .float stat_bugrigs_angle_smoothing;
+       .float stat_bugrigs_planar_movement;
+       .float stat_bugrigs_reverse_speeding;
+       .float stat_bugrigs_friction_floor;
+       .float stat_bugrigs_air_steering;
+       .float stat_bugrigs_friction_brake;
+       .float stat_bugrigs_accel;
+       .float stat_bugrigs_speed_ref;
+       .float stat_bugrigs_speed_pow;
+       .float stat_bugrigs_steer;
+       .float stat_bugrigs_friction_air;
+       .float stat_bugrigs_car_jumping;
+       .float stat_bugrigs_reverse_spinning;
+       .float stat_bugrigs_reverse_stopping;
+
+       .float stat_nostep;
+       .float stat_jumpstep;
 
        #define PHYS_INPUT_ANGLES(s)                            s.v_angle
        #define PHYS_WORLD_ANGLES(s)                            s.angles
@@ -192,6 +240,10 @@ bool IsFlying(entity a);
        #define GAMEPLAYFIX_NOGRAVITYONGROUND                   cvar("sv_gameplayfix_nogravityonground")
        #define GAMEPLAYFIX_Q2AIRACCELERATE                             autocvar_sv_gameplayfix_q2airaccelerate
        #define GAMEPLAYFIX_EASIERWATERJUMP                             cvar("sv_gameplayfix_easierwaterjump")
+       #define GAMEPLAYFIX_DOWNTRACEONGROUND                   cvar("sv_gameplayfix_downtracesupportsongroundflag")
+       #define GAMEPLAYFIX_STEPMULTIPLETIMES                   cvar("sv_gameplayfix_stepmultipletimes")
+       #define GAMEPLAYFIX_UNSTICKPLAYERS                              cvar("sv_gameplayfix_unstickplayers")
+       #define GAMEPLAYFIX_STEPDOWN                                    cvar("sv_gameplayfix_stepdown")
 
        #define IS_DUCKED(s)                                            s.crouch
        #define SET_DUCKED(s)                                           s.crouch = true
@@ -215,6 +267,22 @@ bool IsFlying(entity a);
 
        #define PHYS_DOUBLEJUMP                                         autocvar_sv_doublejump
 
+       #define PHYS_BUGRIGS                                            g_bugrigs
+       #define PHYS_BUGRIGS_ANGLE_SMOOTHING            g_bugrigs_angle_smoothing
+       #define PHYS_BUGRIGS_PLANAR_MOVEMENT            g_bugrigs_planar_movement
+       #define PHYS_BUGRIGS_REVERSE_SPEEDING           g_bugrigs_reverse_speeding
+       #define PHYS_BUGRIGS_FRICTION_FLOOR                     g_bugrigs_friction_floor
+       #define PHYS_BUGRIGS_AIR_STEERING                       g_bugrigs_air_steering
+       #define PHYS_BUGRIGS_FRICTION_BRAKE                     g_bugrigs_friction_brake
+       #define PHYS_BUGRIGS_ACCEL                                      g_bugrigs_accel
+       #define PHYS_BUGRIGS_SPEED_REF                          g_bugrigs_speed_ref
+       #define PHYS_BUGRIGS_SPEED_POW                          g_bugrigs_speed_pow
+       #define PHYS_BUGRIGS_STEER                                      g_bugrigs_steer
+       #define PHYS_BUGRIGS_FRICTION_AIR                       g_bugrigs_friction_air
+       #define PHYS_BUGRIGS_CAR_JUMPING                        g_bugrigs_planar_movement_car_jumping
+       #define PHYS_BUGRIGS_REVERSE_SPINNING           g_bugrigs_reverse_spinning
+       #define PHYS_BUGRIGS_REVERSE_STOPPING           g_bugrigs_reverse_stopping
+
        #define PHYS_JUMPSPEEDCAP_MIN                           autocvar_sv_jumpspeedcap_min
        #define PHYS_JUMPSPEEDCAP_MAX                           autocvar_sv_jumpspeedcap_max
        #define PHYS_JUMPSPEEDCAP_DISABLE_ONRAMPS       autocvar_sv_jumpspeedcap_max_disable_on_ramps
@@ -250,6 +318,8 @@ bool IsFlying(entity a);
        #define PHYS_WARSOWBUNNY_TOPSPEED                       autocvar_sv_warsowbunny_topspeed
        #define PHYS_WARSOWBUNNY_TURNACCEL                      autocvar_sv_warsowbunny_turnaccel
 
+       #define PHYS_WALLFRICTION                                       cvar("sv_wallfriction")
+
        #define PHYS_JETPACK_ACCEL_UP                           autocvar_g_jetpack_acceleration_up
        #define PHYS_JETPACK_ACCEL_SIDE                         autocvar_g_jetpack_acceleration_side
        #define PHYS_JETPACK_ANTIGRAVITY                        autocvar_g_jetpack_antigravity
@@ -259,5 +329,8 @@ bool IsFlying(entity a);
 
        #define PHYS_DODGING_FROZEN                                     autocvar_sv_dodging_frozen
 
+       #define PHYS_NOSTEP                                                     cvar("sv_nostep")
+       #define PHYS_JUMPSTEP                                           cvar("sv_jumpstep")
+
 #endif
 #endif
index 0095c60a31f3614be5c68bfdcd72f840aaa7958d..c3d67ca1a74e2e9d62e825ba2d9f2db7033d051c 100644 (file)
@@ -204,28 +204,28 @@ const int STAT_REVIVE_PROGRESS        = 106;
 // 166 empty?
 // 167 empty?
 // 168 empty?
-// 169 empty?
-// 170 empty?
-// 171 empty?
-// 172 empty?
-// 173 empty?
-// 174 empty?
-// 175 empty?
-// 176 empty?
-// 177 empty?
-// 178 empty?
-// 179 empty?
-// 180 empty?
-// 181 empty?
-// 182 empty?
-// 183 empty?
-// 184 empty?
-// 185 empty?
-// 186 empty?
-// 187 empty?
-// 188 empty?
-// 189 empty?
-const int STAT_GAMEPLAYFIX_EASIERWATERJUMP                       = 190;
+const int STAT_BUGRIGS_REVERSE_STOPPING               = 169;
+const int STAT_BUGRIGS_REVERSE_SPINNING               = 170;
+const int STAT_BUGRIGS_CAR_JUMPING                    = 171;
+const int STAT_BUGRIGS_FRICTION_AIR                   = 172;
+const int STAT_BUGRIGS_STEER                          = 173;
+const int STAT_BUGRIGS_SPEED_POW                      = 174;
+const int STAT_BUGRIGS_SPEED_REF                      = 175;
+const int STAT_BUGRIGS_ACCEL                          = 176;
+const int STAT_BUGRIGS_FRICTION_BRAKE                 = 177;
+const int STAT_BUGRIGS_AIR_STEERING                   = 178;
+const int STAT_BUGRIGS_FRICTION_FLOOR                 = 179;
+const int STAT_BUGRIGS_REVERSE_SPEEDING               = 180;
+const int STAT_BUGRIGS_PLANAR_MOVEMENT                = 181;
+const int STAT_BUGRIGS_ANGLE_SMOOTHING                = 182;
+const int STAT_BUGRIGS                                = 183;
+const int STAT_GAMEPLAYFIX_STEPDOWN                   = 184;
+const int STAT_MOVEVARS_JUMPSTEP                      = 185;
+const int STAT_NOSTEP                                 = 186;
+const int STAT_GAMEPLAYFIX_UNSTICKPLAYERS             = 187;
+const int STAT_GAMEPLAYFIX_STEPMULTIPLETIMES          = 188;
+const int STAT_GAMEPLAYFIX_DOWNTRACEONGROUND          = 189;
+const int STAT_GAMEPLAYFIX_EASIERWATERJUMP            = 190;
 const int STAT_MOVEVARS_FRICTION_SLICK                = 191;
 const int STAT_MOVEVARS_FRICTION_ONLAND               = 192;
 const int STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS  = 193;
index 6019885391005e7491cb3efb7b429c97d6d21552..89ca2e03d6fdc1911d47e722550dd18f031b3346 100644 (file)
@@ -35,10 +35,6 @@ void trigger_impulse_touch1()
        other.lastpushtime = time;
        if(!pushdeltatime) return;
 
-#ifdef CSQC
-       print("Touchie!\n");
-#endif
-
        other.velocity = other.velocity + normalize(targ.origin - self.origin) * str * pushdeltatime;
        other.flags &= ~FL_ONGROUND;
 #ifdef SVQC