]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_move.c
fixed surface traceline code, bouncegrid looks a lot better now
[xonotic/darkplaces.git] / sv_move.c
index 99e1f60b1d24af05d16affb68424f49c3ab2b685..f8a1cfb6cabe0da5e392ae062a7f850f4fe0d007 100644 (file)
--- a/sv_move.c
+++ b/sv_move.c
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // sv_move.c -- monster movement
 
 #include "quakedef.h"
 // sv_move.c -- monster movement
 
 #include "quakedef.h"
+#include "prvm_cmds.h"
 
 /*
 =============
 
 /*
 =============
@@ -51,7 +52,7 @@ qboolean SV_CheckBottom (prvm_edict_t *ent)
                {
                        start[0] = x ? maxs[0] : mins[0];
                        start[1] = y ? maxs[1] : mins[1];
                {
                        start[0] = x ? maxs[0] : mins[0];
                        start[1] = y ? maxs[1] : mins[1];
-                       if (!(SV_PointSuperContents(start) & SUPERCONTENTS_SOLID))
+                       if (!(SV_PointSuperContents(start) & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY)))
                                goto realcheck;
                }
 
                                goto realcheck;
                }
 
@@ -69,7 +70,7 @@ realcheck:
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
        start[0] = stop[0] = (mins[0] + maxs[0])*0.5;
        start[1] = stop[1] = (mins[1] + maxs[1])*0.5;
        stop[2] = start[2] - 2*sv_stepheight.value;
-       trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent);
+       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
 
        if (trace.fraction == 1.0)
                return false;
 
        if (trace.fraction == 1.0)
                return false;
@@ -82,7 +83,7 @@ realcheck:
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
                        start[0] = stop[0] = x ? maxs[0] : mins[0];
                        start[1] = stop[1] = y ? maxs[1] : mins[1];
 
-                       trace = SV_Move (start, vec3_origin, vec3_origin, stop, MOVE_NOMONSTERS, ent);
+                       trace = SV_TraceLine(start, stop, MOVE_NOMONSTERS, ent, SV_GenericHitSuperContentsMask(ent));
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
 
                        if (trace.fraction != 1.0 && trace.endpos[2] > bottom)
                                bottom = trace.endpos[2];
@@ -101,11 +102,10 @@ SV_movestep
 
 Called by monster program code.
 The move will be adjusted for slopes and stairs, but if the move isn't
 
 Called by monster program code.
 The move will be adjusted for slopes and stairs, but if the move isn't
-possible, no move is done, false is returned, and
-prog->globals.server->trace_normal is set to the normal of the blocking wall
+possible, no move is done and false is returned
 =============
 */
 =============
 */
-qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
+qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink, qboolean noenemy, qboolean settrace)
 {
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
 {
        float           dz;
        vec3_t          oldorg, neworg, end, traceendpos;
@@ -124,16 +124,21 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
                for (i=0 ; i<2 ; i++)
                {
                        VectorAdd (ent->fields.server->origin, move, neworg);
                for (i=0 ; i<2 ; i++)
                {
                        VectorAdd (ent->fields.server->origin, move, neworg);
-                       enemy = PRVM_PROG_TO_EDICT(ent->fields.server->enemy);
-                       if (i == 0 && enemy != prog->edicts)
+                       if (noenemy)
+                               enemy = prog->edicts;
+                       else
                        {
                        {
-                               dz = ent->fields.server->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.server->enemy)->fields.server->origin[2];
-                               if (dz > 40)
-                                       neworg[2] -= 8;
-                               if (dz < 30)
-                                       neworg[2] += 8;
+                               enemy = PRVM_PROG_TO_EDICT(ent->fields.server->enemy);
+                               if (i == 0 && enemy != prog->edicts)
+                               {
+                                       dz = ent->fields.server->origin[2] - PRVM_PROG_TO_EDICT(ent->fields.server->enemy)->fields.server->origin[2];
+                                       if (dz > 40)
+                                               neworg[2] -= 8;
+                                       if (dz < 30)
+                                               neworg[2] += 8;
+                               }
                        }
                        }
-                       trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, neworg, MOVE_NORMAL, ent);
+                       trace = SV_TraceBox(ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, neworg, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
 
                        if (trace.fraction == 1)
                        {
 
                        if (trace.fraction == 1)
                        {
@@ -143,7 +148,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
 
                                VectorCopy (traceendpos, ent->fields.server->origin);
                                if (relink)
 
                                VectorCopy (traceendpos, ent->fields.server->origin);
                                if (relink)
-                                       SV_LinkEdict (ent, true);
+                               {
+                                       SV_LinkEdict(ent);
+                                       SV_LinkEdict_TouchAreaGrid(ent);
+                               }
                                return true;
                        }
 
                                return true;
                        }
 
@@ -159,12 +167,12 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
        VectorCopy (neworg, end);
        end[2] -= sv_stepheight.value*2;
 
-       trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+       trace = SV_TraceBox(neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
 
        if (trace.startsolid)
        {
                neworg[2] -= sv_stepheight.value;
-               trace = SV_Move (neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent);
+               trace = SV_TraceBox(neworg, ent->fields.server->mins, ent->fields.server->maxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
                if (trace.startsolid)
                        return false;
        }
                if (trace.startsolid)
                        return false;
        }
@@ -175,7 +183,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
                {
                        VectorAdd (ent->fields.server->origin, move, ent->fields.server->origin);
                        if (relink)
                {
                        VectorAdd (ent->fields.server->origin, move, ent->fields.server->origin);
                        if (relink)
-                               SV_LinkEdict (ent, true);
+                       {
+                               SV_LinkEdict(ent);
+                               SV_LinkEdict_TouchAreaGrid(ent);
+                       }
                        ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        return true;
                }
                        ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_ONGROUND;
                        return true;
                }
@@ -192,7 +203,10 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
                {       // entity had floor mostly pulled out from underneath it
                        // and is trying to correct
                        if (relink)
                {       // entity had floor mostly pulled out from underneath it
                        // and is trying to correct
                        if (relink)
-                               SV_LinkEdict (ent, true);
+                       {
+                               SV_LinkEdict(ent);
+                               SV_LinkEdict_TouchAreaGrid(ent);
+                       }
                        return true;
                }
                VectorCopy (oldorg, ent->fields.server->origin);
                        return true;
                }
                VectorCopy (oldorg, ent->fields.server->origin);
@@ -202,11 +216,24 @@ qboolean SV_movestep (prvm_edict_t *ent, vec3_t move, qboolean relink)
        if ( (int)ent->fields.server->flags & FL_PARTIALGROUND )
                ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_PARTIALGROUND;
 
        if ( (int)ent->fields.server->flags & FL_PARTIALGROUND )
                ent->fields.server->flags = (int)ent->fields.server->flags & ~FL_PARTIALGROUND;
 
+// gameplayfix: check if reached pretty steep plane and bail
+       if ( ! ( (int)ent->fields.server->flags & (FL_SWIM | FL_FLY) ) && sv_gameplayfix_nostepmoveonsteepslopes.integer )
+       {
+               if (trace.plane.normal[ 2 ] < 0.5)
+               {
+                       VectorCopy (oldorg, ent->fields.server->origin);
+                       return false;
+               }
+       }
+
        ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
 
 // the move is ok
        if (relink)
        ent->fields.server->groundentity = PRVM_EDICT_TO_PROG(trace.ent);
 
 // the move is ok
        if (relink)
-               SV_LinkEdict (ent, true);
+       {
+               SV_LinkEdict(ent);
+               SV_LinkEdict_TouchAreaGrid(ent);
+       }
        return true;
 }
 
        return true;
 }
 
@@ -222,14 +249,14 @@ facing it.
 
 ======================
 */
 
 ======================
 */
-void PF_changeyaw (void);
+void VM_changeyaw (void);
 qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
 {
        vec3_t          move, oldorigin;
        float           delta;
 
        ent->fields.server->ideal_yaw = yaw;
 qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
 {
        vec3_t          move, oldorigin;
        float           delta;
 
        ent->fields.server->ideal_yaw = yaw;
-       PF_changeyaw();
+       VM_changeyaw();
 
        yaw = yaw*M_PI*2 / 360;
        move[0] = cos(yaw)*dist;
 
        yaw = yaw*M_PI*2 / 360;
        move[0] = cos(yaw)*dist;
@@ -237,17 +264,19 @@ qboolean SV_StepDirection (prvm_edict_t *ent, float yaw, float dist)
        move[2] = 0;
 
        VectorCopy (ent->fields.server->origin, oldorigin);
        move[2] = 0;
 
        VectorCopy (ent->fields.server->origin, oldorigin);
-       if (SV_movestep (ent, move, false))
+       if (SV_movestep (ent, move, false, false, false))
        {
                delta = ent->fields.server->angles[YAW] - ent->fields.server->ideal_yaw;
                if (delta > 45 && delta < 315)
                {               // not turned far enough, so don't take the step
                        VectorCopy (oldorigin, ent->fields.server->origin);
                }
        {
                delta = ent->fields.server->angles[YAW] - ent->fields.server->ideal_yaw;
                if (delta > 45 && delta < 315)
                {               // not turned far enough, so don't take the step
                        VectorCopy (oldorigin, ent->fields.server->origin);
                }
-               SV_LinkEdict (ent, true);
+               SV_LinkEdict(ent);
+               SV_LinkEdict_TouchAreaGrid(ent);
                return true;
        }
                return true;
        }
-       SV_LinkEdict (ent, true);
+       SV_LinkEdict(ent);
+       SV_LinkEdict_TouchAreaGrid(ent);
 
        return false;
 }
 
        return false;
 }
@@ -367,9 +396,9 @@ qboolean SV_CloseEnough (prvm_edict_t *ent, prvm_edict_t *goal, float dist)
 
        for (i=0 ; i<3 ; i++)
        {
 
        for (i=0 ; i<3 ; i++)
        {
-               if (goal->fields.server->absmin[i] > ent->fields.server->absmax[i] + dist)
+               if (goal->priv.server->areamins[i] > ent->priv.server->areamaxs[i] + dist)
                        return false;
                        return false;
-               if (goal->fields.server->absmax[i] < ent->fields.server->absmin[i] - dist)
+               if (goal->priv.server->areamaxs[i] < ent->priv.server->areamins[i] - dist)
                        return false;
        }
        return true;
                        return false;
        }
        return true;
@@ -386,6 +415,8 @@ void SV_MoveToGoal (void)
        prvm_edict_t            *ent, *goal;
        float           dist;
 
        prvm_edict_t            *ent, *goal;
        float           dist;
 
+       VM_SAFEPARMCOUNT(1, SV_MoveToGoal);
+
        ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
        goal = PRVM_PROG_TO_EDICT(ent->fields.server->goalentity);
        dist = PRVM_G_FLOAT(OFS_PARM0);
        ent = PRVM_PROG_TO_EDICT(prog->globals.server->self);
        goal = PRVM_PROG_TO_EDICT(ent->fields.server->goalentity);
        dist = PRVM_G_FLOAT(OFS_PARM0);