From 8466dc5813db9ffd7edf9f80e59fa336e5b45c3f Mon Sep 17 00:00:00 2001
From: Nev3r <apophycens@gmail.com>
Date: Tue, 10 Dec 2019 18:03:15 +0100
Subject: [PATCH] Move mobj spawn Z calculating to a separate function.

---
 src/p_mobj.c  | 181 +++++++++++++++++++++-----------------------------
 src/p_setup.c |   6 +-
 2 files changed, 79 insertions(+), 108 deletions(-)

diff --git a/src/p_mobj.c b/src/p_mobj.c
index dea4a7a4d..e64fb1537 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -11550,6 +11550,80 @@ void P_MovePlayerToStarpost(INT32 playernum)
 mapthing_t *huntemeralds[MAXHUNTEMERALDS];
 INT32 numhuntemeralds;
 
+
+static fixed_t GetMobjSpawnHeight (const mobjtype_t i, const mapthing_t* mthing, const fixed_t x, const fixed_t y)
+{
+	subsector_t *ss = R_PointInSubsector(x, y);
+	fixed_t z;
+	fixed_t extraoffset = 0;
+	fixed_t heightoffset = 0;
+	boolean flip;
+
+	switch (i)
+	{
+	// Bumpers never spawn flipped.
+	case MT_NIGHTSBUMPER:
+		flip = false;
+		break;
+
+	// Axis objects snap to the floor.
+	case MT_AXIS:
+	case MT_AXISTRANSFER:
+	case MT_AXISTRANSFERLINE:
+		return ONFLOORZ;
+
+	// Objects with a non-zero default height.
+	case MT_CRAWLACOMMANDER:
+	case MT_DETON:
+	case MT_JETTBOMBER:
+	case MT_JETTGUNNER:
+	case MT_EGGMOBILE2:
+		heightoffset = mthing->z ? 0 : 33*FRACUNIT;
+		goto atend;
+	case MT_EGGMOBILE:
+		heightoffset = mthing->z ? 0 : 128*FRACUNIT;
+		goto atend;
+	case MT_GOLDBUZZ:
+	case MT_REDBUZZ:
+		heightoffset = mthing->z ? 0 : 288*FRACUNIT;
+		goto atend;
+
+	// Ring-like items, may float additional units with MTF_AMBUSH.
+	case MT_SPIKEBALL:
+	case MT_EMERALDSPAWN:
+	case MT_TOKEN:
+	case MT_EMBLEM:
+	weaponfloat:
+		flip = mthing->options & MTF_OBJECTFLIP;
+		extraoffset = mthing->options & MTF_AMBUSH ? 24*FRACUNIT : 0;
+		heightoffset = mthing->z*FRACUNIT;
+		break;
+
+	// Remaining objects.
+	default:
+		if (P_WeaponOrPanel(i))
+			goto weaponfloat; // Ring-like items don't use MF_SPAWNCEILING to consider flips.
+
+	atend:
+		heightoffset = mthing->z*FRACUNIT;
+		flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
+	}
+
+	// Establish height.
+	if (flip)
+		return (
+#ifdef ESLOPE
+			ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
+#endif
+			ss->sector->ceilingheight) - extraoffset - mobjinfo[i].height;
+	else
+		return (
+#ifdef ESLOPE
+			ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
+#endif
+			ss->sector->floorheight) + extraoffset + heightoffset;
+}
+
 //
 // P_SpawnMapThing
 // The fields of the mapthing should
@@ -11560,7 +11634,6 @@ void P_SpawnMapThing(mapthing_t *mthing)
 	mobjtype_t i;
 	mobj_t *mobj;
 	fixed_t x, y, z;
-	subsector_t *ss;
 	boolean doangle = true;
 
 	if (!mthing->type)
@@ -11685,13 +11758,6 @@ You should think about modifying the deathmatch starts to take full advantage of
 		if (gametype != GT_COOP)
 			return;
 
-		ss = R_PointInSubsector(mthing->x << FRACBITS, mthing->y << FRACBITS);
-		mthing->z = (INT16)(((
-#ifdef ESLOPE
-								ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, mthing->x << FRACBITS, mthing->y << FRACBITS) :
-#endif
-								ss->sector->floorheight)>>FRACBITS) + (mthing->options >> ZSHIFT));
-
 		if (numhuntemeralds < MAXHUNTEMERALDS)
 			huntemeralds[numhuntemeralds++] = mthing;
 		return;
@@ -11820,102 +11886,7 @@ You should think about modifying the deathmatch starts to take full advantage of
 	// spawn it
 	x = mthing->x << FRACBITS;
 	y = mthing->y << FRACBITS;
