From a36912baef77220d62c88cbfd114c993ff594765 Mon Sep 17 00:00:00 2001
From: toasterbabe <rollerorbital@gmail.com>
Date: Wed, 12 Oct 2016 23:47:18 +0100
Subject: [PATCH] In Mario mode... * shields give you 1000 points * redundant
 shields don't make you puase * checkpoints give you 2000 points * falling
 down a deathpit is just falling, not bouncing

---
 src/info.c    |  2 +-
 src/p_enemy.c | 55 +++++++++++++++++++++------------
 src/p_inter.c | 85 +++++++++++++++++++++++++++++++++------------------
 src/p_local.h |  4 +--
 src/p_mobj.c  |  2 +-
 src/p_user.c  | 21 ++++++++++---
 6 files changed, 111 insertions(+), 58 deletions(-)

diff --git a/src/info.c b/src/info.c
index f7ff3f13d..c27a606fb 100644
--- a/src/info.c
+++ b/src/info.c
@@ -12236,7 +12236,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL,         // missilestate
 		S_NULL,         // deathstate
 		S_NULL,         // xdeathstate
-		sfx_mario3,     // deathsound
+		sfx_None,       // deathsound
 		0,              // speed
 		16*FRACUNIT,    // radius
 		32*FRACUNIT,    // height
diff --git a/src/p_enemy.c b/src/p_enemy.c
index 104e53f1e..dccc6a8ea 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -3058,9 +3058,10 @@ void A_JumpShield(mobj_t *actor)
 
 	player = actor->target->player;
 
-	S_StartSound(player->mo, actor->info->seesound);
-
-	P_SwitchShield(player, SH_JUMP);
+	if (P_SwitchShield(player, SH_JUMP))
+		S_StartSound(player->mo, actor->info->seesound);
+	else if (mariomode)
+		S_StartSound(player->mo, sfx_itemup);
 }
 
 // Function: A_RingShield
@@ -3086,9 +3087,10 @@ void A_RingShield(mobj_t *actor)
 
 	player = actor->target->player;
 
-	S_StartSound(player->mo, actor->info->seesound);
-
-	P_SwitchShield(player, SH_ATTRACT);
+	if (P_SwitchShield(player, SH_ATTRACT))
+		S_StartSound(player->mo, actor->info->seesound);
+	else if (mariomode)
+		S_StartSound(player->mo, sfx_itemup);
 }
 
 // Function: A_RingBox
@@ -3287,10 +3289,9 @@ void A_BombShield(mobj_t *actor)
 	if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB)
 		P_BlackOw(player);
 
-	S_StartSound(player->mo, actor->info->seesound);
-
 	// Now we know for certain that we don't have a bomb shield, so add one. :3
-	P_SwitchShield(player, SH_BOMB);
+	P_SwitchShield(player, SH_BOMB); // will never return false, so no need for sound test
+	S_StartSound(player->mo, actor->info->seesound);
 }
 
 // Function: A_WaterShield
@@ -3316,9 +3317,10 @@ void A_WaterShield(mobj_t *actor)
 
 	player = actor->target->player;
 
-	S_StartSound(player->mo, actor->info->seesound);
-
-	P_SwitchShield(player, SH_ELEMENTAL);
+	if (P_SwitchShield(player, SH_ELEMENTAL))
+		S_StartSound(player->mo, actor->info->seesound);
+	else if (mariomode)
+		S_StartSound(player->mo, sfx_itemup);
 
 	if (player->powers[pw_underwater] && player->powers[pw_underwater] <= 12*TICRATE + 1)
 		P_RestoreMusic(player);
@@ -3355,18 +3357,23 @@ void A_ForceShield(mobj_t *actor)
 
 	player = actor->target->player;
 
-	S_StartSound(player->mo, actor->info->seesound);
-
 	//can't use P_SwitchShield(player, SH_FORCE) - special case
 
-	if (mariomode && player->mo)
+	if (mariomode)
 	{
-		player->mo->movecount = player->powers[pw_shield];
-		player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
+		mobj_t *scoremobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (player->mo->height / 2), MT_SCORE);
+		P_SetMobjState(scoremobj, mobjinfo[MT_SCORE].spawnstate+3); // 1000
+		P_AddPlayerScore(player, 1000);
 	}
 
 	if (!(player->powers[pw_shield] & SH_FORCE))
 	{
+		if (mariomode)
+		{
+			player->mo->movecount = player->powers[pw_shield];
+			player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
+		}
+
 		// Just in case.
 		if (player->pflags & PF_SHIELDABILITY)
 		{
@@ -3376,9 +3383,14 @@ void A_ForceShield(mobj_t *actor)
 
 		player->powers[pw_shield] = SH_FORCE|(player->powers[pw_shield] & SH_STACK)|0x01;
 		P_SpawnShieldOrb(player);
+		S_StartSound(player->mo, actor->info->seesound);
 	}
 	else
+	{
 		player->powers[pw_shield] = SH_FORCE|(player->powers[pw_shield] & SH_STACK)|0x01;
+		if (mariomode)
+			S_StartSound(player->mo, sfx_itemup);
+	}
 }
 
 // Function: A_PityShield
@@ -3408,11 +3420,14 @@ void A_PityShield(mobj_t *actor)
 
 	player = actor->target->player;
 
-	S_StartSound(player->mo, actor->info->seesound);
-
-	if (player->powers[pw_shield] && mariomode) return;
+	if (player->powers[pw_shield] && mariomode)
+	{
+		S_StartSound(player->mo, sfx_itemup);
+		return;
+	}
 
 	P_SwitchShield(player, SH_PITY);
+	S_StartSound(player->mo, actor->info->seesound);
 }
 
 
diff --git a/src/p_inter.c b/src/p_inter.c
index 9c8885411..05f8b3d4e 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1138,6 +1138,20 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 		case MT_FIREFLOWER:
 			if (player->bot)
 				return;
+			{
+				mobj_t *scoremobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + (toucher->height / 2), MT_SCORE);
+				P_SetMobjState(scoremobj, mobjinfo[MT_SCORE].spawnstate+3); // 1000
+				P_AddPlayerScore(player, 1000);
+			}
+
+			if ((player->powers[pw_shield] & SH_NOSTACK) == SH_FIREFLOWER)
+			{
+				S_StartSound(toucher, sfx_itemup);
+				break;
+			}
+			else
+				S_StartSound(toucher, sfx_mario3);
+
 			if (mariomode)
 			{
 				toucher->movecount = player->powers[pw_shield];
@@ -1145,9 +1159,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 				if ((player->powers[pw_shield] & SH_NOSTACK) == SH_PITY)
 					player->powers[pw_shield] &= SH_NOSTACK;
 			}
-			player->powers[pw_shield] |= SH_FIREFLOWER;
+			player->powers[pw_shield] |= SH_FIREFLOWER; //= (player->powers[pw_shield] & SH_NOSTACK)|SH_FIREFLOWER; -- perfect implementation, not worth it whilst we only have one stack power
 			toucher->color = SKINCOLOR_WHITE;
 			G_GhostAddColor(GHC_FIREFLOWER);
+
 			break;
 
 // *************** //
@@ -1211,13 +1226,18 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 
 			S_StartSound(toucher, special->info->painsound);
 
-			if (mariomode && !player->powers[pw_shield])
+			if (mariomode)
 			{
-				S_StartSound(toucher, sfx_mario3);
-				player->mo->movecount = player->powers[pw_shield];
-				player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
-				player->powers[pw_shield] = SH_PITY;
-				P_SpawnShieldOrb(player);
+				mobj_t *scoremobj = P_SpawnMobj(toucher->x, toucher->y, toucher->z + (toucher->height / 2), MT_SCORE);
+				P_SetMobjState(scoremobj, mobjinfo[MT_SCORE].spawnstate+7); // 2000
+				P_AddPlayerScore(player, 2000);
+				if (!player->powers[pw_shield])
+				{
+					S_StartSound(toucher, sfx_mario3);
+					player->mo->movecount = player->powers[pw_shield];
+					player->powers[pw_shield] = SH_PITY;
+					P_SpawnShieldOrb(player);
+				}
 			}
 
 			if (!(netgame && circuitmap && player != &players[consoleplayer]))
@@ -2013,9 +2033,6 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
 		}
 
 		target->flags2 &= ~MF2_DONTDRAW;
-
-		if (mariomode)
-			target->player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
 	}
 
 	// if killed by a player
@@ -2281,24 +2298,32 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
 			break;
 
 		case MT_PLAYER:
-			target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
-			target->momx = target->momy = target->momz = 0;
-			if (damagetype == DMG_DROWNED) // drowned
 			{
-				target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack.
-				if (target->player->charflags & SF_MACHINE)
-					S_StartSound(target, sfx_fizzle);
+				boolean mariodeathpit = (mariomode && damagetype == DMG_DEATHPIT);
+				target->fuse = TICRATE*3; // timer before mobj disappears from view (even if not an actual player)
+				if (!mariodeathpit)
+				{
+					target->player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
+					target->momx = target->momy = target->momz = 0;
+				}
+				if (damagetype == DMG_DROWNED) // drowned
+				{
+					target->movedir = damagetype; // we're MOVING the Damage Into anotheR function... Okay, this is a bit of a hack.
+					if (target->player->charflags & SF_MACHINE)
+						S_StartSound(target, sfx_fizzle);
+					else
+						S_StartSound(target, sfx_drown);
+					// Don't jump up when drowning
+				}
 				else
-					S_StartSound(target, sfx_drown);
-				// Don't jump up when drowning
-			}
-			else
-			{
-				P_SetObjectMomZ(target, 14*FRACUNIT, false);
-				if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
-					S_StartSound(target, sfx_spkdth);
-				else
-					P_PlayDeathSound(target);
+				{
+					if (!mariodeathpit)
+						P_SetObjectMomZ(target, 14*FRACUNIT, false);
+					if ((source && source->type == MT_SPIKE) || damagetype == DMG_SPIKE) // Spikes
+						S_StartSound(target, sfx_spkdth);
+					else
+						P_PlayDeathSound(target);
+				}
 			}
 			break;
 		default:
