]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
fix two bugs introduced in r5828 (2005-11-25) that made monsters and
[xonotic/darkplaces.git] / sv_phys.c
index e189ee92e2722efe722ad9f813f10e9cbbec5187..bd8b50ce30262ed9a36b8092fd8f49a009552867 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -1482,8 +1482,11 @@ Returns true if the push did not result in the entity being teleported by QC cod
 static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, qboolean failonbmodelstartsolid, qboolean dolink)
 {
        int type;
+       int bump;
+       vec3_t original;
        vec3_t end;
 
+       VectorCopy(ent->fields.server->origin, original);
        VectorAdd (ent->fields.server->origin, push, end);
 
        if (ent->fields.server->movetype == MOVETYPE_FLYMISSILE)
@@ -1494,9 +1497,23 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
                type = MOVE_NORMAL;
 
        *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)
+       {
+               vec_t nudge = -trace->startdepth + sv_gameplayfix_nudgeoutofsolid_bias.value;
+               VectorMA(ent->fields.server->origin, nudge, trace->startdepthnormal, ent->fields.server->origin);
+               *trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, end, type, ent, SV_GenericHitSuperContentsMask(ent));
+               bump++;
+               if (bump > 10)
+               {
+                       VectorCopy(original, ent->fields.server->origin);
+                       break;
+               }
+       }
        if (trace->bmodelstartsolid && failonbmodelstartsolid)
                return true;
 
+
        VectorCopy (trace->endpos, ent->fields.server->origin);
        SV_LinkEdict(ent);
 
@@ -2417,10 +2434,12 @@ void SV_Physics_Toss (prvm_edict_t *ent)
        vec3_t move;
        vec_t movetime;
        int bump;
+       prvm_edict_t *groundentity;
 
 // if onground, return without moving
        if ((int)ent->fields.server->flags & FL_ONGROUND)
        {
+               groundentity = PRVM_PROG_TO_EDICT(ent->fields.server->groundentity);
                if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer)
                {
                        // don't stick to ground if onground and moving upward
@@ -2431,7 +2450,7 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                        // we can trust FL_ONGROUND if groundentity is world because it never moves
                        return;
                }
-               else if (ent->priv.server->suspendedinairflag && PRVM_PROG_TO_EDICT(ent->fields.server->groundentity)->priv.server->free)
+               else if (ent->priv.server->suspendedinairflag && groundentity->priv.server->free)
                {
                        // if ent was supported by a brush model on previous frame,
                        // and groundentity is now freed, set groundentity to 0 (world)
@@ -2440,6 +2459,11 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                        if (sv_gameplayfix_noairborncorpse_allowsuspendeditems.integer)
                                return;
                }
+               else if (BoxesOverlap(ent->priv.server->cullmins, ent->priv.server->cullmaxs, groundentity->priv.server->cullmins, groundentity->priv.server->cullmaxs))
+               {
+                       // don't slide if still touching the groundentity
+                       return;
+               }
        }
        ent->priv.server->suspendedinairflag = false;
 
@@ -2591,7 +2615,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                {
                        // freefall if onground and moving upward
                        // freefall if not standing on a world surface (it may be a lift or trap door)
-                       if ((ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer) || ent->fields.server->groundentity)
+                       if (ent->fields.server->velocity[2] >= (1.0 / 32.0) && sv_gameplayfix_upwardvelocityclearsongroundflag.integer)
                        {
                                ent->fields.server->flags -= FL_ONGROUND;
                                SV_CheckVelocity(ent);