* returns true if it found a better place
*/
qboolean SV_UnstickEntity (prvm_edict_t *ent);
+/*! move an entity that is stuck out of the surface it is stuck in (can move large amounts)
+ * returns true if it found a better place
+ */
+qboolean SV_NudgeOutOfSolid(prvm_edict_t *ent);
/// calculates hitsupercontentsmask for a generic qc entity
int SV_GenericHitSuperContentsMask(const prvm_edict_t *edict);
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, true, 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 it started in SUPERCONTENTS_SOLID (not SUPERCONTENTS_BODY used by SOLID_BBOX)
+ // note the SV_PushEntity call above must pass true for failonbmodelstartsolid
+ if (trace.allsolid && (trace.startsupercontents & SUPERCONTENTS_SOLID))
+ {
+ VectorCopy(restore_velocity, PRVM_serveredictvector(ent, velocity));
+ return 3;
+ }
+
if (trace.fraction == 1)
break;
if (trace.plane.normal[2])
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;
end[2] -= 256;
if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
+ SV_NudgeOutOfSolid(ent);
VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
if (trace.startsolid)
{
Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
SV_LinkEdict(ent);
PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
PRVM_serveredictedict(ent, groundentity) = 0;
{
Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
- if (sv_gameplayfix_unstickentities.integer)
- SV_UnstickEntity(ent);
+ if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
+ SV_NudgeOutOfSolid(ent);
SV_LinkEdict(ent);
PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
}
else
{
- if (trace.fraction != 1)
+ if (!trace.allsolid && trace.fraction < 1)
{
- if (trace.fraction < 1)
- VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
+ VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
SV_LinkEdict(ent);
PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);