diff --git a/src/lua_hook.h b/src/lua_hook.h
index 265700e4f..ea11d0236 100644
--- a/src/lua_hook.h
+++ b/src/lua_hook.h
@@ -58,6 +58,7 @@ enum hook {
 	hook_ViewpointSwitch,
 	hook_SeenPlayer,
 	hook_PlayerThink,
+	hook_JingleStatus,
 
 	hook_MAX // last hook
 };
@@ -110,5 +111,6 @@ UINT8 LUAh_ViewpointSwitch(player_t *player, player_t *newdisplayplayer, boolean
 boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend); // Hook for MT_NAMECHECK
 #endif
 #define LUAh_PlayerThink(player) LUAh_PlayerHook(player, hook_PlayerThink) // Hook for P_PlayerThink
+boolean LUAh_JingleStatus(player_t *player, const char *musname); // Hook for whether a jingle of the given music should continue playing
 
 #endif
diff --git a/src/lua_hooklib.c b/src/lua_hooklib.c
index efed9adb7..c56336fca 100644
--- a/src/lua_hooklib.c
+++ b/src/lua_hooklib.c
@@ -69,6 +69,7 @@ const char *const hookNames[hook_MAX+1] = {
 	"ViewpointSwitch",
 	"SeenPlayer",
 	"PlayerThink",
+	"JingleStatus",
 	NULL
 };
 
@@ -80,7 +81,7 @@ struct hook_s
 	UINT16 id;
 	union {
 		mobjtype_t mt;
-		char *skinname;
+		char *skinname; // also used as musname for JingleStatus... I'm lazy
 		char *funcname;
 	} s;
 	boolean error;
@@ -148,6 +149,7 @@ static int lib_addHook(lua_State *L)
 		luaL_argcheck(L, hook.s.mt < NUMMOBJTYPES, 2, "invalid mobjtype_t");
 		break;
 	case hook_BotAI:
+	case hook_JingleStatus:
 		hook.s.skinname = NULL;
 		if (lua_isstring(L, 2))
 		{ // lowercase copy
@@ -1632,4 +1634,49 @@ boolean LUAh_SeenPlayer(player_t *player, player_t *seenfriend)
 }
 #endif // SEENAMES
 
+boolean LUAh_JingleStatus(player_t *player, const char *musname)
+{
+	hook_p hookp;
+	boolean keepplaying = false;
+	if (!gL || !(hooksAvailable[hook_JingleStatus/8] & (1<<(hook_JingleStatus%8))))
+		return true;
+
+	lua_settop(gL, 0);
+	hud_running = true; // local hook
+
+	for (hookp = roothook; hookp; hookp = hookp->next)
+	{
+		if (hookp->type == hook_JingleStatus) CONS_Printf("jingle status hook for %s vs %s\n", hookp->s.skinname, musname);
+
+		if (hookp->type != hook_JingleStatus
+			|| (hookp->s.skinname && strcmp(hookp->s.skinname, musname)))
+			continue;
+
+		if (lua_gettop(gL) == 0)
+		{
+			LUA_PushUserdata(gL, player, META_PLAYER);
+			lua_pushstring(gL, musname);
+		}
+		lua_pushfstring(gL, FMT_HOOKID, hookp->id);
+		lua_gettable(gL, LUA_REGISTRYINDEX);
+		lua_pushvalue(gL, -3);
+		lua_pushvalue(gL, -3);
+		if (lua_pcall(gL, 2, 1, 0)) {
+			if (!hookp->error || cv_debug & DBG_LUA)
+				CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
+			lua_pop(gL, 1);
+			hookp->error = true;
+			continue;
+		}
+		if (!lua_isnil(gL, -1) && lua_toboolean(gL, -1))
+			keepplaying = true; // Keep playing this boolean
+		lua_pop(gL, 1);
+	}
+
+	lua_settop(gL, 0);
+	hud_running = false;
+
+	return keepplaying;
+}
+
 #endif
diff --git a/src/p_local.h b/src/p_local.h
index 5e27379a7..99c465f9b 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -250,7 +250,7 @@ extern jingle_t jingleinfo[NUMJINGLES];
 #define JINGLEPOSTFADE 1000
 
 void P_PlayJingle(player_t *player, jingletype_t jingletype);
-boolean P_EvaluateMusicStatus(UINT16 status);
+boolean P_EvaluateMusicStatus(UINT16 status, const char *musname);
 void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, boolean looping, UINT16 status);
 
 //
diff --git a/src/p_user.c b/src/p_user.c
index 2dcfd872c..ab85897a5 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1541,7 +1541,7 @@ void P_PlayJingleMusic(player_t *player, const char *musname, UINT16 musflags, b
 	S_ChangeMusicInternal(musname, looping);
 }
 
-boolean P_EvaluateMusicStatus(UINT16 status)
+boolean P_EvaluateMusicStatus(UINT16 status, const char *musname)
 {
 	// \todo lua hook
 	int i;
@@ -1598,8 +1598,11 @@ boolean P_EvaluateMusicStatus(UINT16 status)
 				result = (players[i].nightstime && players[i].nightstime <= 10*TICRATE);
 				break;
 
-			case JT_NONE:   // Null state
 			case JT_OTHER:  // Other state
+				result = LUAh_JingleStatus(&players[i], musname);
+				break;
+
+			case JT_NONE:   // Null state
 			case JT_MASTER: // Main level music
 			default:
 				result = true;
diff --git a/src/s_sound.c b/src/s_sound.c
index 8193fdb9b..6507ffc02 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -2045,7 +2045,7 @@ static musicstack_t *S_GetMusicStackEntry(UINT16 status, boolean fromfirst, INT1
 
 		if (!status || mst->status == status)
 		{
-			if (P_EvaluateMusicStatus(mst->status))
+			if (P_EvaluateMusicStatus(mst->status, mst->musname))
 			{
 				if (!S_MusicExists(mst->musname, !midi_disabled, !digital_disabled)) // paranoia
 					S_RemoveMusicStackEntry(mst); // then continue