From a6813ae08eaae54570136e4070aefbd75b918c66 Mon Sep 17 00:00:00 2001
From: toaster <rollerorbital@gmail.com>
Date: Fri, 24 Aug 2018 15:14:18 +0100
Subject: [PATCH] No longer are orbiting/trailing objects in charge of removing
 themselves. 	* They're clearly not quick enough at the job, since it causes
 a bunch of silly race conditions. 	* Instead, K_UpdateHnextList and
 K_CleanHnextList are in charge of removing them, which are called in the
 circumstances itemamount (and itemheld/eggmanheld) is changed. 	*
 Also, tweak a few places so that trailers AND orbiters can use the same
 system. Also, some minor thingies. 	* Turn all the useless ```if (a) { A }
 else if (!a) { B }``` bullshit into ```if (a) { A } else { B }``` bullshit. 
 * Fix up some minor inaccuracies in the playerarrow stuff that doesn't result
 in creating more sprites.

---
 objs/Mingw/SDL/Release/.gitignore |  2 +
 src/k_kart.c                      | 84 ++++++++++++++++++++++++-------
 src/k_kart.h                      |  2 +
 src/p_inter.c                     |  2 +-
 src/p_mobj.c                      | 60 +++++++++-------------
 5 files changed, 95 insertions(+), 55 deletions(-)
 create mode 100644 objs/Mingw/SDL/Release/.gitignore

diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore
new file mode 100644
index 000000000..42c6dc2c6
--- /dev/null
+++ b/objs/Mingw/SDL/Release/.gitignore
@@ -0,0 +1,2 @@
+# DON'T REMOVE
+# This keeps the folder from disappearing
diff --git a/src/k_kart.c b/src/k_kart.c
index f26e5910b..b9cc9febd 100644
--- a/src/k_kart.c
+++ b/src/k_kart.c
@@ -2792,6 +2792,48 @@ killnext:
 		goto killnext;
 }
 
+// Just for firing/dropping items.
+void K_CleanHnextList(mobj_t *work)
+{
+	mobj_t *nextwork;
+
+	if (!work)
+		return;
+
+	work = work->hnext;
+
+	while (work && !P_MobjWasRemoved(work))
+	{
+		nextwork = work->hnext;
+
+		P_RemoveMobj(work);
+
+		work = nextwork;
+	}
+}
+
+// Ditto.
+void K_UpdateHnextList(player_t *player)
+{
+	mobj_t *work = player->mo, *nextwork;
+
+	if (!work)
+		return;
+
+	work = work->hnext;
+
+	while (work && !P_MobjWasRemoved(work))
+	{
+		nextwork = work->hnext;
+
+		if (work->movedir > 0 && work->movedir > (UINT16)player->kartstuff[k_itemamount])
+			P_RemoveMobj(work);
+
+		work = nextwork;
+	}
+}
+
+// When an item in the hnext chain dies.
 void K_RepairOrbitChain(mobj_t *orbit)
 {
 	mobj_t *cachenext = orbit->hnext;
@@ -2832,6 +2874,7 @@ void K_RepairOrbitChain(mobj_t *orbit)
 	}
 }
 
+// Move the hnext chain!
 static void K_MoveHeldObjects(player_t *player)
 {
 	if (!player->mo)
@@ -3657,6 +3700,8 @@ void K_StripItems(player_t *player)
 	player->kartstuff[k_bananadrag] = 0;
 
 	player->kartstuff[k_sadtimer] = 0;
+
+	K_CleanHnextList(player->mo);
 }
 
 //
@@ -3722,6 +3767,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 			K_ThrowKartItem(player, false, MT_FAKEITEM, -1, false);
 			K_PlayTauntSound(player->mo);
 			player->kartstuff[k_eggmanheld] = 0;
