diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index f3df4f103f21aa910daa14cb2d57da0a94b73ed8..ac55febdad57cb9277ac717f59d4f6d3811d7b8d 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -519,8 +519,6 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
 		rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
 	for (j = 0; j < NUMKARTSTUFF; ++j)
 		rsp->kartstuff[j] = LONG(players[i].kartstuff[j]); // SRB2kart
-	for (j = 0; j < MAXPLAYERS; ++j)
-		rsp->collide[j] = (UINT8)players[i].collide[j]; // SRB2kart
 
 	// Score is resynched in the rspfirm resync packet
 	rsp->health = 0; // resynched with mo health
@@ -653,8 +651,6 @@ static void resynch_read_player(resynch_pak *rsp)
 		players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
 	for (j = 0; j < NUMKARTSTUFF; ++j)
 		players[i].kartstuff[j] = LONG(rsp->kartstuff[j]); // SRB2kart
-	for (j = 0; j < MAXPLAYERS; ++j)
-		players[i].collide[j] = (UINT8)rsp->collide[j]; // SRB2kart
 
 	// Score is resynched in the rspfirm resync packet
 	players[i].health = rsp->health;
diff --git a/src/d_player.h b/src/d_player.h
index c4390f9e66019185a636c55e16311d8df50309dd..44902ed6e75ba2517f5e3801a3173bbaa5cdb873 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -366,7 +366,6 @@ typedef struct player_s
 
 	// SRB2kart stuff
 	INT32 kartstuff[NUMKARTSTUFF];
-	boolean collide[MAXPLAYERS];
 
 	// Bit flags.
 	// See pflags_t, above.
diff --git a/src/g_game.c b/src/g_game.c
index effd212776448b8a6f4dd7596e0f334527de31f4..0f01562a8f30b81473681c88ed20c3fea8a8c7ee 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -2120,7 +2120,6 @@ static inline void G_PlayerFinishLevel(INT32 player)
 
 	memset(p->powers, 0, sizeof (p->powers));
 	memset(p->kartstuff, 0, sizeof (p->kartstuff)); // SRB2kart
-	memset(p->collide, 0, sizeof (p->collide)); // SRB2kart
 	p->ringweapons = 0;
 
 	p->mo->flags2 &= ~MF2_SHADOW; // cancel invisibility
diff --git a/src/k_kart.c b/src/k_kart.c
index fc60536845f2d18849b2fdac078cb6069c80219f..3135500da5c1f20565ef4f4c7b4a2287836da16d 100644
--- a/src/k_kart.c
+++ b/src/k_kart.c
@@ -1039,20 +1039,6 @@ static void K_KartItemRouletteByDistance(player_t *player, ticcmd_t *cmd)
 
 //{ SRB2kart p_user.c Stuff
 
-boolean K_IsTouching(mobj_t *mobj1, mobj_t *mobj2)
-{
-	if (mobj1 == NULL || mobj2 == NULL)
-		return false;
-	fixed_t absx = abs(mobj1->x - mobj2->x);
-	fixed_t absy = abs(mobj1->y - mobj2->y);
-	fixed_t absz = abs(mobj1->z - mobj2->z);
-
-	if (absx < 32*FRACUNIT && absy < 32*FRACUNIT && absz < 32*FRACUNIT)
-		return true;
-	else
-		return false;
-}
-
 void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce)
 {
 	fixed_t newx, newy;
@@ -1072,7 +1058,7 @@ void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce)
 		//S_StartSound(mobj2, cv_collidesoundnum.value);
 	}
 
-	fx = P_SpawnMobj((mobj1->x + mobj2->x)/2, (mobj1->y + mobj2->y)/2, (mobj1->z + mobj2->z)/2, MT_BUMP);
+	fx = P_SpawnMobj(mobj1->x/2 + mobj2->x/2, mobj1->y/2 + mobj2->y/2, mobj1->z/2 + mobj2->z/2, MT_BUMP);
 	if (mobj1->eflags & MFE_VERTICALFLIP)
 		fx->eflags |= MFE_VERTICALFLIP;
 	else
@@ -1125,58 +1111,20 @@ void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce)
 		mobj1->momz = mobj2->momz;
 		mobj2->momz = newz;
 	}
-}
 
