]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
vary r_drawparticles_drawdistance and r_drawdecals_drawdistance for
[xonotic/darkplaces.git] / sv_phys.c
index 362689f8795fa954e69421a4e8c524e75bf331e5..dd59d76eceec9b0ad23070f9cfc5130db4554965 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -255,6 +255,63 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
 }
 #endif
 
+int SV_PointSuperContents(const vec3_t point)
+{
+       int supercontents = 0;
+       int i;
+       prvm_edict_t *touch;
+       vec3_t transformed;
+       // matrices to transform into/out of other entity's space
+       matrix4x4_t matrix, imatrix;
+       // model of other entity
+       model_t *model;
+       unsigned int modelindex;
+       int frame;
+       // list of entities to test for collisions
+       int numtouchedicts;
+       prvm_edict_t *touchedicts[MAX_EDICTS];
+
+       // get world supercontents at this point
+       if (sv.worldmodel && sv.worldmodel->PointSuperContents)
+               supercontents = sv.worldmodel->PointSuperContents(sv.worldmodel, 0, point);
+
+       // if sv_gameplayfix_swiminbmodels is off we're done
+       if (!sv_gameplayfix_swiminbmodels.integer)
+               return supercontents;
+
+       // get list of entities at this point
+       numtouchedicts = World_EntitiesInBox(&sv.world, point, point, MAX_EDICTS, touchedicts);
+       if (numtouchedicts > MAX_EDICTS)
+       {
+               // this never happens
+               Con_Printf("SV_EntitiesInBox returned %i edicts, max was %i\n", numtouchedicts, MAX_EDICTS);
+               numtouchedicts = MAX_EDICTS;
+       }
+       for (i = 0;i < numtouchedicts;i++)
+       {
+               touch = touchedicts[i];
+
+               // we only care about SOLID_BSP for pointcontents
+               if (touch->fields.server->solid != SOLID_BSP)
+                       continue;
+
+               // might interact, so do an exact clip
+               modelindex = (unsigned int)touch->fields.server->modelindex;
+               if (modelindex >= MAX_MODELS)
+                       continue;
+               model = sv.models[(int)touch->fields.server->modelindex];
+               if (!model || !model->PointSuperContents)
+                       continue;
+               Matrix4x4_CreateFromQuakeEntity(&matrix, touch->fields.server->origin[0], touch->fields.server->origin[1], touch->fields.server->origin[2], touch->fields.server->angles[0], touch->fields.server->angles[1], touch->fields.server->angles[2], 1);
+               Matrix4x4_Invert_Simple(&imatrix, &matrix);
+               Matrix4x4_Transform(&imatrix, point, transformed);
+               frame = (int)touch->fields.server->frame;
+               supercontents |= model->PointSuperContents(model, bound(0, frame, (model->numframes - 1)), transformed);
+       }
+
+       return supercontents;
+}
+
 /*
 ===============================================================================
 
@@ -552,12 +609,12 @@ void SV_CheckVelocity (prvm_edict_t *ent)
        {
                if (IS_NAN(ent->fields.server->velocity[i]))
                {
-                       Con_Printf("Got a NaN velocity on %s\n", PRVM_GetString(ent->fields.server->classname));
+                       Con_Printf("Got a NaN velocity on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(ent->fields.server->classname));
                        ent->fields.server->velocity[i] = 0;
                }
                if (IS_NAN(ent->fields.server->origin[i]))
                {
-                       Con_Printf("Got a NaN origin on %s\n", PRVM_GetString(ent->fields.server->classname));
+                       Con_Printf("Got a NaN origin on entity #%i (%s)\n", PRVM_NUM_FOR_EDICT(ent), PRVM_GetString(ent->fields.server->classname));
                        ent->fields.server->origin[i] = 0;
                }
        }
@@ -921,7 +978,7 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal, int hitsuperco
        */
 
        // LordHavoc: this came from QW and allows you to get out of water more easily
-       if (sv_gameplayfix_qwplayerphysics.integer && ((int)ent->fields.server->flags & FL_WATERJUMP))
+       if (sv_gameplayfix_easierwaterjump.integer && ((int)ent->fields.server->flags & FL_WATERJUMP))
                VectorCopy(primal_velocity, ent->fields.server->velocity);
        return blocked;
 }
@@ -998,6 +1055,8 @@ SV_PushMove
 void SV_PushMove (prvm_edict_t *pusher, float movetime)
 {
        int i, e, index;
+       int checkcontents;
+       qboolean rotated;
        float savesolid, movetime2, pushltime;
        vec3_t mins, maxs, move, move1, moveangle, pushorig, pushang, a, forward, left, up, org;
        int num_moved;
@@ -1045,6 +1104,8 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
        }
        pushermodel = sv.models[index];
 
