diff --git a/src/dehacked.c b/src/dehacked.c
index 0ba054f07c8be58349ce7373524170633165abfa..a350254949bbe35d56a7393e219c7477eaecc1a2 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -671,6 +671,22 @@ static void readfreeslots(MYFILE *f)
 						break;
 					}
 			}
+			else if (fastcmp(type, "SPR2_"))
+			{
+				// Search if we already have an SPR2 by that name...
+				for (i = SPR_FIRSTFREESLOT; i < free_spr2; i++)
+					if (memcmp(spr2names[i],word,4) == 0)
+						break;
+				// We found it? (Two mods using the same SPR2 name?) Then don't allocate another one.
+				if (i != free_spr2)
+					continue;
+				// Copy in the spr2 name and increment free_spr2.
+				if (free_spr2 < NUMPLAYERSPRITES) {
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
 			else
 				deh_warning("Freeslots: unknown enum class '%s' for '%s_%s'", type, type, word);
 		}
@@ -8292,7 +8308,7 @@ static inline int lib_freeslot(lua_State *L)
 				lua_pushinteger(L, sfx);
 				r++;
 			} else
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free SFX slots!\n");
 		}
 		else if (fastcmp(type, "SPR"))
 		{
@@ -8319,7 +8335,7 @@ static inline int lib_freeslot(lua_State *L)
 				break;
 			}
 			if (j > SPR_LASTFREESLOT)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free sprite slots!\n");
 		}
 		else if (fastcmp(type, "S"))
 		{
@@ -8334,7 +8350,7 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMSTATEFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free State slots!\n");
 		}
 		else if (fastcmp(type, "MT"))
 		{
@@ -8349,7 +8365,26 @@ static inline int lib_freeslot(lua_State *L)
 					break;
 				}
 			if (i == NUMMOBJFREESLOTS)
-				return r;
+				CONS_Alert(CONS_WARNING, "Ran out of free MobjType slots!\n");
+		}
+		else if (fastcmp(type, "SPR2"))
+		{
+			// Search if we already have an SPR2 by that name...
+			enum playersprite i;
+			for (i = SPR_FIRSTFREESLOT; i < free_spr2; i++)
+				if (memcmp(spr2names[i],word,4) == 0)
+					break;
+			// We don't, so allocate a new one.
+			if (i == free_spr2) {
+				if (free_spr2 < NUMPLAYERSPRITES)
+				{
+					CONS_Printf("Sprite SPR2_%s allocated.\n",word);
+					strncpy(spr2names[free_spr2],word,4);
+					spr2names[free_spr2++][4] = 0;
+				} else
+					CONS_Alert(CONS_WARNING, "Ran out of free SPR2 slots!\n");
+			}
+			r++;
 		}
 		Z_Free(s);
 		lua_remove(L, 1);
@@ -8516,7 +8551,7 @@ static inline int lib_getenum(lua_State *L)
 	}
 	else if (fastncmp("SPR2_",word,4)) {
 		p = word+5;
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < free_spr2; i++)
 			if (!spr2names[i][4])
 			{
 				// special 3-char cases, e.g. SPR2_RUN
diff --git a/src/info.c b/src/info.c
index 8d7c249adf02e473e336f349d057685d3fe5379a..d6ccab1f983650dd3779739f88fbf9ee48c4c22c 100644
--- a/src/info.c
+++ b/src/info.c
@@ -99,6 +99,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SRID",
 	"SFLT"
 };
+enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
 
 // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
 state_t states[NUMSTATES] =
diff --git a/src/info.h b/src/info.h
index e313526b92b18950114c1996c170cb56d7822d31..67602b30175c0d3ea419b98ccb21db16806fa97d 100644
--- a/src/info.h
+++ b/src/info.h
@@ -618,6 +618,8 @@ enum playersprite
 	SPR2_SRID,
 	SPR2_SFLT,
 
+	SPR2_FIRSTFREESLOT,
+	SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
 	NUMPLAYERSPRITES
 };
 
@@ -3528,8 +3530,9 @@ typedef struct
 
 extern state_t states[NUMSTATES];
 extern char sprnames[NUMSPRITES + 1][5];
-char spr2names[NUMPLAYERSPRITES][5];
+extern char spr2names[NUMPLAYERSPRITES][5];
 extern state_t *astate;
+extern enum playersprite free_spr2;
 
 typedef enum mobj_type
 {
diff --git a/src/lua_infolib.c b/src/lua_infolib.c
index a983bb00295a348e16dbabb77377c889e223bf17..1925ffd35501c1f388ab6ef7a32ac54986e1364e 100644
--- a/src/lua_infolib.c
+++ b/src/lua_infolib.c
@@ -105,7 +105,7 @@ static int lib_getSpr2name(lua_State *L)
 	if (lua_isnumber(L, 1))
 	{
 		i = lua_tonumber(L, 1);
-		if (i > NUMPLAYERSPRITES)
+		if (i >= free_spr2)
 			return 0;
 		lua_pushlstring(L, spr2names[i], 4);
 		return 1;
@@ -113,7 +113,7 @@ static int lib_getSpr2name(lua_State *L)
 	else if (lua_isstring(L, 1))
 	{
 		const char *name = lua_tostring(L, 1);
-		for (i = 0; i < NUMPLAYERSPRITES; i++)
+		for (i = 0; i < free_spr2; i++)
 			if (fastcmp(name, spr2names[i]))
 			{
 				lua_pushinteger(L, i);
@@ -125,7 +125,7 @@ static int lib_getSpr2name(lua_State *L)
 
 static int lib_spr2namelen(lua_State *L)
 {
-	lua_pushinteger(L, NUMPLAYERSPRITES);
+	lua_pushinteger(L, free_spr2);
 	return 1;
 }
 
diff --git a/src/r_things.c b/src/r_things.c
index 60fbad1af0d7f4a1a18b288d444a03fe0ded3a29..461ac978c918fcc9e3ca5724b996c9824875262e 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2671,7 +2671,7 @@ next_token:
 			if (z < lastlump) lastlump = z;
 
 			// load all sprite sets we are aware of.
-			for (sprite2 = 0; sprite2 < NUMPLAYERSPRITES; sprite2++)
+			for (sprite2 = 0; sprite2 < free_spr2; sprite2++)
 				R_AddSingleSpriteDef(spr2names[sprite2], &skin->sprites[sprite2], wadnum, lump, lastlump);
 		}