-void K_KartBouncer(void)
-{
-	fixed_t i, j;
-	for (i = 0; i < MAXPLAYERS; i++)
-		if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
-			for (j = 0; j < MAXPLAYERS; j++)
-				players[i].collide[j] = false;
-	for (i = 0; i < MAXPLAYERS; i++)
-		if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo)
-			&& !players[i].kartstuff[k_growshrinktimer] 
-			&& !players[i].kartstuff[k_squishedtimer]
-			&& !players[i].kartstuff[k_bootaketimer]
-			&& !players[i].kartstuff[k_spinouttimer]
-			&& !players[i].kartstuff[k_startimer]
-			&& !players[i].kartstuff[k_justbumped])
-		{
-			for (j = i+1; j < MAXPLAYERS; j++)
-				if (playeringame[j] && players[j].mo && !P_MobjWasRemoved(players[j].mo)
-					&& !players[j].kartstuff[k_squishedtimer]
-					&& !players[j].kartstuff[k_growshrinktimer]
-					&& !players[j].kartstuff[k_bootaketimer]
-					&& !players[j].kartstuff[k_spinouttimer]
-					&& !players[j].kartstuff[k_startimer]
-					&& !players[j].kartstuff[k_justbumped])
-				{
-					if (players[j].mo == players[i].mo)
-						break;
-					if (K_IsTouching(players[i].mo, players[j].mo))
-					{
-						if (!players[i].collide[j] && !players[j].collide[i])
-						{
-							if (P_IsObjectOnGround(players[j].mo) && players[i].mo->momz < 0)
-								K_SwapMomentum(players[i].mo, players[j].mo, true);
-							else if (P_IsObjectOnGround(players[i].mo) && players[j].mo->momz < 0)
-								K_SwapMomentum(players[j].mo, players[i].mo, true);
-							else
-								K_SwapMomentum(players[i].mo, players[j].mo, false);
-							players[i].collide[j] = true;
-							players[i].kartstuff[k_justbumped] = 6; // let the animation finish before letting you bump again :V
-							players[j].collide[i] = true;
-							players[j].kartstuff[k_justbumped] = 6;
-						}
-					}
-					else
-					{
-						players[i].collide[j] = false;
-						players[j].collide[i] = false;
-					}
-				}
-		}
+	// Because this is done during collision now, rmomx and rmomy need to be recalculated
+	// so that friction doesn't immediately decide to stop the player if they're at a standstill
+	if (mobj1->player)
+	{
+		mobj1->player->rmomx = mobj1->momx - mobj1->player->cmomx;
+		mobj1->player->rmomy = mobj1->momy - mobj1->player->cmomy;
+	}
+
+	if (mobj2->player)
+	{
+		mobj2->player->rmomx = mobj2->momx - mobj2->player->cmomx;
+		mobj2->player->rmomy = mobj2->momy - mobj2->player->cmomy;
+	}
 }
 
 /**	\brief	Checks that the player is on an offroad subsector for realsies
diff --git a/src/k_kart.h b/src/k_kart.h
index 1cc5e9a1174b143b9079a8d847ed9233427793d6..1cd16e889df800a4ac395c9bfc9bde27a7f52e8e 100644
--- a/src/k_kart.h
+++ b/src/k_kart.h
@@ -15,7 +15,7 @@ UINT8 K_GetKartColorByName(const char *name);
 
 void K_RegisterKartStuff(void);
 
-void K_KartBouncer(void);
+void K_SwapMomentum(mobj_t *mobj1, mobj_t *mobj2, boolean bounce);
 void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
 void K_SpinPlayer(player_t *player, mobj_t *source);
 void K_SquishPlayer(player_t *player, mobj_t *source);
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index 44a27cd1de05b0a4bda28ae5224cb16e20855d41..06cc69e0b08f0f8d572c393e4d0bef3a9890118f 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -130,8 +130,6 @@ static int player_get(lua_State *L)
 		LUA_PushUserdata(L, plr->powers, META_POWERS);
 	else if (fastcmp(field,"kartstuff"))
 		LUA_PushUserdata(L, plr->kartstuff, META_KARTSTUFF);
-	else if (fastcmp(field,"collide"))
-		LUA_PushUserdata(L, plr->collide, META_COLLIDE);
 	else if (fastcmp(field,"pflags"))
 		lua_pushinteger(L, plr->pflags);
 	else if (fastcmp(field,"panim"))
diff --git a/src/lua_script.c b/src/lua_script.c
index 9ba7ce7f1f87548a259aa931004c5692a953f0e9..aafabbb967abe1d0e65dc3c65024f31d82d28750 100644
--- a/src/lua_script.c
+++ b/src/lua_script.c
@@ -435,7 +435,6 @@ void LUA_InvalidatePlayer(player_t *player)
 	LUA_InvalidateUserdata(player);
 	LUA_InvalidateUserdata(player->powers);
 	LUA_InvalidateUserdata(player->kartstuff);
-	LUA_InvalidateUserdata(player->collide);
 	LUA_InvalidateUserdata(&player->cmd);
 }
 
diff --git a/src/p_map.c b/src/p_map.c
index 547444ec59b22803e0d0b552d2797e2aa8a88638..18de0df351302bcbae007c06d02a2e99083e9ebb 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -320,6 +320,7 @@ static void P_DoFanAndGasJet(mobj_t *spring, mobj_t *object)
 	}
 }
 
+#if 0
 static void P_DoTailsCarry(player_t *sonic, player_t *tails)
 {
 	INT32 p;
@@ -400,6 +401,7 @@ static void P_DoTailsCarry(player_t *sonic, player_t *tails)
 		sonic->pflags &= ~PF_CARRIED;
 	}
 }
+#endif
 
 //
 // PIT_CheckThing
@@ -1534,7 +1536,8 @@ static boolean PIT_CheckThing(mobj_t *thing)
 	}
 
 	// Force solid players in hide and seek to avoid corner stacking.
-	if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
+	// Kart: No Tailspickup ever, players are always solid
+	/*if (cv_tailspickup.value && gametype != GT_HIDEANDSEEK)
 	{
 		if (tmthing->player && thing->player)
 		{
@@ -1546,7 +1549,7 @@ static boolean PIT_CheckThing(mobj_t *thing)
 		if (thing->player-players == consoleplayer && botingame)
 			CV_SetValue(&cv_analog2, true);
 		thing->player->pflags &= ~PF_CARRIED;
-	}
+	}*/
 
 	if (thing->player)
 	{
@@ -1592,6 +1595,28 @@ static boolean PIT_CheckThing(mobj_t *thing)
 			&& tmthing->z <= thing->z + thing->height)
 				iwassprung = P_DoSpring(thing, tmthing);
 		}
+		else if (thing->player) // bounce when players collide
+		{
+			if (thing->player->kartstuff[k_growshrinktimer] || thing->player->kartstuff[k_squishedtimer]
+				|| thing->player->kartstuff[k_bootaketimer] || thing->player->kartstuff[k_spinouttimer]
+				|| thing->player->kartstuff[k_startimer] || thing->player->kartstuff[k_justbumped]
+				|| tmthing->player->kartstuff[k_growshrinktimer] || tmthing->player->kartstuff[k_squishedtimer]
+				|| tmthing->player->kartstuff[k_bootaketimer] || tmthing->player->kartstuff[k_spinouttimer]
+				|| tmthing->player->kartstuff[k_startimer] || tmthing->player->kartstuff[k_justbumped])
+			{
+				return true;
+			}
+
+			if (P_IsObjectOnGround(thing) && tmthing->momz < 0)
+				K_SwapMomentum(tmthing, thing, true);
+			else if (P_IsObjectOnGround(tmthing) && thing->momz < 0)
+				K_SwapMomentum(thing, tmthing, true);
+			else
+				K_SwapMomentum(tmthing, thing, false);
+
+			thing->player->kartstuff[k_justbumped] = 6;
+			tmthing->player->kartstuff[k_justbumped] = 6;
+		}
 		// Are you touching the side of the object you're interacting with?
 		else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
 			&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
diff --git a/src/p_saveg.c b/src/p_saveg.c
index e04ee39c78b689ec343462ab814b8d1a76179f54..d813337ba9f3e3a2f6ab41e78da386df227d2dd5 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -138,8 +138,6 @@ static void P_NetArchivePlayers(void)
 			WRITEUINT16(save_p, players[i].powers[j]);
 		for (j = 0; j < NUMKARTSTUFF; j++)
 			WRITEINT32(save_p, players[i].kartstuff[j]);
-		for (j = 0; j < MAXPLAYERS; j++)
-			WRITEUINT8(save_p, players[i].collide[j]);
 
 		WRITEUINT8(save_p, players[i].playerstate);
 		WRITEUINT32(save_p, players[i].pflags);
@@ -321,8 +319,6 @@ static void P_NetUnArchivePlayers(void)
 			players[i].powers[j] = READUINT16(save_p);
 		for (j = 0; j < NUMKARTSTUFF; j++)
 			players[i].kartstuff[j] = READINT32(save_p);
-		for (j = 0; j < MAXPLAYERS; j++)
-			players[i].collide[j] = (boolean)READUINT8(save_p);
 
 		players[i].playerstate = READUINT8(save_p);
 		players[i].pflags = READUINT32(save_p);
diff --git a/src/p_tick.c b/src/p_tick.c
index 71bd3594af46404ce124e0103ba4635e78a21de4..7ea9843508829e701e9b7dbb5509baeec1e0a244 100644
--- a/src/p_tick.c
+++ b/src/p_tick.c
@@ -625,9 +625,6 @@ void P_Ticker(boolean run)
 			if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
 				P_PlayerAfterThink(&players[i]);
 
-		// SRB2kart - runs bounce collision for players
-		K_KartBouncer();
-
 #ifdef HAVE_BLUA
 		LUAh_ThinkFrame();
 #endif
@@ -743,9 +740,6 @@ void P_PreTicker(INT32 frames)
 			if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
 				P_PlayerAfterThink(&players[i]);
 
-		// SRB2kart - runs bounce collision for players
-		K_KartBouncer();
-
 #ifdef HAVE_BLUA
 		LUAh_ThinkFrame();
 #endif