From 15ebb682aa68dae6adb414a5a3e09fc701339fdd Mon Sep 17 00:00:00 2001
From: sphere <spherallic@gmail.com>
Date: Tue, 1 Jun 2021 20:33:17 +0200
Subject: [PATCH] Some improvements to crumbling platforms. - The respawn timer
 can now be changed, instead of always being 15 seconds. - Tweaked the
 flashing so it looks a bit less weird.

---
 extras/conf/SRB2-22.cfg |  6 ++++++
 src/lua_baselib.c       |  3 ++-
 src/p_floor.c           | 11 ++++++-----
 src/p_mobj.c            |  8 ++++++--
 src/p_saveg.c           |  2 ++
 src/p_spec.c            |  9 ++++++++-
 src/p_spec.h            |  3 ++-
 src/p_user.c            |  7 ++++++-
 8 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index dd45a1845a..19a3c0ab39 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -1375,6 +1375,7 @@ linedeftypes
 			flags8text = "[3] Slope skew sides";
 			flags32text = "[5] Only block player";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			3dfloor = true;
 			3dfloorflags = "10019F";
 		}
@@ -1398,6 +1399,7 @@ linedeftypes
 			flags32text = "[5] Only block player";
 			flags64text = "[6] Don't cast shadow";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			3dfloor = true;
 			3dfloorflags = "210841F";
 			flags643dfloorflagsadd = "40";
@@ -1424,6 +1426,7 @@ linedeftypes
 			flags32text = "[5] Only block player";
 			flags64text = "[6] Don't cast shadow";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			flags8192text = "[13] Cut cyan flat pixels";
 			3dfloor = true;
 			3dfloorflags = "210959F";
@@ -1452,6 +1455,7 @@ linedeftypes
 			flags32text = "[5] Only block player";
 			flags64text = "[6] Spindash to move";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			3dfloor = true;
 			3dfloorflags = "14019F";
 		}
@@ -1475,6 +1479,7 @@ linedeftypes
 			flags8text = "[3] Slope skew sides";
 			flags32text = "[5] Only block player";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			3dfloor = true;
 			3dfloorflags = "14019F";
 		}
@@ -1498,6 +1503,7 @@ linedeftypes
 			flags32text = "[5] Only block player";
 			flags64text = "[6] Spindash to move";
 			flags128text = "[7] Only block non-players";
+			flags256text = "[8] Set respawn time to X offset";
 			3dfloor = true;
 			3dfloorflags = "10019F";
 		}
diff --git a/src/lua_baselib.c b/src/lua_baselib.c
index 350c1585fa..7d192e55ce 100644
--- a/src/lua_baselib.c
+++ b/src/lua_baselib.c
@@ -2530,6 +2530,7 @@ static int lib_evStartCrumble(lua_State *L)
 	player_t *player = NULL;
 	fixed_t origalpha;
 	boolean crumblereturn = lua_optboolean(L, 6);
+	int respawntimer = luaL_optinteger(L, 7, 0);
 	NOHUD
 	if (!sec)
 		return LUA_ErrInvalid(L, "sector_t");
@@ -2545,7 +2546,7 @@ static int lib_evStartCrumble(lua_State *L)
 		origalpha = luaL_checkfixed(L, 5);
 	else
 		origalpha = rover->alpha;
-	lua_pushboolean(L, EV_StartCrumble(sec, rover, floating, player, origalpha, crumblereturn) != 0);
+	lua_pushboolean(L, EV_StartCrumble(sec, rover, floating, player, origalpha, crumblereturn, respawntimer) != 0);
 	return 0;
 }
 
diff --git a/src/p_floor.c b/src/p_floor.c
index 263644f702..0c59412703 100644
--- a/src/p_floor.c
+++ b/src/p_floor.c
@@ -790,8 +790,8 @@ void T_StartCrumble(crumble_t *crumble)
 	{
 		if (crumble->timer > 0) // Count down the timer
 		{
-			if (--crumble->timer <= 0)
-				crumble->timer = -15*TICRATE; // Timer until platform returns to original position.
+			if (--crumble->timer <= 0) // Set timer until the platform returns to its original position
+				crumble->timer = (crumble->respawntimer == 0) ? -15*TICRATE : -crumble->respawntimer;
 			else
 			{
 				// Timer isn't up yet, so just keep waiting.
@@ -836,7 +836,7 @@ void T_StartCrumble(crumble_t *crumble)
 		}
 
 		// Flash to indicate that the platform is about to return.
-		if (crumble->timer > -224 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0))
+		if (crumble->timer >= -105 && (leveltime % ((abs(crumble->timer)/8) + 1) == 0))
 		{
 			TAG_ITER_SECTORS(tag, i)
 			{
@@ -859,7 +859,7 @@ void T_StartCrumble(crumble_t *crumble)
 					if (rover->alpha == crumble->origalpha)
 					{
 						rover->flags |= FF_TRANSLUCENT;
-						rover->alpha = 0x00;
+						rover->alpha = abs(crumble->timer) < crumble->origalpha ? abs(crumble->timer) : 0x00;
 					}
 					else
 					{
@@ -2322,7 +2322,7 @@ void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boole
 
 // Some other 3dfloor special things Tails 03-11-2002 (Search p_mobj.c for description)
 INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
-	player_t *player, fixed_t origalpha, boolean crumblereturn)
+	player_t *player, fixed_t origalpha, boolean crumblereturn, INT32 respawntimer)
 {
 	crumble_t *crumble;
 	sector_t *foundsec;
@@ -2356,6 +2356,7 @@ INT32 EV_StartCrumble(sector_t *sec, ffloor_t *rover, boolean floating,
 	crumble->floorwasheight = crumble->sector->floorheight;
 	crumble->ceilingwasheight = crumble->sector->ceilingheight;
 	crumble->timer = TICRATE;
+	crumble->respawntimer = respawntimer;
 	crumble->player = player;
 	crumble->origalpha = origalpha;
 
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 41377373dd..037a73edde 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -3290,7 +3290,7 @@ void P_MobjCheckWater(mobj_t *mobj)
 			{ // Water removes electric and non-water fire shields...
 			    if (electric)
 				    P_FlashPal(p, PAL_WHITE, 1);
-				
+
 				p->powers[pw_shield] = p->powers[pw_shield] & SH_STACK;
 			}
 		}
@@ -3750,6 +3750,7 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj)
 	for (node = mobj->touching_sectorlist; node; node = node->m_sectorlist_next)
 	{
 		ffloor_t *rover;
+		INT32 respawntimer = 0;
 
 		for (rover = node->m_sector->ffloors; rover; rover = rover->next)
 		{
@@ -3770,7 +3771,10 @@ static void P_CheckCrumblingPlatforms(mobj_t *mobj)
 					continue;
 			}
 
-			EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN));
+			if (rover->master->flags & ML_EFFECT3)
+				respawntimer = sides[rover->master->sidenum[0]].textureoffset >> FRACBITS;
+
+			EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), mobj->player, rover->alpha, !(rover->flags & FF_NORETURN), respawntimer);
 		}
 	}
 }
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 1270064c01..1104208b2b 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -2116,6 +2116,7 @@ static void SaveCrumbleThinker(const thinker_t *th, const UINT8 type)
 	WRITEINT32(save_p, ht->direction);
 	WRITEINT32(save_p, ht->origalpha);
 	WRITEINT32(save_p, ht->timer);
