]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Move QC movetypes to common folder
authorMario <zacjardine@y7mail.com>
Sun, 22 Feb 2015 08:57:24 +0000 (19:57 +1100)
committerMario <zacjardine@y7mail.com>
Sun, 22 Feb 2015 08:57:24 +0000 (19:57 +1100)
15 files changed:
qcsrc/client/casings.qc
qcsrc/client/damage.qc
qcsrc/client/movetypes.qc [deleted file]
qcsrc/client/movetypes.qh [deleted file]
qcsrc/client/progs.src
qcsrc/client/vehicles/vehicles.qc
qcsrc/common/movetypes.qc [new file with mode: 0644]
qcsrc/common/movetypes.qh [new file with mode: 0644]
qcsrc/common/nades.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/weapons/weapons.qc
qcsrc/server/g_damage.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/progs.src
qcsrc/server/t_items.qc

index 6068a799f752892a2d1dc8f86b7d412537c0644c..7688e242d72bc09a2778881b013e887710e98527 100644 (file)
@@ -1,5 +1,5 @@
 #if defined(CSQC)
-       #include "movetypes.qh"
+       #include "../common/movetypes.qh"
        #include "prandom.qh"
        #include "rubble.qh"
 
index c3d260863faaeeec23689c88c475c5c53adb28f0..fb3c64589331e90b6cc84ff10e2aef924f4b66d2 100644 (file)
@@ -7,7 +7,7 @@
        #include "autocvars.qh"
        #include "../common/deathtypes.qh"
        #include "damage.qh"
-       #include "movetypes.qh"
+       #include "../common/movetypes.qh"
        #include "prandom.qh"
        #include "vehicles/vehicles.qh"
 #elif defined(MENUQC)
