dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
//return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
vec3_t end;
vec_t len = 0;
- if(!VectorCompare(start, pEnd))
+ if (VectorCompare(start, pEnd))
+ return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
+
+ if(collision_endposnudge.value > 0)
{
// TRICK: make the trace 1 qu longer!
VectorSubtract(pEnd, start, end);
len = VectorNormalizeLength(end);
- VectorAdd(pEnd, end, end);
+ VectorMA(pEnd, collision_endposnudge.value, end, end);
}
else
VectorCopy(pEnd, end);
+#else
+ if (VectorCompare(start, end))
+ return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
#endif
//return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask);
- if (VectorCompare(start, end))
- return SV_TracePoint(start, type, passedict, hitsupercontentsmask);
-
VectorCopy(start, clipstart);
VectorCopy(end, clipend);
VectorClear(clipmins2);
finished:
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
- if(!VectorCompare(start, pEnd))
- Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd);
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
+ Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd);
#endif
return cliptrace;
}
dp_model_t *model;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
vec3_t end;
vec_t len = 0;
- if(!VectorCompare(start, pEnd))
+ if (VectorCompare(mins, maxs))
+ {
+ vec3_t shiftstart, shiftend;
+ VectorAdd(start, mins, shiftstart);
+ VectorAdd(pEnd, mins, shiftend);
+ if (VectorCompare(start, pEnd))
+ trace = SV_TracePoint(shiftstart, type, passedict, hitsupercontentsmask);
+ else
+ trace = SV_TraceLine(shiftstart, shiftend, type, passedict, hitsupercontentsmask);
+ VectorSubtract(trace.endpos, mins, trace.endpos);
+ return trace;
+ }
+
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
{
// TRICK: make the trace 1 qu longer!
VectorSubtract(pEnd, start, end);
len = VectorNormalizeLength(end);
- VectorAdd(pEnd, end, end);
+ VectorMA(pEnd, collision_endposnudge.value, end, end);
}
else
VectorCopy(pEnd, end);
-#endif
-
+#else
if (VectorCompare(mins, maxs))
{
vec3_t shiftstart, shiftend;
VectorSubtract(trace.endpos, mins, trace.endpos);
return trace;
}
+#endif
VectorCopy(start, clipstart);
VectorCopy(end, clipend);
finished:
#ifdef COLLISION_STUPID_TRACE_ENDPOS_IN_SOLID_WORKAROUND
- if(!VectorCompare(start, pEnd))
- Collision_ShortenTrace(&cliptrace, len / (len + 1), pEnd);
+ if(!VectorCompare(start, pEnd) && collision_endposnudge.value > 0)
+ Collision_ShortenTrace(&cliptrace, len / (len + collision_endposnudge.value), pEnd);
#endif
return cliptrace;
}
int frame;
// list of entities to test for collisions
int numtouchedicts;
- prvm_edict_t *touchedicts[MAX_EDICTS];
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
// get world supercontents at this point
if (sv.worldmodel && sv.worldmodel->PointSuperContents)
void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
{
int i, numtouchedicts, old_self, old_other;
- prvm_edict_t *touch, *touchedicts[MAX_EDICTS];
+ prvm_edict_t *touch;
+ static prvm_edict_t *touchedicts[MAX_EDICTS];
if (ent == prog->edicts)
return; // don't add the world
{
if (model != NULL)
{
- if (!model->TraceBox && developer.integer >= 1)
- Con_Printf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
+ if (!model->TraceBox)
+ Con_DPrintf("edict %i: SOLID_BSP with non-collidable model\n", PRVM_NUM_FOR_EDICT(ent));
if (ent->fields.server->angles[0] || ent->fields.server->angles[2] || ent->fields.server->avelocity[0] || ent->fields.server->avelocity[2])
{
*trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
bump = 0;
- while (trace->startsolid && sv_gameplayfix_nudgeoutofsolid.integer)
+ while (trace->bmodelstartsolid && sv_gameplayfix_nudgeoutofsolid.integer)
{
vec_t nudge = -trace->startdepth + sv_gameplayfix_nudgeoutofsolid_bias.value;
VectorMA(ent->fields.server->origin, nudge, trace->startdepthnormal, ent->fields.server->origin);
dp_model_t *pushermodel;
trace_t trace, trace2;
matrix4x4_t pusherfinalmatrix, pusherfinalimatrix;
- unsigned short moved_edicts[MAX_EDICTS];
+ static unsigned short moved_edicts[MAX_EDICTS];
if (!pusher->fields.server->velocity[0] && !pusher->fields.server->velocity[1] && !pusher->fields.server->velocity[2] && !pusher->fields.server->avelocity[0] && !pusher->fields.server->avelocity[1] && !pusher->fields.server->avelocity[2])
{
Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname), offset[0], offset[1], offset[2]);
return true;
case UNSTICK_STUCK:
- if (developer.integer >= 100)
- Con_Printf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+ if (developer_extra.integer)
+ Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
return false;
default:
Con_Printf("SV_UnstickEntityReturnOffset returned a value outside its enum.\n");
*/
void SV_WalkMove (prvm_edict_t *ent)
{
- int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask;
+ int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask, type;
vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity;
trace_t downtrace, trace;
qboolean applygravity;
clip = SV_FlyMove (ent, sv.frametime, applygravity, NULL, hitsupercontentsmask);
+ if(sv_gameplayfix_downtracesupportsongroundflag.integer)
+ if(!(clip & 1))
+ {
+ // only try this if there was no floor in the way in the trace (no,
+ // this check seems to be not REALLY necessary, because if clip & 1,
+ // our trace will hit that thing too)
+ VectorSet(upmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] + 1);
+ VectorSet(downmove, ent->fields.server->origin[0], ent->fields.server->origin[1], ent->fields.server->origin[2] - 1);
+ if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
+ type = MOVE_MISSILE;
+ else if (ent->fields.server->solid == SOLID_TRIGGER || ent->fields.server->solid == SOLID_NOT)
+ type = MOVE_NOMONSTERS; // only clip against bmodels
+ else
+ type = MOVE_NORMAL;
+ trace = SV_TraceBox(upmove, ent->fields.server->mins, ent->fields.server->maxs, downmove, type, ent, SV_GenericHitSuperContentsMask(ent));
+ if(trace.fraction < 1 && trace.plane.normal[2] > 0.7)
+ clip |= 1; // but we HAVE found a floor
+ }
+
// if the move did not hit the ground at any point, we're not on ground
- if (!(clip & 1))
+ if(!(clip & 1))
ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
SV_CheckVelocity(ent);