diff --git a/src/deh_soc.c b/src/deh_soc.c
index dda3b2ef4b31352b1579623421cdc2733da56585..bb1f4aed120b46df5cf27e08d6df38fbbc3a4a2b 100644
--- a/src/deh_soc.c
+++ b/src/deh_soc.c
@@ -3453,6 +3453,18 @@ static void readcondition(UINT8 set, UINT32 id, char *word2)
 			return;
 		}
 	}
+	else if (fastcmp(params[0], "LUA"))
+	{
+		PARAMCHECK(1);
+		ty = UC_LUA;
+		re = atoi(params[1]);
+
+		if (re <= 0 || re > MAXLUACONDITIONS)
+		{
+			deh_warning("Lua condition %d out of range (1 - %d)", re, MAXLUACONDITIONS);
+			return;
+		}
+	}
 	else if (fastcmp(params[0], "CONDITIONSET"))
 	{
 		PARAMCHECK(1);
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index f6b8f462b5a41cee30c33145fd62fa28daa01e92..be054d1ba9dbb67b1498a52d7a202885f9fd05c7 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -3856,6 +3856,34 @@ static int lib_gAddGametype(lua_State *L)
 	return 0;
 }
 
+// Lua exclusive function to unlock Lua Conditions
+// Up to Lua scripter
+static int lib_gUnlockCondition(lua_State* L)
+{
+	int id = luaL_checkinteger(L, 1) - 1;
+	boolean global = luaL_checkboolean(L, 2);
+
+	if (id <= 0 || id > MAXLUACONDITIONS)
+	{
+		luaL_error(L, "Lua condition %d out of range (1 - %d)", id + 1, MAXLUACONDITIONS);
+		return 0;
+	}
+
+	if (global)
+	{
+		serverGamedata->lua[id] = true;
+		M_SilentUpdateUnlockablesAndEmblems(serverGamedata);
+	}
+
+	clientGamedata->lua[id] = true;
+	if (M_UpdateUnlockablesAndExtraEmblems(clientGamedata))
+	{
+		S_StartSound(NULL, sfx_s3k68);
+	}
+
+	return 0;
+}
+
 // Bot adding function!
 // Partly lifted from Got_AddPlayer
 static int lib_gAddPlayer(lua_State *L)
@@ -4603,6 +4631,7 @@ static luaL_Reg lib[] = {
 	{"G_AddGametype", lib_gAddGametype},
 	{"G_AddPlayer", lib_gAddPlayer},
 	{"G_RemovePlayer", lib_gRemovePlayer},
+	{"G_UnlockCondition", lib_gUnlockCondition},
 	{"G_SetUsedCheats", lib_gSetUsedCheats},
 	{"G_BuildMapName",lib_gBuildMapName},
 	{"G_BuildMapTitle",lib_gBuildMapTitle},
diff --git a/src/lua_hook.h b/src/lua_hook.h
index 37eb779d25f263845421abb4bf4a7b3484a6db1a..5208c56ab312a71076d914855d028f4dbeab9633 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -87,6 +87,7 @@ automatically.
 	X (scores),/* emblems/multiplayer list */\
 	X (title),/* titlescreen */\
 	X (titlecard),\
+	X (escpanel) /* rings/time/score/emblem panel in pause menu */,\
 	X (intermission),\
 	X (continue),\
 	X (playersetup),\
@@ -129,6 +130,10 @@ int  LUA_HookCharacterHUD
 	INT32 skinIndex, UINT8 sprite2, UINT8 frame, UINT8 rotation, skincolornum_t color,
 	INT32 ticker, boolean mode
 );
+int LUA_HookEscapePanel(
+	int hook, huddrawlist_h drawlist,
+	int x, int y, int width, int height
+);
 
 int  LUA_HookMobj(mobj_t *, int hook);
 int  LUA_Hook2Mobj(mobj_t *, mobj_t *, int hook);
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index b3ad0db311797202454d3507362fa8d32d50d7ee..a4d55d62433e1a89ef7e55c9f07c9c9c8218094b 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -710,6 +710,22 @@ int LUA_HookCharacterHUD
 	return hook.status;
 }
 
