]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
added sv_waterfriction, sv_airaccelerate, sv_wateraccelerate cvars (and corresponding...
[xonotic/darkplaces.git] / sv_phys.c
index 035a72d665fdeb2af4a04c6f726c5ed2b8274ec0..2355d16b7764716ebcee306df6993b647a2954f4 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -42,6 +42,7 @@ solid_edge items only clip against bsp models.
 */
 
 cvar_t sv_friction = {CVAR_NOTIFY, "sv_friction","4", "how fast you slow down"};
+cvar_t sv_waterfriction = {CVAR_NOTIFY, "sv_waterfriction","-1", "how fast you slow down, if less than 0 the sv_friction variable is used instead"};
 cvar_t sv_stopspeed = {CVAR_NOTIFY, "sv_stopspeed","100", "how fast you come to a complete stop"};
 cvar_t sv_gravity = {CVAR_NOTIFY, "sv_gravity","800", "how fast you fall (512 = roughly earth gravity)"};
 cvar_t sv_maxvelocity = {CVAR_NOTIFY, "sv_maxvelocity","2000", "universal speed limit on all entities"};
@@ -81,9 +82,13 @@ SV_TestEntityPosition
 returns true if the entity is in solid currently
 ============
 */
-static int SV_TestEntityPosition (prvm_edict_t *ent, int movemode)
+static int SV_TestEntityPosition (prvm_edict_t *ent)
 {
-       return SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, movemode, ent).startsolid;
+       trace_t trace = SV_Move (ent->fields.server->origin, ent->fields.server->mins, ent->fields.server->maxs, ent->fields.server->origin, MOVE_NOMONSTERS, ent);
+       if (trace.startsupercontents & SUPERCONTENTS_SOLID)
+               return true;
+       else
+               return false;
 }
 
 /*
@@ -108,7 +113,7 @@ void SV_CheckAllEnts (void)
                 || check->fields.server->movetype == MOVETYPE_NOCLIP)
                        continue;
 
-               if (SV_TestEntityPosition (check, MOVE_NORMAL))
+               if (SV_TestEntityPosition (check))
                        Con_Print("entity in invalid position\n");
        }
 }
@@ -366,15 +371,15 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
                Con_Print("\n");
 #endif
 
-               /*
-               if (trace.startsolid)
+               if (trace.bmodelstartsolid)
                {
-                       // LordHavoc: note: this code is what makes entities stick in place if embedded in another object (which can be the world)
+                       // LordHavoc: note: this code is what makes entities stick in place
+                       // if embedded in world only (you can walk through other objects if
+                       // stuck)
                        // entity is trapped in another solid
                        VectorClear(ent->fields.server->velocity);
                        return 3;
                }
-               */
 
                // break if it moved the entire distance
                if (trace.fraction == 1)
@@ -628,13 +633,13 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                SV_LinkEdict (pusher, false);
                return;
        default:
-               Con_Printf("SV_PushMove: unrecognized solid type %f\n", pusher->fields.server->solid);
+               Con_Printf("SV_PushMove: entity #%i, unrecognized solid type %f\n", PRVM_NUM_FOR_EDICT(pusher), pusher->fields.server->solid);
                return;
        }
        index = (int) pusher->fields.server->modelindex;
        if (index < 1 || index >= MAX_MODELS)
        {
-               Con_Printf("SV_PushMove: invalid modelindex %f\n", pusher->fields.server->modelindex);
+               Con_Printf("SV_PushMove: entity #%i has an invalid modelindex %f\n", PRVM_NUM_FOR_EDICT(pusher), pusher->fields.server->modelindex);
                return;
        }
        pushermodel = sv.models[index];
@@ -758,7 +763,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                pusher->fields.server->solid = savesolid; // was SOLID_BSP
 
                // if it is still inside the pusher, block
