]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_phys.c
added sv_areadebug cvar which disables the use of the areagrid (VERY bad
[xonotic/darkplaces.git] / sv_phys.c
index 24276208d401cdff987cfdc66ece0feb19862e91..c0142c5940125072a1e0de64364b00f6c723d3dc 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -174,7 +174,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -340,7 +340,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -553,7 +553,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
        // clip to entities
        // because this uses World_EntitiestoBox, we know all entity boxes overlap
        // the clip region, so we can skip culling checks in the loop below
-       numtouchedicts = World_EntitiesInBox(&sv.world, clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(clipboxmins, clipboxmaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -662,7 +662,7 @@ int SV_PointSuperContents(const vec3_t point)
                return supercontents;
 
        // get list of entities at this point
-       numtouchedicts = World_EntitiesInBox(&sv.world, point, point, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(point, point, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -699,6 +699,34 @@ Linking entities into the world culling system
 ===============================================================================
 */
 
+int SV_EntitiesInBox(const vec3_t mins, const vec3_t maxs, int maxedicts, prvm_edict_t **resultedicts)
+{
+       vec3_t paddedmins, paddedmaxs;
+       if (maxedicts < 1 || resultedicts == NULL)
+               return 0;
+       VectorSet(paddedmins, mins[0] - 10, mins[1] - 10, mins[2] - 1);
+       VectorSet(paddedmaxs, maxs[0] + 10, maxs[1] + 10, maxs[2] + 1);
+       if (sv_areadebug.integer)
+       {
+               int numresultedicts = 0;
+               int edictindex;
+               prvm_edict_t *ed;
+               for (edictindex = 1;edictindex < prog->num_edicts;edictindex++)
+               {
+                       ed = PRVM_EDICT_NUM(edictindex);
+                       if (!ed->priv.required->free && BoxesOverlap(PRVM_serveredictvector(ed, absmin), PRVM_serveredictvector(ed, absmax), paddedmins, paddedmaxs))
+                       {
+                               resultedicts[numresultedicts++] = ed;
+                               if (numresultedicts == maxedicts)
+                                       break;
+                       }
+               }
+               return numresultedicts;
+       }
+       else
+               return World_EntitiesInBox(&sv.world, paddedmins, paddedmaxs, maxedicts, resultedicts);
+}
+
 void SV_LinkEdict_TouchAreaGrid_Call(prvm_edict_t *touch, prvm_edict_t *ent)
 {
        PRVM_serverglobaledict(self) = PRVM_EDICT_TO_PROG(touch);
@@ -737,7 +765,7 @@ void SV_LinkEdict_TouchAreaGrid(prvm_edict_t *ent)
 
        // build a list of edicts to touch, because the link loop can be corrupted
        // by IncreaseEdicts called during touch functions
-       numtouchedicts = World_EntitiesInBox(&sv.world, ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts);
+       numtouchedicts = SV_EntitiesInBox(ent->priv.server->areamins, ent->priv.server->areamaxs, MAX_EDICTS, touchedicts);
        if (numtouchedicts > MAX_EDICTS)
        {
                // this never happens
@@ -919,7 +947,7 @@ static int SV_TestEntityPosition (prvm_edict_t *ent, vec3_t offset)
        trace_t trace;
        contents = SV_GenericHitSuperContentsMask(ent);
        VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
-       trace = SV_TraceBox(org, PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), MOVE_NOMONSTERS, ent, contents);
+       trace = SV_TraceBox(org, PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), PRVM_serveredictvector(ent, origin), ((PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), ent, contents);
        if (trace.startsupercontents & contents)
                return true;
        else
@@ -987,7 +1015,8 @@ void SV_CheckAllEnts (void)
                if (PRVM_serveredictfloat(check, movetype) == MOVETYPE_PUSH
                 || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NONE
                 || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FOLLOW
-                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NOCLIP)
+                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_NOCLIP
+                || PRVM_serveredictfloat(check, movetype) == MOVETYPE_FLY_WORLDONLY)
                        continue;
 
                if (SV_TestEntityPosition (check, vec3_origin))
@@ -1598,6 +1627,8 @@ static qboolean SV_PushEntity (trace_t *trace, prvm_edict_t *ent, vec3_t push, q
 
        if (movetype == MOVETYPE_FLYMISSILE)
                type = MOVE_MISSILE;
+       else if (movetype == MOVETYPE_FLY_WORLDONLY)
+               type = MOVE_WORLDONLY;
        else if (solid == SOLID_TRIGGER || solid == SOLID_NOT)
                type = MOVE_NOMONSTERS; // only clip against bmodels
        else
@@ -1774,7 +1805,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
        if (PRVM_serveredictfloat(pusher, movetype) == MOVETYPE_FAKEPUSH) // Tenebrae's MOVETYPE_PUSH variant that doesn't push...
                numcheckentities = 0;
        else // MOVETYPE_PUSH
-               numcheckentities = World_EntitiesInBox(&sv.world, mins, maxs, MAX_EDICTS, checkentities);
+               numcheckentities = SV_EntitiesInBox(mins, maxs, MAX_EDICTS, checkentities);
        for (e = 0;e < numcheckentities;e++)
        {
                prvm_edict_t *check = checkentities[e];
@@ -1785,6 +1816,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                case MOVETYPE_PUSH:
                case MOVETYPE_FOLLOW:
                case MOVETYPE_NOCLIP:
+               case MOVETYPE_FLY_WORLDONLY:
                        continue;
                default:
                        break;
@@ -2260,7 +2292,8 @@ void SV_WalkMove (prvm_edict_t *ent)
        if (sv.frametime <= 0)
                return;
 
-       SV_CheckStuck (ent);
+       if (sv_gameplayfix_unstickplayers.integer)
+               SV_CheckStuck (ent);
 
        applygravity = !SV_CheckWater (ent) && PRVM_serveredictfloat(ent, movetype) == MOVETYPE_WALK && ! ((int)PRVM_serveredictfloat(ent, flags) & FL_WATERJUMP);
 
@@ -2286,6 +2319,8 @@ void SV_WalkMove (prvm_edict_t *ent)
                VectorSet(downmove, PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2] - 1);
                if (PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLYMISSILE)
                        type = MOVE_MISSILE;
+               else if (PRVM_serveredictfloat(ent, movetype) == MOVETYPE_FLY_WORLDONLY)
+                       type = MOVE_WORLDONLY;
                else if (PRVM_serveredictfloat(ent, solid) == SOLID_TRIGGER || PRVM_serveredictfloat(ent, solid) == SOLID_NOT)
                        type = MOVE_NOMONSTERS; // only clip against bmodels
                else
@@ -2498,25 +2533,28 @@ SV_CheckWaterTransition
 */
 void SV_CheckWaterTransition (prvm_edict_t *ent)
 {
+       // LordHavoc: bugfixes in this function are keyed to the sv_gameplayfix_bugfixedcheckwatertransition cvar - if this cvar is 0 then all the original bugs should be reenabled for compatibility
        int cont;
        cont = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_serveredictvector(ent, origin)));
        if (!PRVM_serveredictfloat(ent, watertype))
        {
                // just spawned here
-               PRVM_serveredictfloat(ent, watertype) = cont;
-               PRVM_serveredictfloat(ent, waterlevel) = 1;
-               return;
+               if (!sv_gameplayfix_fixedcheckwatertransition.integer)
+               {
+                       PRVM_serveredictfloat(ent, watertype) = cont;
+                       PRVM_serveredictfloat(ent, waterlevel) = 1;
+                       return;
+               }
        }
-
        // DRESK - Support for Entity Contents Transition Event
        // NOTE: Call here BEFORE updating the watertype below,
        // and suppress watersplash sound if a valid function
        // call was made to allow for custom "splash" sounds.
-       if( !SV_CheckContentsTransition(ent, cont) )
+       else if( !SV_CheckContentsTransition(ent, cont) )
        { // Contents Transition Function Invalid; Potentially Play Water Sound
                // check if the entity crossed into or out of water
                if (sv_sound_watersplash.string && ((PRVM_serveredictfloat(ent, watertype) == CONTENTS_WATER || PRVM_serveredictfloat(ent, watertype) == CONTENTS_SLIME) != (cont == CONTENTS_WATER || cont == CONTENTS_SLIME)))
-                       SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false);
+                       SV_StartSound (ent, 0, sv_sound_watersplash.string, 255, 1, false, 1.0f);
        }
 
        if (cont <= CONTENTS_WATER)
@@ -2527,7 +2565,7 @@ void SV_CheckWaterTransition (prvm_edict_t *ent)
        else
        {
                PRVM_serveredictfloat(ent, watertype) = CONTENTS_EMPTY;
-               PRVM_serveredictfloat(ent, waterlevel) = 0;
+               PRVM_serveredictfloat(ent, waterlevel) = sv_gameplayfix_fixedcheckwatertransition.integer ? 0 : cont;
        }
 }
 
@@ -2538,6 +2576,7 @@ SV_Physics_Toss
 Toss, bounce, and fly movement.  When onground, do nothing.
 =============
 */
+
 void SV_Physics_Toss (prvm_edict_t *ent)
 {
        trace_t trace;
@@ -2598,7 +2637,8 @@ void SV_Physics_Toss (prvm_edict_t *ent)
                if (trace.bmodelstartsolid)
                {
                        // try to unstick the entity
-                       SV_UnstickEntity(ent);
+                       if (sv_gameplayfix_unstickentities.integer)
+                               SV_UnstickEntity(ent);
                        if(!SV_PushEntity (&trace, ent, move, false, true))
                                return; // teleported
                        if (ent->priv.server->free)
@@ -2759,7 +2799,7 @@ void SV_Physics_Step (prvm_edict_t *ent)
                                else
                                // Check for Engine Landing Sound
                                if(sv_sound_land.string)
-                                       SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false);
+                                       SV_StartSound(ent, 0, sv_sound_land.string, 255, 1, false, 1.0f);
                        }
                        ent->priv.server->waterposition_forceupdate = true;
                }
@@ -2826,6 +2866,7 @@ static void SV_Physics_Entity (prvm_edict_t *ent)
        case MOVETYPE_BOUNCEMISSILE:
        case MOVETYPE_FLYMISSILE:
        case MOVETYPE_FLY:
+       case MOVETYPE_FLY_WORLDONLY:
                // regular thinking
                if (SV_RunThink (ent))
                        SV_Physics_Toss (ent);
@@ -2998,6 +3039,7 @@ static void SV_Physics_ClientEntity(prvm_edict_t *ent)
                SV_Physics_Toss (ent);
                break;
        case MOVETYPE_FLY:
+       case MOVETYPE_FLY_WORLDONLY:
                SV_RunThink (ent);
                SV_WalkMove (ent);
                break;