]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
newline change?
[xonotic/darkplaces.git] / sv_phys.c
index ff2b16c315fb689aa26f8d7f5a2362b51a7b1f57..09ec4653e5b7df58d5965028270fd3a8cfeb55e4 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -161,10 +161,10 @@ Two entities have touched, so run their touch functions
 void SV_Impact (edict_t *e1, edict_t *e2)
 {
        int             old_self, old_other;
-       
+
        old_self = pr_global_struct->self;
        old_other = pr_global_struct->other;
-       
+
        pr_global_struct->time = sv.time;
        if (e1->v.touch && e1->v.solid != SOLID_NOT)
        {
@@ -200,7 +200,7 @@ int ClipVelocity (vec3_t in, vec3_t normal, vec3_t out, float overbounce)
        float   backoff;
        float   change;
        int             i, blocked;
-       
+
        blocked = 0;
        if (normal[2] > 0)
                blocked |= 1;           // floor
@@ -247,7 +247,7 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
        trace_t         trace;
        vec3_t          end;
        float           time_left;
-       int                     blocked;
+       int                     blocked, impact;
 
        numbumps = 4;
 
@@ -268,11 +268,13 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
 
                trace = SV_Move (ent->v.origin, ent->v.mins, ent->v.maxs, end, MOVE_NORMAL, ent);
 
+               /*
                if (trace.allsolid)
                {       // entity is trapped in another solid
                        VectorClear(ent->v.velocity);
                        return 3;
                }
+               */
 
                if (trace.fraction > 0)
                {       // actually covered some distance
@@ -287,10 +289,23 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
                if (!trace.ent)
                        Host_Error ("SV_FlyMove: !trace.ent");
 
+               if ((int) ent->v.flags & FL_ONGROUND)
+               {
+                       if (ent->v.groundentity == EDICT_TO_PROG(trace.ent))
+                               impact = false;
+                       else
+                       {
+                               ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+                               impact = true;
+                       }
+               }
+               else
+                       impact = true;
+
                if (trace.plane.normal[2] > 0.7)
                {
                        blocked |= 1;           // floor
-                       if (trace.ent->v.solid == SOLID_BSP)
+                       //if (trace.ent->v.solid == SOLID_BSP)
                        {
                                ent->v.flags =  (int)ent->v.flags | FL_ONGROUND;
                                ent->v.groundentity = EDICT_TO_PROG(trace.ent);
@@ -306,7 +321,8 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace)
 //
 // run the impact function
 //
-               SV_Impact (ent, trace.ent);
+               if (impact)
+                       SV_Impact (ent, trace.ent);
                if (ent->free)
                        break;          // removed by the impact function
 
@@ -429,7 +445,7 @@ trace_t SV_PushEntity (edict_t *ent, vec3_t push, vec3_t pushangles)
        ent->v.angles[1] += trace.fraction * pushangles[1];
        SV_LinkEdict (ent, true);
 
-       if (trace.ent)
+       if (trace.ent && (!((int)ent->v.flags & FL_ONGROUND) || ent->v.groundentity != EDICT_TO_PROG(trace.ent)))
                SV_Impact (ent, trace.ent);
        return trace;
 }
@@ -795,7 +811,7 @@ qboolean SV_CheckWater (edict_t *ent)
 
        point[0] = ent->v.origin[0];
        point[1] = ent->v.origin[1];
-       point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;       
+       point[2] = ent->v.origin[2] + ent->v.mins[2] + 1;
        
        ent->v.waterlevel = 0;
        ent->v.watertype = CONTENTS_EMPTY;
@@ -866,7 +882,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
        vec3_t  dir;
        int             clip;
        trace_t steptrace;
-       
+
        VectorCopy (ent->v.origin, oldorg);
        VectorClear (dir);
 
@@ -884,7 +900,7 @@ int SV_TryUnstick (edict_t *ent, vec3_t oldvel)
                        case 6: dir[0] = 2; dir[1] = -2; break;
                        case 7: dir[0] = -2; dir[1] = -2; break;
                }
-               
+
                SV_PushEntity (ent, dir, vec3_origin);
 
 // retry the original move
@@ -930,7 +946,7 @@ void SV_WalkMove (edict_t *ent)
 //
        oldonground = (int)ent->v.flags & FL_ONGROUND;
        ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
-       
+
        VectorCopy (ent->v.origin, oldorg);
        VectorCopy (ent->v.velocity, oldvel);
 
@@ -941,13 +957,13 @@ void SV_WalkMove (edict_t *ent)
 
        if (!oldonground && ent->v.waterlevel == 0)
                return;         // don't stair up while jumping
-       
+
        if (ent->v.movetype != MOVETYPE_WALK)
                return;         // gibbed by a trigger
-       
+
        if (sv_nostep.integer)
                return;
-       
+
        if ( (int)sv_player->v.flags & FL_WATERJUMP )
                return;
 
@@ -983,7 +999,7 @@ void SV_WalkMove (edict_t *ent)
                        clip = SV_TryUnstick (ent, oldvel);
                }
        }
-       
+
 // extra friction based on view angle
        if ( clip & 2 )
                SV_WallFriction (ent, &steptrace);
@@ -1024,11 +1040,11 @@ void SV_Physics_Client (edict_t *ent, int num)
 
 //
 // call standard client pre-think
-//     
+//
        pr_global_struct->time = sv.time;
        pr_global_struct->self = EDICT_TO_PROG(ent);
        PR_ExecuteProgram (pr_global_struct->PlayerPreThink, "QC function PlayerPreThink is missing");
-       
+
 //
 // do a move
 //
@@ -1052,7 +1068,7 @@ void SV_Physics_Client (edict_t   *ent, int num)
                SV_CheckStuck (ent);
                SV_WalkMove (ent);
                break;