diff --git a/qcsrc/client/movetypes.qc b/qcsrc/client/movetypes.qc
deleted file mode 100644 (file)
index 916e6e0..0000000
+++ /dev/null
@@ -1,801 +0,0 @@
-#include "../common/physics.qh"
-
-#if defined(CSQC)
-       #include "../dpdefs/csprogsdefs.qh"
-       #include "defs.qh"
-       #include "../common/stats.qh"
-       #include "../common/util.qh"
-       #include "movetypes.qh"
-       #include "../csqcmodellib/common.qh"
-       #include "../server/t_items.qh"
-#elif defined(MENUQC)
-#elif defined(SVQC)
-       #include "../server/autocvars.qh"
-#endif
-
-
-#ifdef SVQC
-#define GRAVITY_UNAFFECTED_BY_TICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
-
-#define TICRATE sys_frametime
-#elif defined(CSQC)
-#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
-
-#define TICRATE ticrate
-#endif
-
-.entity move_groundentity; // FIXME add move_groundnetworkentity?
-.float move_suspendedinair;
-.float move_didgravity;
-
-void _Movetype_CheckVelocity() // SV_CheckVelocity
-{
-}
-
-float _Movetype_CheckWater(entity ent) // SV_CheckWater
-{
-       vector point = ent.move_origin;
-       point_z += (ent.mins_z + 1);
-
-       int nativecontents = pointcontents(point);
-
-       if(ent.move_watertype)
-       if(ent.move_watertype != nativecontents)
-       {
-               //print(sprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents));
-               if(ent.contentstransition)
-                       ent.contentstransition(ent.move_watertype, nativecontents);
-       }
-
-       ent.move_waterlevel = 0;
-       ent.move_watertype = CONTENT_EMPTY;
-
-       int supercontents = Mod_Q1BSP_SuperContentsFromNativeContents(nativecontents);
-       if(supercontents & DPCONTENTS_LIQUIDSMASK)
-       {
-               ent.move_watertype = nativecontents;
-               ent.move_waterlevel = 1;
-               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;
-                       if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
-                               ent.move_waterlevel = 3;
-               }
-       }
-
-       return (ent.move_waterlevel > 1);
-}
-
-void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
-{
-       float contents = pointcontents(ent.move_origin);
-
-       if(!ent.move_watertype)
-       {
-               // just spawned here
-               if(!autocvar_cl_gameplayfix_fixedcheckwatertransition)
-               {
-                       ent.move_watertype = contents;
-                       ent.move_waterlevel = 1;
-                       return;
-               }
-       }
-       else if(ent.move_watertype != contents)
-       {
-               //print(sprintf("_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);
-       }
-
-       if(contents <= CONTENT_WATER)
-       {
-               ent.move_watertype = contents;
-               ent.move_waterlevel = 1;
-       }
-       else
-       {
-               ent.move_watertype = CONTENT_EMPTY;
-               ent.move_waterlevel = (autocvar_cl_gameplayfix_fixedcheckwatertransition ? 0 : contents);
-       }
-}
-
-void _Movetype_Impact(entity oth) // SV_Impact
-{
-       entity oldother, oldself;
-
-       oldself = self;
-       oldother = other;
-
-       if(self.move_touch)
-       {
-               other = oth;
-
-               self.move_touch();
-
-               other = oldother;
-       }
-
-       if(oth.move_touch)
-       {
-               other = self;
-               self = oth;
-
-               self.move_touch();
-
-               self = oldself;
-               other = oldother;
-       }
-}
-
-void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
-{
-       entity e, oldself, oldother;
-
-       oldself = self;
-       oldother = other;
-
-       for(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))
-               {
-                       self = e;
-                       other = oldself;
-
-                       trace_allsolid = false;
-                       trace_startsolid = false;
-                       trace_fraction = 1;
-                       trace_inwater = false;
-                       trace_inopen = true;
-                       trace_endpos = e.origin;
-                       trace_plane_normal = '0 0 1';
-                       trace_plane_dist = 0;
-                       trace_ent = oldself;
-
-                       e.move_touch();
-               }
-       }
-
-       other = oldother;
-       self = oldself;
-}
-
-void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
-{
-       vector mi, ma;
-       if(self.solid == SOLID_BSP)
-       {
-               // TODO set the absolute bbox
-               mi = self.mins;
-               ma = self.maxs;
-       }
-       else
-       {
-               mi = self.mins;
-               ma = self.maxs;
-       }
-       mi = mi + self.origin;
-       ma = ma + self.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;
-       }
-       else
-       {
-               mi_x -= 1;
-               mi_y -= 1;
-               mi_z -= 1;
-               ma_x += 1;
-               ma_y += 1;
-               ma_z += 1;
-       }
-
-       self.absmin = mi;
-       self.absmax = ma;
-
-       if(touch_triggers)
-               _Movetype_LinkEdict_TouchAreaGrid();
-}
-
-float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
-{
-       vector org;
-       org = self.move_origin + ofs;
-
-       int cont = self.dphitcontentsmask;
-       self.dphitcontentsmask = DPCONTENTS_SOLID;
-       tracebox(self.move_origin, self.mins, self.maxs, self.move_origin, MOVE_NOMONSTERS, self);
-       self.dphitcontentsmask = cont;
-
-       if(trace_startsolid)
-               return true;
-
-       if(vlen(trace_endpos - self.move_origin) > 0.0001)
-               self.move_origin = trace_endpos;
-       return false;
-}
-
-float _Movetype_UnstickEntity() // SV_UnstickEntity
-{
-       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;
-       if(!_Movetype_TestEntityPosition('0 1 0')) goto success;
-       if(!_Movetype_TestEntityPosition('-1 -1 0')) goto success;
-       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)
-       {
-               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));
-       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));
-       _Movetype_LinkEdict(true);
-       return true;
-}
-
-vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
-{
-       vel = 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;
-
-       return vel;
-}
-
-void _Movetype_PushEntityTrace(vector push)
-{
-       vector end;
-       float type;
-
-       end = self.move_origin + push;
-
-       if(self.move_nomonsters)
-               type = max(0, self.move_nomonsters);
-       else if(self.move_movetype == MOVETYPE_FLYMISSILE)
-               type = MOVE_MISSILE;
-       else if(self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
-               type = MOVE_NOMONSTERS;
-       else
-               type = MOVE_NORMAL;
-
-       tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
-}
-
-float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
-{
-       _Movetype_PushEntityTrace(push);
-
-       if(trace_startsolid && failonstartsolid)
-               return trace_fraction;
-
-       self.move_origin = trace_endpos;
-
-       if(trace_fraction < 1)
-               if(self.solid >= SOLID_TRIGGER && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
-                       _Movetype_Impact(trace_ent);
-
-       return trace_fraction;
-}
-
-
-.float ltime;
-.void() blocked;
-void _Movetype_AngleVectorsFLU(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);
-       if(v_forward)
-       {
-               v_forward_x = cp*cy;
-               v_forward_y = cp*sy;
-               v_forward_z = -sp;
-       }
-       if(v_right || v_up)
-       {
-               if(myangles_z)
-               {
-                       angle = myangles_z * (M_PI*2 / 360);
-                       sr = sin(angle);
-                       cr = cos(angle);
-                       if(v_right)
-                       {
-                               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;
-                       }
-               }
-               else
-               {
-                       if(v_right)
-                       {
-                               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;
-                       }
-               }
-       }
-}
-
-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')
-       {
-               self.move_ltime += dt;
-               return;
-       }
-
-       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;
-       }
-
-       rotated = dotproduct(self.move_angles, self.move_angles) + dotproduct(self.move_avelocity, self.move_avelocity) > 0;
-
-       movetime2 = dt;
-
-       move1 = self.move_velocity * movetime2;
-       moveangle = self.move_avelocity * movetime2;
-
-       a = -moveangle;
-       // sets v_forward, v_right and v_up
-       _Movetype_AngleVectorsFLU(a);
-
-       pushorig = self.move_origin;
-       pushang = self.move_angles;
-       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;
-
-       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)
-       {
-               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;
-
-               pivot = check.mins + 0.5 * (check.maxs - check.mins);
-               //VectorClear(pivot);
-
-               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;
-                       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))
-               {
-                       self = oldself;
-                       // entity "check" got teleported
-                       check.move_angles_y += trace_fraction * moveangle_y;
-                       self.solid = savesolid;
-                       continue; // pushed enough
-               }
-               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));
-}
-
-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)
-       {
-               movetime = thinktime - self.move_ltime;
-               if(movetime < 0)
-                       movetime = 0;
-       }
-       else
-               movetime = dt;
-
-       if(movetime)
-               // advances self.move_ltime if not blocked
-               _Movetype_PushMove(movetime);
-
-       if(thinktime > oldltime && thinktime <= self.move_ltime)
-       {
-               self.move_nextthink = 0;
-               self.move_time = time;
-               other = world;
-               if(self.move_think)
-                       self.move_think();
-       }
-}
-
-void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
-{
-       if(self.move_flags & FL_ONGROUND)
-       {
-               if(self.move_velocity_z >= 1/32)
-                       self.move_flags &= ~FL_ONGROUND;
-               else if(!self.move_groundentity)
-                       return;
-               else if(self.move_suspendedinair && wasfreed(self.move_groundentity))
-               {
-                       self.move_groundentity = world;
-                       return;
-               }
-       }
-
-       self.move_suspendedinair = false;
-
-       _Movetype_CheckVelocity();
-
-       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_angles = self.move_angles + self.move_avelocity * dt;
-
-       float movetime, bump;
-       movetime = dt;
-       for(bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
-       {
-               vector move;
-               move = self.move_velocity * movetime;
-               _Movetype_PushEntity(move, true);
-               if(wasfreed(self))
-                       return;
-
-               if(trace_startsolid)
-               {
-                       _Movetype_UnstickEntity();
-                       _Movetype_PushEntity(move, false);
-                       if(wasfreed(self))
-                               return;
-               }
-
-               if(trace_fraction == 1)
-                       break;
-
-               movetime *= 1 - min(1, trace_fraction);
-
-               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)
-               {
-                       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;
-
-                       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)
-                       {
-                               self.move_flags |= FL_ONGROUND;
-                               self.move_groundentity = trace_ent;
-                               self.move_velocity = '0 0 0';
-                               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)
-                       {
-                               self.move_flags |= FL_ONGROUND;
-                               self.move_groundentity = trace_ent;
-                               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)
-                       break;
-
-               // DP revision 8918 (WHY...)
-               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;
-       }
-
-       _Movetype_CheckWaterTransition(self);
-}
-
-void _Movetype_Physics_Frame(float movedt)
-{
-       self.move_didgravity = -1;
-       switch(self.move_movetype)
-       {
-               case MOVETYPE_PUSH:
-               case MOVETYPE_FAKEPUSH:
-                       _Movetype_Physics_Pusher(movedt);
-                       break;
-               case MOVETYPE_NONE:
-                       break;
-               case MOVETYPE_FOLLOW:
-                       error("SV_Physics_Follow not implemented");
-                       break;
-               case MOVETYPE_NOCLIP:
-                       _Movetype_CheckWater(self);
-                       self.move_origin = self.move_origin + TICRATE * self.move_velocity;
-                       self.move_angles = self.move_angles + TICRATE * self.move_avelocity;
-                       _Movetype_LinkEdict(false);
-                       break;
-               case MOVETYPE_STEP:
-                       error("SV_Physics_Step not implemented");
-                       break;
-               case MOVETYPE_WALK:
-                       error("SV_Physics_Walk not implemented");
-                       break;
-               case MOVETYPE_TOSS:
-               case MOVETYPE_BOUNCE:
-               case MOVETYPE_BOUNCEMISSILE:
-               case MOVETYPE_FLYMISSILE:
-               case MOVETYPE_FLY:
-                       _Movetype_Physics_Toss(movedt);
-                       break;
-       }
-}
-
-void Movetype_Physics_NoMatchServer() // optimized
-{
-       float movedt;
-
-       movedt = time - self.move_time;
-       self.move_time = time;
-
-       _Movetype_Physics_Frame(movedt);
-       if(wasfreed(self))
-               return;
-
-       self.avelocity = self.move_avelocity;
-       self.velocity = self.move_velocity;
-       self.angles = self.move_angles;
-       setorigin(self, self.move_origin);
-}
-
-void Movetype_Physics_MatchServer(bool sloppy)
-{
-       Movetype_Physics_MatchTicrate(TICRATE, sloppy);
-}
-
-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;
-
-       movedt = tr;
-       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)
-       {
-               _Movetype_Physics_Frame(movedt);
-               if(wasfreed(self))
-                       return;
-       }
-
-       self.avelocity = self.move_avelocity;
-
-       if(dt > 0 && self.move_movetype != MOVETYPE_NONE && !(self.move_flags & FL_ONGROUND))
-       {
-               // now continue the move from move_time to time
-               self.velocity = self.move_velocity;
-
-               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.angles = self.move_angles + dt * self.avelocity;
-
-               if(sloppy || self.movetype == MOVETYPE_NOCLIP)
-               {
-                       setorigin(self, self.move_origin + dt * self.velocity);
-               }
-               else
-               {
-                       _Movetype_PushEntityTrace(dt * self.velocity);
-                       if(!trace_startsolid)
-                               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;
-                       }
-               }
-       }
-       else
-       {
-               self.velocity = self.move_velocity;
-               self.angles = self.move_angles;
-               setorigin(self, self.move_origin);
-       }
-}
diff --git a/qcsrc/client/movetypes.qh b/qcsrc/client/movetypes.qh
deleted file mode 100644 (file)
index 5fc0493..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-#ifndef MOVETYPES_H
-#define MOVETYPES_H
-
-.float move_ltime;
-.void(void) move_think;
-.float move_nextthink;
-.void(void) move_blocked;
-
-.float move_movetype;
-.float move_time;
-.vector move_origin;
-.vector move_angles;
-.vector move_velocity;
-.vector move_avelocity;
-.int move_flags;
-.int move_watertype;
-.int move_waterlevel;
-.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
-
-// should match sv_gameplayfix_fixedcheckwatertransition
-float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
-
-void Movetype_Physics_MatchTicrate(float tr, bool sloppy);
-void Movetype_Physics_MatchServer(bool sloppy);
-void Movetype_Physics_NoMatchServer();
-void _Movetype_LinkEdict(float touch_triggers);
-void _Movetype_LinkEdict_TouchAreaGrid();
-
-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_FOLLOW           = 12;
-const int MOVETYPE_FLY_WORLDONLY    = 33;
-
-const int FL_ITEM                   = 256;
-const int FL_ONGROUND                          = 512;
-#endif
-
-const int MOVETYPE_FAKEPUSH         = 13;
-
-const float MOVEFLAG_Q2AIRACCELERATE            = 1;
-const float MOVEFLAG_NOGRAVITYONGROUND          = 2;
-const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
-
-#ifdef CSQC
-// TODO: figure out server's version of this
-#define moveflags (getstati(STAT_MOVEFLAGS))
-#endif
-
-#endif
index 098fbbdd54ad30b3bc923bf1aa0924eed6c054ae..ff8632cc9a49adea69fb14c8566608a5bdd41710 100644 (file)
@@ -17,7 +17,6 @@ main.qc
 mapvoting.qc
 miscfunctions.qc
 modeleffects.qc