+	WRITEINT32(save_p, ht->respawntimer);
 	WRITEFIXED(save_p, ht->speed);
 	WRITEFIXED(save_p, ht->floorwasheight);
 	WRITEFIXED(save_p, ht->ceilingwasheight);
@@ -3248,6 +3249,7 @@ static thinker_t* LoadCrumbleThinker(actionf_p1 thinker)
 	ht->direction = READINT32(save_p);
 	ht->origalpha = READINT32(save_p);
 	ht->timer = READINT32(save_p);
+	ht->respawntimer = READINT32(save_p);
 	ht->speed = READFIXED(save_p);
 	ht->floorwasheight = READFIXED(save_p);
 	ht->ceilingwasheight = READFIXED(save_p);
diff --git a/src/p_spec.c b/src/p_spec.c
index 71628c4e2e..670e9e9cda 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -3174,6 +3174,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 				boolean foundrover = false; // for debug, "Can't find a FOF" message
 				player_t *player = NULL; // player that caused FOF to fall
 				boolean respawn = true; // should the fallen FOF respawn?
+				INT32 respawntimer = 0; // time before respawning
 
 				if (mo) // NULL check
 					player = mo->player;
@@ -3181,6 +3182,9 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 				if (line->flags & ML_NOCLIMB) // don't respawn!
 					respawn = false;
 
+				if (line->flags & ML_EFFECT3) // Set respawn time via X offset, so ACTUALLY use the tag for the sector tag :p
+					sectag = Tag_FGet(&line->tags);
+
 				TAG_ITER_SECTORS(sectag, secnum)
 				{
 					sec = sectors + secnum;
@@ -3200,7 +3204,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
 							if (line->flags & ML_BLOCKMONSTERS) // FOF flags determine respawn ability instead?
 								respawn = !(rover->flags & FF_NORETURN) ^ !!(line->flags & ML_NOCLIMB); // no climb inverts
 
-							EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn);
+							if (line->flags & ML_EFFECT3)
+								respawntimer = sides[line->sidenum[0]].textureoffset >> FRACBITS;
+
+							EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, respawn, respawntimer);
 						}
 					}
 
diff --git a/src/p_spec.h b/src/p_spec.h
index 3b8abfcf8a..b9e43cf73d 100644
--- a/src/p_spec.h
+++ b/src/p_spec.h
@@ -322,6 +322,7 @@ typedef struct
 	INT32 direction;
 	INT32 origalpha;
 	INT32 timer;
+	INT32 respawntimer;
 	fixed_t speed;
 	fixed_t floorwasheight; // Height the floor WAS at
 	fixed_t ceilingwasheight; // Height the ceiling WAS at
@@ -446,7 +447,7 @@ void EV_BounceSector(sector_t *sector, fixed_t momz, line_t *sourceline);
 
 // Some other special 3dfloor types
 INT32 EV_StartCrumble(sector_t *sector, ffloor_t *rover,
-	boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn);
+	boolean floating, player_t *player, fixed_t origalpha, boolean crumblereturn, INT32 respawntimer);
 
 void EV_DoContinuousFall(sector_t *sec, sector_t *backsector, fixed_t spd, boolean backwards);
 
diff --git a/src/p_user.c b/src/p_user.c
index 6eb2688d5c..e9fa9d1ea5 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3342,7 +3342,12 @@ static void P_DoClimbing(player_t *player)
 					if (floorclimb)
 					{
 						if (rover->flags & FF_CRUMBLE && !(netgame && player->spectator))
-							EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN));
+						{
+							INT32 respawntimer = 0;
+							if (rover->master->flags & ML_EFFECT3)
+								respawntimer = sides[rover->master->sidenum[0]].textureoffset >> FRACBITS;
+							EV_StartCrumble(rover->master->frontsector, rover, (rover->flags & FF_FLOATBOB), player, rover->alpha, !(rover->flags & FF_NORETURN), respawntimer);
+						}
 						break;
 					}
 				}
-- 
GitLab