@@ -2656,9 +2681,11 @@ static void P_KillPlayer(player_t *player, mobj_t *source, INT32 damage)
 		P_PlayerEmeraldBurst(player, false);
 	}
 
-	// Get rid of shield
-	player->powers[pw_shield] = SH_NONE;
-	player->mo->color = player->skincolor;
+	if (!mariomode) // Get rid of shield
+	{
+		player->powers[pw_shield] = SH_NONE;
+		player->mo->color = player->skincolor;
+	}
 
 	// Get rid of emeralds
 	player->powers[pw_emeralds] = 0;
diff --git a/src/p_local.h b/src/p_local.h
index b1c9366c5..f10ac2a4d 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -62,7 +62,7 @@
 #define twodlevel (maptol & TOL_2D)
 
 #define mariomode (maptol & TOL_MARIO)
-#define shortmario(player) ((player && mariomode && !player->powers[pw_shield]) ? 1 : 0)
+#define shortmario(player) ((player && mariomode && !player->powers[pw_shield] && !objectplacing) ? 1 : 0)
 
 #define MARIOFLASHINGTICS 21
 
@@ -146,7 +146,7 @@ boolean P_InQuicksand(mobj_t *mo);
 void P_SetObjectMomZ(mobj_t *mo, fixed_t value, boolean relative);
 void P_RestoreMusic(player_t *player);
 void P_SpawnShieldOrb(player_t *player);
-void P_SwitchShield(player_t *player, UINT16 shieldtype);
+boolean P_SwitchShield(player_t *player, UINT16 shieldtype);
 mobj_t *P_SpawnGhostMobj(mobj_t *mobj);
 void P_GivePlayerRings(player_t *player, INT32 num_rings);
 void P_GivePlayerLives(player_t *player, INT32 numlives);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index de544362c..72b2eaf1d 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -3102,7 +3102,7 @@ static void P_PlayerZMovement(mobj_t *mo)
 
 		if (P_MobjFlip(mo)*mo->momz < 0) // falling
 		{
-			boolean clipmomz = true;
+			boolean clipmomz = !(P_CheckDeathPitCollide(mo));
 
 			mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement.
 
diff --git a/src/p_user.c b/src/p_user.c
index 1589d308a..d81c9e19f 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -1424,16 +1424,23 @@ void P_SpawnShieldOrb(player_t *player)
 //
 // Not for use if shieldtype would be SH_FORCE.
 //
-void P_SwitchShield(player_t *player, UINT16 shieldtype)
+boolean P_SwitchShield(player_t *player, UINT16 shieldtype)
 {
-	if (mariomode && player->mo)
+	if (mariomode)
 	{
-		player->mo->movecount = player->powers[pw_shield];
-		player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
-		player->powers[pw_nocontrol] += MARIOFLASHINGTICS;
+		mobj_t *scoremobj = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + (player->mo->height / 2), MT_SCORE);
+		P_SetMobjState(scoremobj, mobjinfo[MT_SCORE].spawnstate+3); // 1000
+		P_AddPlayerScore(player, 1000);
 	}
+
 	if ((player->powers[pw_shield] & SH_NOSTACK) != shieldtype)
 	{
+		if (mariomode)
+		{
+			player->mo->movecount = player->powers[pw_shield];
+			player->powers[pw_marioflashing] = MARIOFLASHINGTICS;
+		}
+
 		// Just in case.
 		if (player->pflags & PF_SHIELDABILITY)
 		{
@@ -1451,7 +1458,9 @@ void P_SwitchShield(player_t *player, UINT16 shieldtype)
 
 		player->powers[pw_shield] = shieldtype|(player->powers[pw_shield] & SH_STACK);
 		P_SpawnShieldOrb(player);
+		return true;
 	}
+	return false;
 }
 
 //
@@ -6232,6 +6241,8 @@ void P_BlackOw(player_t *player)
 
 	P_NukeEnemies(player->mo, player->mo, 1536*FRACUNIT); // Search for all nearby enemies and nuke their pants off!
 	player->powers[pw_shield] = player->powers[pw_shield] & SH_STACK;
+	if (mariomode && !player->powers[pw_shield])
+		player->powers[pw_shield] = SH_PITY;
 }
 
 void P_ElementalFire(player_t *player, boolean cropcircle)