-	ss = R_PointInSubsector(x, y);
-
-	if (i == MT_NIGHTSBUMPER)
-		z = (
-#ifdef ESLOPE
-			ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
-#endif
-			ss->sector->floorheight) + ((mthing->options >> ZSHIFT) << FRACBITS);
-	else if (i == MT_AXIS || i == MT_AXISTRANSFER || i == MT_AXISTRANSFERLINE)
-		z = ONFLOORZ;
-	else if (i == MT_SPIKEBALL || P_WeaponOrPanel(i) || i == MT_EMERALDSPAWN || i == MT_TOKEN || i == MT_EMBLEM)
-	{
-		if (mthing->options & MTF_OBJECTFLIP)
-		{
-			z = (
-#ifdef ESLOPE
-			ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
-#endif
-			ss->sector->ceilingheight);
-
-			if (mthing->options & MTF_AMBUSH) // Special flag for rings
-				z -= 24*FRACUNIT;
-			if (mthing->options >> ZSHIFT)
-				z -= (mthing->options >> ZSHIFT)*FRACUNIT;
-
-			z -= mobjinfo[i].height; //Don't forget the height!
-		}
-		else
-		{
-			z = (
-#ifdef ESLOPE
-			ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
-#endif
-			ss->sector->floorheight);
-
-			if (mthing->options & MTF_AMBUSH) // Special flag for rings
-				z += 24*FRACUNIT;
-			if (mthing->options >> ZSHIFT)
-				z += (mthing->options >> ZSHIFT)*FRACUNIT;
-		}
-
-		if (z == ONFLOORZ)
-			mthing->z = 0;
-		else
-			mthing->z = (INT16)(z>>FRACBITS);
-	}
-	else
-	{
-		fixed_t offset = 0;
-		boolean flip = (!!(mobjinfo[i].flags & MF_SPAWNCEILING) ^ !!(mthing->options & MTF_OBJECTFLIP));
-
-		// base positions
-		if (flip)
-			z = (
-#ifdef ESLOPE
-			ss->sector->c_slope ? P_GetZAt(ss->sector->c_slope, x, y) :
-#endif
-			ss->sector->ceilingheight) - mobjinfo[i].height;
-		else
-			z = (
-#ifdef ESLOPE
-			ss->sector->f_slope ? P_GetZAt(ss->sector->f_slope, x, y) :
-#endif
-			ss->sector->floorheight);
-
-		// offsetting
-		if (mthing->options >> ZSHIFT)
-			offset = ((mthing->options >> ZSHIFT) << FRACBITS);
-		else if (i == MT_CRAWLACOMMANDER || i == MT_DETON || i == MT_JETTBOMBER || i == MT_JETTGUNNER || i == MT_EGGMOBILE2)
-			offset = 33*FRACUNIT;
-		else if (i == MT_EGGMOBILE)
-			offset = 128*FRACUNIT;
-		else if (i == MT_GOLDBUZZ || i == MT_REDBUZZ)
-			offset = 288*FRACUNIT;
-
-		// applying offsets! (if any)
-		if (flip)
-		{
-			if (offset)
-				z -= offset;
-			else
-				z = ONCEILINGZ;
-		}
-		else
-		{
-			if (offset)
-				z += offset;
-			else
-				z = ONFLOORZ;
-		}
-
-		if (z == ONFLOORZ)
-			mthing->z = 0;
-		else
-			mthing->z = (INT16)(z>>FRACBITS);
-	}
+	z = GetMobjSpawnHeight(i, mthing, x, y);
 
 	mobj = P_SpawnMobj(x, y, z, i);
 	mobj->spawnpoint = mthing;
@@ -12019,7 +11990,7 @@ You should think about modifying the deathmatch starts to take full advantage of
 		if (mthing->angle)
 			mobj->health = mthing->angle;
 		else
-			mobj->health = FixedMul(ss->sector->ceilingheight-ss->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
+			mobj->health = FixedMul(mobj->subsector->sector->ceilingheight - mobj->subsector->sector->floorheight, 3*(FRACUNIT/4))>>FRACBITS;
 		break;
 	case MT_METALSONIC_RACE:
 	case MT_METALSONIC_BATTLE:
diff --git a/src/p_setup.c b/src/p_setup.c
index 86cc9d810..d40c728ab 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1025,10 +1025,10 @@ static void P_PrepareRawThings(UINT8 *data, size_t i)
 
 		mt->type &= 4095;
 
-		if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo)) // NiGHTS Hoops
-			mt->z = mthing->options;
+		if (mt->type == 1705 || (mt->type == 750 && mt->extrainfo))
+			mt->z = mt->options; // NiGHTS Hoops use the full flags bits to set the height.
 		else
-			mt->z = mthing->options >> ZSHIFT;
+			mt->z = mt->options >> ZSHIFT;
 	}
 }
 
-- 
GitLab