-movetypes.qc
 noise.qc
 particles.qc
 player_skeleton.qc
@@ -41,6 +40,7 @@ weapons/projectile.qc // TODO
 ../common/animdecide.qc
 ../common/buffs.qc
 ../common/mapinfo.qc
+../common/movetypes.qc
 ../common/nades.qc
 ../common/net_notice.qc
 ../common/notifications.qc
index 290385e495fcdd389aa4629b22fbe773a159d961..81bdc801d881eda13fa0a27a9b8758ed563513b2 100644 (file)
@@ -6,7 +6,7 @@
     #include "../../common/util.qh"
     #include "../../common/buffs.qh"
     #include "../autocvars.qh"
-    #include "../movetypes.qh"
+    #include "../../common/movetypes.qh"
     #include "../prandom.qh"
     #include "../main.qh"
     #include "vehicles.qh"
diff --git a/qcsrc/common/movetypes.qc b/qcsrc/common/movetypes.qc
new file mode 100644 (file)
index 0000000..7109b0e
--- /dev/null
@@ -0,0 +1,801 @@
+#include "physics.qh"
+
+#if defined(CSQC)
+       #include "../dpdefs/csprogsdefs.qh"
+       #include "../client/defs.qh"
+       #include "stats.qh"
+       #include "util.qh"
+       #include "movetypes.qh"
+       #include "../csqcmodellib/common.qh"
+       #include "../server/t_items.qh"
+#elif defined(MENUQC)
+#elif defined(SVQC)
+       #include "../server/autocvars.qh"
+#endif
+
+
+#ifdef SVQC
+#define GRAVITY_UNAFFECTED_BY_TICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
+
+#define TICRATE sys_frametime
+#elif defined(CSQC)
+#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
+
+#define TICRATE ticrate
+#endif
+
+.entity move_groundentity; // FIXME add move_groundnetworkentity?
+.float move_suspendedinair;
+.float move_didgravity;
+
+void _Movetype_CheckVelocity() // SV_CheckVelocity
+{
+}
+
+float _Movetype_CheckWater(entity ent) // SV_CheckWater
+{
+       vector point = ent.move_origin;
+       point_z += (ent.mins_z + 1);
+
+       int nativecontents = pointcontents(point);
+
+       if(ent.move_watertype)
+       if(ent.move_watertype != nativecontents)
+       {
+               //print(sprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents));
+               if(ent.contentstransition)
+                       ent.contentstransition(ent.move_watertype, nativecontents);
+       }
+
+       ent.move_waterlevel = 0;
+       ent.move_watertype = CONTENT_EMPTY;
+
+       int supercontents = Mod_Q1BSP_SuperContentsFromNativeContents(nativecontents);
+       if(supercontents & DPCONTENTS_LIQUIDSMASK)
+       {
+               ent.move_watertype = nativecontents;
+               ent.move_waterlevel = 1;
+               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;
+                       if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
+                               ent.move_waterlevel = 3;
+               }
+       }
+
+       return (ent.move_waterlevel > 1);
+}
+
+void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
+{
+       float contents = pointcontents(ent.move_origin);
+
+       if(!ent.move_watertype)
+       {
+               // just spawned here
+               if(!autocvar_cl_gameplayfix_fixedcheckwatertransition)
+               {
+                       ent.move_watertype = contents;
+                       ent.move_waterlevel = 1;
+                       return;
+               }
+       }
+       else if(ent.move_watertype != contents)
+       {
+               //print(sprintf("_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);
+       }
+
+       if(contents <= CONTENT_WATER)
+       {
+               ent.move_watertype = contents;
+               ent.move_waterlevel = 1;
+       }
+       else
+       {
+               ent.move_watertype = CONTENT_EMPTY;
+               ent.move_waterlevel = (autocvar_cl_gameplayfix_fixedcheckwatertransition ? 0 : contents);
+       }
+}
+
+void _Movetype_Impact(entity oth) // SV_Impact
+{
+       entity oldother, oldself;
+
+       oldself = self;
+       oldother = other;
+
+       if(self.move_touch)
+       {
+               other = oth;
+
+               self.move_touch();
+
+               other = oldother;
+       }
+
+       if(oth.move_touch)
+       {
+               other = self;
+               self = oth;
+
+               self.move_touch();
+
+               self = oldself;
+               other = oldother;
+       }
+}
+
+void _Movetype_LinkEdict_TouchAreaGrid() // SV_LinkEdict_TouchAreaGrid
+{
+       entity e, oldself, oldother;
+
+       oldself = self;
+       oldother = other;
+
+       for(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))
+               {
+                       self = e;
+                       other = oldself;
+
+                       trace_allsolid = false;
+                       trace_startsolid = false;
+                       trace_fraction = 1;
+                       trace_inwater = false;
+                       trace_inopen = true;
+                       trace_endpos = e.origin;
+                       trace_plane_normal = '0 0 1';
+                       trace_plane_dist = 0;
+                       trace_ent = oldself;
+
+                       e.move_touch();
+               }
+       }
+
+       other = oldother;
+       self = oldself;
+}
+
+void _Movetype_LinkEdict(float touch_triggers) // SV_LinkEdict
+{
+       vector mi, ma;
+       if(self.solid == SOLID_BSP)
+       {
+               // TODO set the absolute bbox
+               mi = self.mins;
+               ma = self.maxs;
+       }
+       else
+       {
+               mi = self.mins;
+               ma = self.maxs;
+       }
+       mi = mi + self.origin;
+       ma = ma + self.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;
+       }
+       else
+       {
+               mi_x -= 1;
+               mi_y -= 1;
+               mi_z -= 1;
+               ma_x += 1;
+               ma_y += 1;
+               ma_z += 1;
+       }
+
+       self.absmin = mi;
+       self.absmax = ma;
+
+       if(touch_triggers)
+               _Movetype_LinkEdict_TouchAreaGrid();
+}
+
+float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
+{
+       vector org;
+       org = self.move_origin + ofs;
+
+       int cont = self.dphitcontentsmask;
+       self.dphitcontentsmask = DPCONTENTS_SOLID;
+       tracebox(self.move_origin, self.mins, self.maxs, self.move_origin, MOVE_NOMONSTERS, self);
+       self.dphitcontentsmask = cont;
+
+       if(trace_startsolid)
+               return true;
+
+       if(vlen(trace_endpos - self.move_origin) > 0.0001)
+               self.move_origin = trace_endpos;
+       return false;
+}
+
+float _Movetype_UnstickEntity() // SV_UnstickEntity
+{
+       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;
+       if(!_Movetype_TestEntityPosition('0 1 0')) goto success;
+       if(!_Movetype_TestEntityPosition('-1 -1 0')) goto success;
+       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)
+       {
+               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));
+       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));
+       _Movetype_LinkEdict(true);
+       return true;
+}
+
+vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
+{
+       vel = 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;
+
+       return vel;
+}
+
+void _Movetype_PushEntityTrace(vector push)
+{
+       vector end;
+       float type;
+
+       end = self.move_origin + push;
+
+       if(self.move_nomonsters)
+               type = max(0, self.move_nomonsters);
+       else if(self.move_movetype == MOVETYPE_FLYMISSILE)
+               type = MOVE_MISSILE;
+       else if(self.solid == SOLID_TRIGGER || self.solid == SOLID_NOT)
+               type = MOVE_NOMONSTERS;
+       else
+               type = MOVE_NORMAL;
+
+       tracebox(self.move_origin, self.mins, self.maxs, end, type, self);
+}
+
+float _Movetype_PushEntity(vector push, float failonstartsolid) // SV_PushEntity
+{
+       _Movetype_PushEntityTrace(push);
+
+       if(trace_startsolid && failonstartsolid)
+               return trace_fraction;
+
+       self.move_origin = trace_endpos;
+
+       if(trace_fraction < 1)
+               if(self.solid >= SOLID_TRIGGER && (!(self.move_flags & FL_ONGROUND) || (self.move_groundentity != trace_ent)))
+                       _Movetype_Impact(trace_ent);
+
+       return trace_fraction;
+}
+
+
+.float ltime;
+.void() blocked;
+void _Movetype_AngleVectorsFLU(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);
+       if(v_forward)
+       {
+               v_forward_x = cp*cy;
+               v_forward_y = cp*sy;
+               v_forward_z = -sp;
+       }
+       if(v_right || v_up)
+       {
+               if(myangles_z)
+               {
+                       angle = myangles_z * (M_PI*2 / 360);
+                       sr = sin(angle);
+                       cr = cos(angle);
+                       if(v_right)
+                       {
+                               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;
+                       }
+               }
+               else
+               {
+                       if(v_right)
+                       {
+                               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;
+                       }
+               }
+       }
+}
+
+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')
+       {
+               self.move_ltime += dt;
+               return;
+       }
+
+       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;
+       }
+
+       rotated = dotproduct(self.move_angles, self.move_angles) + dotproduct(self.move_avelocity, self.move_avelocity) > 0;
+
+       movetime2 = dt;
+
+       move1 = self.move_velocity * movetime2;
+       moveangle = self.move_avelocity * movetime2;
+
+       a = -moveangle;
+       // sets v_forward, v_right and v_up
+       _Movetype_AngleVectorsFLU(a);
+
+       pushorig = self.move_origin;
+       pushang = self.move_angles;
+       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;
+
+       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)
+       {
+               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;
+
+               pivot = check.mins + 0.5 * (check.maxs - check.mins);
+               //VectorClear(pivot);
+
+               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;
+                       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))
+               {
+                       self = oldself;
+                       // entity "check" got teleported
+                       check.move_angles_y += trace_fraction * moveangle_y;
+                       self.solid = savesolid;
+                       continue; // pushed enough
+               }
+               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));
+}
+
+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)
+       {
+               movetime = thinktime - self.move_ltime;
+               if(movetime < 0)
+                       movetime = 0;
+       }
+       else
+               movetime = dt;
+
+       if(movetime)
+               // advances self.move_ltime if not blocked
+               _Movetype_PushMove(movetime);
+
+       if(thinktime > oldltime && thinktime <= self.move_ltime)
+       {
+               self.move_nextthink = 0;
+               self.move_time = time;
+               other = world;
+               if(self.move_think)
+                       self.move_think();
+       }
+}
+
+void _Movetype_Physics_Toss(float dt) // SV_Physics_Toss
+{
+       if(self.move_flags & FL_ONGROUND)
+       {
+               if(self.move_velocity_z >= 1/32)
+                       self.move_flags &= ~FL_ONGROUND;
+               else if(!self.move_groundentity)
+                       return;
+               else if(self.move_suspendedinair && wasfreed(self.move_groundentity))
+               {
+                       self.move_groundentity = world;
+                       return;
+               }
+       }
+
+       self.move_suspendedinair = false;
+
+       _Movetype_CheckVelocity();
+
+       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_angles = self.move_angles + self.move_avelocity * dt;
+
+       float movetime, bump;
+       movetime = dt;
+       for(bump = 0; bump < MAX_CLIP_PLANES && movetime > 0; ++bump)
+       {
+               vector move;
+               move = self.move_velocity * movetime;
+               _Movetype_PushEntity(move, true);
+               if(wasfreed(self))
+                       return;
+
+               if(trace_startsolid)
+               {
+                       _Movetype_UnstickEntity();
+                       _Movetype_PushEntity(move, false);
+                       if(wasfreed(self))
+                               return;
+               }
+
+               if(trace_fraction == 1)
+                       break;
+
+               movetime *= 1 - min(1, trace_fraction);
+
+               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)
+               {
+                       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;
+
+                       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)
+                       {
+                               self.move_flags |= FL_ONGROUND;
+                               self.move_groundentity = trace_ent;
+                               self.move_velocity = '0 0 0';
+                               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)
+                       {
+                               self.move_flags |= FL_ONGROUND;
+                               self.move_groundentity = trace_ent;
+                               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)
+                       break;
+
+               // DP revision 8918 (WHY...)
+               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;
+       }
+
+       _Movetype_CheckWaterTransition(self);
+}
+
+void _Movetype_Physics_Frame(float movedt)
+{
+       self.move_didgravity = -1;
+       switch(self.move_movetype)
+       {
+               case MOVETYPE_PUSH:
+               case MOVETYPE_FAKEPUSH:
+                       _Movetype_Physics_Pusher(movedt);
+                       break;
+               case MOVETYPE_NONE:
+                       break;
+               case MOVETYPE_FOLLOW:
+                       error("SV_Physics_Follow not implemented");
+                       break;
+               case MOVETYPE_NOCLIP:
+                       _Movetype_CheckWater(self);
+                       self.move_origin = self.move_origin + TICRATE * self.move_velocity;
+                       self.move_angles = self.move_angles + TICRATE * self.move_avelocity;
+                       _Movetype_LinkEdict(false);
+                       break;
+               case MOVETYPE_STEP:
+                       error("SV_Physics_Step not implemented");
+                       break;
+               case MOVETYPE_WALK:
+                       error("SV_Physics_Walk not implemented");
+                       break;
+               case MOVETYPE_TOSS:
+               case MOVETYPE_BOUNCE:
+               case MOVETYPE_BOUNCEMISSILE:
+               case MOVETYPE_FLYMISSILE:
+               case MOVETYPE_FLY:
+                       _Movetype_Physics_Toss(movedt);
+                       break;
+       }
+}
+
+void Movetype_Physics_NoMatchServer() // optimized
+{
+       float movedt;
+
+       movedt = time - self.move_time;
+       self.move_time = time;
+
+       _Movetype_Physics_Frame(movedt);
+       if(wasfreed(self))
+               return;
+
+       self.avelocity = self.move_avelocity;
+       self.velocity = self.move_velocity;
+       self.angles = self.move_angles;
+       setorigin(self, self.move_origin);
+}
+
+void Movetype_Physics_MatchServer(bool sloppy)
+{
+       Movetype_Physics_MatchTicrate(TICRATE, sloppy);
+}
+
+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;
+
+       movedt = tr;
+       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)
+       {
+               _Movetype_Physics_Frame(movedt);
+               if(wasfreed(self))
+                       return;
+       }
+
+       self.avelocity = self.move_avelocity;
+
+       if(dt > 0 && self.move_movetype != MOVETYPE_NONE && !(self.move_flags & FL_ONGROUND))
+       {
+               // now continue the move from move_time to time
+               self.velocity = self.move_velocity;
+
+               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.angles = self.move_angles + dt * self.avelocity;
+
+               if(sloppy || self.movetype == MOVETYPE_NOCLIP)
+               {
+                       setorigin(self, self.move_origin + dt * self.velocity);
+               }
+               else
+               {
+                       _Movetype_PushEntityTrace(dt * self.velocity);
+                       if(!trace_startsolid)
+                               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;
+                       }
+               }
+       }
+       else
+       {
+               self.velocity = self.move_velocity;
+               self.angles = self.move_angles;
+               setorigin(self, self.move_origin);
+       }
+}
diff --git a/qcsrc/common/movetypes.qh b/qcsrc/common/movetypes.qh
new file mode 100644 (file)
index 0000000..5fc0493
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef MOVETYPES_H
+#define MOVETYPES_H
+
+.float move_ltime;
+.void(void) move_think;
+.float move_nextthink;
+.void(void) move_blocked;
+
+.float move_movetype;
+.float move_time;
+.vector move_origin;
+.vector move_angles;
+.vector move_velocity;
+.vector move_avelocity;
+.int move_flags;
+.int move_watertype;
+.int move_waterlevel;
+.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
+
+// should match sv_gameplayfix_fixedcheckwatertransition
+float autocvar_cl_gameplayfix_fixedcheckwatertransition = 1;
+
+void Movetype_Physics_MatchTicrate(float tr, bool sloppy);
+void Movetype_Physics_MatchServer(bool sloppy);
+void Movetype_Physics_NoMatchServer();
+void _Movetype_LinkEdict(float touch_triggers);
+void _Movetype_LinkEdict_TouchAreaGrid();
+
+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_FOLLOW           = 12;
+const int MOVETYPE_FLY_WORLDONLY    = 33;
+
+const int FL_ITEM                   = 256;
+const int FL_ONGROUND                          = 512;
+#endif
+
+const int MOVETYPE_FAKEPUSH         = 13;
+
+const float MOVEFLAG_Q2AIRACCELERATE            = 1;
+const float MOVEFLAG_NOGRAVITYONGROUND          = 2;
+const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
+
+#ifdef CSQC
+// TODO: figure out server's version of this
+#define moveflags (getstati(STAT_MOVEFLAGS))
+#endif
+
+#endif
index 4225a19f03cb76e98b5afa198312d94f2c575cfc..855efff12c0c521d6675811592b49e765da80534 100644 (file)
@@ -3,7 +3,7 @@
        #include "../client/defs.qh"
        #include "nades.qh"
        #include "buffs.qh"