-               
+
        case MOVETYPE_TOSS:
        case MOVETYPE_BOUNCE:
                SV_Physics_Toss (ent);
@@ -1064,21 +1080,21 @@ void SV_Physics_Client (edict_t *ent, int num)
                SV_CheckWater (ent);
                SV_FlyMove (ent, sv.frametime, NULL);
                break;
-               
+
        case MOVETYPE_NOCLIP:
                if (!SV_RunThink (ent))
                        return;
                SV_CheckWater (ent);
                VectorMA (ent->v.origin, sv.frametime, ent->v.velocity, ent->v.origin);
                break;
-               
+
        default:
                Host_Error ("SV_Physics_client: bad movetype %i", (int)ent->v.movetype);
        }
 
 //
 // call standard player post-think
-//             
+//
        SV_LinkEdict (ent, true);
 
        pr_global_struct->time = sv.time;
@@ -1227,13 +1243,15 @@ void SV_Physics_Toss (edict_t *ent)
 {
        trace_t trace;
        vec3_t  move;
-       float   backoff;
-       edict_t *groundentity;
+       //edict_t *groundentity;
        // regular thinking
        if (!SV_RunThink (ent))
                return;
 
 // if onground, return without moving
+       if (((int)ent->v.flags & FL_ONGROUND) && ent->v.groundentity == 0)
+               return;
+       /*
        if ( ((int)ent->v.flags & FL_ONGROUND) )
        {
                // LordHavoc: fall if the groundentity was removed
@@ -1244,7 +1262,7 @@ void SV_Physics_Toss (edict_t *ent)
                                return;
                }
        }
-       ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+       */
 
        SV_CheckVelocity (ent);
 
@@ -1260,44 +1278,34 @@ void SV_Physics_Toss (edict_t *ent)
 // move origin
        VectorScale (ent->v.velocity, sv.frametime, move);
        trace = SV_PushEntity (ent, move, vec3_origin);
-       if (trace.fraction == 1)
-               return;
        if (ent->free)
                return;
+       if (trace.fraction == 1)
+               return;
 
-       if (ent->v.movetype == MOVETYPE_BOUNCE)
-               backoff = 1.5;
-       else if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE)
-               backoff = 2.0;
-       else
-               backoff = 1;
-
-       ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, backoff);
-
-// stop if on ground
        if (ent->v.movetype == MOVETYPE_BOUNCEMISSILE)
+       {
+               ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, 2.0);
                ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+       }
        else if (ent->v.movetype == MOVETYPE_BOUNCE)
        {
-               if (trace.plane.normal[2] > 0.7)
+               ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, 1.5);
+               // LordHavoc: fixed grenades not bouncing when fired down a slope
+               if (trace.plane.normal[2] > 0.7 && DotProduct(trace.plane.normal, ent->v.velocity) < 60)
+               //if (trace.plane.normal[2] > 0.7 && ent->v.velocity[2] < 60)
                {
-                       // LordHavoc: fixed grenades not bouncing when fired down a slope
-                       if (DotProduct(trace.plane.normal, ent->v.velocity) < 100)
-                       //if (ent->v.velocity[2] < 60)
-                       {
-                               ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
-                               ent->v.groundentity = EDICT_TO_PROG(trace.ent);
-                               VectorClear (ent->v.velocity);
-                               VectorClear (ent->v.avelocity);
-                       }
-                       else
-                               ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
+                       ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
+                       ent->v.groundentity = EDICT_TO_PROG(trace.ent);
+                       VectorClear (ent->v.velocity);
+                       VectorClear (ent->v.avelocity);
                }
                else
                        ent->v.flags = (int)ent->v.flags & ~FL_ONGROUND;
        }
        else
        {
+               ClipVelocity (ent->v.velocity, trace.plane.normal, ent->v.velocity, 1.0);
                if (trace.plane.normal[2] > 0.7)
                {
                        ent->v.flags = (int)ent->v.flags | FL_ONGROUND;
@@ -1334,23 +1342,41 @@ will fall if the floor is pulled out from under them.
 */
 void SV_Physics_Step (edict_t *ent)
 {
-       qboolean        hitsound;
+       int flags, fall, hitsound;
+
+       // freefall if not fly/swim
+       fall = true;
+       flags = (int)ent->v.flags;
+       if (flags & (FL_FLY | FL_SWIM))
+       {
+               if (flags & FL_FLY)
+                       fall = false;
+               else if ((flags & FL_SWIM) && SV_PointContents(ent->v.origin) != CONTENTS_EMPTY)
+                       fall = false;
+       }
+       if (fall && (flags & FL_ONGROUND) && ent->v.groundentity == 0)
+               fall = false;
 
-// freefall if not onground
-       if ( ! ((int)ent->v.flags & (FL_ONGROUND | FL_FLY | FL_SWIM) ) )
+       if (fall)
        {
                if (ent->v.velocity[2] < sv_gravity.value*-0.1)
+               {
                        hitsound = true;
+                       if (flags & FL_ONGROUND)
+                               hitsound = false;
+               }
                else
                        hitsound = false;
 
                SV_AddGravity (ent);
                SV_CheckVelocity (ent);
                SV_FlyMove (ent, sv.frametime, NULL);
-               SV_LinkEdict (ent, true);
+               SV_LinkEdict (ent, false);
 
-               if ( (int)ent->v.flags & FL_ONGROUND )  // just hit ground
+               // just hit ground
+               if ((int)ent->v.flags & FL_ONGROUND)
                {
+                       VectorClear(ent->v.velocity);
                        if (hitsound)
                                SV_StartSound (ent, 0, "demon/dland2.wav", 255, 1);
                }