+			K_CleanHnextList(player->mo);
 		}
 		// Rocket Sneaker
 		else if (ATTACK_IS_DOWN && !HOLDING_ITEM && onground && NO_HYUDORO
@@ -3796,7 +3842,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 							mo->flags |= MF_NOCLIPTHING;
 							mo->threshold = 10;
 							mo->movecount = player->kartstuff[k_itemamount];
-							mo->lastlook = moloop+1;
+							mo->movedir = moloop+1;
 							P_SetTarget(&mo->target, player->mo);
 							P_SetTarget(&mo->hprev, prev);
 							P_SetTarget(&prev->hnext, mo);
@@ -3807,8 +3853,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 					{
 						K_ThrowKartItem(player, false, MT_BANANA, -1, false);
 						K_PlayTauntSound(player->mo);
-						if (!(--player->kartstuff[k_itemamount]))
-							player->kartstuff[k_itemheld] = 0;
+						player->kartstuff[k_itemamount]--;
+						K_UpdateHnextList(player);
 					}
 					break;
 				case KITEM_EGGMAN:
@@ -3824,7 +3870,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 							mo->flags |= MF_NOCLIPTHING;
 							mo->threshold = 10;
 							mo->movecount = 1;
-							mo->lastlook = 1;
+							mo->movedir = 1;
 							P_SetTarget(&mo->target, player->mo);
 							P_SetTarget(&player->mo->hnext, mo);
 						}
@@ -3871,9 +3917,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 					{
 						K_ThrowKartItem(player, true, MT_ORBINAUT, 1, false);
 						K_PlayTauntSound(player->mo);
-
-						if (!(--player->kartstuff[k_itemamount]))
-							player->kartstuff[k_itemheld] = 0;
+						player->kartstuff[k_itemamount]--;
+						K_UpdateHnextList(player);
 					}
 					break;
 				case KITEM_JAWZ:
@@ -3919,9 +3964,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 						else if (player->kartstuff[k_throwdir] == -1) // Throwing backward gives you a dud that doesn't home in
 							K_ThrowKartItem(player, true, MT_JAWZ_DUD, -1, false);
 						K_PlayTauntSound(player->mo);
-
-						if (!(--player->kartstuff[k_itemamount]))
-							player->kartstuff[k_itemheld] = 0;
+						player->kartstuff[k_itemamount]--;
+						K_UpdateHnextList(player);
 					}
 					break;
 				case KITEM_MINE:
@@ -3936,7 +3980,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 							mo->flags |= MF_NOCLIPTHING;
 							mo->threshold = 10;
 							mo->movecount = 1;
-							mo->lastlook = 1;
+							mo->movedir = 1;
 							P_SetTarget(&mo->target, player->mo);
 							P_SetTarget(&player->mo->hnext, mo);
 						}
@@ -3947,6 +3991,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 						K_PlayTauntSound(player->mo);
 						player->kartstuff[k_itemamount]--;
 						player->kartstuff[k_itemheld] = 0;
+						K_CleanHnextList(player->mo);
 					}
 					break;
 				case KITEM_BALLHOG:
@@ -4073,8 +4118,11 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
 		}
 
 		// No more!
-		if (!player->kartstuff[k_itemamount] && !player->kartstuff[k_itemheld])
+		if (!player->kartstuff[k_itemamount])
+		{
+			player->kartstuff[k_itemheld] = 0;
 			player->kartstuff[k_itemtype] = KITEM_NONE;
+		}
 
 		if (player->kartstuff[k_itemtype] != KITEM_THUNDERSHIELD)
 			player->kartstuff[k_curshield] = 0;
@@ -4999,7 +5047,7 @@ static void K_drawKartItem(void)
 		{
 			if (leveltime & 2)
 				localpatch = kp_hyudoro[offset];
-			else if (!(leveltime & 2))
+			else
 				localpatch = kp_nodraw;
 		}
 		else if ((stplyr->kartstuff[k_stealingtimer] > 0) && (leveltime & 2))
@@ -5010,7 +5058,7 @@ static void K_drawKartItem(void)
 		{
 			if (leveltime & 1)
 				localpatch = kp_eggman[offset];
-			else if (!(leveltime & 1))
+			else
 				localpatch = kp_nodraw;
 		}
 		else if (stplyr->kartstuff[k_rocketsneakertimer] > 1)
