-const float STAT_MOVEFLAGS = 225;
-const float MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE = 4;
-#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
-
-.entity move_groundentity; // FIXME add move_groundnetworkentity?
-.float move_suspendedinair;
-.float move_didgravity;
-
-void _Movetype_CheckVelocity() // SV_CheckVelocity
-{
-}
-
-#if 0
-int Mod_Q1BSP_SuperContentsFromNativeContents(dp_model_t *model, int nativecontents)
-{
- switch(nativecontents)
- {
- case CONTENTS_EMPTY:
- return 0;
- case CONTENTS_SOLID:
- return SUPERCONTENTS_SOLID | SUPERCONTENTS_OPAQUE;
- case CONTENTS_WATER:
- return SUPERCONTENTS_WATER;
- case CONTENTS_SLIME:
- return SUPERCONTENTS_SLIME;
- case CONTENTS_LAVA:
- return SUPERCONTENTS_LAVA | SUPERCONTENTS_NODROP;
- case CONTENTS_SKY:
- return SUPERCONTENTS_SKY | SUPERCONTENTS_NODROP | SUPERCONTENTS_OPAQUE; // to match behaviour of Q3 maps, let sky count as opaque
- }
- return 0;
-}
-int Mod_Q1BSP_NativeContentsFromSuperContents(dp_model_t *model, int supercontents)
-{
- if (supercontents & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY))
- return CONTENTS_SOLID;
- if (supercontents & SUPERCONTENTS_SKY)
- return CONTENTS_SKY;
- if (supercontents & SUPERCONTENTS_LAVA)
- return CONTENTS_LAVA;
- if (supercontents & SUPERCONTENTS_SLIME)
- return CONTENTS_SLIME;
- if (supercontents & SUPERCONTENTS_WATER)
- return CONTENTS_WATER;
- return CONTENTS_EMPTY;
-}
-static qboolean SV_CheckWater (prvm_edict_t *ent)
-{
- prvm_prog_t *prog = SVVM_prog;
- int cont;
- int nNativeContents;
- vec3_t point;
-
- point[0] = PRVM_serveredictvector(ent, origin)[0];
- point[1] = PRVM_serveredictvector(ent, origin)[1];
- point[2] = PRVM_serveredictvector(ent, origin)[2] + PRVM_serveredictvector(ent, mins)[2] + 1;
-
- // DRESK - Support for Entity Contents Transition Event
- // NOTE: Some logic needed to be slightly re-ordered
- // to not affect performance and allow for the feature.
-
- // Acquire Super Contents Prior to Resets
- cont = SV_PointSuperContents(point);
- // Acquire Native Contents Here
- nNativeContents = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, cont);
-
- // DRESK - Support for Entity Contents Transition Event
- if(PRVM_serveredictfloat(ent, watertype))
- // Entity did NOT Spawn; Check
- SV_CheckContentsTransition(ent, nNativeContents);
-
-
- PRVM_serveredictfloat(ent, waterlevel) = 0;
- PRVM_serveredictfloat(ent, watertype) = CONTENTS_EMPTY;
- cont = SV_PointSuperContents(point);
- if (cont & (SUPERCONTENTS_LIQUIDSMASK))
- {
- PRVM_serveredictfloat(ent, watertype) = nNativeContents;
- PRVM_serveredictfloat(ent, waterlevel) = 1;
- point[2] = PRVM_serveredictvector(ent, origin)[2] + (PRVM_serveredictvector(ent, mins)[2] + PRVM_serveredictvector(ent, maxs)[2])*0.5;
- if (SV_PointSuperContents(point) & (SUPERCONTENTS_LIQUIDSMASK))
- {
- PRVM_serveredictfloat(ent, waterlevel) = 2;
- point[2] = PRVM_serveredictvector(ent, origin)[2] + PRVM_serveredictvector(ent, view_ofs)[2];
- if (SV_PointSuperContents(point) & (SUPERCONTENTS_LIQUIDSMASK))
- PRVM_serveredictfloat(ent, waterlevel) = 3;
- }
- }
+#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
- return PRVM_serveredictfloat(ent, waterlevel) > 1;
-}
-static int SV_CheckContentsTransition(prvm_edict_t *ent, const int nContents)
-{
- prvm_prog_t *prog = SVVM_prog;
- int bValidFunctionCall;
-
- // Default Valid Function Call to False
- bValidFunctionCall = false;
-
- if(PRVM_serveredictfloat(ent, watertype) != nContents)
- { // Changed Contents
- // Acquire Contents Transition Function from QC
- if(PRVM_serveredictfunction(ent, contentstransition))
- { // Valid Function; Execute
- // Assign Valid Function
- bValidFunctionCall = true;
- // Prepare Parameters (Original Contents, New Contents)
- // Original Contents
- PRVM_G_FLOAT(OFS_PARM0) = PRVM_serveredictfloat(ent, watertype);
- // New Contents
- PRVM_G_FLOAT(OFS_PARM1) = nContents;
- // Assign Self
- PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(ent);
- // Set Time
- PRVM_serverglobalfloat(time) = sv.time;
- // Execute VM Function
- prog->ExecuteProgram(prog, PRVM_serveredictfunction(ent, contentstransition), "contentstransition: NULL function");
- }
- }
- // Return if Function Call was Valid
- return bValidFunctionCall;
-}
+#ifdef SVQC
+#define GRAVITY_UNAFFECTED_BY_TICRATE autocvar_sv_gameplayfix_gravityunaffectedbyticrate
-static void SV_CheckWaterTransition (prvm_edict_t *ent)
-{
- vec3_t entorigin;
- prvm_prog_t *prog = SVVM_prog;
- // LordHavoc: bugfixes in this function are keyed to the sv_gameplayfix_bugfixedcheckwatertransition cvar - if this cvar is 0 then all the original bugs should be reenabled for compatibility
- int cont;
- VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
- cont = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(entorigin));
- if (!PRVM_serveredictfloat(ent, watertype))
- {
- // just spawned here
- if (!sv_gameplayfix_fixedcheckwatertransition.integer)
- {
- PRVM_serveredictfloat(ent, watertype) = cont;
- PRVM_serveredictfloat(ent, waterlevel) = 1;
- return;
- }
- }
- // DRESK - Support for Entity Contents Transition Event
- // NOTE: Call here BEFORE updating the watertype below,
- // and suppress watersplash sound if a valid function
- // call was made to allow for custom "splash" sounds.
- else if( !SV_CheckContentsTransition(ent, cont) )
- { // Contents Transition Function Invalid; Potentially Play Water Sound
- // check if the entity crossed into or out of water
- if (sv_sound_watersplash.string && ((PRVM_serveredictfloat(ent, watertype) == CONTENTS_WATER || PRVM_serveredictfloat(ent, watertype) == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
- SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false, 1.0f);
- }
+#define TICRATE sys_frametime
+#elif defined(CSQC)
+#define GRAVITY_UNAFFECTED_BY_TICRATE (getstati(STAT_MOVEFLAGS) & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)
- if (cont <= CONTENTS_WATER)
- {
- PRVM_serveredictfloat(ent, watertype) = cont;
- PRVM_serveredictfloat(ent, waterlevel) = 1;
- }
- else
- {
- PRVM_serveredictfloat(ent, watertype) = CONTENTS_EMPTY;
- PRVM_serveredictfloat(ent, waterlevel) = sv_gameplayfix_fixedcheckwatertransition.integer ? 0 : cont;
- }
-}
+#define TICRATE ticrate
#endif
-.float watertype;
-.float waterlevel;
-float Mod_Q1BSP_SuperContentsFromNativeContents(float nativecontents)
-{
- switch(nativecontents)
- {
- case CONTENT_EMPTY:
- return 0;
- case CONTENT_SOLID:
- return DPCONTENTS_SOLID | DPCONTENTS_OPAQUE;
- case CONTENT_WATER:
- return DPCONTENTS_WATER;
- case CONTENT_SLIME:
- return DPCONTENTS_SLIME;
- case CONTENT_LAVA:
- return DPCONTENTS_LAVA | DPCONTENTS_NODROP;
- case CONTENT_SKY:
- return DPCONTENTS_SKY | DPCONTENTS_NODROP | DPCONTENTS_OPAQUE; // to match behaviour of Q3 maps, let sky count as opaque
- }
- return 0;
-}
+.entity move_groundentity; // FIXME add move_groundnetworkentity?
+.float move_suspendedinair;
+.float move_didgravity;
-float Mod_Q1BSP_NativeContentsFromSuperContents(float supercontents)
+void _Movetype_CheckVelocity() // SV_CheckVelocity
{
- if (supercontents & (DPCONTENTS_SOLID | DPCONTENTS_BODY))
- return CONTENT_SOLID;
- if (supercontents & DPCONTENTS_SKY)
- return CONTENT_SKY;
- if (supercontents & DPCONTENTS_LAVA)
- return CONTENT_LAVA;
- if (supercontents & DPCONTENTS_SLIME)
- return CONTENT_SLIME;
- if (supercontents & DPCONTENTS_WATER)
- return CONTENT_WATER;
- return CONTENT_EMPTY;
}
float _Movetype_CheckWater(entity ent) // SV_CheckWater
{
- float contents;
- float nativecontents;
- vector point;
-
- point = ent.move_origin;
+ vector point = ent.move_origin;
point_z += (ent.mins_z + 1);
- contents = pointcontents(point);
- nativecontents = Mod_Q1BSP_NativeContentsFromSuperContents(contents);
+ int nativecontents = pointcontents(point);
- if(ent.watertype)
- if(ent.watertype != nativecontents)
+ if(ent.move_watertype)
+ if(ent.move_watertype != nativecontents)
{
- print(sprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.watertype, nativecontents));
- //ent.contentstransition(ent.watertype, contents);
+ //print(sprintf("_Movetype_CheckWater(): Original: '%d', New: '%d'\n", ent.move_watertype, nativecontents));
+ if(ent.contentstransition)
+ ent.contentstransition(ent.move_watertype, nativecontents);
}
- ent.waterlevel = 0;
- ent.watertype = CONTENT_EMPTY;
-
- contents = pointcontents(point);
- if(contents & DPCONTENTS_LIQUIDSMASK)
+ ent.move_waterlevel = 0;
+ ent.move_watertype = CONTENT_EMPTY;
+
+ int supercontents = Mod_Q1BSP_SuperContentsFromNativeContents(nativecontents);
+ if(supercontents & DPCONTENTS_LIQUIDSMASK)
{
- ent.watertype = nativecontents;
- ent.waterlevel = 1;
+ ent.move_watertype = nativecontents;
+ ent.move_waterlevel = 1;
point_y = (ent.origin_y + ((ent.mins_z + ent.maxs_y) * 0.5));
- if(pointcontents(point) & DPCONTENTS_LIQUIDSMASK)
+ if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
{
- ent.waterlevel = 2;
+ ent.move_waterlevel = 2;
point_y = ent.origin_y + ent.view_ofs_y;
- if(pointcontents(point) & DPCONTENTS_LIQUIDSMASK)
- ent.waterlevel = 3;
+ if(Mod_Q1BSP_SuperContentsFromNativeContents(pointcontents(point)) & DPCONTENTS_LIQUIDSMASK)
+ ent.move_waterlevel = 3;
}
}
- return (ent.waterlevel > 1);
+ return (ent.move_waterlevel > 1);
}
-#if 0
-void _Movetype_CheckContentsTransition(entity ent, float contents)
-{
- if(ent.watertype != contents)
- {
- print(sprintf("_Movetype_CheckWaterTransition(): Original: '%d', New: '%d'\n", ent.watertype, contents));
- //ent.contentstransition(ent.watertype, contents);
- }
-}
-#endif
-
-float autocvar_sv_gameplayfix_fixedcheckwatertransition;
void _Movetype_CheckWaterTransition(entity ent) // SV_CheckWaterTransition
{
- float contents = Mod_Q1BSP_NativeContentsFromSuperContents(pointcontents(ent.move_origin));
-
- if(!ent.watertype)
+ float contents = pointcontents(ent.move_origin);
+
+ if(!ent.move_watertype)
{
// just spawned here
- if(!autocvar_sv_gameplayfix_fixedcheckwatertransition)
+ if(!autocvar_cl_gameplayfix_fixedcheckwatertransition)
{
- ent.watertype = contents;
- ent.waterlevel = 1;
+ ent.move_watertype = contents;
+ ent.move_waterlevel = 1;
return;
}
}
- //else if(!_Movetype_CheckContentsTransition(ent, contents))
- //{
- //if (sv_sound_watersplash.string && ((PRVM_serveredictfloat(ent, watertype) == CONTENTS_WATER || PRVM_serveredictfloat(ent, watertype) == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
- // SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false, 1.0f);
- //}
- else if(ent.watertype != contents)
+ else if(ent.move_watertype != contents)
{
- print(sprintf("_Movetype_CheckWaterTransition(): Original: '%d', New: '%d'\n", ent.watertype, contents));
- //ent.contentstransition(ent.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.watertype = contents;
- ent.waterlevel = 1;
+ ent.move_watertype = contents;
+ ent.move_waterlevel = 1;
}
else
{
- ent.watertype = CONTENT_EMPTY;
- ent.waterlevel = (autocvar_sv_gameplayfix_fixedcheckwatertransition ? 0 : contents);
+ ent.move_watertype = CONTENT_EMPTY;
+ ent.move_waterlevel = (autocvar_cl_gameplayfix_fixedcheckwatertransition ? 0 : contents);
}
}
self = e;
other = oldself;
- trace_allsolid = FALSE;
- trace_startsolid = FALSE;
+ trace_allsolid = false;
+ trace_startsolid = false;
trace_fraction = 1;
- trace_inwater = FALSE;
- trace_inopen = TRUE;
+ trace_inwater = false;
+ trace_inopen = true;
trace_endpos = e.origin;
trace_plane_normal = '0 0 1';
trace_plane_dist = 0;
float _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
{
vector org;
- float cont;
org = self.move_origin + ofs;
- cont = self.dphitcontentsmask;
+ 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;
+ return true;
if(vlen(trace_endpos - self.move_origin) > 0.0001)
self.move_origin = trace_endpos;
- return FALSE;
+ return false;
}
float _Movetype_UnstickEntity() // SV_UnstickEntity
{
if(!_Movetype_TestEntityPosition('0 0 0'))
- return TRUE;
+ 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 0 -1' * i)) goto success;
if(!_Movetype_TestEntityPosition('0 0 1' * i)) goto success;
}
- dprint(sprintf(_("Can't unstick an entity (edict: %d, classname: %s, origin: %s)\n"), num_for_edict(self), self.classname, vtos(self.move_origin)));
- return FALSE;
+ 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
- dprint(sprintf(_("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;
+ 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
return trace_fraction;
}
-#define MAX_CLIP_PLANES 5
+
+.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)
}
}
- self.move_suspendedinair = FALSE;
+ self.move_suspendedinair = false;
_Movetype_CheckVelocity();
if(GRAVITY_UNAFFECTED_BY_TICRATE)
{
if(self.gravity)
- self.move_velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
else
- self.move_velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
}
else
{
if(self.gravity)
- self.move_velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= dt * self.gravity * PHYS_GRAVITY;
else
- self.move_velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= dt * PHYS_GRAVITY;
}
}
{
vector move;
move = self.move_velocity * movetime;
- _Movetype_PushEntity(move, TRUE);
+ _Movetype_PushEntity(move, true);
if(wasfreed(self))
return;
if(trace_startsolid)
{
_Movetype_UnstickEntity();
- _Movetype_PushEntity(move, FALSE);
+ _Movetype_PushEntity(move, false);
if(wasfreed(self))
return;
}
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 * getstatf(STAT_MOVEVARS_GRAVITY);
+ bouncestop *= self.gravity * PHYS_GRAVITY;
else
- bouncestop *= getstatf(STAT_MOVEVARS_GRAVITY);
+ bouncestop *= PHYS_GRAVITY;
self.move_velocity = _Movetype_ClipVelocity(self.move_velocity, trace_plane_normal, 1 + bouncefac);
self.move_flags |= FL_ONGROUND;
self.move_groundentity = trace_ent;
if(trace_ent.solid == SOLID_BSP)
- self.move_suspendedinair = TRUE;
+ self.move_suspendedinair = true;
self.move_velocity = '0 0 0';
self.move_avelocity = '0 0 0';
}
if(!(self.move_flags & FL_ONGROUND))
{
if(self.gravity)
- self.move_velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
else
- self.move_velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.move_velocity_z -= 0.5 * dt * PHYS_GRAVITY;
}
_Movetype_CheckWaterTransition(self);
{
case MOVETYPE_PUSH:
case MOVETYPE_FAKEPUSH:
- error("SV_Physics_Pusher not implemented");
+ _Movetype_Physics_Pusher(movedt);
break;
case MOVETYPE_NONE:
break;
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);
+ 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");
setorigin(self, self.move_origin);
}
-void Movetype_Physics_MatchServer(float sloppy)
+void Movetype_Physics_MatchServer(bool sloppy)
{
- Movetype_Physics_MatchTicrate(ticrate, sloppy);
+ Movetype_Physics_MatchTicrate(TICRATE, sloppy);
}
-void Movetype_Physics_MatchTicrate(float tr, float sloppy) // SV_Physics_Entity
+void Movetype_Physics_MatchTicrate(float tr, bool sloppy) // SV_Physics_Entity
{
float n, i, dt, movedt;
if(GRAVITY_UNAFFECTED_BY_TICRATE)
{
if(self.gravity)
- self.velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
else
- self.velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
}
else
{
if(self.gravity)
- self.velocity_z -= dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= dt * self.gravity * PHYS_GRAVITY;
else
- self.velocity_z -= dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= dt * PHYS_GRAVITY;
}
}
if(GRAVITY_UNAFFECTED_BY_TICRATE)
{
if(self.gravity)
- self.velocity_z -= 0.5 * dt * self.gravity * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= 0.5 * dt * self.gravity * PHYS_GRAVITY;
else
- self.velocity_z -= 0.5 * dt * getstatf(STAT_MOVEVARS_GRAVITY);
+ self.velocity_z -= 0.5 * dt * PHYS_GRAVITY;
}
}
}