// clip to world
Collision_ClipPointToWorld(&cliptrace, sv.worldmodel, clipstart, hitsupercontentsmask);
- cliptrace.bmodelstartsolid = cliptrace.startsolid;
+ cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
if (cliptrace.startsolid || cliptrace.fraction < 1)
cliptrace.ent = prog->edicts;
if (type == MOVE_WORLDONLY)
// clip to world
Collision_ClipLineToWorld(&cliptrace, sv.worldmodel, clipstart, clipend, hitsupercontentsmask, false);
- cliptrace.bmodelstartsolid = cliptrace.startsolid;
+ cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
if (cliptrace.startsolid || cliptrace.fraction < 1)
cliptrace.ent = prog->edicts;
if (type == MOVE_WORLDONLY)
// clip to world
Collision_ClipToWorld(&cliptrace, sv.worldmodel, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
- cliptrace.bmodelstartsolid = cliptrace.startsolid;
+ cliptrace.worldstartsolid = cliptrace.bmodelstartsolid = cliptrace.startsolid;
if (cliptrace.startsolid || cliptrace.fraction < 1)
cliptrace.ent = prog->edicts;
if (type == MOVE_WORLDONLY)
vec3_t paddedmins, paddedmaxs;
if (maxedicts < 1 || resultedicts == NULL)
return 0;
- VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
- VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+ // LordHavoc: discovered this actually causes its own bugs (dm6 teleporters being too close to info_teleport_destination)
+ //VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
+ //VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+ VectorCopy(mins, paddedmins);
+ VectorCopy(maxs, paddedmaxs);
if (sv_areadebug.integer)
{
int numresultedicts = 0;
============
*/
static float SV_Gravity (prvm_edict_t *ent);
-static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink);
+static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean dolink);
#define MAX_CLIP_PLANES 5
static int SV_FlyMove (prvm_edict_t *ent, float time, qboolean applygravity, float *stepnormal, int hitsupercontentsmask, float stepheight)
{
int i, j, numplanes;
float d, time_left, gravity;
vec3_t dir, push, planes[MAX_CLIP_PLANES];
- prvm_vec3_t primal_velocity, original_velocity, new_velocity;
+ prvm_vec3_t primal_velocity, original_velocity, new_velocity, restore_velocity;
#if 0
vec3_t end;
#endif
return 0;
gravity = 0;
+ VectorCopy(PRVM_serveredictvector(ent, velocity), restore_velocity);
+
if(applygravity)
{
gravity = SV_Gravity(ent);
break;
VectorScale(PRVM_serveredictvector(ent, velocity), time_left, push);
- if(!SV_PushEntity(&trace, ent, push, false, false))
+ if(!SV_PushEntity(&trace, ent, push, false))
{
// we got teleported by a touch function
// let's abort the move
break;
}
+ // this code is used by MOVETYPE_WALK and MOVETYPE_STEP and SV_UnstickEntity
+ // abort move if we're stuck in the world (and didn't make it out)
+ if (trace.worldstartsolid && trace.allsolid)
+ {
+ VectorCopy(restore_velocity, PRVM_serveredictvector(ent, velocity));
+ return 3;
+ }
+
if (trace.fraction == 1)
break;
if (trace.plane.normal[2])
//Con_Printf("step %f %f %f : ", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
VectorSet(steppush, 0, 0, stepheight);
VectorCopy(PRVM_serveredictvector(ent, origin), org);
- if(!SV_PushEntity(&steptrace, ent, steppush, false, false))
+ if(!SV_PushEntity(&steptrace, ent, steppush, false))
{
blocked |= 8;
break;
}
//Con_Printf("%f %f %f : ", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- if(!SV_PushEntity(&steptrace2, ent, push, false, false))
+ if(!SV_PushEntity(&steptrace2, ent, push, false))
{
blocked |= 8;
break;
}
//Con_Printf("%f %f %f : ", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
VectorSet(steppush, 0, 0, org[2] - PRVM_serveredictvector(ent, origin)[2]);
- if(!SV_PushEntity(&steptrace3, ent, steppush, false, false))
+ if(!SV_PushEntity(&steptrace3, ent, steppush, false))
{
blocked |= 8;
break;
return true;
}
-static qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent)
+qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent)
{
prvm_prog_t *prog = SVVM_prog;
- int bump;
+ int bump, pass;
trace_t stucktrace;
vec3_t stuckorigin;
vec3_t stuckmins, stuckmaxs;
vec_t separation = sv_gameplayfix_nudgeoutofsolid_separation.value;
if (sv.worldmodel && sv.worldmodel->brushq1.numclipnodes)
separation = 0.0f; // when using hulls, it can not be enlarged
- VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin);
VectorCopy(PRVM_serveredictvector(ent, mins), stuckmins);
VectorCopy(PRVM_serveredictvector(ent, maxs), stuckmaxs);
stuckmins[0] -= separation;
stuckmaxs[0] += separation;
stuckmaxs[1] += separation;
stuckmaxs[2] += separation;
- for (bump = 0;bump < 10;bump++)
+ // first pass we try to get it out of brush entities
+ // second pass we try to get it out of world only (can't win them all)
+ for (pass = 0;pass < 2;pass++)
{
- stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
- if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
+ VectorCopy(PRVM_serveredictvector(ent, origin), stuckorigin);
+ for (bump = 0;bump < 10;bump++)
{
- // found a good location, use it
- VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin));
- return true;
+ stucktrace = SV_TraceBox(stuckorigin, stuckmins, stuckmaxs, stuckorigin, pass ? MOVE_WORLDONLY : MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
+ if (!stucktrace.bmodelstartsolid || stucktrace.startdepth >= 0)
+ {
+ // found a good location, use it
+ VectorCopy(stuckorigin, PRVM_serveredictvector(ent, origin));
+ return true;
+ }
+ nudge = -stucktrace.startdepth;
+ VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin);
}
- nudge = -stucktrace.startdepth;
- VectorMA(stuckorigin, nudge, stucktrace.startdepthnormal, stuckorigin);
}
return false;
}
Returns true if the push did not result in the entity being teleported by QC code.
============
*/
-static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
+static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean dolink)
{
prvm_prog_t *prog = SVVM_prog;
int solid;
type = MOVE_NORMAL;
*trace = SV_TraceBox(start, mins, maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
- if (trace->bmodelstartsolid && failonbmodelstartsolid)
+ // fail the move if stuck in world
+ if (trace->worldstartsolid)
return true;
VectorCopy(trace->endpos, PRVM_serveredictvector(ent, origin));
// try moving the contacted entity
PRVM_serveredictfloat(pusher, solid) = SOLID_NOT;
- if(!SV_PushEntity (&trace, check, move, true, true))
+ if(!SV_PushEntity (&trace, check, move, true))
{
// entity "check" got teleported
PRVM_serveredictvector(check, angles)[1] += trace.fraction * moveangle[1];
{
// hack to invoke all necessary movement triggers
VectorClear(move2);
- if(!SV_PushEntity(&trace2, check, move2, true, true))
+ if(!SV_PushEntity(&trace2, check, move2, true))
{
// entity "check" got teleported
continue;
return;
// only step up while jumping if that is enabled
- if (!(sv_jumpstep.integer && sv_gameplayfix_stepwhilejumping.integer))
+ if (sv_jumpstep.integer)
if (!oldonground && PRVM_serveredictfloat(ent, waterlevel) == 0)
return;
}
// move up
VectorClear (upmove);
upmove[2] = sv_stepheight.value;
- if(!SV_PushEntity(&trace, ent, upmove, false, true))
+ if(!SV_PushEntity(&trace, ent, upmove, true))
{
// we got teleported when upstepping... must abort the move
return;
// move down
VectorClear (downmove);
downmove[2] = -sv_stepheight.value + start_velocity[2]*sv.frametime;
- if(!SV_PushEntity (&downtrace, ent, downmove, false, true))
+ if(!SV_PushEntity (&downtrace, ent, downmove, true))
{
// we got teleported when downstepping... must abort the move
return;
{
// move origin
VectorScale(PRVM_serveredictvector(ent, velocity), movetime, move);
- if(!SV_PushEntity(&trace, ent, move, true, true))
+ if(!SV_PushEntity(&trace, ent, move, true))
return; // teleported
if (ent->priv.server->free)
return;
- if (trace.bmodelstartsolid)
+ if (trace.bmodelstartsolid && sv_gameplayfix_unstickentities.integer)
{
// try to unstick the entity
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
- if(!SV_PushEntity(&trace, ent, move, false, true))
+ SV_UnstickEntity(ent);
+ if(!SV_PushEntity(&trace, ent, move, true))
return; // teleported
if (ent->priv.server->free)
return;
{
prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
- if (!host_client->spawned)
+ if (!host_client->begun)
return;
// make sure the velocity is sane (not a NaN)
{
prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
- if (!host_client->spawned)
+ if (!host_client->begun)
return;
// make sure the velocity is sane (not a NaN)
{
prvm_prog_t *prog = SVVM_prog;
// don't do physics on disconnected clients, FrikBot relies on this
- if (!host_client->spawned)
+ if (!host_client->begun)
{
memset(&host_client->cmd, 0, sizeof(host_client->cmd));
return;