this.move_movetype = mt;
if (mt == MOVETYPE_PHYSICS) {
this.move_qcphysics = false;
+ } else if (autocvar_sv_qcphysics == 2) {
+ this.move_qcphysics = true;
}
if(!IL_CONTAINS(g_moveables, this))
IL_PUSH(g_moveables, this); // add it to the moveable entities list (even if it doesn't move!) logic: if an object never sets its movetype, we assume it never does anything notable
return 0;
int blockedflag = 0;
- int i, j, numplanes = 0;
+ int numplanes = 0;
float time_left = dt, grav = 0;
vector push;
vector primal_velocity, original_velocity;
vector restore_velocity = this.velocity;
- for(i = 0; i < MAX_CLIP_PLANES; ++i)
- planes[i] = '0 0 0';
+ for(int j = 0; j < MAX_CLIP_PLANES; ++j)
+ planes[j] = '0 0 0';
if(applygravity)
{
break;
push = this.velocity * time_left;
- if(!_Movetype_PushEntity(this, push, true, false))
+ if(!_Movetype_PushEntity(this, push, false))
{
// we got teleported by a touch function
// let's abort the move
if(trace_fraction == 1)
break;
+ time_left *= 1 - trace_fraction;
+
float my_trace_fraction = trace_fraction;
vector my_trace_plane_normal = trace_plane_normal;
{
// step - handle it immediately
vector org = this.origin;
- vector steppush = '0 0 1' * stepheight;
+ vector steppush = vec3(0, 0, stepheight);
+ push = this.velocity * time_left;
- if(!_Movetype_PushEntity(this, steppush, true, false))
+ if(!_Movetype_PushEntity(this, steppush, false))
{
blockedflag |= 8;
break;
}
- if(!_Movetype_PushEntity(this, push, true, false))
+ if(!_Movetype_PushEntity(this, push, false))
{
blockedflag |= 8;
break;
}
float trace2_fraction = trace_fraction;
steppush = vec3(0, 0, org.z - this.origin_z);
- if(!_Movetype_PushEntity(this, steppush, true, false))
+ if(!_Movetype_PushEntity(this, steppush, false))
{
blockedflag |= 8;
break;
}
// accept the new position if it made some progress...
- if(fabs(this.origin_x - org.x) >= 0.03125 || fabs(this.origin_y - org.y) >= 0.03125)
+ // previously this checked if absolute distance >= 0.03125 which made stepping up unreliable
+ if(this.origin_x - org.x || this.origin_y - org.y)
{
trace_endpos = this.origin;
time_left *= 1 - trace2_fraction;
numplanes = 0;
}
- time_left *= 1 - my_trace_fraction;
-
// clipped to another plane
if(numplanes >= MAX_CLIP_PLANES)
{
// modify original_velocity so it parallels all of the clip planes
vector new_velocity = '0 0 0';
- for (i = 0;i < numplanes;i++)
+ int plane;
+ for (plane = 0;plane < numplanes;plane++)
{
- new_velocity = _Movetype_ClipVelocity(original_velocity, planes[i], 1);
- for (j = 0;j < numplanes;j++)
+ int newplane;
+ new_velocity = _Movetype_ClipVelocity(original_velocity, planes[plane], 1);
+ for (newplane = 0;newplane < numplanes;newplane++)
{
- if(j != i)
+ if(newplane != plane)
{
// not ok
- if((new_velocity * planes[j]) < 0)
+ if((new_velocity * planes[newplane]) < 0)
break;
}
}
- if(j == numplanes)
+ if(newplane == numplanes)
break;
}
- if(i != numplanes)
+ if(plane != numplanes)
{
// go along this plane
this.velocity = new_velocity;
}
vector dir = cross(planes[0], planes[1]);
// 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;
+ dir = normalize(dir);
float d = (dir * this.velocity);
this.velocity = dir * d;
}
if(!this && !oth)
return;
+ // due to a lack of pointers in QC, we must save the trace values and restore them for other functions
+ bool save_trace_allsolid = trace_allsolid;
+ bool save_trace_startsolid = trace_startsolid;
+ float save_trace_fraction = trace_fraction;
+ bool save_trace_inwater = trace_inwater;
+ bool save_trace_inopen = trace_inopen;
+ vector save_trace_endpos = trace_endpos;
+ vector save_trace_plane_normal = trace_plane_normal;
+ float save_trace_plane_dist = trace_plane_dist;
+ entity save_trace_ent = trace_ent;
+ int save_trace_dpstartcontents = trace_dpstartcontents;
+ int save_trace_dphitcontents = trace_dphitcontents;
+ int save_trace_dphitq3surfaceflags = trace_dphitq3surfaceflags;
+ string save_trace_dphittexturename = trace_dphittexturename;
+
if(this.solid != SOLID_NOT && gettouch(this))
gettouch(this)(this, oth);
if(oth.solid != SOLID_NOT && gettouch(oth))
gettouch(oth)(oth, this);
+
+ trace_allsolid = save_trace_allsolid;
+ trace_startsolid = save_trace_startsolid;
+ trace_fraction = save_trace_fraction;
+ trace_inwater = save_trace_inwater;
+ trace_inopen = save_trace_inopen;
+ trace_endpos = save_trace_endpos;
+ trace_plane_normal = save_trace_plane_normal;
+ trace_plane_dist = save_trace_plane_dist;
+ trace_ent = save_trace_ent;
+ trace_dpstartcontents = save_trace_dpstartcontents;
+ trace_dphitcontents = save_trace_dphitcontents;
+ trace_dphitq3surfaceflags = save_trace_dphitq3surfaceflags;
+ trace_dphittexturename = save_trace_dphittexturename;
}
void _Movetype_LinkEdict_TouchAreaGrid(entity this) // SV_LinkEdict_TouchAreaGrid
if(this.solid == SOLID_NOT)
return;
+ // due to a lack of pointers in QC, we must save the trace values and restore them for other functions
+ bool save_trace_allsolid = trace_allsolid;
+ bool save_trace_startsolid = trace_startsolid;
+ float save_trace_fraction = trace_fraction;
+ bool save_trace_inwater = trace_inwater;
+ bool save_trace_inopen = trace_inopen;
+ vector save_trace_endpos = trace_endpos;
+ vector save_trace_plane_normal = trace_plane_normal;
+ float save_trace_plane_dist = trace_plane_dist;
+ entity save_trace_ent = trace_ent;
+ int save_trace_dpstartcontents = trace_dpstartcontents;
+ int save_trace_dphitcontents = trace_dphitcontents;
+ int save_trace_dphitq3surfaceflags = trace_dphitq3surfaceflags;
+ string save_trace_dphittexturename = trace_dphittexturename;
+
FOREACH_ENTITY_RADIUS_ORDERED(0.5 * (this.absmin + this.absmax), 0.5 * vlen(this.absmax - this.absmin), true, {
if (it.solid == SOLID_TRIGGER && it != this)
if (it.move_nomonsters != MOVE_NOMONSTERS && it.move_nomonsters != MOVE_WORLDONLY)
gettouch(it)(it, this);
}
});
+
+ trace_allsolid = save_trace_allsolid;
+ trace_startsolid = save_trace_startsolid;
+ trace_fraction = save_trace_fraction;
+ trace_inwater = save_trace_inwater;
+ trace_inopen = save_trace_inopen;
+ trace_endpos = save_trace_endpos;
+ trace_plane_normal = save_trace_plane_normal;
+ trace_plane_dist = save_trace_plane_dist;
+ trace_ent = save_trace_ent;
+ trace_dpstartcontents = save_trace_dpstartcontents;
+ trace_dphitcontents = save_trace_dphitcontents;
+ trace_dphitq3surfaceflags = save_trace_dphitq3surfaceflags;
+ trace_dphittexturename = save_trace_dphittexturename;
}
bool autocvar__movetype_debug = false;
}
}
-vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
+vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // ClipVelocity
{
vel -= ((vel * norm) * norm) * f;
tracebox(this.origin, this.mins, this.maxs, end, type, this);
}
-bool _Movetype_PushEntity(entity this, vector push, bool failonstartsolid, bool dolink) // SV_PushEntity
+bool _Movetype_PushEntity(entity this, vector push, bool dolink) // SV_PushEntity
{
_Movetype_PushEntityTrace(this, push);
// NOTE: this is a workaround for the QC's lack of a worldstartsolid trace parameter
- if(trace_startsolid && failonstartsolid)
+ if(trace_startsolid)
{
int oldtype = this.move_nomonsters;
this.move_nomonsters = MOVE_WORLDONLY;
case MOVETYPE_FLY:
case MOVETYPE_FLY_WORLDONLY:
_Movetype_Physics_Toss(this, movedt);
- if(wasfreed(this))
- return;
- _Movetype_LinkEdict(this, true);
break;
case MOVETYPE_PHYSICS:
break;
this.angles = this.angles + movedt * this.avelocity;
break;
case MOVETYPE_STEP:
- if (GAMEPLAYFIX_UNSTICKPLAYERS(this) == 2)
- _Movetype_CheckStuck(this);
_Movetype_Physics_Step(this, movedt);
break;
case MOVETYPE_WALK:
case MOVETYPE_FLY:
case MOVETYPE_FLY_WORLDONLY:
- if (movedt > 0 && GAMEPLAYFIX_UNSTICKPLAYERS(this) == 2)
- _Movetype_CheckStuck(this);
_Movetype_Physics_Walk(this, movedt);
break;
case MOVETYPE_TOSS: