}
else if (passedict->fields.server->solid == SOLID_CORPSE)
return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+ else if (passedict->fields.server->solid == SOLID_TRIGGER)
+ return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
else
return SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
}
#endif
{
vec3_t hullmins, hullmaxs;
- int i;
+ int i, bodysupercontents;
int passedictprog;
qboolean pointtrace;
prvm_edict_t *traceowner, *touch;
continue;
}
+ bodysupercontents = touch->fields.server->solid == SOLID_CORPSE ? SUPERCONTENTS_CORPSE : SUPERCONTENTS_BODY;
+
// might interact, so do an exact clip
model = NULL;
if ((int) touch->fields.server->solid == SOLID_BSP || type == MOVE_HITMODEL)
// if the modelindex is 0, it shouldn't be SOLID_BSP!
if (modelindex > 0 && modelindex < MAX_MODELS)
model = sv.models[(int)touch->fields.server->modelindex];
- Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
}
+ if (model)
+ Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
else
Matrix4x4_CreateTranslate(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2]);
Matrix4x4_Invert_Simple(&imatrix, &matrix);
if ((int)touch->fields.server->flags & FL_MONSTER)
- Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins2, clipmaxs2, clipend, hitsupercontentsmask);
else
- Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, SUPERCONTENTS_BODY, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+ Collision_ClipToGenericEntity(&trace, model, touch->fields.server->frame, touch->fields.server->mins, touch->fields.server->maxs, bodysupercontents, &matrix, &imatrix, clipstart, clipmins, clipmaxs, clipend, hitsupercontentsmask);
+
Collision_CombineTraces(&cliptrace, &trace, (void *)touch, touch->fields.server->solid == SOLID_BSP);
}
trace.ent = prog->edicts;
}
- if (((int) ent->fields.server->flags & FL_ONGROUND) && ent->fields.server->groundentity == PRVM_EDICT_TO_PROG(trace.ent))
- impact = false;
- else
- {
- ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
- impact = true;
- }
+ impact = !((int) ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace.ent);
if (trace.plane.normal[2])
{
continue;
// if the entity is standing on the pusher, it will definitely be moved
- if (((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher)
- {
- // remove the onground flag for non-players
- if (check->fields.server->movetype != MOVETYPE_WALK)
- check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND;
- }
- else
+ // if the entity is not standing on the pusher, but is in the pusher's
+ // final position, move it
+ if (!((int)check->fields.server->flags & FL_ONGROUND) || PRVM_PROG_TO_EDICT(check->fields.server->groundentity) != pusher)
{
- // if the entity is not inside the pusher's final position, leave it alone
Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
if (!trace.startsolid)
continue;
pusher->fields.server->solid = savesolid; // was SOLID_BSP
//Con_Printf("%s:%d frac %f startsolid %d bmodelstartsolid %d allsolid %d\n", __FILE__, __LINE__, trace.fraction, trace.startsolid, trace.bmodelstartsolid, trace.allsolid);
+ // this check is for items riding platforms that are passing under (or
+ // through) walls intended to knock the items off
+ if (trace.fraction < 1 && check->fields.server->movetype != MOVETYPE_WALK)
+ check->fields.server->flags = (int)check->fields.server->flags & ~FL_ONGROUND;
+
// if it is still inside the pusher, block
Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
if (trace.startsolid)
*/
void SV_WalkMove (prvm_edict_t *ent)
{
- int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity;
+ int clip, oldonground, originalmove_clip, originalmove_flags, originalmove_groundentity, hitsupercontentsmask;
vec3_t upmove, downmove, start_origin, start_velocity, stepnormal, originalmove_origin, originalmove_velocity;
trace_t downtrace;
if (sv.frametime <= 0)
return;
+ hitsupercontentsmask = SV_GenericHitSuperContentsMask(ent);
+
SV_CheckVelocity(ent);
// do a regular slide move unless it looks like you ran into a step
oldonground = (int)ent->fields.server->flags & FL_ONGROUND;
- ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
VectorCopy (ent->fields.server->origin, start_origin);
VectorCopy (ent->fields.server->velocity, start_velocity);
- clip = SV_FlyMove (ent, sv.frametime, NULL, SV_GenericHitSuperContentsMask(ent));
+ clip = SV_FlyMove (ent, sv.frametime, NULL, hitsupercontentsmask);
+
+ // if the move did not hit the ground at any point, we're not on ground
+ if (!(clip & 1))
+ ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
SV_CheckVelocity(ent);
// move forward
ent->fields.server->velocity[2] = 0;
- clip = SV_FlyMove (ent, sv.frametime, stepnormal, SV_GenericHitSuperContentsMask(ent));
+ clip = SV_FlyMove (ent, sv.frametime, stepnormal, hitsupercontentsmask);
ent->fields.server->velocity[2] += start_velocity[2];
SV_CheckVelocity(ent);
if (clip & 2 && sv_wallfriction.integer)
SV_WallFriction (ent, stepnormal);
}
- // skip out if stepdown is enabled, moving downward, not in water, and the move started onground and ended offground
- else if (!(sv_gameplayfix_stepdown.integer && ent->fields.server->waterlevel < 2 && start_velocity[2] < (1.0 / 32.0) && oldonground && !((int)ent->fields.server->flags & FL_ONGROUND)))
+ // don't do the down move if stepdown is disabled, moving upward, not in water, or the move started offground or ended onground
+ else if (!sv_gameplayfix_stepdown.integer || ent->fields.server->waterlevel >= 3 || start_velocity[2] >= (1.0 / 32.0) || !oldonground || ((int)ent->fields.server->flags & FL_ONGROUND))
return;
// move down
if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7)
{
// this has been disabled so that you can't jump when you are stepping
- // up while already jumping (also known as the Quake2 stair jump bug)
+ // up while already jumping (also known as the Quake2 double jump bug)
#if 0
// LordHavoc: disabled this check so you can walk on monsters/players
//if (ent->fields.server->solid == SOLID_BSP)