-       #include "../client/movetypes.qh"
+       #include "../common/movetypes.qh"
        #include "../server/tturrets/include/turrets_early.qh"
        #include "../client/main.qh"
        #include "../csqcmodellib/cl_model.qh"
index adf62cf2a827f9b97c088a17f55ca0c3b53ee092..4c33de568c3f2571586aa496ff94e02ab3d06a0c 100644 (file)
@@ -1,7 +1,7 @@
 // TODO: split target_push and put it in the target folder
 #ifdef SVQC
 #include "jumppads.qh"
-#include "../../../client/movetypes.qh"
+#include "../../movetypes.qh"
 
 void trigger_push_use()
 {
index 55fcc0e14ffa597cbfaace6da0d52f09a4329f4d..ea04ce1457c8f727c8f7cbf492eacf6502e8cc15 100644 (file)
@@ -17,7 +17,7 @@
        #include "../../client/autocvars.qh"
        #include "../deathtypes.qh"
        #include "../../csqcmodellib/interpolate.qh"
-       #include "../../client/movetypes.qh"
+       #include "../movetypes.qh"
        #include "../../client/main.qh"
        #include "../../csqcmodellib/cl_model.qh"
 #elif defined(MENUQC)
index eb784f6796f131391e7fa46e695c231639313222..af1cdefd4e26882ef25dd2cb511136992a5b5d8b 100644 (file)
@@ -25,7 +25,7 @@
     #include "g_hook.qh"
     #include "scores.qh"
     #include "spawnpoints.qh"
-       #include "../client/movetypes.qh"
+       #include "../common/movetypes.qh"
 #endif
 
 float Damage_DamageInfo_SendEntity(entity to, float sf)
index a040bff121a1caa1ced77eb096e189f6114041fc..5295dbb9b0e16b16ad325dc5cbb39ed23f4a73f1 100644 (file)
@@ -1,4 +1,4 @@
-#include "../../client/movetypes.qh"
+#include "../../common/movetypes.qh"
 
 void ctf_FakeTimeLimit(entity e, float t)
 {
index d407a4d66d664e0e8e1d74436ada61cb3606bce2..f1d38384a561d7af6d63c538be5014bf6f4e68c0 100644 (file)
@@ -74,8 +74,6 @@ weapons/tracing.qc
 weapons/weaponstats.qc
 weapons/weaponsystem.qc
 
-../client/movetypes.qc
-
 ../common/animdecide.qc
 ../common/buffs.qc
 ../common/campaign_file.qc
@@ -87,6 +85,7 @@ weapons/weaponsystem.qc
 ../common/monsters/monsters.qc
 ../common/monsters/spawn.qc
 ../common/monsters/sv_monsters.qc
+../common/movetypes.qc
 ../common/nades.qc
 ../common/net_notice.qc
 ../common/notifications.qc
index ba0ee4410daddd992a6567dd644412e07db7db34..143d7dc09e76cfd4f12e675732990c3d97e95438 100644 (file)
@@ -4,7 +4,7 @@
     #include "../common/buffs.qh"
     #include "../common/weapons/weapons.qh"
     #include "../client/autocvars.qh"
-    #include "../client/movetypes.qh"
+    #include "../common/movetypes.qh"
     #include "../client/main.qh"
     #include "../csqcmodellib/common.qh"
     #include "../csqcmodellib/cl_model.qh"