diff --git a/src/p_inter.c b/src/p_inter.c
index 71740822e6a7ed1b02903490298be939b448a47f..b2d1580621d7d5b2c19a1c037204838743705af5 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1869,6 +1869,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 
 	S_StartSound(toucher, special->info->deathsound); // was NULL, but changed to player so you could hear others pick up rings
 	P_KillMobj(special, NULL, toucher, 0);
+	special->shadowscale = 0;
 }
 
 /** Prints death messages relating to a dying or hit player.
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 50f6106d12e22fb26280730d861985d53aa66438..e4de5903194c9be9bc45bc54d9135f42573efd51 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -10557,6 +10557,22 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
 	else
 		mobj->z = z;
 
+	// Set shadowscale here, before spawn hook so that Lua can change it
+	if (
+		type == MT_PLAYER ||
+		type == MT_ROLLOUTROCK ||
+		type == MT_EGGMOBILE4_MACE ||
+		(type >= MT_SMALLMACE && type <= MT_REDSPRINGBALL) ||
+		(mobj->flags & MF_ENEMY)
+	)
+		mobj->shadowscale = FRACUNIT;
+	else if (
+		type >= MT_RING && type <= MT_FLINGEMERALD && type != MT_EMERALDSPAWN
+	)
+		mobj->shadowscale = 2*FRACUNIT/3;
+	else
+		mobj->shadowscale = 0;
+
 #ifdef HAVE_BLUA
 	// DANGER! This can cause P_SpawnMobj to return NULL!
 	// Avoid using P_RemoveMobj on the newly created mobj in "MobjSpawn" Lua hooks!
diff --git a/src/p_mobj.h b/src/p_mobj.h
index 92160d9e2d70f4634d90d47feed67cfa5940b1a9..fd0c95a56e16d1c0059515d7eb1653232af52b23 100644
--- a/src/p_mobj.h
+++ b/src/p_mobj.h
@@ -375,6 +375,7 @@ typedef struct mobj_s
 #endif
 
 	boolean colorized; // Whether the mobj uses the rainbow colormap
+	fixed_t shadowscale; // If this object casts a shadow, and the size relative to radius
 
 	// WARNING: New fields must be added separately to savegame and Lua.
 } mobj_t;
diff --git a/src/r_things.c b/src/r_things.c
index ff999352546418daf42e432576c3dff2b1a6d642..0fc80607170a91cc755312f5bcf770fb28226881 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -1902,19 +1902,8 @@ static void R_ProjectSprite(mobj_t *thing)
 	if (thing->subsector->sector->numlights)
 		R_SplitSprite(vis);
 
-	///@TODO temporary: whitelist. eventually: MF/2/E flag?
-	if ((
-		oldthing->type == MT_PLAYER ||
-		(oldthing->state - states) == S_RING ||
-		oldthing->type == MT_ROLLOUTROCK ||
-		oldthing->flags & MF_ENEMY ||
-		oldthing->type == MT_EGGMOBILE4_MACE ||
-		(oldthing->type >= MT_SMALLMACE && oldthing->type <= MT_REDSPRINGBALL) // .W.
-	) && !papersprite)
-		R_ProjectDropShadow(oldthing, vis,
-			///@TODO make this scale configurable!
-			((oldthing->state - states) == S_RING) ? 2*FRACUNIT/3 : FRACUNIT,
-		basetx, tz);
+	if (oldthing->shadowscale && !papersprite)
+		R_ProjectDropShadow(oldthing, vis, oldthing->shadowscale, basetx, tz);
 
 	// Debug
 	++objectsdrawn;