+       rotated = VectorLength2(pusher->fields.server->angles) + VectorLength2(pusher->fields.server->avelocity) > 0;
+
        movetime2 = movetime;
        VectorScale(pusher->fields.server->velocity, movetime2, move1);
        VectorScale(pusher->fields.server->avelocity, movetime2, moveangle);
@@ -1126,7 +1187,6 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
        for (e = 0;e < numcheckentities;e++)
        {
                prvm_edict_t *check = checkentities[e];
-               int checkcontents = SV_GenericHitSuperContentsMask(check);
                if (check->fields.server->movetype == MOVETYPE_NONE
                 || check->fields.server->movetype == MOVETYPE_PUSH
                 || check->fields.server->movetype == MOVETYPE_FOLLOW
@@ -1134,18 +1194,28 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                 || check->fields.server->movetype == MOVETYPE_FAKEPUSH)
                        continue;
 
+               //Con_Printf("%i %s ", PRVM_NUM_FOR_EDICT(check), PRVM_GetString(check->fields.server->classname));
+
+               // tell any MOVETYPE_STEP entity that it may need to check for water transitions
+               check->priv.server->waterposition_forceupdate = true;
+
+               checkcontents = SV_GenericHitSuperContentsMask(check);
+
                // if the entity is standing on the pusher, it will definitely be moved
                // if the entity is not standing on the pusher, but is in the pusher's
                // final position, move it
                if (!((int)check->fields.server->flags & FL_ONGROUND) || PRVM_PROG_TO_EDICT(check->fields.server->groundentity) != pusher)
                {
                        Collision_ClipToGenericEntity(&trace, pushermodel, pusher->fields.server->frame, pusher->fields.server->mins, pusher->fields.server->maxs, SUPERCONTENTS_BODY, &pusherfinalmatrix, &pusherfinalimatrix, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, checkcontents);
+                       //trace = SV_Move(check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, MOVE_NOMONSTERS, check, checkcontents);
                        if (!trace.startsolid)
+                       {
+                               //Con_Printf("- not in solid\n");
                                continue;
+                       }
                }
 
-
-               if (forward[0] != 1 || left[1] != 1) // quick way to check if any rotation is used
+               if (rotated)
                {
                        vec3_t org2;
                        VectorSubtract (check->fields.server->origin, pusher->fields.server->origin, org);
@@ -1158,6 +1228,8 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                else
                        VectorCopy (move1, move);
 
+               //Con_Printf("- pushing %f %f %f\n", move[0], move[1], move[2]);
+
                VectorCopy (check->fields.server->origin, check->priv.server->moved_from);
                VectorCopy (check->fields.server->angles, check->priv.server->moved_fromangles);
                moved_edicts[num_moved++] = PRVM_NUM_FOR_EDICT(check);
@@ -1916,6 +1988,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                                SV_CheckVelocity(ent);
                                SV_FlyMove(ent, sv.frametime, NULL, SV_GenericHitSuperContentsMask(ent));
                                SV_LinkEdict(ent, true);
+                               ent->priv.server->waterposition_forceupdate = true;
                        }
                }
                else
@@ -1931,13 +2004,20 @@ void SV_Physics_Step (prvm_edict_t *ent)
                        // just hit ground
                        if (hitsound && (int)ent->fields.server->flags & FL_ONGROUND && sv_sound_land.string)
                                SV_StartSound(ent, 0, sv_sound_land.string, 255, 1);
+                       ent->priv.server->waterposition_forceupdate = true;
                }
        }
 
 // regular thinking
-       SV_RunThink(ent);
+       if (!SV_RunThink(ent))
+               return;
 
-       SV_CheckWaterTransition(ent);
+       if (ent->priv.server->waterposition_forceupdate || !VectorCompare(ent->fields.server->origin, ent->priv.server->waterposition_origin))
+       {
+               ent->priv.server->waterposition_forceupdate = false;
+               VectorCopy(ent->fields.server->origin, ent->priv.server->waterposition_origin);
+               SV_CheckWaterTransition(ent);
+       }
 }
 
 //============================================================================
@@ -2115,7 +2195,6 @@ void SV_Physics_ClientEntity(prvm_edict_t *ent)
                                SV_AddGravity (ent);
                        SV_CheckStuck (ent);
                        SV_WalkMove (ent);
-                       host_client->cmd.time = max(host_client->cmd.time, sv.time); // ignore client movement data for anything before NOW
                }
                break;
        case MOVETYPE_TOSS: