From 6c1629868fe84414d4f7595d28c8030dffab35d7 Mon Sep 17 00:00:00 2001
From: Lighto97 <lighto97@outlook.com>
Date: Fri, 7 Mar 2025 01:11:17 -0300
Subject: [PATCH] fix bubble shield trap respawn softlock

---
 src/d_player.h      |  2 ++
 src/k_respawn.c     |  6 ++++++
 src/lua_playerlib.c | 13 +++++++++++++
 src/p_inter.c       |  2 ++
 src/p_mobj.c        |  1 +
 5 files changed, 24 insertions(+)

diff --git a/src/d_player.h b/src/d_player.h
index f1458f7fc..3c010fbfc 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -775,6 +775,8 @@ struct player_t
 	UINT8 curshield;	// see kartshields_t
 	UINT8 bubblecool;	// Bubble Shield use cooldown
 	UINT8 bubbleblowup;	// Bubble Shield usage blowup
+	mobj_t *bubbletrap; // Bubble player is trapped inside
+	boolean gotbubbletrapped; //to know if player was got trapped
 	UINT16 flamedash;	// Flame Shield dash power
 	UINT16 flamemeter;	// Flame Shield dash meter left
 	UINT8 flamelength;	// Flame Shield dash meter, number of segments
diff --git a/src/k_respawn.c b/src/k_respawn.c
index 6fe2f9897..e8ba03976 100644
--- a/src/k_respawn.c
+++ b/src/k_respawn.c
@@ -726,6 +726,12 @@ static void K_DropDashWait(player_t *player)
 	if (player->pflags & PF_FAULT)
 		return;
 
+	// if player got trapped inside a ubble but lost its bubble object in a unintended way, remove no gravity flag
+	if ((P_MobjWasRemoved(player->bubbletrap) && player->gotbubbletrapped == true) && (player->mo->flags & MF_NOGRAVITY)
+	{
+		player->mo->flags &= ~MF_NOGRAVITY;
+	}
+
 	if (leveltime % 8 == 0)
 	{
 		const UINT8 ns = 8;
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index ee56da06f..daabaa701 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -430,6 +430,10 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->bubblecool);
 	else if (fastcmp(field,"bubbleblowup"))
 		lua_pushinteger(L, plr->bubbleblowup);
+	else if (fastcmp(field,"bubbletrap"))
+		LUA_PushUserdata(L, plr->bubbletrap, META_MOBJ);
+	else if (fastcmp(field,"gotbubbletrapped"))
+		lua_pushboolean(L, plr->gotbubbletrapped);
 	else if (fastcmp(field,"flamedash"))
 		lua_pushinteger(L, plr->flamedash);
 	else if (fastcmp(field,"counterdash"))
@@ -994,6 +998,15 @@ static int player_set(lua_State *L)
 		plr->bubblecool = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"bubbleblowup"))
 		plr->bubbleblowup = luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"bubbletrap"))
+	{
+		mobj_t *mo = NULL;
+		if (!lua_isnil(L, 3))
+			mo = *((mobj_t **)luaL_checkudata(L, 3, META_MOBJ));
+		P_SetTarget(&plr->bubbletrap, mo);
+	}
+	else if (fastcmp(field,"gotbubbletrapped"))
+		plr->gotbubbletrapped = luaL_checkboolean(L, 3);
 	else if (fastcmp(field,"flamedash"))
 		plr->flamedash = luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"counterdash"))
diff --git a/src/p_inter.c b/src/p_inter.c
index 49cae6cab..ed35a65b0 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -642,6 +642,8 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 			P_SetTarget(&special->tracer, toucher);
 			toucher->flags |= MF_NOGRAVITY;
 			toucher->momz = (8*toucher->scale) * P_MobjFlip(toucher);
+			toucher->player->gotbubbletrapped = true;
+			P_SetTarget(&toucher->player->bubbletrap, special); //allow it to access later on and to know if player is trapped
 
 			// Snap to the unfortunate player and quit moving laterally, or we can end up quite far away
 			special->momx = 0;
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 896af74d6..3eebff507 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -9387,6 +9387,7 @@ static boolean P_MobjRegularThink(mobj_t *mobj)
 			{
 				S_StartSound(mobj->tracer, sfx_s3k77);
 				mobj->tracer->flags &= ~MF_NOGRAVITY;
+				mobj->tracer->player->gotbubbletrapped = false;
 				P_KillMobj(mobj, mobj->tracer, mobj->tracer, DMG_NORMAL);
 				break;
 			}
-- 
GitLab