+int LUA_HookEscapePanel(int hook, huddrawlist_h drawlist, int x, int y, int width, int height)
+{
+	Hook_State hookstate;
+	if (prepare_hud_hook(&hookstate, false, hook))
+	{
+		LUA_SetHudHook(hook, drawlist);
+		lua_pushinteger(gL, x);
+		lua_pushinteger(gL, y);
+		lua_pushinteger(gL, width);
+		lua_pushinteger(gL, height);
+		call_hud_hooks(&hookstate, 1, res_true);
+	}
+	return hookstate.status;
+}
+
+
 /* =========================================================================
                                SPECIALIZED HOOKS
    ========================================================================= */
diff --git a/src/lua_script.c b/src/lua_script.c
index 057899555480383611652c552e41bf41398b0e2b..d34ab2b5fdeabfd7f02c5fc4c130c678772d8f65 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -412,6 +412,15 @@ int LUA_PushGlobals(lua_State *L, const char *word)
 	} else if (fastcmp(word, "token")) {
 		lua_pushinteger(L, token);
 		return 1;
+	} else if (fastcmp(word, "emblems")) {
+		lua_pushinteger(L, M_CountEmblems(clientGamedata));
+		return 1;
+	} else if (fastcmp(word, "numemblems")) {
+		lua_pushinteger(L, numemblems);
+		return 1;
+	} else if (fastcmp(word, "numextraemblems")) {
+		lua_pushinteger(L, numextraemblems);
+		return 1;
 	} else if (fastcmp(word, "gamestate")) {
 		lua_pushinteger(L, gamestate);
 		return 1;
diff --git a/src/m_cond.c b/src/m_cond.c
index 5a5913297157e24ada893ca5fad77a4d38ffd3e3..279eca8faf40a553f1df4c6fcd2ecbad29651498 100644
--- a/src/m_cond.c
+++ b/src/m_cond.c
@@ -155,6 +155,8 @@ void M_ClearSecrets(gamedata_t *data)
 		data->unlocked[i] = false;
 	for (i = 0; i < MAXCONDITIONSETS; ++i)
 		data->achieved[i] = false;
+	for (i = 0; i < MAXLUACONDITIONS; ++i)
+		data->lua[i] = false;
 
 	data->timesBeaten = data->timesBeatenWithEmeralds = data->timesBeatenUltimate = 0;
 
@@ -214,6 +216,8 @@ static UINT8 M_CheckCondition(condition_t *cn, gamedata_t *data)
 			return data->collected[cn->requirement-1];
 		case UC_EXTRAEMBLEM: // Requires extra emblem x to be obtained
 			return data->extraCollected[cn->requirement-1];
+		case UC_LUA:
+			return data->lua[cn->requirement-1];
 		case UC_CONDITIONSET: // requires condition set x to already be achieved
 			return M_Achieved(cn->requirement-1, data);
 	}
diff --git a/src/m_cond.h b/src/m_cond.h
index 2491a384c02aa5f34ba47933eba689811ac599d0..2e6606f560390044b4e04239f5b139587030b28f 100644
--- a/src/m_cond.h
+++ b/src/m_cond.h
@@ -47,6 +47,7 @@ typedef enum
 	UC_EMBLEM,          // EMBLEM [emblem number]
 	UC_EXTRAEMBLEM,     // EXTRAEMBLEM [extra emblem number]
 	UC_CONDITIONSET,    // CONDITIONSET [condition set number]
+	UC_LUA,				// LUA [condition set number]
 } conditiontype_t;
 
 // Condition Set information
@@ -141,6 +142,7 @@ typedef struct
 #define MAXEMBLEMS       512
 #define MAXEXTRAEMBLEMS   48
 #define MAXUNLOCKABLES    80
+#define MAXLUACONDITIONS 128
 
 /** Time attack information, currently a very small structure.
   */
@@ -202,6 +204,9 @@ typedef struct
 	// UNLOCKABLES UNLOCKED
 	boolean unlocked[MAXUNLOCKABLES];
 
