2 new cvars: sv_gameplayfix_unstickentities and sv_gameplayfix_unstickplayers to...
authorvortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 21 Aug 2011 14:55:40 +0000 (14:55 +0000)
committervortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Sun, 21 Aug 2011 14:55:40 +0000 (14:55 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11289 d7cf8633-e32d-0410-b094-e92efae38249

cl_screen.c
clvm_cmds.c
csprogs.h
gl_rmain.c
meshqueue.c
server.h
sv_main.c
sv_phys.c
svvm_cmds.c

index d5ca01e..0d891b6 100644 (file)
@@ -1608,17 +1608,16 @@ static void SCR_DrawTouchscreenOverlay(void)
        }
 }
 
-extern void R_UpdateFogColor(void);
+extern void R_UpdateFog(void);
 void R_ClearScreen(qboolean fogcolor)
 {
        float clearcolor[4];
        // clear to black
        Vector4Clear(clearcolor);
-       if (fogcolor)
+       if (fogcolor && r_fog_clear.integer)
        {
-               R_UpdateFogColor();
-               if (r_fog_clear.integer)
-                       VectorCopy(r_refdef.fogcolor, clearcolor);
+               R_UpdateFog();
+               VectorCopy(r_refdef.fogcolor, clearcolor);
        }
        // clear depth is 1.0
        // LordHavoc: we use a stencil centered around 128 instead of 0,
index d9b8c77..fd4207c 100644 (file)
@@ -889,6 +889,38 @@ void VM_CL_R_SetView (void)
                case VF_CLEARSCREEN:
                        PRVM_G_FLOAT(OFS_RETURN) = r_refdef.view.isoverlay;
                        break;
+               case VF_FOG_DENSITY:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_density;
+                       break;
+               case VF_FOG_COLOR:
+                       PRVM_G_VECTOR(OFS_RETURN)[0] = r_refdef.fog_red;
+                       PRVM_G_VECTOR(OFS_RETURN)[1] = r_refdef.fog_green;
+                       PRVM_G_VECTOR(OFS_RETURN)[2] = r_refdef.fog_blue;
+                       break;
+               case VF_FOG_COLOR_R:
+                       PRVM_G_VECTOR(OFS_RETURN)[0] = r_refdef.fog_red;
+                       break;
+               case VF_FOG_COLOR_G:
+                       PRVM_G_VECTOR(OFS_RETURN)[1] = r_refdef.fog_green;
+                       break;
+               case VF_FOG_COLOR_B:
+                       PRVM_G_VECTOR(OFS_RETURN)[2] = r_refdef.fog_blue;
+                       break;
+               case VF_FOG_ALPHA:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_alpha;
+                       break;
+               case VF_FOG_START:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_start;
+                       break;
+               case VF_FOG_END:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_end;
+                       break;
+               case VF_FOG_HEIGHT:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_height;
+                       break;
+               case VF_FOG_FADEDEPTH:
+                       PRVM_G_FLOAT(OFS_RETURN) = r_refdef.fog_fadedepth;
+                       break;
                default:
                        PRVM_G_FLOAT(OFS_RETURN) = 0;
                        VM_Warning("VM_CL_R_GetView : unknown parm %i\n", c);
@@ -1004,6 +1036,38 @@ void VM_CL_R_SetView (void)
        case VF_CLEARSCREEN:
                r_refdef.view.isoverlay = !k;
                break;
+       case VF_FOG_DENSITY:
+               r_refdef.fog_density = k;
+               break;
+       case VF_FOG_COLOR:
+               r_refdef.fog_red = f[0];
+               r_refdef.fog_green = f[1];
+               r_refdef.fog_blue = f[2];
+               break;
+       case VF_FOG_COLOR_R:
+               r_refdef.fog_red = k;
+               break;
+       case VF_FOG_COLOR_G:
+               r_refdef.fog_green = k;
+               break;
+       case VF_FOG_COLOR_B:
+               r_refdef.fog_blue = k;
+               break;
+       case VF_FOG_ALPHA:
+               r_refdef.fog_alpha = k;
+               break;
+       case VF_FOG_START:
+               r_refdef.fog_start = k;
+               break;
+       case VF_FOG_END:
+               r_refdef.fog_end = k;
+               break;
+       case VF_FOG_HEIGHT:
+               r_refdef.fog_height = k;
+               break;
+       case VF_FOG_FADEDEPTH:
+               r_refdef.fog_fadedepth = k;
+               break;
        default:
                PRVM_G_FLOAT(OFS_RETURN) = 0;
                VM_Warning("VM_CL_R_SetView : unknown parm %i\n", c);
@@ -3034,6 +3098,7 @@ void VM_CL_R_RenderScene (void)
        // we need to update any RENDER_VIEWMODEL entities at this point because
        // csqc supplies its own view matrix
        CL_UpdateViewEntities();
+
        // now draw stuff!
        R_RenderView();
 
index bb0a3fb..c82974b 100644 (file)
--- a/csprogs.h
+++ b/csprogs.h
 #define VF_PERSPECTIVE         200 //(float)
 #define VF_CLEARSCREEN         201 //(float)
 
+#define VF_FOG_DENSITY         202 //(float)
+#define VF_FOG_COLOR           203 //(vector)
+#define VF_FOG_COLOR_R         204 //(float)
+#define VF_FOG_COLOR_G         205 //(float)
+#define VF_FOG_COLOR_B         206 //(float)
+#define VF_FOG_ALPHA           207 //(float)
+#define VF_FOG_START           208 //(float)
+#define VF_FOG_END             209 //(float)
+#define VF_FOG_HEIGHT          210 //(float)
+#define VF_FOG_FADEDEPTH       211 //(float)
+
 #define RF_VIEWMODEL           1       // The entity is never drawn in mirrors. In engines with realtime lighting, it casts no shadows.
 #define RF_EXTERNALMODEL       2       // The entity is appears in mirrors but not in the normal view. It does still cast shadows in engines with realtime lighting.
 #define RF_DEPTHHACK           4       // The entity appears closer to the view than normal, either by scaling it wierdly or by just using a depthrange. This will usually be found in conjunction with RF_VIEWMODEL
index 435cefe..68b0d8f 100644 (file)
@@ -126,6 +126,7 @@ cvar_t r_fog_exp2 = {0, "r_fog_exp2", "0", "uses GL_EXP2 fog (as in Nehahra) rat
 cvar_t r_fog_clear = {0, "r_fog_clear", "1", "clears renderbuffer with fog color before render starts"};
 cvar_t r_drawfog = {CVAR_SAVE, "r_drawfog", "1", "allows one to disable fog rendering"};
 cvar_t r_transparentdepthmasking = {CVAR_SAVE, "r_transparentdepthmasking", "0", "enables depth writes on transparent meshes whose materially is normally opaque, this prevents seeing the inside of a transparent mesh"};
+cvar_t r_transparent_sortmindist = {CVAR_SAVE, "r_transparent_sortmindist", "0", "lower distance limit for transparent sorting"};
 cvar_t r_transparent_sortmaxdist = {CVAR_SAVE, "r_transparent_sortmaxdist", "32768", "upper distance limit for transparent sorting"};
 cvar_t r_transparent_sortarraysize = {CVAR_SAVE, "r_transparent_sortarraysize", "4096", "number of distance-sorting layers"};
 
@@ -4239,6 +4240,7 @@ void GL_Main_Init(void)
        Cvar_RegisterVariable(&r_fog_clear);
        Cvar_RegisterVariable(&r_drawfog);
        Cvar_RegisterVariable(&r_transparentdepthmasking);
+       Cvar_RegisterVariable(&r_transparent_sortmindist);
        Cvar_RegisterVariable(&r_transparent_sortmaxdist);
        Cvar_RegisterVariable(&r_transparent_sortarraysize);
        Cvar_RegisterVariable(&r_texture_dds_load);
@@ -6530,67 +6532,9 @@ static void R_BlendView(void)
 
 matrix4x4_t r_waterscrollmatrix;
 
-void R_UpdateFogColor(void) // needs to be called before HDR subrender too, as that changes colorscale!
+void R_UpdateFog(void) // needs to be called before HDR subrender too, as that changes colorscale!
 {
-       if (r_refdef.fog_density)
-       {
-               r_refdef.fogcolor[0] = r_refdef.fog_red;
-               r_refdef.fogcolor[1] = r_refdef.fog_green;
-               r_refdef.fogcolor[2] = r_refdef.fog_blue;
-
-               Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
-               r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
-               r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
-               r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
-
-               {
-                       vec3_t fogvec;
-                       VectorCopy(r_refdef.fogcolor, fogvec);
-                       //   color.rgb *= ContrastBoost * SceneBrightness;
-                       VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
-                       r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
-                       r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
-                       r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
-               }
-       }
-}
-
-void R_UpdateVariables(void)
-{
-       R_Textures_Frame();
-
-       r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
-
-       r_refdef.farclip = r_farclip_base.value;
-       if (r_refdef.scene.worldmodel)
-               r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
-       r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
-
-       if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
-               Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
-       r_refdef.polygonfactor = 0;
-       r_refdef.polygonoffset = 0;
-       r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
-       r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
-
-       r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
-       r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
-       r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
-       r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
-       r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
-       if (FAKELIGHT_ENABLED)
-       {
-               r_refdef.lightmapintensity *= r_fakelight_intensity.value;
-       }
-       if (r_showsurfaces.integer)
-       {
-               r_refdef.scene.rtworld = false;
-               r_refdef.scene.rtworldshadows = false;
-               r_refdef.scene.rtdlight = false;
-               r_refdef.scene.rtdlightshadows = false;
-               r_refdef.lightmapintensity = 0;
-       }
-
+       // Nehahra fog
        if (gamemode == GAME_NEHAHRA)
        {
                if (gl_fogenable.integer)
@@ -6621,12 +6565,11 @@ void R_UpdateVariables(void)
                }
        }
 
+       // fog parms
        r_refdef.fog_alpha = bound(0, r_refdef.fog_alpha, 1);
        r_refdef.fog_start = max(0, r_refdef.fog_start);
        r_refdef.fog_end = max(r_refdef.fog_start + 0.01, r_refdef.fog_end);
 
-       // R_UpdateFogColor(); // why? R_RenderScene does it anyway
-
        if (r_refdef.fog_density && r_drawfog.integer)
        {
                r_refdef.fogenabled = true;
@@ -6652,6 +6595,66 @@ void R_UpdateVariables(void)
        else
                r_refdef.fogenabled = false;
 
+       // fog color
+       if (r_refdef.fog_density)
+       {
+               r_refdef.fogcolor[0] = r_refdef.fog_red;
+               r_refdef.fogcolor[1] = r_refdef.fog_green;
+               r_refdef.fogcolor[2] = r_refdef.fog_blue;
+
+               Vector4Set(r_refdef.fogplane, 0, 0, 1, -r_refdef.fog_height);
+               r_refdef.fogplaneviewdist = DotProduct(r_refdef.fogplane, r_refdef.view.origin) + r_refdef.fogplane[3];
+               r_refdef.fogplaneviewabove = r_refdef.fogplaneviewdist >= 0;
+               r_refdef.fogheightfade = -0.5f/max(0.125f, r_refdef.fog_fadedepth);
+
+               {
+                       vec3_t fogvec;
+                       VectorCopy(r_refdef.fogcolor, fogvec);
+                       //   color.rgb *= ContrastBoost * SceneBrightness;
+                       VectorScale(fogvec, r_refdef.view.colorscale, fogvec);
+                       r_refdef.fogcolor[0] = bound(0.0f, fogvec[0], 1.0f);
+                       r_refdef.fogcolor[1] = bound(0.0f, fogvec[1], 1.0f);
+                       r_refdef.fogcolor[2] = bound(0.0f, fogvec[2], 1.0f);
+               }
+       }
+}
+
+void R_UpdateVariables(void)
+{
+       R_Textures_Frame();
+
+       r_refdef.scene.ambient = r_ambient.value * (1.0f / 64.0f);
+
+       r_refdef.farclip = r_farclip_base.value;
+       if (r_refdef.scene.worldmodel)
+               r_refdef.farclip += r_refdef.scene.worldmodel->radius * r_farclip_world.value * 2;
+       r_refdef.nearclip = bound (0.001f, r_nearclip.value, r_refdef.farclip - 1.0f);
+
+       if (r_shadow_frontsidecasting.integer < 0 || r_shadow_frontsidecasting.integer > 1)
+               Cvar_SetValueQuick(&r_shadow_frontsidecasting, 1);
+       r_refdef.polygonfactor = 0;
+       r_refdef.polygonoffset = 0;
+       r_refdef.shadowpolygonfactor = r_refdef.polygonfactor + r_shadow_polygonfactor.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+       r_refdef.shadowpolygonoffset = r_refdef.polygonoffset + r_shadow_polygonoffset.value * (r_shadow_frontsidecasting.integer ? 1 : -1);
+
+       r_refdef.scene.rtworld = r_shadow_realtime_world.integer != 0;
+       r_refdef.scene.rtworldshadows = r_shadow_realtime_world_shadows.integer && vid.stencil;
+       r_refdef.scene.rtdlight = r_shadow_realtime_dlight.integer != 0 && !gl_flashblend.integer && r_dynamic.integer;
+       r_refdef.scene.rtdlightshadows = r_refdef.scene.rtdlight && r_shadow_realtime_dlight_shadows.integer && vid.stencil;
+       r_refdef.lightmapintensity = r_refdef.scene.rtworld ? r_shadow_realtime_world_lightmaps.value : 1;
+       if (FAKELIGHT_ENABLED)
+       {
+               r_refdef.lightmapintensity *= r_fakelight_intensity.value;
+       }
+       if (r_showsurfaces.integer)
+       {
+               r_refdef.scene.rtworld = false;
+               r_refdef.scene.rtworldshadows = false;
+               r_refdef.scene.rtdlight = false;
+               r_refdef.scene.rtdlightshadows = false;
+               r_refdef.lightmapintensity = 0;
+       }
+
        switch(vid.renderpath)
        {
        case RENDERPATH_GL20:
@@ -6899,7 +6902,7 @@ void R_RenderScene(void)
 
        r_refdef.stats.renders++;
 
-       R_UpdateFogColor();
+       R_UpdateFog();
 
        // don't let sound skip if going slow
        if (r_refdef.scene.extraupdate)
index d21ba62..34334e6 100644 (file)
@@ -17,6 +17,7 @@ int trans_sortarraysize;
 meshqueue_t **trans_hash = NULL;
 meshqueue_t ***trans_hashpointer = NULL;
 extern cvar_t r_transparent_sortarraysize;
+extern cvar_t r_transparent_sortmindist;
 extern cvar_t r_transparent_sortmaxdist;
 
 float mqt_viewplanedist;
@@ -73,8 +74,10 @@ void R_MeshQueue_RenderTransparent(void)
        // check for bad cvars
        if (r_transparent_sortarraysize.integer < 1 || r_transparent_sortarraysize.integer > 32768)
                Cvar_SetValueQuick(&r_transparent_sortarraysize, bound(1, r_transparent_sortarraysize.integer, 32768));
-       if (r_transparent_sortmaxdist.integer < 1 || r_transparent_sortmaxdist.integer > 32768)
-               Cvar_SetValueQuick(&r_transparent_sortmaxdist, bound(1, r_transparent_sortmaxdist.integer, 32768));
+       if (r_transparent_sortmindist.integer < 1 || r_transparent_sortmindist.integer >= r_transparent_sortmaxdist.integer)
+               Cvar_SetValueQuick(&r_transparent_sortmindist, 0);
+       if (r_transparent_sortmaxdist.integer < r_transparent_sortmindist.integer || r_transparent_sortmaxdist.integer > 32768)
+               Cvar_SetValueQuick(&r_transparent_sortmaxdist, bound(r_transparent_sortmindist.integer, r_transparent_sortmaxdist.integer, 32768));
 
        // update hash array
        if (trans_sortarraysize != r_transparent_sortarraysize.integer)
@@ -96,7 +99,7 @@ void R_MeshQueue_RenderTransparent(void)
        maxhashindex = trans_sortarraysize - 1;
        for (i = 0, mqt = mqt_array; i < mqt_count; i++, mqt++)
        {
-               hashindex = bound(0, (int)(min(mqt->dist, r_transparent_sortmaxdist.integer) * distscale), maxhashindex);
+               hashindex = bound(0, (int)(bound(0, mqt->dist - r_transparent_sortmindist.integer, r_transparent_sortmaxdist.integer) * distscale), maxhashindex);
                // link to tail of hash chain (to preserve render order)
                mqt->next = NULL;
                *trans_hashpointer[hashindex] = mqt;
index ed552a1..538a622 100644 (file)
--- a/server.h
+++ b/server.h
@@ -451,6 +451,8 @@ extern cvar_t sv_gameplayfix_swiminbmodels;
 extern cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag;
 extern cvar_t sv_gameplayfix_downtracesupportsongroundflag;
 extern cvar_t sv_gameplayfix_q1bsptracelinereportstexture;
+extern cvar_t sv_gameplayfix_unstickplayers;
+extern cvar_t sv_gameplayfix_unstickentities;
 extern cvar_t sv_gravity;
 extern cvar_t sv_idealpitchscale;
 extern cvar_t sv_jumpstep;
index 87187b5..aa7ce32 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -121,6 +121,8 @@ cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1", "
 cvar_t sv_gameplayfix_upwardvelocityclearsongroundflag = {0, "sv_gameplayfix_upwardvelocityclearsongroundflag", "1", "prevents monsters, items, and most other objects from being stuck to the floor when pushed around by damage, and other situations in mods"};
 cvar_t sv_gameplayfix_downtracesupportsongroundflag = {0, "sv_gameplayfix_downtracesupportsongroundflag", "1", "prevents very short moves from clearing onground (which may make the player stick to the floor at high netfps)"};
 cvar_t sv_gameplayfix_q1bsptracelinereportstexture = {0, "sv_gameplayfix_q1bsptracelinereportstexture", "1", "enables mods to get accurate trace_texture results on q1bsp by using a surface-hitting traceline implementation rather than the standard solidbsp method, q3bsp always reports texture accurately"};
+cvar_t sv_gameplayfix_unstickplayers = {0, "sv_gameplayfix_unstickplayers", "1", "big hack to try and fix the rare case of MOVETYPE_WALK entities getting stuck in the world clipping hull."};
+cvar_t sv_gameplayfix_unstickentities = {0, "sv_gameplayfix_unstickentities", "1", "hack to check if entities are crossing world collision hull and try to move them to the right position"};
 cvar_t sv_gravity = {CVAR_NOTIFY, "sv_gravity","800", "how fast you fall (512 = roughly earth gravity)"};
 cvar_t sv_idealpitchscale = {0, "sv_idealpitchscale","0.8", "how much to look up/down slopes and stairs when not using freelook"};
 cvar_t sv_jumpstep = {CVAR_NOTIFY, "sv_jumpstep", "0", "whether you can step up while jumping (sv_gameplayfix_stepwhilejumping must also be 1)"};
@@ -525,6 +527,8 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_upwardvelocityclearsongroundflag);
        Cvar_RegisterVariable (&sv_gameplayfix_downtracesupportsongroundflag);
        Cvar_RegisterVariable (&sv_gameplayfix_q1bsptracelinereportstexture);
+       Cvar_RegisterVariable (&sv_gameplayfix_unstickplayers);
+       Cvar_RegisterVariable (&sv_gameplayfix_unstickentities);
        Cvar_RegisterVariable (&sv_gravity);
        Cvar_RegisterVariable (&sv_idealpitchscale);
        Cvar_RegisterVariable (&sv_jumpstep);
index 7b9d705..629727c 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -2264,7 +2264,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);
 
@@ -2544,6 +2545,7 @@ SV_Physics_Toss
 Toss, bounce, and fly movement.  When onground, do nothing.
 =============
 */
+
 void SV_Physics_Toss (prvm_edict_t *ent)
 {
        trace_t trace;
@@ -2604,7 +2606,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)
index 617d1e3..f5d3293 100644 (file)
@@ -1101,6 +1101,7 @@ VM_SV_droptofloor
 void() droptofloor
 ===============
 */
+
 static void VM_SV_droptofloor (void)
 {
        prvm_edict_t            *ent;
@@ -1128,7 +1129,8 @@ static void VM_SV_droptofloor (void)
        end[2] -= 256;
 
        if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
-               SV_UnstickEntity(ent);
+               if (sv_gameplayfix_unstickentities.integer)
+                       SV_UnstickEntity(ent);
 
        trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
        if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
@@ -1141,7 +1143,8 @@ static void VM_SV_droptofloor (void)
                if (trace.startsolid)
                {
                        Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
-                       SV_UnstickEntity(ent);
+                       if (sv_gameplayfix_unstickentities.integer)
+                               SV_UnstickEntity(ent);
                        SV_LinkEdict(ent);
                        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
                        PRVM_serveredictedict(ent, groundentity) = 0;
@@ -1151,7 +1154,8 @@ static void VM_SV_droptofloor (void)
                {
                        Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
                        VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
-                       SV_UnstickEntity(ent);
+                       if (sv_gameplayfix_unstickentities.integer)
+                               SV_UnstickEntity(ent);
                        SV_LinkEdict(ent);
                        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
                        PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);