@@ -5018,26 +5066,26 @@ static void K_drawKartItem(void)
 			itembar = stplyr->kartstuff[k_rocketsneakertimer];
 			if (leveltime & 1)
 				localpatch = kp_rocketsneaker[offset];
-			else if (!(leveltime & 1))
+			else
 				localpatch = kp_nodraw;
 		}
 		else if (stplyr->kartstuff[k_growshrinktimer] > 1)
 		{
 			if (leveltime & 1)
 				localpatch = kp_grow[offset];
-			else if (!(leveltime & 1))
+			else
 				localpatch = kp_nodraw;
 		}
 		else if (stplyr->kartstuff[k_sadtimer] > 0)
 		{
 			if (leveltime & 2)
 				localpatch = kp_sadface[offset];
-			else if (!(leveltime & 2))
+			else
 				localpatch = kp_nodraw;
 		}
 		else
 		{
-			if (!(stplyr->kartstuff[k_itemamount] || stplyr->kartstuff[k_itemheld]))
+			if (stplyr->kartstuff[k_itemamount] <= 0)
 				return;
 
 			switch(stplyr->kartstuff[k_itemtype])
diff --git a/src/k_kart.h b/src/k_kart.h
index 29eed33d9..89f1ea7e7 100644
--- a/src/k_kart.h
+++ b/src/k_kart.h
@@ -39,6 +39,8 @@ void K_DriftDustHandling(mobj_t *spawner);
 void K_DoSneaker(player_t *player, boolean doPFlag);
 void K_DoPogoSpring(mobj_t *mo, fixed_t vertispeed, boolean mute);
 void K_KillBananaChain(mobj_t *banana, mobj_t *inflictor, mobj_t *source);
+void K_CleanHnextList(mobj_t *work);
+void K_UpdateHnextList(player_t *player);
 void K_RepairOrbitChain(mobj_t *orbit);
 boolean K_CheckPlayersRespawnColliding(INT32 playernum, fixed_t x, fixed_t y);
 INT16 K_GetKartTurnValue(player_t *player, INT16 turnvalue);
diff --git a/src/p_inter.c b/src/p_inter.c
index 9fd8d5cda..f980e70d1 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -2221,7 +2221,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
 			if ((target->type == MT_BANANA_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_BANANA) // trail items
 				|| (target->type == MT_SSMINE_SHIELD && target->target->player->kartstuff[k_itemtype] == KITEM_MINE))
 			{
-				if (target->lastlook != 0 && target->lastlook < target->target->player->kartstuff[k_itemamount])
+				if (target->movedir != 0 && target->movedir < (UINT16)target->target->player->kartstuff[k_itemamount])
 				{
 					if (target->target->hnext)
 						K_KillBananaChain(target->target->hnext, inflictor, source);
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 82c0c769a..eea69ddef 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -6715,12 +6715,15 @@ void P_MobjThinker(mobj_t *mobj)
 				}
 				break;
 			}
-			case MT_ORBINAUT_SHIELD: // Kart orbit items
+			case MT_ORBINAUT_SHIELD: // Kart orbit/trail items
 			case MT_JAWZ_SHIELD:
-				if (mobj->health > 0 && mobj->target && mobj->target->player
+			case MT_BANANA_SHIELD:
+			case MT_SSMINE_SHIELD:
+			case MT_FAKESHIELD:
+				/*if (mobj->health > 0 && mobj->target && mobj->target->player
 					&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
 				{
-					// Was this so hard?
+					// Was this so hard? -- Handled this with K_UpdateHnextList and K_ClearHnextList instead of thinking it away...
 					if ((mobj->type == MT_ORBINAUT_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_ORBINAUT)
 						|| (mobj->type == MT_JAWZ_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_JAWZ)
 						|| (mobj->movedir > 0 && ((UINT16)mobj->target->player->kartstuff[k_itemamount] < mobj->movedir))
@@ -6730,33 +6733,7 @@ void P_MobjThinker(mobj_t *mobj)
 						return;
 					}
 				}
-				else if ((mobj->health > 0
-					&& (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator))
-					|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
-					|| P_CheckDeathPitCollide(mobj)) // When in death state
-				{
-					P_RemoveMobj(mobj);
-					return;
-				}
-				break;
-			case MT_BANANA_SHIELD: // Kart trailing items
-			case MT_SSMINE_SHIELD:
-			case MT_FAKESHIELD:
-				if (mobj->health > 0 && mobj->target && mobj->target->player
-					&& mobj->target->player->health > 0 && !mobj->target->player->spectator)
-				{
-					// Was this so hard?
-					if ((mobj->type == MT_BANANA_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_BANANA)
-						|| (mobj->type == MT_SSMINE_SHIELD && mobj->target->player->kartstuff[k_itemtype] != KITEM_MINE)
-						|| (mobj->type == MT_FAKESHIELD && !mobj->target->player->kartstuff[k_eggmanheld])
-						|| (mobj->type != MT_FAKESHIELD && (!mobj->target->player->kartstuff[k_itemheld]
-						|| (mobj->lastlook > 0 && mobj->target->player->kartstuff[k_itemamount] < mobj->lastlook))))
-					{
-						P_RemoveMobj(mobj);
-						return;
-					}
-				}
-				else if ((mobj->health > 0
+				else*/ if ((mobj->health > 0
 					&& (!mobj->target || !mobj->target->player || mobj->target->player->health <= 0 || mobj->target->player->spectator))
 					|| (mobj->health <= 0 && mobj->z <= mobj->floorz)
 					|| P_CheckDeathPitCollide(mobj)) // When in death state
@@ -6973,10 +6950,10 @@ void P_MobjThinker(mobj_t *mobj)
 							P_SetMobjState(mobj, S_PLAYERARROW_BOX);
 							mobj->tracer->sprite = SPR_ITEM;
 							mobj->tracer->frame = FF_FULLBRIGHT|KITEM_HYUDORO;
-							if (!(leveltime & 2))
-								mobj->tracer->flags2 |= MF2_DONTDRAW;
-							else
+							if (leveltime & 2)
 								mobj->tracer->flags2 &= ~MF2_DONTDRAW;
+							else
+								mobj->tracer->flags2 |= MF2_DONTDRAW;
 						}
 						else if ((mobj->target->player->kartstuff[k_stealingtimer] > 0) && (leveltime & 2))
 						{
@@ -6991,9 +6968,20 @@ void P_MobjThinker(mobj_t *mobj)
 							mobj->tracer->sprite = SPR_ITEM;
 							mobj->tracer->frame = FF_FULLBRIGHT|KITEM_EGGMAN;
 							if (leveltime & 1)
-								mobj->tracer->flags2 |= MF2_DONTDRAW;
+								mobj->tracer->flags2 &= ~MF2_DONTDRAW;
 							else
+								mobj->tracer->flags2 |= MF2_DONTDRAW;
+						}
+						else if (stplyr->kartstuff[k_rocketsneakertimer] > 1)
+						{
+							//itembar = stplyr->kartstuff[k_rocketsneakertimer]; -- not today satan
+							P_SetMobjState(mobj, S_PLAYERARROW_BOX);
+							mobj->tracer->sprite = SPR_ITEM;
+							mobj->tracer->frame = FF_FULLBRIGHT|KITEM_ROCKETSNEAKER;
+							if (leveltime & 1)
 								mobj->tracer->flags2 &= ~MF2_DONTDRAW;
+							else
+								mobj->tracer->flags2 |= MF2_DONTDRAW;
 						}
 						else if (mobj->target->player->kartstuff[k_growshrinktimer] > 0)
 						{
@@ -7002,9 +6990,9 @@ void P_MobjThinker(mobj_t *mobj)
 							mobj->tracer->frame = FF_FULLBRIGHT|KITEM_GROW;
 
 							if (leveltime & 1)
-								mobj->tracer->flags2 |= MF2_DONTDRAW;
-							else
 								mobj->tracer->flags2 &= ~MF2_DONTDRAW;
+							else
+								mobj->tracer->flags2 |= MF2_DONTDRAW;
 						}
 						else if (mobj->target->player->kartstuff[k_itemtype] && mobj->target->player->kartstuff[k_itemamount] > 0)
 						{
-- 
GitLab