+	// LUA DATA (NOT SAVED INTO GAMEDATA)
+	boolean lua[MAXLUACONDITIONS];
+
 	// TIME ATTACK DATA
 	recorddata_t *mainrecords[NUMMAPS];
 	nightsdata_t *nightsrecords[NUMMAPS];
diff --git a/src/m_menu.c b/src/m_menu.c
index 4d8ee17e8a50c582b910a1748d741997515d9457..30dc94a861dd328d13d8355599581466a206d7f9 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -186,6 +186,7 @@ static tic_t keydown = 0;
 
 // Lua
 static huddrawlist_h luahuddrawlist_playersetup;
+static huddrawlist_h luahuddrawlist_infoscreen;
 
 //
 // PROTOTYPES
@@ -393,6 +394,7 @@ static void M_DrawColorRamp(INT32 x, INT32 y, INT32 w, INT32 h, skincolor_t colo
 // Handling functions
 static boolean M_ExitPandorasBox(void);
 static boolean M_QuitMultiPlayerMenu(void);
+static boolean M_QuitPauseMenu(void);
 static void M_HandleAddons(INT32 choice);
 static void M_HandleLevelPlatter(INT32 choice);
 static void M_HandleSoundTest(INT32 choice);
@@ -3763,6 +3765,14 @@ void M_StartControlPanel(void)
 	CON_ToggleOff(); // move away console
 }
 
+static boolean M_QuitPauseMenu(void)
+{
+	LUA_HUD_DestroyDrawList(luahuddrawlist_infoscreen);
+	luahuddrawlist_infoscreen = NULL;
+
+	return true;
+}
+
 void M_EndModeAttackRun(void)
 {
 	G_ClearModeAttackRetryFlag();
@@ -4712,8 +4722,29 @@ static void M_DrawPauseMenu(void)
 		emblem_t *emblem_detail[3] = {NULL, NULL, NULL};
 		char emblem_text[3][20];
 		INT32 i;
+		INT16 xbox = 27;
+		INT16 ybox = 16;
+		INT16 widthbox = 32;
+		INT16 heightbox = 6;
 
-		M_DrawTextBox(27, 16, 32, 6);
+		M_DrawTextBox(xbox, ybox, widthbox, heightbox);
+
+		if (!LUA_HUD_IsDrawListValid(luahuddrawlist_infoscreen))
+		{
+			LUA_HUD_DestroyDrawList(luahuddrawlist_infoscreen);
+			luahuddrawlist_infoscreen = LUA_HUD_CreateDrawList();
+		}
+		LUA_HUD_ClearDrawList(luahuddrawlist_infoscreen);
+		
+		boolean esc_override = LUA_HookEscapePanel(
+			HUD_HOOK(escpanel),
+			luahuddrawlist_infoscreen,
+			xbox+5, ybox+5, widthbox*8+6, heightbox*8+6);
+
+		LUA_HUD_DrawList(luahuddrawlist_infoscreen);
+
+		if (esc_override)
+			goto draw_rest;
 
 		// Draw any and all emblems at the top.
 		M_DrawMapEmblems(gamemap, 272, 28, true);
@@ -4846,7 +4877,10 @@ static void M_DrawPauseMenu(void)
 		}
 	}
 
-	M_DrawGenericMenu();
+	draw_rest:
+	{
+		M_DrawGenericMenu();
+	}	
 }
 
 static void M_DrawCenteredMenu(void)
diff --git a/src/m_menu.h b/src/m_menu.h
index 99a5b6de4266be02b1cba0e98a26addac5524548..a791d56f40984c41bfd30c92006d5ad3e767d250 100644
--- a/src/m_menu.h
+++ b/src/m_menu.h
@@ -523,7 +523,7 @@ void M_FreePlayerSetupColors(void);
 	M_DrawPauseMenu,\
 	x, y,\
 	0,\
-	NULL\
+	M_QuitPauseMenu\
 }
 
 #define CENTERMENUSTYLE(id, header, source, prev, y)\