-               if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID).startsolid)
+               if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
                {
                        // try moving the contacted entity a tiny bit further to account for precision errors
                        vec3_t move2;
@@ -768,7 +773,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                        VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
                        SV_PushEntity (check, move2);
                        pusher->fields.server->solid = savesolid;
-                       if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID).startsolid)
+                       if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
                        {
                                // try moving the contacted entity a tiny bit less to account for precision errors
                                pusher->fields.server->solid = SOLID_NOT;
@@ -777,7 +782,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                                VectorCopy (check->priv.server->moved_fromangles, check->fields.server->angles);
                                SV_PushEntity (check, move2);
                                pusher->fields.server->solid = savesolid;
-                               if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID).startsolid)
+                               if (SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
                                {
                                        // still inside pusher, so it's really blocked
 
@@ -881,7 +886,7 @@ void SV_CheckStuck (prvm_edict_t *ent)
        int i, j, z;
        vec3_t org;
 
-       if (!SV_TestEntityPosition(ent, MOVE_NORMAL))
+       if (!SV_TestEntityPosition(ent))
        {
                VectorCopy (ent->fields.server->origin, ent->fields.server->oldorigin);
                return;
@@ -889,30 +894,30 @@ void SV_CheckStuck (prvm_edict_t *ent)
 
        VectorCopy (ent->fields.server->origin, org);
        VectorCopy (ent->fields.server->oldorigin, ent->fields.server->origin);
-       if (!SV_TestEntityPosition(ent, MOVE_NORMAL))
+       if (!SV_TestEntityPosition(ent))
        {
-               Con_DPrintf("Unstuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+               Con_DPrintf("Unstuck player entity %i (classname \"%s\") by restoring oldorigin.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
                SV_LinkEdict (ent, true);
                return;
        }
 
-       for (z=0 ; z< 18 ; z++)
+       for (z=-1 ; z< 18 ; z++)
                for (i=-1 ; i <= 1 ; i++)
                        for (j=-1 ; j <= 1 ; j++)
                        {
                                ent->fields.server->origin[0] = org[0] + i;
                                ent->fields.server->origin[1] = org[1] + j;
                                ent->fields.server->origin[2] = org[2] + z;
-                               if (!SV_TestEntityPosition(ent, MOVE_NORMAL))
+                               if (!SV_TestEntityPosition(ent))
                                {
-                                       Con_DPrintf("Unstuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+                                       Con_DPrintf("Unstuck player entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname), (float)i, (float)j, (float)z);
                                        SV_LinkEdict (ent, true);
                                        return;
                                }
                        }
 
        VectorCopy (org, ent->fields.server->origin);
-       Con_DPrintf("Stuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+       Con_DPrintf("Stuck player entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
 }
 
 static void SV_UnstickEntity (prvm_edict_t *ent)
@@ -921,21 +926,21 @@ static void SV_UnstickEntity (prvm_edict_t *ent)
        vec3_t org;
 
        // if not stuck in a bmodel, just return
-       if (!SV_TestEntityPosition(ent, MOVE_NOMONSTERS))
+       if (!SV_TestEntityPosition(ent))
                return;
 
        VectorCopy (ent->fields.server->origin, org);
 
-       for (z=0 ; z< 18 ; z += 6)
+       for (z=-1 ; z< 18 ; z += 6)
                for (i=-1 ; i <= 1 ; i++)
                        for (j=-1 ; j <= 1 ; j++)
                        {
                                ent->fields.server->origin[0] = org[0] + i;
                                ent->fields.server->origin[1] = org[1] + j;
                                ent->fields.server->origin[2] = org[2] + z;
-                               if (!SV_TestEntityPosition(ent, MOVE_NOMONSTERS))
+                               if (!SV_TestEntityPosition(ent))
                                {
-                                       Con_DPrintf("Unstuck entity %i (classname \"%s\").\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname));
+                                       Con_DPrintf("Unstuck entity %i (classname \"%s\") with offset %f %f %f.\n", (int)PRVM_EDICT_TO_PROG(ent), PRVM_GetString(ent->fields.server->classname), (float)i, (float)j, (float)z);
                                        SV_LinkEdict (ent, true);
                                        return;
                                }