From 580f909c6ca805e1421f955779f55a259f8c3b3b Mon Sep 17 00:00:00 2001
From: ZTsukei <ztsukei@gmail.com>
Date: Tue, 7 Feb 2017 17:19:04 -0500
Subject: [PATCH] Added Accelcode, start boosting, reverted drifting, etc.

---
 src/d_clisrv.c         |   4 +
 src/d_clisrv.h         |   4 +
 src/d_main.c           |  10 +-
 src/d_netcmd.c         |  14 +-
 src/d_player.h         |   8 +
 src/dehacked.c         |   2 +
 src/doomdef.h          |   6 +-
 src/doomstat.h         |   6 +-
 src/g_game.c           |  94 +++++---
 src/hu_stuff.c         |  86 ++++++-
 src/info.c             | 236 ++++++++++++++----
 src/info.h             |  29 +++
 src/k_kart.c           | 330 +++++++++++++++++--------
 src/k_kart.h           |   8 +-
 src/lua_playerlib.c    |  12 +
 src/lua_skinlib.c      |  16 ++
 src/m_menu.c           |  31 ++-
 src/m_misc.h           |   2 +-
 src/p_inter.c          | 125 +++++++++-
 src/p_local.h          |   4 +
 src/p_map.c            | 532 +++++++++++++++++++++++++++++++++++++++++
 src/p_saveg.c          |   8 +
 src/p_setup.c          |  10 +-
 src/p_spec.c           | 189 ++++++++++-----
 src/p_user.c           |  39 ++-
 src/r_main.c           |   2 +-
 src/r_things.c         |  14 ++
 src/r_things.h         |   5 +
 src/s_sound.c          |   8 +-
 src/s_sound.h          |   2 +-
 src/win32/Makefile.cfg |   4 +-
 src/win32/Srb2win.ico  | Bin 372798 -> 82992 bytes
 src/y_inter.c          | 389 +++++++++++++++++++++---------
 src/y_inter.h          |  18 +-
 34 files changed, 1834 insertions(+), 413 deletions(-)

diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index c0f81ba32..9ea9e8424 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -506,6 +506,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
 	rsp->skin = LONG(players[i].skin);
 	// Just in case Lua does something like
 	// modify these at runtime
+	// SRB2kart
+	rsp->kartspeed = (fixed_t)LONG(players[i].kartspeed);
+	rsp->kartweight = (fixed_t)LONG(players[i].kartweight);
+	//
 	rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
 	rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
 	rsp->thrustfactor = players[i].thrustfactor;
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index 79ade64fc..6ebe8f53b 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -168,6 +168,10 @@ typedef struct
 	INT32 skin;
 	// Just in case Lua does something like
 	// modify these at runtime
+	// SRB2kart
+	UINT8 kartspeed;
+	UINT8 kartweight;
+	//
 	fixed_t normalspeed;
 	fixed_t runspeed;
 	UINT8 thrustfactor;
diff --git a/src/d_main.c b/src/d_main.c
index d114a843e..6023b906b 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -259,7 +259,7 @@ static void D_Display(void)
 		{
 			if (intertype == int_spec) // Special Stage
 				wipedefindex = wipe_specinter_toblack;
-			else if (intertype != int_coop) // Multiplayer
+			else //if (intertype != int_coop) // Multiplayer
 				wipedefindex = wipe_multinter_toblack;
 		}
 
@@ -642,7 +642,7 @@ void D_StartTitle(void)
 	INT32 i;
 	if (netgame)
 	{
-		if (gametype == GT_COOP)
+		if (gametype == GT_RACE) // SRB2kart
 		{
 			G_SetGamestate(GS_WAITINGPLAYERS); // hack to prevent a command repeat
 
@@ -687,7 +687,7 @@ void D_StartTitle(void)
 	playerdeadview = false;
 	displayplayer = consoleplayer = 0;
 	//demosequence = -1;
-	gametype = GT_COOP;
+	gametype = GT_RACE; // SRB2kart
 	paused = false;
 	advancedemo = false;
 	F_StartTitleScreen();
@@ -1244,9 +1244,9 @@ void D_SRB2Main(void)
 
 	// user settings come before "+" parameters.
 	if (dedicated)
-		COM_ImmedExecute(va("exec \"%s"PATHSEP"adedserv.cfg\"\n", srb2home));
+		COM_ImmedExecute(va("exec \"%s"PATHSEP"kartserv.cfg\"\n", srb2home));
 	else
-		COM_ImmedExecute(va("exec \"%s"PATHSEP"autoexec.cfg\" -noerror\n", srb2home));
+		COM_ImmedExecute(va("exec \"%s"PATHSEP"kartexec.cfg\" -noerror\n", srb2home));
 
 	if (!autostart)
 		M_PushSpecialParameters(); // push all "+" parameters at the command buffer
diff --git a/src/d_netcmd.c b/src/d_netcmd.c
index 50d06424d..ab7985494 100644
--- a/src/d_netcmd.c
+++ b/src/d_netcmd.c
@@ -351,7 +351,7 @@ static CV_PossibleValue_t timelimit_cons_t[] = {{0, "MIN"}, {30, "MAX"}, {0, NUL
 consvar_t cv_timelimit = {"timelimit", "0", CV_NETVAR|CV_CALL|CV_NOINIT, timelimit_cons_t,
 	TimeLimit_OnChange, 0, NULL, NULL, 0, 0, NULL};
 static CV_PossibleValue_t numlaps_cons_t[] = {{0, "MIN"}, {50, "MAX"}, {0, NULL}};
-consvar_t cv_numlaps = {"numlaps", "4", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
+consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_cons_t,
 	NumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_usemapnumlaps = {"usemaplaps", "Yes", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
 
@@ -386,9 +386,9 @@ consvar_t cv_mute = {"mute", "Off", CV_NETVAR|CV_CALL, CV_OnOff, Mute_OnChange,
 
 consvar_t cv_sleep = {"cpusleep", "-1", CV_SAVE, sleeping_cons_t, NULL, -1, NULL, NULL, 0, 0, NULL};
 
-INT16 gametype = GT_COOP;
+INT16 gametype = GT_RACE; // SRB2kart
 boolean splitscreen = false;
-boolean circuitmap = false;
+boolean circuitmap = true; // SRB2kart
 INT32 adminplayer = -1;
 
 // =========================================================================
@@ -1017,8 +1017,8 @@ UINT8 CanChangeSkin(INT32 playernum)
 		if (gametype == GT_COOP)
 			return true;
 
-		// Can change skin during initial countdown.
-		if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
+		// Can change skin during initial countdown. // SRB2kart - Can always change skin in the level
+		if (gametype == GT_RACE || gametype == GT_COMPETITION) // if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
 			return true;
 
 		if (G_TagGametype())
@@ -2601,7 +2601,7 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
 	// Clear player score and rings if a spectator.
 	if (players[playernum].spectator)
 	{
-		players[playernum].score = 0;
+		//players[playernum].score = 0; // SRB2kart
 		players[playernum].health = 1;
 		if (players[playernum].mo)
 			players[playernum].mo->health = 1;
@@ -3453,7 +3453,7 @@ void D_GameTypeChanged(INT32 lastgametype)
 	}
 	else if (!multiplayer && !netgame)
 	{
-		gametype = GT_COOP;
+		gametype = GT_RACE; // SRB2kart
 		// These shouldn't matter anymore
 		//CV_Set(&cv_itemrespawntime, cv_itemrespawntime.defaultvalue);
 		//CV_SetValue(&cv_itemrespawn, 0);
diff --git a/src/d_player.h b/src/d_player.h
index a32868287..06792418b 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -247,6 +247,7 @@ typedef enum
 	k_sounds,			// Used this to avoid sounds being played every tic
 	
 	k_boosting,			// Determines if you're currently shroom-boosting to change how drifting works
+	k_floorboost,		// Prevents Mushroom sounds for a breif duration when triggered by a floor panel
 	k_spinout,			// Separate confirmation to prevent endless wipeout loops
 	k_spinouttype,		// Determines whether to thrust forward or not while spinning out; 0 = move forwards, 1 = stay still
 	
@@ -255,6 +256,7 @@ typedef enum
 	k_boostcharge,		// Charge-up for boosting at the start of the race, or when Lakitu drops you
 	k_jmp,				// In Mario Kart, letting go of the jump button stops the drift
 	k_lakitu,			// > 0 = Lakitu fishing, < 0 = Lakitu lap counter (was "player->airtime") // NOTE: Check for ->lakitu, replace with this
+	k_offroad,			// In Super Mario Kart, going offroad has lee-way of about 1 second before you start losing speed
 	
 	k_itemroulette,		// Used for the roulette when deciding what item to give you (was "pw_kartitem")
 	k_itemclose,		// Used to animate the item window closing (was "pw_psychic")
@@ -297,6 +299,7 @@ typedef enum
 	k_tripleredshell,	// 0x1 = 1 Red Shell orbiting, 0x2 = 2 Red Shells orbiting
 						// 0x4 = 3 Red Shells orbiting, 0x8 = Triple Red Shell in inventory
 	k_lightning,		// 0x1 = Lightning in inventory
+	k_kitchensink,		// 0x1 = Sink in inventory
 
 	NUMKARTSTUFF
 } kartstufftype_t;
@@ -381,6 +384,11 @@ typedef struct player_s
 	fixed_t dashspeed; // dashing speed
 	INT32 dashtime; // tics dashing, used for rev sound
 
+	// SRB2kart
+	UINT8 kartspeed; // Kart speed stat between 1 and 9
+	UINT8 kartweight; // Kart weight stat between 1 and 9
+	//
+
 	fixed_t normalspeed; // Normal ground
 	fixed_t runspeed; // Speed you break into the run animation
 	UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
diff --git a/src/dehacked.c b/src/dehacked.c
index 9d4e56af2..a55519e85 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -994,6 +994,8 @@ static const struct {
 	{"CHRISTMAS",TOL_XMAS},
 	{"WINTER",TOL_XMAS},
 
+	{"KART",TOL_KART}, // SRB2kart
+
 	{NULL, 0}
 };
 
diff --git a/src/doomdef.h b/src/doomdef.h
index af7ed97b2..06958eb88 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -220,8 +220,8 @@ extern FILE *logstream;
 // The maximum number of players, multiplayer/networking.
 // NOTE: it needs more than this to increase the number of players...
 
-#define MAXPLAYERS 32
-#define MAXSKINS MAXPLAYERS
+#define MAXPLAYERS 16
+#define MAXSKINS 32
 #define PLAYERSMASK (MAXPLAYERS-1)
 #define MAXPLAYERNAME 21
 
@@ -325,7 +325,7 @@ typedef enum
 #define NEWTICRATERATIO 1 // try 4 for 140 fps :)
 #define NEWTICRATE (TICRATE*NEWTICRATERATIO)
 
-#define RING_DIST 512*FRACUNIT // how close you need to be to a ring to attract it
+#define RING_DIST 1280*FRACUNIT // how close you need to be to a ring to attract it
 
 #define PUSHACCEL (2*FRACUNIT) // Acceleration for MF2_SLIDEPUSH items.
 
diff --git a/src/doomstat.h b/src/doomstat.h
index 4fb391ecb..8ac5e5baa 100644
--- a/src/doomstat.h
+++ b/src/doomstat.h
@@ -249,6 +249,9 @@ typedef struct
 	// (This is not ifdeffed so the map header structure can stay identical, just in case.)
 	UINT8 numCustomOptions;     ///< Internal. For Lua custom value support.
 	customoption_t *customopts; ///< Custom options. Allocated dynamically for space reasons. Be careful.
+	
+	// SRB2kart
+	boolean automap;      ///< Displays a level's white map outline in modified games
 } mapheader_t;
 
 // level flags
@@ -287,7 +290,8 @@ enum TypeOfLevel
 	TOL_MARIO  = 0x0200, ///< Mario
 	TOL_NIGHTS = 0x0400, ///< NiGHTS
 	TOL_ERZ3   = 0x0800, ///< ERZ3
-	TOL_XMAS   = 0x1000  ///< Christmas NiGHTS
+	TOL_XMAS   = 0x1000, ///< Christmas NiGHTS
+	TOL_KART   = 0x4000  ///< Kart 32768
 };
 
 // Gametypes
diff --git a/src/g_game.c b/src/g_game.c
index 6c71e7def..dd9c46b2d 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -61,8 +61,9 @@ JoyType_t Joystick2;
 // 1024 bytes is plenty for a savegame
 #define SAVEGAMESIZE (1024)
 
-char gamedatafilename[64] = "gamedata.dat";
-char timeattackfolder[64] = "main";
+// SRB2kart
+char gamedatafilename[64] = "kartdata.dat";
+char timeattackfolder[64] = "kart";
 char customversionstring[32] = "\0";
 
 static void G_DoCompleted(void);
@@ -189,7 +190,7 @@ boolean CheckForReverseGravity;
 // Powerup durations
 UINT16 invulntics = 20*TICRATE;
 UINT16 sneakertics = 20*TICRATE;
-UINT16 flashingtics = 3*TICRATE;
+UINT16 flashingtics = 3*TICRATE/2; // SRB2kart
 UINT16 tailsflytics = 8*TICRATE;
 UINT16 underwatertics = 30*TICRATE;
 UINT16 spacetimetics = 11*TICRATE + (TICRATE/2);
@@ -446,7 +447,7 @@ consvar_t cv_firenaxis2 = {"joyaxis2_firenormal", "None", CV_SAVE, joyaxis_cons_
 #endif
 
 
-#if MAXPLAYERS > 32
+#if MAXPLAYERS > 16
 #error "please update player_name table using the new value for MAXPLAYERS"
 #endif
 
@@ -471,24 +472,8 @@ char player_names[MAXPLAYERS][MAXPLAYERNAME+1] =
 	"Player 13",
 	"Player 14",
 	"Player 15",
-	"Player 16",
-	"Player 17",
-	"Player 18",
-	"Player 19",
-	"Player 20",
-	"Player 21",
-	"Player 22",
-	"Player 23",
-	"Player 24",
-	"Player 25",
-	"Player 26",
-	"Player 27",
-	"Player 28",
-	"Player 29",
-	"Player 30",
-	"Player 31",
-	"Player 32"
-};
+	"Player 16"
+}; // SRB2kart - removed Players 17 through 32
 
 INT16 rw_maximums[NUM_WEAPONS] =
 {
@@ -1094,12 +1079,13 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics)
 
 	// some people strafe left & right with mouse buttons
 	// those people are weird
+
+	/* // SRB2kart - these aren't used in kart
 	if (PLAYER1INPUTDOWN(gc_straferight))
 		side += sidemove[speed];
 	if (PLAYER1INPUTDOWN(gc_strafeleft))
 		side -= sidemove[speed];
 
-	/* // SRB2kart - these aren't used in kart
 	if (PLAYER1INPUTDOWN(gc_driftleft))
 		cmd->buttons |= BT_WEAPONNEXT; // Next Weapon
 	if (PLAYER1INPUTDOWN(gc_driftright))
@@ -1983,6 +1969,7 @@ void G_Ticker(boolean run)
 {
 	UINT32 i;
 	INT32 buf;
+	ticcmd_t *cmd;
 
 	P_MapStart();
 	// do player reborns if needed
@@ -2023,8 +2010,20 @@ void G_Ticker(boolean run)
 	// read/write demo and check turbo cheat
 	for (i = 0; i < MAXPLAYERS; i++)
 	{
+		cmd = &players[i].cmd;
+		
 		if (playeringame[i])
-			G_CopyTiccmd(&players[i].cmd, &netcmds[buf][i], 1);
+			G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
+			
+			// SRB2kart
+			// Save the dir the player is holding
+			//  to allow items to be thrown forward or backward.
+			if (cmd->forwardmove > 0)
+					players[i].kartstuff[k_throwdir] = 1;
+			else if (cmd->forwardmove < 0)
+					players[i].kartstuff[k_throwdir] = -1;
+			else
+					players[i].kartstuff[k_throwdir] = 0;
 	}
 
 	// do main actions
@@ -2146,6 +2145,10 @@ void G_PlayerReborn(INT32 player)
 	INT32 continues;
 	UINT8 charability;
 	UINT8 charability2;
+	// SRB2kart
+	UINT8 kartspeed;
+	UINT8 kartweight;
+	//
 	fixed_t normalspeed;
 	fixed_t runspeed;
 	UINT8 thrustfactor;
@@ -2185,7 +2188,7 @@ void G_PlayerReborn(INT32 player)
 	INT32 playerahead;
 	INT32 starpostwp;
 	INT32 lakitu;
-
+	INT32 offroad;
 
 	score = players[player].score;
 	lives = players[player].lives;
@@ -2208,6 +2211,10 @@ void G_PlayerReborn(INT32 player)
 	skin = players[player].skin;
 	charability = players[player].charability;
 	charability2 = players[player].charability2;
+	// SRB2kart
+	kartspeed = players[player].kartspeed;
+	kartweight = players[player].kartweight;
+	//
 	normalspeed = players[player].normalspeed;
 	runspeed = players[player].runspeed;
 	thrustfactor = players[player].thrustfactor;
@@ -2238,6 +2245,7 @@ void G_PlayerReborn(INT32 player)
 	playerahead = players[player].kartstuff[k_playerahead];
 	starpostwp = players[player].kartstuff[k_starpostwp];
 	lakitu = players[player].kartstuff[k_lakitu];
+	offroad = players[player].kartstuff[k_offroad];
 
 	p = &players[player];
 	memset(p, 0, sizeof (*p));
@@ -2255,6 +2263,10 @@ void G_PlayerReborn(INT32 player)
 	p->skin = skin;
 	p->charability = charability;
 	p->charability2 = charability2;
+	// SRB2kart
+	p->kartspeed = kartspeed;
+	p->kartweight = kartweight;
+	//
 	p->normalspeed = normalspeed;
 	p->runspeed = runspeed;
 	p->thrustfactor = thrustfactor;
@@ -2291,6 +2303,7 @@ void G_PlayerReborn(INT32 player)
 	p->kartstuff[k_playerahead] = playerahead;
 	p->kartstuff[k_starpostwp] = starpostwp;
 	p->kartstuff[k_lakitu] = lakitu;
+	p->kartstuff[k_offroad] = offroad;
 
 	// Don't do anything immediately
 	p->pflags |= PF_USEDOWN;
@@ -2646,7 +2659,7 @@ void G_DoReborn(INT32 playernum)
 			// Do a wipe
 			wipegamestate = -1;
 
-			if (player->starposttime)
+			if (player->starpostnum) // SRB2kart
 				starpost = true;
 
 			if (camera.chase)
@@ -2691,7 +2704,7 @@ void G_DoReborn(INT32 playernum)
 		// respawn at the start
 		mobj_t *oldmo = NULL;
 
-		if (player->starposttime)
+		if (player->starpostnum) // SRB2kart
 			starpost = true;
 
 		// first dissasociate the corpse
@@ -2832,7 +2845,7 @@ boolean G_TagGametype(void)
 INT16 G_TOLFlag(INT32 pgametype)
 {
 	if (!multiplayer)                 return TOL_SP;
-	if (pgametype == GT_COOP)         return TOL_COOP;
+	if (pgametype == GT_COOP)         return TOL_RACE; // SRB2kart
 	if (pgametype == GT_COMPETITION)  return TOL_COMPETITION;
 	if (pgametype == GT_RACE)         return TOL_RACE;
 	if (pgametype == GT_MATCH)        return TOL_MATCH;
@@ -3050,7 +3063,7 @@ static void G_DoWorldDone(void)
 {
 	if (server)
 	{
-		if (gametype == GT_COOP)
+		if (gametype == GT_RACE) // SRB2kart
 			// don't reset player between maps
 			D_MapChange(nextmap+1, gametype, ultimatemode, false, 0, false, false);
 		else
@@ -3683,6 +3696,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
 			{
 				players[i].lives = cv_startinglives.value;
 				players[i].continues = 0;
+				players[i].kartstuff[k_lakitu] = 0; // SRB2kart
 			}
 			else if (pultmode)
 			{
@@ -3693,6 +3707,7 @@ void G_InitNew(UINT8 pultmode, const char *mapname, boolean resetplayer, boolean
 			{
 				players[i].lives = 3;
 				players[i].continues = 1;
+				players[i].kartstuff[k_lakitu] = 0; // SRB2kart
 			}
 
 			// The latter two should clear by themselves, but just in case
@@ -4806,6 +4821,10 @@ void G_BeginRecording(void)
 	WRITEUINT8(demo_p,player->actionspd>>FRACBITS);
 	WRITEUINT8(demo_p,player->mindash>>FRACBITS);
 	WRITEUINT8(demo_p,player->maxdash>>FRACBITS);
+	// SRB2kart
+	WRITEUINT8(demo_p,player->kartspeed>>FRACBITS);
+	WRITEUINT8(demo_p,player->kartweight>>FRACBITS);
+	//
 	WRITEUINT8(demo_p,player->normalspeed>>FRACBITS);
 	WRITEUINT8(demo_p,player->runspeed>>FRACBITS);
 	WRITEUINT8(demo_p,player->thrustfactor);
@@ -5041,7 +5060,7 @@ void G_DoPlayDemo(char *defdemoname)
 	char skin[17],color[17],*n,*pdemoname;
 	UINT8 version,subversion,charability,charability2,thrustfactor,accelstart,acceleration;
 	UINT32 randseed;
-	fixed_t actionspd,mindash,maxdash,normalspeed,runspeed,jumpfactor;
+	fixed_t actionspd,mindash,maxdash,kartspeed,kartweight,normalspeed,runspeed,jumpfactor;
 	char msg[1024];
 
 	skin[16] = '\0';
@@ -5182,6 +5201,10 @@ void G_DoPlayDemo(char *defdemoname)
 	actionspd = (fixed_t)READUINT8(demo_p)<<FRACBITS;
 	mindash = (fixed_t)READUINT8(demo_p)<<FRACBITS;
 	maxdash = (fixed_t)READUINT8(demo_p)<<FRACBITS;
+	// SRB2kart
+	kartspeed = READUINT8(demo_p)<<FRACBITS;
+	kartweight = READUINT8(demo_p)<<FRACBITS;
+	//
 	normalspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS;
 	runspeed = (fixed_t)READUINT8(demo_p)<<FRACBITS;
 	thrustfactor = READUINT8(demo_p);
@@ -5226,7 +5249,8 @@ void G_DoPlayDemo(char *defdemoname)
 	memset(playeringame,0,sizeof(playeringame));
 	playeringame[0] = true;
 	P_SetRandSeed(randseed);
-	G_InitNew(false, G_BuildMapName(gamemap), true, true);
+	//G_InitNew(false, G_BuildMapName(gamemap), true, true); // resetplayer needs to be false to retain score
+	G_InitNew(false, G_BuildMapName(gamemap), false, true);
 
 	// Set skin
 	SetPlayerSkin(0, skin);
@@ -5255,6 +5279,10 @@ void G_DoPlayDemo(char *defdemoname)
 	players[0].actionspd = actionspd;
 	players[0].mindash = mindash;
 	players[0].maxdash = maxdash;
+	// SRB2kart
+	players[0].kartspeed = kartspeed;
+	players[0].kartweight = kartweight;
+	//
 	players[0].normalspeed = normalspeed;
 	players[0].runspeed = runspeed;
 	players[0].thrustfactor = thrustfactor;
@@ -5397,6 +5425,10 @@ void G_AddGhost(char *defdemoname)
 	p++; // actionspd
 	p++; // mindash
 	p++; // maxdash
+	// SRB2kart
+	p++; // kartspeed
+	p++; // kartweight
+	//
 	p++; // normalspeed
 	p++; // runspeed
 	p++; // thrustfactor
diff --git a/src/hu_stuff.c b/src/hu_stuff.c
index 048caf42c..11f6ba68e 100644
--- a/src/hu_stuff.c
+++ b/src/hu_stuff.c
@@ -1068,6 +1068,79 @@ static void HU_DrawDemoInfo(void)
 //
 void HU_Drawer(void)
 {
+	// SRB2kart 010217 - Automap Hud (temporarily commented out)
+	/*
+	INT32 amnumxpos;
+	INT32 amnumypos;
+	INT32 amxpos;
+	INT32 amypos;
+	INT32 lumpnum;
+	patch_t *AutomapPic;
+	INT32 i = 0;
+
+	// Draw the HUD only when playing in a level.
+	// hu_stuff needs this, unlike st_stuff.
+	if (Playing() && gamestate == GS_LEVEL)
+	{
+		INT32 x, y;
+
+		lumpnum = W_CheckNumForName(va("%sR", G_BuildAutoMapName(gamemap)));
+
+		if (lumpnum != -1 && (!modifiedgame || (modifiedgame && mapheaderinfo[gamemap-1].automap)))
+			AutomapPic = W_CachePatchName(va("%sR", G_BuildAutoMapName(gamemap)), PU_CACHE);
+		else
+			AutomapPic = W_CachePatchName(va("NOMAPR"), PU_CACHE);
+
+		if (splitscreen)
+		{
+			x = 160 - (AutomapPic->width/4);
+			y = 100 - (AutomapPic->height/4);
+		}
+		else
+		{
+			x = 312 - (AutomapPic->width/2);
+			y = 60;
+		}
+
+		V_DrawSmallScaledPatch(x, y, 0, AutomapPic);
+
+		// Player's tiny icons on the Automap.
+		if (lumpnum != -1 && (!modifiedgame || (modifiedgame && mapheaderinfo[gamemap-1].automap)))
+		{
+			for (i = 0; i < MAXPLAYERS; i++)
+			{
+				if (players[i].mo && !players[i].spectator)
+				{
+					// amnum xpos & ypos are the icon's speed around the HUD.
+					// The number being divided by is for how fast it moves.
+					// The higher the number, the slower it moves.
+
+					// am xpos & ypos are the icon's starting position. Withouht
+					// it, they wouldn't 'spawn' on the top-right side of the HUD.
+					amnumxpos = (players[i].mo->x / 320) >> FRACBITS;
+					amnumypos = (-players[i].mo->y / 340) >> FRACBITS;
+					
+					amxpos = (x + amnumxpos) - (iconprefix[players[i].skin]->width/4);
+					amypos = (y + amnumypos) - (iconprefix[players[i].skin]->height/4);
+
+					if (!players[i].skincolor) // 'default' color
+					{
+						V_DrawSmallScaledPatch(amxpos, amypos, 0, iconprefix[players[i].skin]);
+					}
+					else
+					{
+						UINT8 *colormap = translationtables[players[i].skin] - 256 + (players[i].skincolor<<8);
+						V_DrawSmallMappedPatch(amxpos, amypos, 0,iconprefix[players[i].skin], colormap);
+					}
+				}
+			}
+		}
+		if (!splitscreen && maptol & TOL_KART && !hu_showscores)
+			HU_DrawRaceRankings();
+	}
+	*/
+	//
+	
 	// draw chat string plus cursor
 	if (chat_on)
 		HU_DrawChat();
@@ -1272,9 +1345,18 @@ void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, I
 			if (circuitmap)
 			{
 				if (players[tab[i].num].exiting)
-					V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
+					V_DrawRightAlignedString(x+240, y, V_YELLOWMAP, va("%d:%02d.%02d", 
+						players[tab[i].num].realtime/(60*TICRATE), 
+						players[tab[i].num].realtime/TICRATE % 60, 
+						players[tab[i].num].realtime % TICRATE));
+					//V_DrawRightAlignedString(x+240, y, 0, va("%i:%02i.%02i", G_TicsToMinutes(players[tab[i].num].realtime,true), G_TicsToSeconds(players[tab[i].num].realtime), G_TicsToCentiseconds(players[tab[i].num].realtime)));
 				else
-					V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
+					V_DrawRightAlignedString(x+240, y, 0, va("(CP%02d) %d:%02d.%02d",
+						tab[i].count,
+						players[tab[i].num].starposttime/(60*TICRATE),
+						players[tab[i].num].starposttime/TICRATE % 60,
+						(int)((players[tab[i].num].starposttime % TICRATE) * (100.00f/TICRATE))));
+					//V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%u", tab[i].count));
 			}
 			else
 				V_DrawRightAlignedString(x+240, y, ((players[tab[i].num].health > 0) ? 0 : V_60TRANS), va("%i:%02i.%02i", G_TicsToMinutes(tab[i].count,true), G_TicsToSeconds(tab[i].count), G_TicsToCentiseconds(tab[i].count)));
diff --git a/src/info.c b/src/info.c
index 8c51df09e..984fb250d 100644
--- a/src/info.c
+++ b/src/info.c
@@ -56,7 +56,8 @@ char sprnames[NUMSPRITES + 1][5] =
 	"SRBJ","SRBK","SRBL","SRBM","SRBN","SRBO",
 	//SRB2kart Sprites
 	"SPRG","BSPR","RNDM","SPRK","KFRE","DRIF","DSMO","FAKE","DFAK","BANA",
-	"DBAN","GSHE","GSTR","DGSH","RSHE","RSTR","DRSH","BOMB","BLIG","LIGH"
+	"DBAN","GSHE","GSTR","DGSH","RSHE","RSTR","DRSH","BOMB","BLIG","LIGH",
+	"SINK","SITR","POKE"
 };
 
 // Doesn't work with g++, needs actionf_p1 (don't modify this comment)
@@ -2589,30 +2590,30 @@ state_t states[NUMSTATES] =
 	{SPR_KFRE, FF_FULLBRIGHT|5,  2, {NULL}, 0, 0, S_KARTFIRE8}, // S_KARTFIRE7
 	{SPR_KFRE, FF_FULLBRIGHT|6,  2, {NULL}, 0, 0, S_NULL},      // S_KARTFIRE8
 
-	{SPR_FAKE,  0,   3, {NULL}, 0, 0, S_FAKEITEM2},  // S_FAKEITEM1
-	{SPR_FAKE,  1,   3, {NULL}, 0, 0, S_FAKEITEM3},  // S_FAKEITEM2
-	{SPR_FAKE,  2,   3, {NULL}, 0, 0, S_FAKEITEM4},  // S_FAKEITEM3
-	{SPR_FAKE,  3,   3, {NULL}, 0, 0, S_FAKEITEM5},  // S_FAKEITEM4
-	{SPR_FAKE,  4,   3, {NULL}, 0, 0, S_FAKEITEM6},  // S_FAKEITEM5
-	{SPR_FAKE,  5,   3, {NULL}, 0, 0, S_FAKEITEM7},  // S_FAKEITEM6
-	{SPR_FAKE,  6,   3, {NULL}, 0, 0, S_FAKEITEM8},  // S_FAKEITEM7
-	{SPR_FAKE,  7,   3, {NULL}, 0, 0, S_FAKEITEM9},  // S_FAKEITEM8
-	{SPR_FAKE,  8,   3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9
-	{SPR_FAKE,  9,   3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10
-	{SPR_FAKE, 10,   3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11
-	{SPR_FAKE, 11,   3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12
-	{SPR_FAKE, 12,   3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13
-	{SPR_FAKE, 13,   3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14
-	{SPR_FAKE, 14,   3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15
-	{SPR_FAKE, 15,   3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16
-	{SPR_FAKE, 16,   3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17
-	{SPR_FAKE, 17,   3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18
-	{SPR_FAKE, 18,   3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19
-	{SPR_FAKE, 19,   3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20
-	{SPR_FAKE, 20,   3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21
-	{SPR_FAKE, 21,   3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22
-	{SPR_FAKE, 22,   3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23
-	{SPR_FAKE, 23,   3, {NULL}, 0, 0, S_FAKEITEM1},  // S_FAKEITEM24
+	{SPR_FITE,  0,   3, {NULL}, 0, 0, S_FAKEITEM2},  // S_FAKEITEM1
+	{SPR_FITE,  1,   3, {NULL}, 0, 0, S_FAKEITEM3},  // S_FAKEITEM2
+	{SPR_FITE,  2,   3, {NULL}, 0, 0, S_FAKEITEM4},  // S_FAKEITEM3
+	{SPR_FITE,  3,   3, {NULL}, 0, 0, S_FAKEITEM5},  // S_FAKEITEM4
+	{SPR_FITE,  4,   3, {NULL}, 0, 0, S_FAKEITEM6},  // S_FAKEITEM5
+	{SPR_FITE,  5,   3, {NULL}, 0, 0, S_FAKEITEM7},  // S_FAKEITEM6
+	{SPR_FITE,  6,   3, {NULL}, 0, 0, S_FAKEITEM8},  // S_FAKEITEM7
+	{SPR_FITE,  7,   3, {NULL}, 0, 0, S_FAKEITEM9},  // S_FAKEITEM8
+	{SPR_FITE,  8,   3, {NULL}, 0, 0, S_FAKEITEM10}, // S_FAKEITEM9
+	{SPR_FITE,  9,   3, {NULL}, 0, 0, S_FAKEITEM11}, // S_FAKEITEM10
+	{SPR_FITE, 10,   3, {NULL}, 0, 0, S_FAKEITEM12}, // S_FAKEITEM11
+	{SPR_FITE, 11,   3, {NULL}, 0, 0, S_FAKEITEM13}, // S_FAKEITEM12
+	{SPR_FITE, 12,   3, {NULL}, 0, 0, S_FAKEITEM14}, // S_FAKEITEM13
+	{SPR_FITE, 13,   3, {NULL}, 0, 0, S_FAKEITEM15}, // S_FAKEITEM14
+	{SPR_FITE, 14,   3, {NULL}, 0, 0, S_FAKEITEM16}, // S_FAKEITEM15
+	{SPR_FITE, 15,   3, {NULL}, 0, 0, S_FAKEITEM17}, // S_FAKEITEM16
+	{SPR_FITE, 16,   3, {NULL}, 0, 0, S_FAKEITEM18}, // S_FAKEITEM17
+	{SPR_FITE, 17,   3, {NULL}, 0, 0, S_FAKEITEM19}, // S_FAKEITEM18
+	{SPR_FITE, 18,   3, {NULL}, 0, 0, S_FAKEITEM20}, // S_FAKEITEM19
+	{SPR_FITE, 19,   3, {NULL}, 0, 0, S_FAKEITEM21}, // S_FAKEITEM20
+	{SPR_FITE, 20,   3, {NULL}, 0, 0, S_FAKEITEM22}, // S_FAKEITEM21
+	{SPR_FITE, 21,   3, {NULL}, 0, 0, S_FAKEITEM23}, // S_FAKEITEM22
+	{SPR_FITE, 22,   3, {NULL}, 0, 0, S_FAKEITEM24}, // S_FAKEITEM23
+	{SPR_FITE, 23,   3, {NULL}, 0, 0, S_FAKEITEM1},  // S_FAKEITEM24
 	{SPR_DFAK,  0, 175, {NULL}, 0, 0, S_FAKEITEM1},  // S_DEADFAKEITEM
 
 	{SPR_BANA, 0,  -1, {NULL}, 0, 0, S_NULL}, // S_BANANAITEM
@@ -2642,15 +2643,15 @@ state_t states[NUMSTATES] =
 	{SPR_GSHE, 5, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM7}, // S_GREENITEM6
 	{SPR_GSHE, 6, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM8}, // S_GREENITEM7
 	{SPR_GSHE, 7, 2, {A_SmokeTrailer}, MT_GREENTRAIL, 0, S_GREENITEM1}, // S_GREENITEM8
-	{SPR_GSHE, 0, 1, {NULL}, 0, 0, S_GREENTRAIL2},                      // S_GREENTRAIL1
-	{SPR_GSHE, 1, 1, {NULL}, 0, 0, S_GREENTRAIL3},                      // S_GREENTRAIL2
-	{SPR_GSHE, 2, 1, {NULL}, 0, 0, S_GREENTRAIL4},                      // S_GREENTRAIL3
-	{SPR_GSHE, 3, 1, {NULL}, 0, 0, S_GREENTRAIL5},                      // S_GREENTRAIL4
-	{SPR_GSHE, 4, 1, {NULL}, 0, 0, S_GREENTRAIL6},                      // S_GREENTRAIL5
-	{SPR_GSHE, 5, 1, {NULL}, 0, 0, S_GREENTRAIL7},                      // S_GREENTRAIL6
-	{SPR_GSHE, 6, 1, {NULL}, 0, 0, S_GREENTRAIL8},                      // S_GREENTRAIL7
-	{SPR_GSHE, 7, 1, {NULL}, 0, 0, S_GREENTRAIL9},                      // S_GREENTRAIL8
-	{SPR_GSHE, 8, 1, {NULL}, 0, 0, S_NULL},                             // S_GREENTRAIL9
+	{SPR_GSTR, 0, 1, {NULL}, 0, 0, S_GREENTRAIL2},                      // S_GREENTRAIL1
+	{SPR_GSTR, 1, 1, {NULL}, 0, 0, S_GREENTRAIL3},                      // S_GREENTRAIL2
+	{SPR_GSTR, 2, 1, {NULL}, 0, 0, S_GREENTRAIL4},                      // S_GREENTRAIL3
+	{SPR_GSTR, 3, 1, {NULL}, 0, 0, S_GREENTRAIL5},                      // S_GREENTRAIL4
+	{SPR_GSTR, 4, 1, {NULL}, 0, 0, S_GREENTRAIL6},                      // S_GREENTRAIL5
+	{SPR_GSTR, 5, 1, {NULL}, 0, 0, S_GREENTRAIL7},                      // S_GREENTRAIL6
+	{SPR_GSTR, 6, 1, {NULL}, 0, 0, S_GREENTRAIL8},                      // S_GREENTRAIL7
+	{SPR_GSTR, 7, 1, {NULL}, 0, 0, S_GREENTRAIL9},                      // S_GREENTRAIL8
+	{SPR_GSTR, 8, 1, {NULL}, 0, 0, S_NULL},                             // S_GREENTRAIL9
 	{SPR_DGSH, 0, 175, {NULL}, 0, 0, S_NULL},                           // S_DEADGREEN
 
 	{SPR_RSHE, 0, 2, {A_RotateSpikeBall}, 0, 0, S_TRIPLEREDSHIELD2},              // S_TRIPLEREDSHIELD1
@@ -2679,15 +2680,15 @@ state_t states[NUMSTATES] =
 	{SPR_RSHE, 7, 2, {A_DualAction}, S_REDITEMCHASE, S_REDITEMTRAIL, S_REDITEM1}, // S_REDITEM8
 	{SPR_RSHE, 0, 2, {A_RedShellChase}, 0, 0, S_REDITEM2},                        // S_REDITEMCHASE
 	{SPR_RSHE, 1, 2, {A_SmokeTrailer}, MT_REDTRAIL, 0, S_REDITEM3},               // S_REDITEMTRAIL
-	{SPR_RSHE, 0, 1, {NULL}, 0, 0, S_REDTRAIL2},                                  // S_REDTRAIL1
-	{SPR_RSHE, 1, 1, {NULL}, 0, 0, S_REDTRAIL3},                                  // S_REDTRAIL2
-	{SPR_RSHE, 2, 1, {NULL}, 0, 0, S_REDTRAIL4},                                  // S_REDTRAIL3
-	{SPR_RSHE, 3, 1, {NULL}, 0, 0, S_REDTRAIL5},                                  // S_REDTRAIL4
-	{SPR_RSHE, 4, 1, {NULL}, 0, 0, S_REDTRAIL6},                                  // S_REDTRAIL5
-	{SPR_RSHE, 5, 1, {NULL}, 0, 0, S_REDTRAIL7},                                  // S_REDTRAIL6
-	{SPR_RSHE, 6, 1, {NULL}, 0, 0, S_REDTRAIL8},                                  // S_REDTRAIL7
-	{SPR_RSHE, 7, 1, {NULL}, 0, 0, S_REDTRAIL9},                                  // S_REDTRAIL8
-	{SPR_RSHE, 8, 1, {NULL}, 0, 0, S_NULL},                                       // S_REDTRAIL9
+	{SPR_RSTR, 0, 1, {NULL}, 0, 0, S_REDTRAIL2},                                  // S_REDTRAIL1
+	{SPR_RSTR, 1, 1, {NULL}, 0, 0, S_REDTRAIL3},                                  // S_REDTRAIL2
+	{SPR_RSTR, 2, 1, {NULL}, 0, 0, S_REDTRAIL4},                                  // S_REDTRAIL3
+	{SPR_RSTR, 3, 1, {NULL}, 0, 0, S_REDTRAIL5},                                  // S_REDTRAIL4
+	{SPR_RSTR, 4, 1, {NULL}, 0, 0, S_REDTRAIL6},                                  // S_REDTRAIL5
+	{SPR_RSTR, 5, 1, {NULL}, 0, 0, S_REDTRAIL7},                                  // S_REDTRAIL6
+	{SPR_RSTR, 6, 1, {NULL}, 0, 0, S_REDTRAIL8},                                  // S_REDTRAIL7
+	{SPR_RSTR, 7, 1, {NULL}, 0, 0, S_REDTRAIL9},                                  // S_REDTRAIL8
+	{SPR_RSTR, 8, 1, {NULL}, 0, 0, S_NULL},                                       // S_REDTRAIL9
 	{SPR_DRSH, 0, 175, {NULL}, 0, 0, S_NULL},                                     // S_DEADRED
 
 	{SPR_BOMB, 0,  1, {NULL}, 0, 0, S_BOMBSHIELD},                 // S_BOMBSHIELD
@@ -2706,6 +2707,20 @@ state_t states[NUMSTATES] =
 	{SPR_LIGH, 0,  2, {NULL}, 0, 0, S_LIGHTNING4}, // S_LIGHTNING3
 	{SPR_LIGH, 0,  2, {NULL}, 0, 0, S_NULL},       // S_LIGHTNING4
 
+	{SPR_SINK, 0,  4, {A_SmokeTrailer}, MT_SINKTRAIL, 0, S_SINK}, // S_SINK
+	{SPR_SITR, 0,  1, {NULL}, 0, 0, S_SINKTRAIL2},                       // S_SINKTRAIL1
+	{SPR_SITR, 1,  5, {NULL}, 0, 0, S_SINKTRAIL3},                       // S_SINKTRAIL2
+	{SPR_SITR, 2,  3, {NULL}, 0, 0, S_NULL},                             // S_SINKTRAIL3
+
+	{SPR_POKE, 0,  2, {A_MoveAbsolute},   0, 2, S_POKEY2}, // S_POKEY1
+	{SPR_POKE, 1,  2, {A_MoveAbsolute},   0, 2, S_POKEY3}, // S_POKEY2
+	{SPR_POKE, 2,  2, {A_MoveAbsolute},   0, 2, S_POKEY4}, // S_POKEY3
+	{SPR_POKE, 3,  2, {A_MoveAbsolute},   0, 2, S_POKEY1}, // S_POKEY4
+	{SPR_POKE, 0,  2, {A_MoveAbsolute}, 180, 2, S_POKEY6}, // S_POKEY5
+	{SPR_POKE, 1,  2, {A_MoveAbsolute}, 180, 2, S_POKEY7}, // S_POKEY6
+	{SPR_POKE, 2,  2, {A_MoveAbsolute}, 180, 2, S_POKEY8}, // S_POKEY7
+	{SPR_POKE, 3,  2, {A_MoveAbsolute}, 180, 2, S_POKEY5}, // S_POKEY8
+	{SPR_NULL, 0, -1, {NULL}, 0, 0, S_NULL},               // S_POKEYIDLE
 
 #ifdef SEENAMES
 	{SPR_NULL, 0, 1, {NULL}, 0, 0, S_NULL}, // S_NAMECHECK
@@ -14881,6 +14896,141 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
+	{           // MT_SINK
+		-1,             // doomednum
+		S_SINK,         // spawnstate
+		105,            // spawnhealth
+		S_NULL,         // seestate
+		sfx_None,       // seesound
+		8,              // reactiontime
+		sfx_None,       // attacksound
+		256*FRACUNIT,   // painstate
+		100,            // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_shbrk,      // deathsound
+		0,              // speed
+		16*FRACUNIT,    // radius
+		24*FRACUNIT,    // height
+		0,              // display offset
+		100,            // mass
+		1,              // damage
+		sfx_bomb,       // activesound
+		MF_BOUNCE|MF_FLOAT|MF_NOCLIPTHING|MF_MISSILE|MF_SHOOTABLE, // flags
+		S_NULL          // raisestate
+	},
+
+	{           // MT_SINKTRAIL
+		-1,             // doomednum
+		S_SINKTRAIL1,   // spawnstate
+		1000,           // spawnhealth
+		S_NULL,         // seestate
+		sfx_None,       // seesound
+		8,              // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		0,              // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_None,       // deathsound
+		8,              // speed
+		20*FRACUNIT,    // radius
+		16*FRACUNIT,    // height
+		0,              // display offset
+		100,            // mass
+		0,              // damage
+		sfx_None,       // activesound
+		MF_NOBLOCKMAP|MF_NOGRAVITY|MF_NOCLIP|MF_SCENERY, // flags
+		S_NULL          // raisestate
+	},
+
+	{           // MT_POKEY
+		2002,           // doomednum
+		S_POKEY1,       // spawnstate
+		1000,           // spawnhealth
+		S_POKEY1,       // seestate
+		sfx_None,       // seesound
+		32,             // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		100,            // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_None,       // deathsound
+		3,              // speed
+		21*FRACUNIT,    // radius
+		69*FRACUNIT,    // height
+		0,              // display offset
+		100,            // mass
+		0,              // damage
+		sfx_None,       // activesound
+		MF_SPECIAL|MF_SHOOTABLE, // flags
+		S_NULL          // raisestate
+	},
+
+	{           // MT_ENEMYFLIP
+		2003,           // doomednum
+		S_NULL,         // spawnstate
+		1000,           // spawnhealth
+		S_NULL,         // seestate
+		sfx_None,       // seesound
+		8,              // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		100,            // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_None,       // deathsound
+		8,              // speed
+		32*FRACUNIT,    // radius
+		64*FRACUNIT,    // height
+		0,              // display offset
+		100,            // mass
+		0,              // damage
+		sfx_None,       // activesound
+		MF_SCENERY,     // flags
+		S_NULL          // raisestate
+	},
+
+	{           // MT_WAYPOINT
+		2001,           // doomednum
+		S_NULL,         // spawnstate
+		1000,           // spawnhealth
+		S_NULL,         // seestate
+		sfx_None,       // seesound
+		0,              // reactiontime
+		sfx_None,       // attacksound
+		S_NULL,         // painstate
+		100,            // painchance
+		sfx_None,       // painsound
+		S_NULL,         // meleestate
+		S_NULL,         // missilestate
+		S_NULL,         // deathstate
+		S_NULL,         // xdeathstate
+		sfx_None,       // deathsound
+		0,              // speed
+		1*FRACUNIT,     // radius
+		2*FRACUNIT,     // height
+		0,              // display offset
+		100,            // mass
+		0,              // damage
+		sfx_None,       // activesound
+		MF_NOBLOCKMAP|MF_NOSECTOR|MF_NOCLIP|MF_NOGRAVITY, // flags
+		S_NULL          // raisestate
+	},
+
 #ifdef SEENAMES
 	{           // MT_NAMECHECK
 		-1,             // doomednum
diff --git a/src/info.h b/src/info.h
index 3ddd9d249..4af684e6f 100644
--- a/src/info.h
+++ b/src/info.h
@@ -598,6 +598,11 @@ typedef enum sprite
 	SPR_BOMB, // Bob-omb
 	SPR_BLIG, // Blue Lightning
 	SPR_LIGH, // Lightning
+	SPR_SINK, // Kitchen Sink
+	SPR_SITR, // Kitchen Sink Trail
+	
+	// Additional Kart Objects
+	SPR_POKE, // Lightning
 
 	SPR_FIRSTFREESLOT,
 	SPR_LASTFREESLOT = SPR_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
@@ -3194,6 +3199,23 @@ typedef enum state
 	S_LIGHTNING3,
 	S_LIGHTNING4,
 
+	// The legend
+	S_SINK,
+	S_SINKTRAIL1,
+	S_SINKTRAIL2,
+	S_SINKTRAIL3,
+
+	// Pokey
+	S_POKEY1,
+	S_POKEY2,
+	S_POKEY3,
+	S_POKEY4,
+	S_POKEY5,
+	S_POKEY6,
+	S_POKEY7,
+	S_POKEY8,
+	S_POKEYIDLE,
+
 #ifdef SEENAMES
 	S_NAMECHECK,
 #endif
@@ -3764,6 +3786,13 @@ typedef enum mobj_type
 	MT_BLUEEXPLOSION,
 	MT_LIGHTNING,
 
+	MT_SINK, // Kitchen Sink Stuff
+	MT_SINKTRAIL,
+
+	MT_POKEY, // Huh, thought this was a default asset for some reason, guess not.
+	MT_ENEMYFLIP,
+	MT_WAYPOINT,
+
 #ifdef SEENAMES
 	MT_NAMECHECK,
 #endif
diff --git a/src/k_kart.c b/src/k_kart.c
index bee2aaf20..71210a63e 100644
--- a/src/k_kart.c
+++ b/src/k_kart.c
@@ -9,6 +9,7 @@
 #include "g_game.h"
 #include "m_random.h"
 #include "p_local.h"
+#include "p_slopes.h"
 #include "r_draw.h"
 #include "r_local.h"
 #include "s_sound.h"
@@ -898,7 +899,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
 void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
 {
 	// This spawns the drift sparks when k_driftcharge hits 30. Its own AI handles life/death and color
-	if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) 
+	if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) 
 		&& player->kartstuff[k_driftcharge] == 30)
 		P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_DRIFT)->target = player->mo;
 	
@@ -911,12 +912,18 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd)
 	if (player->kartstuff[k_spinouttimer])
 		player->kartstuff[k_spinouttimer]--;
 	
+	if (player->kartstuff[k_spinout] == 0 && player->kartstuff[k_spinouttimer] == 0 && player->powers[pw_flashing] == flashingtics)
+		player->powers[pw_flashing]--;
+	
 	if (player->kartstuff[k_magnettimer])
 		player->kartstuff[k_magnettimer]--;
 	
 	if (player->kartstuff[k_mushroomtimer])
 		player->kartstuff[k_mushroomtimer]--;
 	
+	if (player->kartstuff[k_floorboost])
+		player->kartstuff[k_floorboost]--;
+	
 	if (player->kartstuff[k_startimer])
 		player->kartstuff[k_startimer]--;
 	
@@ -1026,23 +1033,26 @@ void K_PlayTauntSound(mobj_t *source)
 		S_StartSound(source, sfx_taunt4);
 }
 
-boolean K_SpinPlayer(player_t *player, mobj_t *source)
+void K_SpinPlayer(player_t *player, mobj_t *source)
 {
 	if (player->health <= 0)
-		return false;
+		return;
 
 	if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0)
 		|| player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0)
-		return false;
+		return;
 
 	player->kartstuff[k_mushroomtimer] = 0;
 
-	if (player->kartstuff[k_spinouttype] == 0)
+	if (player->kartstuff[k_spinouttype] <= 0)
 	{
-		player->kartstuff[k_spinouttimer] = 2*TICRATE;
+		if (player->kartstuff[k_spinouttype] == 0)
+			player->kartstuff[k_spinouttimer] = 2*TICRATE;
+		else
+			player->kartstuff[k_spinouttimer] = 3*TICRATE/2;
 
 		if (player->speed < player->normalspeed/4)
-			P_InstaThrust(player->mo, player->mo->angle, player->normalspeed*FRACUNIT/4);
+			P_InstaThrust(player->mo, player->mo->angle, FixedMul(player->normalspeed/4, player->mo->scale));
 
 		S_StartSound(player->mo, sfx_slip);
 	}
@@ -1058,17 +1068,17 @@ boolean K_SpinPlayer(player_t *player, mobj_t *source)
 
 	player->kartstuff[k_spinouttype] = 0;
 
-	return true;
+	return;
 }
 
-boolean K_SquishPlayer(player_t *player, mobj_t *source)
+void K_SquishPlayer(player_t *player, mobj_t *source)
 {
 	if (player->health <= 0)
-		return false;
+		return;
 
 	if (player->powers[pw_flashing] > 0	|| player->kartstuff[k_squishedtimer] > 0 
 		|| player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0)
-		return false;
+		return;
 
 	player->kartstuff[k_mushroomtimer] = 0;
 
@@ -1083,17 +1093,17 @@ boolean K_SquishPlayer(player_t *player, mobj_t *source)
 
 	P_PlayRinglossSound(player->mo);
 
-	return true;
+	return;
 }
 
-boolean K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
+void K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we just throw the player up higher here and extend their spinout timer
 {
 	if (player->health <= 0)
-		return false;
+		return;
 
 	if (player->powers[pw_flashing] > 0 || player->kartstuff[k_squishedtimer] > 0 || (player->kartstuff[k_spinouttimer] > 0 && player->kartstuff[k_spinout] > 0)
 		|| player->kartstuff[k_startimer] > 0 || player->kartstuff[k_growshrinktimer] > 0 || player->kartstuff[k_bootaketimer] > 0)
-		return false;
+		return;
 
 	player->mo->momz = 18*FRACUNIT;
 	player->mo->momx = player->mo->momy = 0;
@@ -1113,7 +1123,7 @@ boolean K_ExplodePlayer(player_t *player, mobj_t *source) // A bit of a hack, we
 
 	P_PlayRinglossSound(player->mo);
 
-	return true;
+	return;
 }
 
 void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit)
@@ -1281,7 +1291,7 @@ void K_SpawnDriftTrail(player_t *player)
 				ground -= FixedMul(mobjinfo[MT_MUSHROOMTRAIL].height, player->mo->scale);
 		}
 #endif
-		if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && player->kartstuff[k_mushroomtimer] == 0)
+		if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) && player->kartstuff[k_mushroomtimer] == 0)
 			flame = P_SpawnMobj(newx, newy, ground, MT_DRIFTSMOKE);
 		else
 			flame = P_SpawnMobj(newx, newy, ground, MT_MUSHROOMTRAIL);
@@ -1558,9 +1568,11 @@ static void K_DoBooSteal(player_t * player)
 
 void K_DoMushroom(player_t *player, boolean doPFlag)
 {
-	S_StartSound(player->mo, sfx_mush);
+	if (!player->kartstuff[k_floorboost] || player->kartstuff[k_floorboost] == 3)
+		S_StartSound(player->mo, sfx_mush);
+
 	player->kartstuff[k_mushroomtimer] = mushroomtime;
-	
+
 	if (doPFlag)
 		player->pflags |= PF_ATTACKDOWN;
 
@@ -1594,6 +1606,187 @@ void K_DoLightning(player_t *player, boolean bluelightning)
 	player->kartstuff[k_sounds] = 70;
 }
 
+void K_KartDrift(player_t *player, ticcmd_t *cmd, boolean onground)
+{
+	// Drifting is actually straffing + automatic turning.
+	// Holding the Jump button will enable drifting.
+	if (cmd->buttons & BT_DRIFTRIGHT)
+		player->kartstuff[k_turndir] = 1;
+	else if (cmd->buttons & BT_DRIFTLEFT)
+		player->kartstuff[k_turndir] = -1;
+	else
+		player->kartstuff[k_turndir] = 0;
+
+	// Drift Release (Moved here so you can't "chain" drifts)
+	if ((player->kartstuff[k_drift] == 0) 
+		// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
+		&& player->kartstuff[k_driftcharge] < 30
+		&& onground)
+	{
+		player->kartstuff[k_drift] = 0;
+		player->kartstuff[k_driftcharge] = 0;
+	}
+	else if ((player->kartstuff[k_drift] == 0) 
+		// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
+		&& (player->kartstuff[k_driftcharge] >= 30 && player->kartstuff[k_driftcharge] < 60)
+		&& onground)
+	{
+		player->powers[pw_sneakers] += 17;
+		S_StartSound(player->mo, sfx_mush);
+		player->kartstuff[k_drift] = 0;
+		player->kartstuff[k_driftcharge] = 0;
+	}
+	else if ((player->kartstuff[k_drift] == 0) 
+		// || (player->kartstuff[k_drift] >= 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_turndir] != -1))
+		&& player->kartstuff[k_driftcharge] >= 60
+		&& onground)
+	{
+		player->powers[pw_sneakers] += 35;
+		S_StartSound(player->mo, sfx_mush);
+		player->kartstuff[k_drift] = 0;
+		player->kartstuff[k_driftcharge] = 0;
+	}
+
+	// Drifting: left or right?
+	if (player->kartstuff[k_turndir] == 1 && player->speed > 10 && player->kartstuff[k_jmp] == 1
+		&& player->kartstuff[k_drift] < 3 && player->kartstuff[k_drift] > -1) // && player->kartstuff[k_drift] != 1)
+		player->kartstuff[k_drift] = 1;
+	else if (player->kartstuff[k_turndir] == -1 && player->speed > 10 && player->kartstuff[k_jmp] == 1
+		&& player->kartstuff[k_drift] > -3 && player->kartstuff[k_drift] < 1) // && player->kartstuff[k_drift] != -1)
+		player->kartstuff[k_drift] = -1;
+	else if (player->kartstuff[k_jmp] == 0) // || player->kartstuff[k_turndir] == 0)
+		player->kartstuff[k_drift] = 0;
+
+	// Incease/decrease the drift value to continue drifting in that direction
+	if (player->kartstuff[k_spinouttimer] == 0 && player->kartstuff[k_jmp] == 1 && onground
+		&& (player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1))
+	{
+		player->kartstuff[k_driftcharge]++;
+
+		if (player->kartstuff[k_drift] >= 1) // Drifting to the Right
+		{
+			player->kartstuff[k_drift]++;
+			if (player->kartstuff[k_drift] > 3)
+				player->kartstuff[k_drift] = 3;
+			
+			// Left = +450 Right = -450
+			// Player 1
+			if (player == &players[consoleplayer])
+			{
+				if (player->kartstuff[k_turndir] == -1)     // Turning Left  while Drifting Right
+					localangle -=  600*FRACUNIT;
+				else if (player->kartstuff[k_turndir] == 1) // Turning Right while Drifting Right
+					localangle -=  225*FRACUNIT;
+				else                                        // No Direction  while Drifting Right
+					localangle -=  450*FRACUNIT;
+			}
+
+			// Player 2
+			if (splitscreen	&& player == &players[secondarydisplayplayer])
+			{
+				
+			}
+		}
+		else if (player->kartstuff[k_drift] <= -1) // Drifting to the Left
+		{
+			player->kartstuff[k_drift]--;
+			if (player->kartstuff[k_drift] < -3)
+				player->kartstuff[k_drift] = -3;
+			
+			// Left = +450 Right = -450
+			// Player 1
+			if (player == &players[consoleplayer])
+			{
+				if (player->kartstuff[k_turndir] == 1)       // Turning Right  while Drifting Left
+					localangle +=  600*FRACUNIT;
+				else if (player->kartstuff[k_turndir] == -1) // Turning Left while Drifting Left
+					localangle +=  225*FRACUNIT;
+				else                                         // No Direction  while Drifting Left
+					localangle +=  450*FRACUNIT;
+			}
+
+			// Player 2
+			if (splitscreen	&& player == &players[secondarydisplayplayer] && player->kartstuff[k_turndir] == 1)
+				localangle2 += (300+192)*FRACUNIT;
+			else if (splitscreen && player == &players[secondarydisplayplayer])
+				localangle2 += (300)*FRACUNIT;
+		}
+	}
+
+	// Stop drifting
+	if (player->kartstuff[k_spinouttimer] > 0 // banana peel
+	|| player->speed < 10) // you're too slow!
+	{
+		player->kartstuff[k_drift] = 0;
+		player->kartstuff[k_driftcharge] = 0;
+	}
+}
+
+UINT64 K_GetKartSpeed(player_t *player)
+{
+	UINT64 k_speed = 47*FRACUNIT + FRACUNIT/2;
+	
+	// Speed is a value between 48 and 52, incremented by halves
+	k_speed += player->kartspeed*FRACUNIT/2;
+	
+	return k_speed;
+}
+
+UINT64 K_GetKartAccel(player_t *player)
+{
+	UINT64 k_accel = 45;
+	
+	// Acceleration is a given base, minus the speed value.
+	k_accel -= 3*player->kartspeed;
+	
+	return k_accel;
+}
+
+fixed_t K_3dKartMovement(player_t *player, boolean onground)
+{
+	// If the player isn't on the ground, there is no change in speed
+	if (!onground) return 0;
+	
+	fixed_t accelmax = 2000;	// AccelMax
+	fixed_t f_beater = 2*FRACUNIT - (0xE8<<(FRACBITS-8)); //1.10345f;	// Friction Beater  Friction = (0xE8 << (FRACBITS-8))
+	fixed_t g_cc = 1*FRACUNIT; 					// Game CC
+	
+	fixed_t newspeed, oldspeed, finalspeed;
+	fixed_t boostpower = 1*FRACUNIT;
+	fixed_t p_speed = K_GetKartSpeed(player);
+	fixed_t p_accel = K_GetKartAccel(player);
+	
+	sector_t *nextsector = R_PointInSubsector(player->mo->x + player->mo->momx*2, player->mo->y + player->mo->momy*2)->sector;
+	
+	// Determine boostpower by checking every power. There's probably a cleaner way to do this, but eh whatever.
+	if (!(player->kartstuff[k_startimer] || player->kartstuff[k_bootaketimer] || player->powers[pw_sneakers] || 
+		  player->kartstuff[k_mushroomtimer] || player->kartstuff[k_growshrinktimer] > 1) && P_IsObjectOnGround(player->mo) &&
+		  nextsector->special & 256 && nextsector->special != 768 && (nextsector->special != 1024 || nextsector->special != 4864))
+													boostpower = FixedMul(boostpower, FRACUNIT/4);	// Off-road, unless you're ignoring off-road.
+	if (player->kartstuff[k_growshrinktimer] < -1) 	boostpower = FixedMul(boostpower, FRACUNIT/3);	// Shrink
+	if (player->kartstuff[k_squishedtimer] > 0) 	boostpower = FixedMul(boostpower, FRACUNIT/2);	// Squished
+	if (player->powers[pw_sneakers]) 				boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/4);	// Slide Boost
+	if (player->kartstuff[k_growshrinktimer] > 1) 	boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/3);	// Mega Mushroom
+	if (player->kartstuff[k_startimer]) 			boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/2);	// Star
+	if (player->kartstuff[k_mushroomtimer]) 		boostpower = FixedMul(boostpower, FRACUNIT+FRACUNIT/1);	// Mushroom
+	
+	// Boostpower is applied to each stat individually, and NOT the calculation.
+	// Applying to the calculation fails due to friction never getting beaten, or getting overshot really far.
+	// It's easier this way.
+	// Similarly, the CC of the game is also multiplied directly. 
+	// This assures a growth in speed without affecting acceleration curving.
+	p_speed  = FixedMul(FixedMul(p_speed,  boostpower), g_cc);
+	p_accel  = FixedMul(FixedMul(p_accel,  boostpower), g_cc);
+	accelmax = FixedMul(FixedMul(accelmax, boostpower), g_cc);
+
+	// Now, the code that made Iceman's eyes rub erotically against a toaster.
+	oldspeed = FixedMul(FixedMul(P_AproxDistance(player->rmomx, player->rmomy), player->mo->scale), f_beater);
+	newspeed = FixedMul(FixedDiv(FixedMul(oldspeed, accelmax - p_accel) + FixedMul(p_speed, p_accel), accelmax), f_beater);
+	finalspeed = newspeed - oldspeed;
+
+	return (fixed_t)finalspeed;
+}
+
 void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 {
 	boolean ATTACK_IS_DOWN = ((cmd->buttons & BT_ATTACK) && !(player->pflags & PF_ATTACKDOWN));
@@ -1972,9 +2165,9 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 		if (player->kartstuff[k_mushroomtimer] > 0 && player->kartstuff[k_boosting] == 0 && onground)
 		{
 			cmd->forwardmove = 1;
-			if (player->kartstuff[k_drift] == 1)
+			if (player->kartstuff[k_drift] >= 1)
 				P_InstaThrust(player->mo, player->mo->angle+ANGLE_45, 55*FRACUNIT);
-			else if (player->kartstuff[k_drift] == -1)
+			else if (player->kartstuff[k_drift] <= -1)
 				P_InstaThrust(player->mo, player->mo->angle-ANGLE_45, 55*FRACUNIT);
 			else
 				P_InstaThrust(player->mo, player->mo->angle, 55*FRACUNIT);
@@ -2020,79 +2213,7 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 	if (splitscreen && player == &players[secondarydisplayplayer])
 		CV_SetValue(&cv_cam2_dist, 190);
 
-	// DRRRRIIIIFFFFFFTTT!!!!
-	// Drifting is actually straffing + automatic turning.
-	// Holding the Jump button will enable drifting.
-
-	// Instead of instantly straffing, you go from running
-	// straight to slowly turning left/right.
-	// 536870912 is the normal straffing angle, 90 degrees.
-	// 35791394 is the speed that's added from 0 to 90.
-
-	// localangle is SRB2's turning code, not angle direction.
-	// Adding or subtracting by 300 is how much you can turn.
-	// The higher it is, the faster you turn.
-
-	if (cmd->buttons & BT_DRIFTRIGHT)
-		player->kartstuff[k_turndir] = 1;
-	else if (cmd->buttons & BT_DRIFTLEFT)
-		player->kartstuff[k_turndir] = -1;
-	else
-		player->kartstuff[k_turndir] = 0;
-
-	// Moved here so you can't "chain" drifts
-	// Drift Release
-	if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1))
-		&& player->kartstuff[k_driftcharge] < 30
-		&& onground)
-	{
-		player->kartstuff[k_drift] = 0;
-		player->kartstuff[k_driftcharge] = 0;
-	}
-	else if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1))
-		&& (player->kartstuff[k_driftcharge] >= 30 && player->kartstuff[k_driftcharge] < 60)
-		&& onground)
-	{
-		player->powers[pw_sneakers] += 17;
-		S_StartSound(player->mo, sfx_mush);
-		player->kartstuff[k_drift] = 0;
-		player->kartstuff[k_driftcharge] = 0;
-	}
-	else if (((player->kartstuff[k_drift] == 0) || (player->kartstuff[k_drift] == 1 && player->kartstuff[k_turndir] != 1) || (player->kartstuff[k_drift] == -1 && player->kartstuff[k_turndir] != -1))
-		&& player->kartstuff[k_driftcharge] >= 60
-		&& onground)
-	{
-		player->powers[pw_sneakers] += 35;
-		S_StartSound(player->mo, sfx_mush);
-		player->kartstuff[k_drift] = 0;
-		player->kartstuff[k_driftcharge] = 0;
-	}
-
-	if (player->kartstuff[k_turndir] == 1 && player->speed > 10
-		&& player->kartstuff[k_jmp] == 1
-		&& player->kartstuff[k_drift] != 1)
-		player->kartstuff[k_drift] = 1;
-	else if (player->kartstuff[k_turndir] == -1 && player->speed > 10
-		&& player->kartstuff[k_jmp] == 1
-		&& player->kartstuff[k_drift] != -1)
-		player->kartstuff[k_drift] = -1;
-	else if (player->kartstuff[k_jmp] == 0 || player->kartstuff[k_turndir] == 0)
-		player->kartstuff[k_drift] = 0;
-
-	// If you press any strafe key while turning right, then drift right.
-	if (player->kartstuff[k_spinouttimer] == 0
-	&& player->kartstuff[k_jmp] == 1 && (player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1)
-	&& onground) //Right
-	{
-		player->kartstuff[k_driftcharge]++;
-	}
-	// Stop drifting
-	if (player->kartstuff[k_spinouttimer] > 0 // banana peel
-	|| player->speed < 10) // you're too slow!
-	{
-		player->kartstuff[k_drift] = 0;
-		player->kartstuff[k_driftcharge] = 0;
-	}
+	K_KartDrift(player, cmd, onground);
 
 	// Quick Turning
 	// You can't turn your kart when you're not moving.
@@ -2161,7 +2282,6 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 		}
 	}
 	*/
-	player->kartstuff[k_boostcharge] = 0;
 	
 	// Play the stop light's sounds
 	if ((leveltime == (TICRATE-4)*2) || (leveltime == (TICRATE-2)*3))
@@ -2175,7 +2295,7 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 		player->kartstuff[k_boostcharge] = 0;
 	// Increase your size while charging your engine.
 	if (leveltime < 150)
-		player->mo->destscale = FRACUNIT*((100 + player->kartstuff[k_boostcharge])/100);
+		player->mo->destscale = FRACUNIT + (player->kartstuff[k_boostcharge]*655);
 
 	// Determine the outcome of your charge.
 	if (leveltime > 140 && player->kartstuff[k_boostcharge])
@@ -2187,7 +2307,10 @@ void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground)
 		}
 		// You overcharged your engine? Those things are expensive!!!
 		if (player->kartstuff[k_boostcharge] > 10)
-			player->kartstuff[k_boostcharge] = 40;
+		{
+			player->powers[pw_nocontrol] = 40;
+			S_StartSound(player->mo, sfx_slip);
+		}
 
 		player->kartstuff[k_boostcharge] = 0;
 	}
@@ -2351,6 +2474,7 @@ static patch_t *kp_blueshell;
 static patch_t *kp_fireflower;
 static patch_t *kp_tripleredshell;
 static patch_t *kp_lightning;
+static patch_t *kp_kitchensink;
 static patch_t *kp_itemused1;
 static patch_t *kp_itemused2;
 static patch_t *kp_itemused3;
@@ -2447,6 +2571,7 @@ void K_LoadKartHUDGraphics(void)
 	kp_fireflower = 			W_CachePatchName("K_ITFIRE", PU_HUDGFX);
 	kp_tripleredshell = 		W_CachePatchName("K_ITTRED", PU_HUDGFX);
 	kp_lightning = 				W_CachePatchName("K_ITLIGH", PU_HUDGFX);
+	kp_kitchensink = 			W_CachePatchName("K_ITSINK", PU_HUDGFX);
 	
 	// Item-used - Closing the item window after an item is used
 	kp_itemused1 = 				W_CachePatchName("K_ITUSE1", PU_HUDGFX);
@@ -2725,6 +2850,7 @@ static void K_drawKartRetroItem(void)
 	if 		((stplyr->kartstuff[k_bootaketimer] > 0 
 		|| stplyr->kartstuff[k_boostolentimer] > 0) && (leveltime & 2)) 	localpatch = kp_boosteal;
 	else if (stplyr->kartstuff[k_boostolentimer] > 0 && !(leveltime & 2))	localpatch = kp_noitem;
+	else if (stplyr->kartstuff[k_kitchensink] == 1)							localpatch = kp_kitchensink;
 	else if (stplyr->kartstuff[k_lightning] == 1)							localpatch = kp_lightning;
 	else if (stplyr->kartstuff[k_tripleredshell] & 8)						localpatch = kp_tripleredshell;
 	else if (stplyr->kartstuff[k_fireflower] == 1)							localpatch = kp_fireflower;
@@ -3083,15 +3209,9 @@ void K_drawKartHUD(void)
 	K_DrawKartPositionNum(stplyr->kartstuff[k_spinout]);
 	//K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
 	
-	// Why is this here?????
-	/*
+	// Plays the music after the starting countdown. This is here since it checks every frame regularly.
 	if (leveltime > 157 && leveltime < (TICRATE+1)*7)
-	{
-		if (!(mapmusic & 2048)) // TODO: Might not need this here
-			mapmusic = mapheaderinfo[gamemap-1].musicslot;
-
-		S_ChangeMusic(mapmusic & 2047, true);
-	}*/
+		S_ChangeMusicInternal(mapmusname, true);
 }
 
 //}
diff --git a/src/k_kart.h b/src/k_kart.h
index 5f822cd63..014eb5819 100644
--- a/src/k_kart.h
+++ b/src/k_kart.h
@@ -16,11 +16,13 @@ UINT8 K_GetKartColorByName(const char *name);
 void K_RegisterKartStuff(void);
 
 void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
-boolean K_SpinPlayer(player_t *player, mobj_t *source);
-boolean K_SquishPlayer(player_t *player, mobj_t *source);
-boolean K_ExplodePlayer(player_t *player, mobj_t *source);
+void K_SpinPlayer(player_t *player, mobj_t *source);
+void K_SquishPlayer(player_t *player, mobj_t *source);
+void K_ExplodePlayer(player_t *player, mobj_t *source);
 void K_SpawnKartExplosion(fixed_t x, fixed_t y, fixed_t z, fixed_t radius, INT32 number, mobjtype_t type, angle_t rotangle, boolean spawncenter, boolean ghostit);
 void K_SpawnDriftTrail(player_t *player);
+void K_DoMushroom(player_t *player, boolean doPFlag);
+fixed_t K_3dKartMovement(player_t *player, boolean onground);
 void K_MoveKartPlayer(player_t *player, ticcmd_t *cmd, boolean onground);
 
 void K_LoadKartHUDGraphics(void);
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index bd5605f23..29bcd7364 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -144,6 +144,12 @@ static int player_get(lua_State *L)
 		lua_pushfixed(L, plr->dashspeed);
 	else if (fastcmp(field,"dashtime"))
 		lua_pushinteger(L, plr->dashtime);
+	// SRB2kart
+	else if (fastcmp(field,"kartspeed"))
+		lua_pushfixed(L, plr->kartspeed);
+	else if (fastcmp(field,"kartweight"))
+		lua_pushfixed(L, plr->kartweight);
+	//
 	else if (fastcmp(field,"normalspeed"))
 		lua_pushfixed(L, plr->normalspeed);
 	else if (fastcmp(field,"runspeed"))
@@ -401,6 +407,12 @@ static int player_set(lua_State *L)
 		plr->dashspeed = luaL_checkfixed(L, 3);
 	else if (fastcmp(field,"dashtime"))
 		plr->dashtime = (INT32)luaL_checkinteger(L, 3);
+	// SRB2kart
+	else if (fastcmp(field,"kartspeed"))
+		plr->kartspeed = (UINT8)luaL_checkfixed(L, 3);
+	else if (fastcmp(field,"kartweight"))
+		plr->kartweight = (UINT8)luaL_checkfixed(L, 3);
+	//
 	else if (fastcmp(field,"normalspeed"))
 		plr->normalspeed = luaL_checkfixed(L, 3);
 	else if (fastcmp(field,"runspeed"))
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index 28d5fed23..85e029e64 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -38,6 +38,10 @@ enum skin {
 	skin_actionspd,
 	skin_mindash,
 	skin_maxdash,
+	// SRB2kart
+	skin_kartspeed,
+	skin_kartweight,
+	//
 	skin_normalspeed,
 	skin_runspeed,
 	skin_thrustfactor,
@@ -68,6 +72,10 @@ static const char *const skin_opt[] = {
 	"actionspd",
 	"mindash",
 	"maxdash",
+	// SRB2kart
+	"kartspeed",
+	"kartweight",
+	//
 	"normalspeed",
 	"runspeed",
 	"thrustfactor",
@@ -155,6 +163,14 @@ static int skin_get(lua_State *L)
 	case skin_maxdash:
 		lua_pushfixed(L, skin->maxdash);
 		break;
+	// SRB2kart
+	case skin_kartspeed:
+		lua_pushfixed(L, skin->kartspeed);
+		break;
+	case skin_kartweight:
+		lua_pushfixed(L, skin->kartweight);
+		break;
+	//
 	case skin_normalspeed:
 		lua_pushfixed(L, skin->normalspeed);
 		break;
diff --git a/src/m_menu.c b/src/m_menu.c
index 2b623651d..38c9acfea 100644
--- a/src/m_menu.c
+++ b/src/m_menu.c
@@ -376,6 +376,9 @@ consvar_t cv_chooseskin = {"chooseskin", DEFAULTSKIN, CV_HIDEN|CV_CALL, skins_co
 // When you add gametypes here, don't forget to update them in CV_AddValue!
 CV_PossibleValue_t gametype_cons_t[] =
 {
+	{GT_RACE, "Race"}, {GT_MATCH, "Match"},
+
+	/*						// SRB2kart
 	{GT_COOP, "Co-op"},
 
 	{GT_COMPETITION, "Competition"},
@@ -388,9 +391,10 @@ CV_PossibleValue_t gametype_cons_t[] =
 	{GT_HIDEANDSEEK, "Hide and Seek"},
 
 	{GT_CTF, "CTF"},
+	*/
 	{0, NULL}
 };
-consvar_t cv_newgametype = {"newgametype", "Co-op", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_newgametype = {"newgametype", "Race", CV_HIDEN|CV_CALL, gametype_cons_t, Newgametype_OnChange, 0, NULL, NULL, 0, 0, NULL};
 
 static CV_PossibleValue_t serversort_cons_t[] = {
 	{0,"Ping"},
@@ -1899,19 +1903,19 @@ static void Newgametype_OnChange(void)
 		if(!mapheaderinfo[cv_nextmap.value-1])
 			P_AllocMapHeader((INT16)(cv_nextmap.value-1));
 
-		if ((cv_newgametype.value == GT_COOP && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COOP)) ||
-			(cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) ||
-			(cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) ||
-			((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH)) ||
-			((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) ||
-			(cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF)))
+		if ((cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) || // SRB2kart
+			//(cv_newgametype.value == GT_COMPETITION && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_COMPETITION)) ||
+			//(cv_newgametype.value == GT_RACE && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_RACE)) ||
+			((cv_newgametype.value == GT_MATCH || cv_newgametype.value == GT_TEAMMATCH) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_MATCH))) // ||
+			//((cv_newgametype.value == GT_TAG || cv_newgametype.value == GT_HIDEANDSEEK) && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_TAG)) ||
+			//(cv_newgametype.value == GT_CTF && !(mapheaderinfo[cv_nextmap.value-1]->typeoflevel & TOL_CTF)))
 		{
 			INT32 value = 0;
 
 			switch (cv_newgametype.value)
 			{
 				case GT_COOP:
-					value = TOL_COOP;
+					value = TOL_RACE; // SRB2kart
 					break;
 				case GT_COMPETITION:
 					value = TOL_COMPETITION;
@@ -4264,7 +4268,7 @@ static void M_NewGame(void)
 	fromlevelselect = false;
 
 	startmap = spstage_start;
-	CV_SetValue(&cv_newgametype, GT_COOP); // Graue 09-08-2004
+	CV_SetValue(&cv_newgametype, GT_RACE); // SRB2kart
 
 	M_SetupChoosePlayer(0);
 }
@@ -6213,6 +6217,15 @@ static void M_DrawServerMenu(void)
 	}
 #endif
 
+	// SRB2kart
+	// A 70x70 image of the level's gametype
+	/*
+	if (mapheaderinfo[cv_nextmap.value-1].typeoflevel & TOL_KART)
+		V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("KART", PU_STATIC));
+	else
+		V_DrawSmallScaledPatch(BASEVIDWIDTH/2,130,0,W_CachePatchName("SONR", PU_STATIC));
+	*/
+
 	//  A 160x100 image of the level as entry MAPxxP
 	lumpnum = W_CheckNumForName(va("%sP", G_BuildMapName(cv_nextmap.value)));
 
diff --git a/src/m_misc.h b/src/m_misc.h
index fa1f3b33c..f2a8bb546 100644
--- a/src/m_misc.h
+++ b/src/m_misc.h
@@ -38,7 +38,7 @@ void M_StopMovie(void);
 #elif defined (PSP)
 #define CONFIGFILENAME "srb2psp.cfg"
 #else
-#define CONFIGFILENAME "config.cfg"
+#define CONFIGFILENAME "kartconfig.cfg"
 #endif
 
 INT32 M_MapNumber(char first, char second);
diff --git a/src/p_inter.c b/src/p_inter.c
index 1c97302d0..15d2e1f17 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -1151,6 +1151,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 		case MT_STARPOST:
 			if (player->bot)
 				return;
+			// SRB2kart - 150117
+			if (player->exiting) //STOP MESSING UP MY STATS FASDFASDF
+			{
+				player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint];
+				return;
+			}
+			//
 			// In circuit, player must have touched all previous starposts
 			if (circuitmap
 				&& special->health - player->starpostnum > 1)
@@ -1173,7 +1180,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 				return; // Already hit this post
 
 			// Save the player's time and position.
-			player->starposttime = leveltime;
+			player->starposttime = player->realtime; //this makes race mode's timers work correctly whilst not affecting sp -x
+			if (((special->health - 1) + (numstarposts+1)*player->laps) < 256) // SIGSEGV prevention
+				player->checkpointtimes[(special->health - 1) + (numstarposts+1)*player->laps] = player->realtime;
+			//player->starposttime = leveltime;
 			player->starpostx = toucher->x>>FRACBITS;
 			player->starposty = toucher->y>>FRACBITS;
 			player->starpostz = special->z>>FRACBITS;
@@ -1181,6 +1191,10 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 			player->starpostnum = special->health;
 			P_ClearStarPost(special->health);
 
+			// SRB2kart
+			if (gametype == GT_RACE)
+				player->kartstuff[k_playerahead] = P_CheckPlayerAhead(player, (special->health - 1) + (numstarposts+1)*player->laps);
+
 			// Find all starposts in the level with this value.
 			{
 				thinker_t *th;
@@ -1479,6 +1493,58 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 	P_KillMobj(special, NULL, toucher);
 }
 
+// SRB2kart
+INT32 P_CheckPlayerAhead(player_t *player, INT32 tocheck)
+{
+	INT32 i, retvalue = 0, me = -1;
+	tic_t besttime = 0xffffffff;
+
+	if (tocheck >= 256)
+		return 0; //Don't SIGSEGV.
+
+	for (i = 0; i < MAXPLAYERS; i++)
+	{
+		if (!playeringame[i])
+			continue;
+
+		if (player == &players[i]) //you're me!
+		{
+			me = i;
+			continue;
+		}
+
+		if (!players[i].checkpointtimes[tocheck])
+			continue;
+
+		if (players[i].checkpointtimes[tocheck] >= besttime)
+			continue;
+
+		besttime = players[i].checkpointtimes[tocheck];
+		retvalue = i+1;
+	}
+
+	if (!retvalue)
+		return 0;
+
+	if (besttime >= player->realtime) // > sign is practically paranoia
+	{
+		if (!players[retvalue-1].kartstuff[k_playerahead] && me != -1
+			&& players[retvalue-1].laps == player->laps
+			&& players[retvalue-1].starpostnum == player->starpostnum)
+			players[retvalue-1].kartstuff[k_playerahead] = 65536;
+		return 65536; //we're tied!
+	}
+
+	//checkplayerahead does this too!
+	if (!players[retvalue-1].kartstuff[k_playerahead] && me != -1
+		&& players[retvalue-1].laps == player->laps
+		&& players[retvalue-1].starpostnum == player->starpostnum)
+		players[retvalue-1].kartstuff[k_playerahead] = 257 + me;
+
+	return retvalue;
+}
+//
+
 /** Prints death messages relating to a dying or hit player.
   *
   * \param player    Affected player.
@@ -1956,14 +2022,60 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
 	if (inflictor && (inflictor->type == MT_SHELL || inflictor->type == MT_FIREBALL))
 		P_SetTarget(&target->tracer, inflictor);
 
+	// SRB2kart
+	// I wish I knew a better way to do this
+	if (target->target && target->target->player && target->target->player->mo)
+	{
+		if (target->type == MT_GREENSHIELD && target->target->player->kartstuff[k_greenshell] & 1)
+			target->target->player->kartstuff[k_greenshell] &= ~1;
+		else if (target->type == MT_REDSHIELD && target->target->player->kartstuff[k_redshell] & 1)
+			target->target->player->kartstuff[k_redshell] &= ~1;
+		else if (target->type == MT_BANANASHIELD && target->target->player->kartstuff[k_banana] & 1)
+			target->target->player->kartstuff[k_banana] &= ~1;
+		else if (target->type == MT_FAKESHIELD && target->target->player->kartstuff[k_fakeitem] & 1)
+			target->target->player->kartstuff[k_fakeitem] &= ~1;
+		else if (target->type == MT_BOMBSHIELD && target->target->player->kartstuff[k_bobomb] & 1)
+			target->target->player->kartstuff[k_bobomb] &= ~1;
+		else if (target->type == MT_TRIPLEGREENSHIELD1 && target->target->player->kartstuff[k_triplegreenshell] & 1)
+			target->target->player->kartstuff[k_triplegreenshell] &= ~1;
+		else if (target->type == MT_TRIPLEGREENSHIELD2 && target->target->player->kartstuff[k_triplegreenshell] & 2)
+			target->target->player->kartstuff[k_triplegreenshell] &= ~2;
+		else if (target->type == MT_TRIPLEGREENSHIELD3 && target->target->player->kartstuff[k_triplegreenshell] & 4)
+			target->target->player->kartstuff[k_triplegreenshell] &= ~4;
+		else if (target->type == MT_TRIPLEREDSHIELD1 && target->target->player->kartstuff[k_tripleredshell] & 1)
+			target->target->player->kartstuff[k_tripleredshell] &= ~1;
+		else if (target->type == MT_TRIPLEREDSHIELD2 && target->target->player->kartstuff[k_tripleredshell] & 2)
+			target->target->player->kartstuff[k_tripleredshell] &= ~2;
+		else if (target->type == MT_TRIPLEREDSHIELD3 && target->target->player->kartstuff[k_tripleredshell] & 4)
+			target->target->player->kartstuff[k_tripleredshell] &= ~4;
+		else if (target->type == MT_TRIPLEBANANASHIELD1 && target->target->player->kartstuff[k_triplebanana] & 1)
+			target->target->player->kartstuff[k_triplebanana] &= ~1;
+		else if (target->type == MT_TRIPLEBANANASHIELD2 && target->target->player->kartstuff[k_triplebanana] & 2)
+			target->target->player->kartstuff[k_triplebanana] &= ~2;
+		else if (target->type == MT_TRIPLEBANANASHIELD3 && target->target->player->kartstuff[k_triplebanana] & 4)
+			target->target->player->kartstuff[k_triplebanana] &= ~4;
+	}
+	//
+
 	if (!useNightsSS && G_IsSpecialStage(gamemap) && target->player && sstimer > 6)
 		sstimer = 6; // Just let P_Ticker take care of the rest.
 
 	if (target->flags & (MF_ENEMY|MF_BOSS))
 		target->momx = target->momy = target->momz = 0;
 
-	if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR))
-		target->flags |= MF_NOGRAVITY|MF_NOCLIP|MF_NOCLIPHEIGHT; // Don't drop Tails 03-08-2000
+	// SRB2kart
+	if (target->type != MT_PLAYER && !(target->flags & MF_MONITOR)
+		 && !(target->type == MT_GREENITEM || target->type == MT_GREENSHIELD 
+		 || target->type == MT_TRIPLEGREENSHIELD1 || target->type == MT_TRIPLEGREENSHIELD2 || target->type == MT_TRIPLEGREENSHIELD3
+		 || target->type == MT_REDITEM || target->type == MT_REDITEMDUD || target->type == MT_REDSHIELD 
+		 || target->type == MT_TRIPLEREDSHIELD1 || target->type == MT_TRIPLEREDSHIELD2 || target->type == MT_TRIPLEREDSHIELD3
+		 || target->type == MT_BANANAITEM || target->type == MT_BANANASHIELD 
+		 || target->type == MT_TRIPLEBANANASHIELD1 || target->type == MT_TRIPLEBANANASHIELD2 || target->type == MT_TRIPLEBANANASHIELD3
+		 || target->type == MT_FAKEITEM || target->type == MT_FAKESHIELD)) // kart dead items
+		target->flags |= MF_NOGRAVITY; // Don't drop Tails 03-08-2000
+	else
+		target->flags &= ~MF_NOGRAVITY; // lose it if you for whatever reason have it, I'm looking at you shields
+	//
 
 	if (target->flags2 & MF2_NIGHTSPULL)
 		P_SetTarget(&target->tracer, NULL);
@@ -2894,6 +3006,13 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
 			return false;
 	}
 
+	// SRB2kart 011617 - Special Case for Pokey so it doesn't die.
+	if (target->type == MT_POKEY)
+	{
+		target->threshold = 1;
+		return false;
+	}
+
 	// Special case for Crawla Commander
 	if (target->type == MT_CRAWLACOMMANDER)
 	{
diff --git a/src/p_local.h b/src/p_local.h
index c8930aeda..707b861ce 100644
--- a/src/p_local.h
+++ b/src/p_local.h
@@ -387,6 +387,10 @@ void P_CheckPointLimit(void);
 void P_CheckSurvivors(void);
 boolean P_CheckRacers(void);
 
+// SRB2kart
+INT32  P_CheckPlayerAhead(player_t *player, INT32 tocheck);
+//
+
 void P_ClearStarPost(INT32 postnum);
 void P_ResetStarposts(void);
 
diff --git a/src/p_map.c b/src/p_map.c
index 79ae5ddf7..b9ff15974 100644
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -24,6 +24,7 @@
 #include "r_sky.h"
 #include "s_sound.h"
 #include "w_wad.h"
+#include "k_kart.h" // SRB2kart 011617
 
 #include "r_splats.h"
 
@@ -553,6 +554,537 @@ static boolean PIT_CheckThing(mobj_t *thing)
 		}
 	}
 
+	// SRB2kart 011617 - Colission code for kart items //{
+	
+	if (tmthing->type == MT_GREENITEM || tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || 
+		tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD || 
+		tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3 || 
+		tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
+			return true;
+
+		if (tmthing->health <= 0 || thing->health <= 0)
+			return true;
+
+		if (((tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3
+			|| tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3)
+			&& (thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3))
+			&& (tmthing->target == thing->target)) // Don't hit each other if you have the same target
+			return true;
+
+		if (thing->type == MT_PLAYER)
+		{
+			// Player Damage
+			P_DamageMobj(thing, tmthing, tmthing->target, 1);
+
+
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
+			|| thing->type == MT_GREENSHIELD || thing->type == MT_REDSHIELD
+			|| thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3
+			|| thing->type == MT_BANANAITEM || thing->type == MT_BANANASHIELD
+			|| thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3
+			)
+		{
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+			
+
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD)
+		{
+			if (tmthing->type == MT_GREENSHIELD || tmthing->type == MT_REDSHIELD
+				|| tmthing->type == MT_TRIPLEGREENSHIELD1 || tmthing->type == MT_TRIPLEGREENSHIELD2 || tmthing->type == MT_TRIPLEGREENSHIELD3
+				|| tmthing->type == MT_TRIPLEREDSHIELD1 || tmthing->type == MT_TRIPLEREDSHIELD2 || tmthing->type == MT_TRIPLEREDSHIELD3)
+			{
+				// This Item Damage
+				if (tmthing->eflags & MFE_VERTICALFLIP)
+					tmthing->z -= tmthing->height;
+				else
+					tmthing->z += tmthing->height;
+
+				S_StartSound(tmthing, tmthing->info->deathsound);
+				P_KillMobj(tmthing, thing, thing);
+
+				P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+				P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+			}
+			
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM)
+		{
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+
+
+			// Bomb death
+			P_KillMobj(thing, tmthing, tmthing);
+		}
+		else if (thing->flags & MF_SPRING && (tmthing->type == MT_REDITEM || tmthing->type == MT_REDITEMDUD || tmthing->type == MT_GREENITEM))
+			P_DoSpring(thing, tmthing);
+
+		return true;
+	}
+	else if (tmthing->flags & MF_SPRING && (thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD || thing->type == MT_GREENITEM))
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (thing->health <= 0)
+			return true;
+
+		P_DoSpring(tmthing, thing);
+
+		return true;
+	}
+	else if (tmthing->type == MT_SINK)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
+			return true;
+
+		if (thing->type == MT_PLAYER)
+		{
+			S_StartSound(NULL, sfx_cgot); //let all players hear it.
+			HU_SetCEchoFlags(0);
+			HU_SetCEchoDuration(5);
+			HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[thing->player-players]));
+			I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[thing->player-players]);
+			P_DamageMobj(thing, tmthing, tmthing->target, 10000);
+			P_KillMobj(tmthing, thing, thing);
+		}
+
+		return true;
+	}
+	else if (tmthing->type == MT_BOMBEXPLOSION)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (!(thing->type == MT_PLAYER))
+			return true;
+
+		if (thing->type == MT_PLAYER)
+		{
+			K_SpinPlayer(thing->player, tmthing->target);
+		}
+
+		return true; // This doesn't collide with anything, but we want it to effect the player anyway.
+	}
+	else if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_BANANAITEM 
+		|| tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
+			return true;
+
+		if (tmthing->health <= 0 || thing->health <= 0)
+			return true;
+
+		if (((tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3)
+			&& (thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3))
+			&& (tmthing->target == thing->target)) // Don't hit each other if you have the same target
+			return true;
+
+		if (thing->type == MT_PLAYER)
+		{
+			// Player Damage
+			K_SpinPlayer(thing->player, tmthing->target);
+
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM
+			|| thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3
+			|| thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
+			|| thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3)
+		{
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+			
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD)
+		{
+			if (tmthing->type == MT_BANANASHIELD || tmthing->type == MT_TRIPLEBANANASHIELD1 || tmthing->type == MT_TRIPLEBANANASHIELD2 || tmthing->type == MT_TRIPLEBANANASHIELD3)
+			{
+				// This Item Damage
+				if (tmthing->eflags & MFE_VERTICALFLIP)
+					tmthing->z -= tmthing->height;
+				else
+					tmthing->z += tmthing->height;
+
+				S_StartSound(tmthing, tmthing->info->deathsound);
+				P_KillMobj(tmthing, thing, thing);
+
+				P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+				P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+			}
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+
+		return true;
+	}
+	else if (tmthing->type == MT_FAKESHIELD || tmthing->type == MT_FAKEITEM)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
+			return true;
+
+		if (tmthing->health <= 0 || thing->health <= 0)
+			return true;
+
+		if (thing->type == MT_GREENITEM // When these items collide with the fake item, just the fake item is destroyed
+			|| thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD 
+			|| thing->type == MT_BOMBITEM
+			|| thing->type == MT_BANANAITEM)
+		{
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3 // When these items collide with the fake item, both of them are destroyed
+			|| thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3
+			|| thing->type == MT_BOMBSHIELD 
+			|| thing->type == MT_BANANASHIELD || thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3
+			|| thing->type == MT_FAKEITEM || thing->type == MT_FAKESHIELD)
+		{
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+			
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_PLAYER)
+		{
+			// Player Damage
+			P_DamageMobj(thing, tmthing, tmthing->target, 1);
+
+			// This Item Damage
+			if (tmthing->eflags & MFE_VERTICALFLIP)
+				tmthing->z -= tmthing->height;
+			else
+				tmthing->z += tmthing->height;
+
+			S_StartSound(tmthing, tmthing->info->deathsound);
+			P_KillMobj(tmthing, thing, thing);
+
+			P_SetObjectMomZ(tmthing, 8*FRACUNIT, false);
+			P_InstaThrust(tmthing, R_PointToAngle2(thing->x, thing->y, tmthing->x, tmthing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+
+		return true;
+	}
+	else if (tmthing->type == MT_BOMBSHIELD || tmthing->type == MT_BOMBITEM)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (((tmthing->target == thing) || (tmthing->target == thing->target)) && (tmthing->threshold > 0 || (thing->type != MT_PLAYER && thing->threshold > 0)))
+			return true;
+
+		if (tmthing->health <= 0 || thing->health <= 0)
+			return true;
+
+		if (thing->type == MT_PLAYER) 
+		{
+			P_KillMobj(tmthing, thing, thing);
+		}
+		else if (thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
+			|| thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3)
+		{
+			P_KillMobj(tmthing, thing, thing);
+
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+
+		return true;
+	}
+	else if (tmthing->type == MT_PLAYER && 
+			(thing->type == MT_GREENSHIELD || thing->type == MT_GREENITEM
+			|| thing->type == MT_REDSHIELD || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
+			|| thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3
+			|| thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM
+			|| thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM
+			|| thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3 
+			|| thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM
+			|| thing->type == MT_BOMBEXPLOSION
+			|| thing->type == MT_SINK
+			))
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (thing->type == MT_GREENSHIELD || thing->type == MT_TRIPLEGREENSHIELD1 || thing->type == MT_TRIPLEGREENSHIELD2 || thing->type == MT_TRIPLEGREENSHIELD3
+			|| thing->type == MT_REDSHIELD || thing->type == MT_TRIPLEREDSHIELD1 || thing->type == MT_TRIPLEREDSHIELD2 || thing->type == MT_TRIPLEREDSHIELD3
+			|| thing->type == MT_GREENITEM || thing->type == MT_REDITEM || thing->type == MT_REDITEMDUD
+			|| thing->type == MT_FAKESHIELD || thing->type == MT_FAKEITEM)
+		{
+			if ((thing->target == tmthing) && (thing->threshold > 0))
+				return true;
+
+			if (tmthing->health <= 0 || thing->health <= 0)
+				return true;
+
+			// Player Damage
+			P_DamageMobj(tmthing, thing, thing->target, 1);
+
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_BANANASHIELD || thing->type == MT_BANANAITEM
+			|| thing->type == MT_TRIPLEBANANASHIELD1 || thing->type == MT_TRIPLEBANANASHIELD2 || thing->type == MT_TRIPLEBANANASHIELD3)
+		{
+			if ((thing->target == tmthing) && (thing->threshold > 0))
+				return true;
+
+			if (tmthing->health <= 0 || thing->health <= 0)
+				return true;
+
+			// Player Damage
+			K_SpinPlayer(tmthing->player, thing->target);
+
+			// Other Item Damage
+			if (thing->eflags & MFE_VERTICALFLIP)
+				thing->z -= thing->height;
+			else
+				thing->z += thing->height;
+
+			S_StartSound(thing, thing->info->deathsound);
+			P_KillMobj(thing, tmthing, tmthing);
+
+			P_SetObjectMomZ(thing, 8*FRACUNIT, false);
+			P_InstaThrust(thing, R_PointToAngle2(tmthing->x, tmthing->y, thing->x, thing->y)+ANGLE_90, 16*FRACUNIT);
+		}
+		else if (thing->type == MT_BOMBSHIELD || thing->type == MT_BOMBITEM)
+		{
+			if ((thing->target == tmthing) && (thing->threshold > 0))
+				return true;
+
+			if (tmthing->health <= 0 || thing->health <= 0)
+				return true;
+
+			P_KillMobj(thing, tmthing, tmthing);
+		}
+		else if (thing->type == MT_BOMBEXPLOSION)
+		{
+			// Player Damage
+			K_SpinPlayer(tmthing->player, thing->target);
+
+			return true;
+		}
+		else if (thing->type == MT_SINK)
+		{
+			if ((thing->target == tmthing) && (thing->threshold > 0))
+				return true;
+
+			S_StartSound(NULL, sfx_cgot); //let all players hear it.
+			HU_SetCEchoFlags(0);
+			HU_SetCEchoDuration(5);
+			HU_DoCEcho(va("%s\\was hit by a kitchen sink.\\\\\\\\", player_names[tmthing->player-players]));
+			I_OutputMsg("%s was hit by a kitchen sink.\n", player_names[tmthing->player-players]);
+			P_DamageMobj(tmthing, thing, thing->target, 10000);
+			P_KillMobj(thing, tmthing, tmthing);
+		}
+
+		return true;
+	}
+
+
+	if (thing->type == MT_POKEY)
+	{
+		// see if it went over / under
+		if (tmthing->z > thing->z + thing->height)
+			return true; // overhead
+		if (tmthing->z + tmthing->height < thing->z)
+			return true; // underneath
+
+		if (tmthing->type == MT_ENEMYFLIP)
+		{
+			if (tmthing->angle)
+				P_SetMobjState(thing, S_POKEY5);
+			else
+				P_SetMobjState(thing, S_POKEY1);
+		}
+		if (tmthing->type == MT_PLAYER && !thing->threshold)
+			P_DamageMobj(tmthing, thing, thing->target, 1);
+	}
+	
+	//}
+
 	if ((thing->type == MT_SPRINGSHELL || thing->type == MT_YELLOWSHELL) && thing->health > 0
 	 && (tmthing->player || (tmthing->flags & MF_PUSHABLE)) && tmthing->health > 0)
 	{
diff --git a/src/p_saveg.c b/src/p_saveg.c
index aee50e615..0454232e3 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -268,6 +268,10 @@ static void P_NetArchivePlayers(void)
 		WRITEFIXED(save_p, players[i].actionspd);
 		WRITEFIXED(save_p, players[i].mindash);
 		WRITEFIXED(save_p, players[i].maxdash);
+		// SRB2kart
+		WRITEUINT8(save_p, players[i].kartspeed);
+		WRITEUINT8(save_p, players[i].kartweight);
+		//
 		WRITEFIXED(save_p, players[i].normalspeed);
 		WRITEFIXED(save_p, players[i].runspeed);
 		WRITEUINT8(save_p, players[i].thrustfactor);
@@ -434,6 +438,10 @@ static void P_NetUnArchivePlayers(void)
 		players[i].actionspd = READFIXED(save_p);
 		players[i].mindash = READFIXED(save_p);
 		players[i].maxdash = READFIXED(save_p);
+		// SRB2kart
+		players[i].kartspeed = READUINT8(save_p);
+		players[i].kartweight = READUINT8(save_p);
+		//
 		players[i].normalspeed = READFIXED(save_p);
 		players[i].runspeed = READFIXED(save_p);
 		players[i].thrustfactor = READUINT8(save_p);
diff --git a/src/p_setup.c b/src/p_setup.c
index b36bf0b80..bf2292710 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -2481,9 +2481,13 @@ boolean P_SetupLevel(boolean skipprecip)
 	S_StopSounds();
 	S_ClearSfx();
 
-	// As oddly named as this is, this handles music only.
-	// We should be fine starting it here.
-	S_Start();
+	// SRB2kart 010217
+	if (leveltime < 157)
+		S_StopMusic();
+	if (leveltime > 157)
+		// As oddly named as this is, this handles music only.
+		// We should be fine starting it here.
+		S_Start();
 
 	// Let's fade to black here
 	// But only if we didn't do the special stage wipe
diff --git a/src/p_spec.c b/src/p_spec.c
index 18378b843..2ec4d7b2e 100644
--- a/src/p_spec.c
+++ b/src/p_spec.c
@@ -35,6 +35,8 @@
 #include "m_cond.h" //unlock triggers
 #include "lua_hook.h" // LUAh_LinedefExecute
 
+#include "k_kart.h" // SRB2kart
+
 #ifdef HW3SOUND
 #include "hardware/hw3sound.h"
 #endif
@@ -50,6 +52,9 @@ mobj_t *skyboxmo[2];
 
 // Amount (dx, dy) vector linedef is shifted right to get scroll amount
 #define SCROLL_SHIFT 5
+ 
+// This must be updated whenever we up the max flat size - quicker to assume rather than figuring out the sqrt of the specific flat's filesize.
+#define MAXFLATSIZE (2048<<FRACBITS)
 
 /** Animated texture descriptor
   * This keeps track of an animated texture or an animated flat.
@@ -3845,14 +3850,25 @@ DoneSection2:
 			//	P_SetPlayerMobjState(player->mo, S_PLAY_FALL1);
 			break;
 
-		case 6: // Super Sonic transformer
-			if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds))
+
+		case 6: // Super Sonic transformer // SRB2kart 190117- Replaced. This is now a Mushroom Boost Panel
+			if (!player->kartstuff[k_floorboost])
+				player->kartstuff[k_floorboost] = 3;
+			else
+				player->kartstuff[k_floorboost] = 2;
+			K_DoMushroom(player, false);
+			break;
+
+			/* if (player->mo->health > 0 && !player->bot && (player->charflags & SF_SUPER) && !player->powers[pw_super] && ALL7EMERALDS(emeralds))
 				P_DoSuperTransformation(player, true);
+			break; */
+
+		case 7: // Make player spin // SRB2kart 190117- Replaced. This is now an Oil Slick (Oddly ironic considering)
+			player->kartstuff[k_spinouttype] = -1;
+			K_SpinPlayer(player, NULL);
 			break;
 
-		case 7: // Make player spin
-			/* // SRB2kart - no.
-			if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH))
+			/* if (!(player->pflags & PF_SPINNING) && P_IsObjectOnGround(player->mo) && (player->charability2 == CA2_SPINDASH))
 			{
 				player->pflags |= PF_SPINNING;
 				P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
@@ -3861,8 +3877,8 @@ DoneSection2:
 				if (abs(player->rmomx) < FixedMul(5*FRACUNIT, player->mo->scale)
 				&& abs(player->rmomy) < FixedMul(5*FRACUNIT, player->mo->scale))
 					P_InstaThrust(player->mo, player->mo->angle, FixedMul(10*FRACUNIT, player->mo->scale));
-			}*/
-			break;
+			}
+			break; */
 
 		case 8: // Zoom Tube Start
 			{
@@ -3924,11 +3940,15 @@ DoneSection2:
 
 				P_SetTarget(&player->mo->tracer, waypoint);
 				player->speed = speed;
+				player->pflags &= ~PF_SPINNING; // SRB2kart 200117
 				player->pflags |= PF_SPINNING;
 				player->pflags &= ~PF_JUMPED;
 				player->pflags &= ~PF_GLIDING;
 				player->climbing = 0;
 
+				if (!(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2]))
+					P_SetPlayerMobjState(player->mo, S_KART_RUN1);
+
 				//if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) // SRB2kart
 				//{
 				//	P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
@@ -3998,9 +4018,13 @@ DoneSection2:
 
 				P_SetTarget(&player->mo->tracer, waypoint);
 				player->speed = speed;
+				player->pflags &= ~PF_SPINNING; // SRB2kart 200117
 				player->pflags |= PF_SPINNING;
 				player->pflags &= ~PF_JUMPED;
 
+				if (!(player->mo->state >= &states[S_KART_RUN1] && player->mo->state <= &states[S_KART_RUN2]))
+					P_SetPlayerMobjState(player->mo, S_KART_RUN1);
+
 				//if (!(player->mo->state >= &states[S_PLAY_ATK1] && player->mo->state <= &states[S_PLAY_ATK4])) // SRB2kart
 				//{
 				//	P_SetPlayerMobjState(player->mo, S_PLAY_ATK1);
@@ -4010,6 +4034,10 @@ DoneSection2:
 			break;
 
 		case 10: // Finish Line
+			// SRB2kart - 150117
+			if (gametype == GT_RACE && (player->starpostnum == numstarposts || player->exiting))
+				player->kartstuff[k_starpostwp] = player->kartstuff[k_waypoint] = 0;
+			//
 			if (gametype == GT_RACE && !player->exiting)
 			{
 				if (player->starpostnum == numstarposts) // Must have touched all the starposts
@@ -4021,16 +4049,47 @@ DoneSection2:
 
 					if (player->laps >= (UINT8)cv_numlaps.value)
 						CONS_Printf(M_GetText("%s has finished the race.\n"), player_names[player-players]);
+					else if (player->laps == (UINT8)(cv_numlaps.value - 1))
+						CONS_Printf("%s started the final lap\n", player_names[player-players]);
 					else
 						CONS_Printf(M_GetText("%s started lap %u\n"), player_names[player-players], (UINT32)player->laps+1);
 
 					// Reset starposts (checkpoints) info
-					player->starpostangle = player->starposttime = player->starpostnum = 0;
+					// SRB2kart 200117
+					player->starpostangle = player->starpostnum = 0;
 					player->starpostx = player->starposty = player->starpostz = 0;
+					//except the time!
+					player->starposttime = player->realtime;
+					if (((numstarposts+1)*player->laps - 1) < 256) //SIGSEGV prevention
+						player->checkpointtimes[(numstarposts+1)*player->laps - 1] = player->realtime;
+					player->kartstuff[k_playerahead] = P_CheckPlayerAhead(player, (numstarposts+1)*player->laps - 1);
+
+					if (P_IsLocalPlayer(player))
+					{
+						if (player->laps < (UINT8)(cv_numlaps.value - 1))
+						{
+							S_StartSound(NULL, sfx_mlap);
+							player->kartstuff[k_lakitu] = -64;
+						}
+						else if (player->laps == (UINT8)(cv_numlaps.value - 1))
+						{
+							player->kartstuff[k_lakitu] = -64;
+
+							if (!splitscreen || (splitscreen && !players[consoleplayer].exiting
+							&& !players[secondarydisplayplayer].exiting))
+							{
+								//player->powers[pw_sounds] = 1;
+								S_ChangeMusicInternal("finlap", false);
+							}
+						}
+					}
+					//
+					//player->starpostangle = player->starposttime = player->starpostnum = 0;
+					//player->starpostx = player->starposty = player->starpostz = 0;
 					P_ResetStarposts();
 
 					// Play the starpost sound for 'consistency'
-					S_StartSound(player->mo, sfx_strpst);
+					// S_StartSound(player->mo, sfx_strpst);
 				}
 				else if (player->starpostnum)
 				{
@@ -4044,9 +4103,22 @@ DoneSection2:
 				{
 					if (P_IsLocalPlayer(player))
 					{
-						HU_SetCEchoFlags(0);
-						HU_SetCEchoDuration(5);
-						HU_DoCEcho("FINISHED!");
+						// SRB2kart 200117
+						if (!splitscreen)
+						{
+							if (player->kartstuff[k_position] == 1)
+								S_ChangeMusicInternal("karwin", true);
+							else if (player->kartstuff[k_position] == 2 || player->kartstuff[k_position] == 3)
+								S_ChangeMusicInternal("karok", true);
+							else if (player->kartstuff[k_position] >= 4)
+								S_ChangeMusicInternal("karlos", true);
+						}
+						else
+							S_ChangeMusicInternal("karwin", true);
+						//
+						//HU_SetCEchoFlags(0);
+						//HU_SetCEchoDuration(5);
+						//HU_DoCEcho("FINISHED!");
 					}
 
 					P_DoPlayerExit(player);
@@ -5485,37 +5557,31 @@ void P_SpawnSpecials(INT32 fromnetsave)
 			secthinkers[secnum].thinkers[secthinkers[secnum].count++] = th;
 	}
 
-
 	// Init line EFFECTs
 	for (i = 0; i < numlines; i++)
 	{
-		// set line specials to 0 here too, same reason as above
-		if (netgame || multiplayer)
-		{
-			// future: nonet flag?
-		}
-		else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
+		if (lines[i].special != 7) // This is a hack. I can at least hope nobody wants to prevent flat alignment with arbitrary skin setups...
 		{
-			lines[i].special = 0;
-			continue;
-		}
-		else
-		{
-			if (players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
+			// set line specials to 0 here too, same reason as above
+			if (netgame || multiplayer)
 			{
-				lines[i].special = 0;
-				continue;
+				// future: nonet flag?
 			}
-			if (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
+			else if ((lines[i].flags & ML_NETONLY) == ML_NETONLY)
 			{
 				lines[i].special = 0;
 				continue;
 			}
-			if (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX))
+			/*else -- commented out because irrelevant to kart
 			{
-				lines[i].special = 0;
-				continue;
-			}
+				if ((players[consoleplayer].charability == CA_THOK && (lines[i].flags & ML_NOSONIC))
+				|| (players[consoleplayer].charability == CA_FLY && (lines[i].flags & ML_NOTAILS))
+				|| (players[consoleplayer].charability == CA_GLIDEANDCLIMB && (lines[i].flags & ML_NOKNUX)))
+				{
+					lines[i].special = 0;
+					continue;
+				}
+			}*/
 		}
 
 		switch (lines[i].special)
@@ -5559,50 +5625,55 @@ void P_SpawnSpecials(INT32 fromnetsave)
 				I_Error("Failed to catch a disable linedef");
 				break;
 #endif
-
-			case 7: // Flat alignment
-				if (lines[i].flags & ML_EFFECT4) // Align angle
+			case 7: // Flat alignment - redone by toast
+				if ((lines[i].flags & (ML_NOSONIC|ML_NOTAILS)) != (ML_NOSONIC|ML_NOTAILS)) // If you can do something...
 				{
-					if (!(lines[i].flags & ML_EFFECT5)) // Align floor unless ALLTRIGGER flag is set
+					angle_t flatangle = InvAngle(R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y));
+					fixed_t xoffs;
+					fixed_t yoffs;
+ 
+					if (lines[i].flags & ML_NOKNUX) // Set offset through x and y texture offsets if NOKNUX flag is set
 					{
-						for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
-							sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
+						xoffs = sides[lines[i].sidenum[0]].textureoffset;
+						yoffs = sides[lines[i].sidenum[0]].rowoffset;
 					}
-
-					if (!(lines[i].flags & ML_BOUNCY)) // Align ceiling unless BOUNCY flag is set
+					else // Otherwise, set calculated offsets such that line's v1 is the apparent origin
 					{
-						for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
-							sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = R_PointToAngle2(lines[i].v1->x, lines[i].v1->y, lines[i].v2->x, lines[i].v2->y);
+						fixed_t cosinecomponent = FINECOSINE(flatangle>>ANGLETOFINESHIFT);
+						fixed_t sinecomponent = FINESINE(flatangle>>ANGLETOFINESHIFT);
+						xoffs = (-FixedMul(lines[i].v1->x, cosinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, sinecomponent) % MAXFLATSIZE); // No danger of overflow thanks to the strategically placed modulo operations.
+						yoffs = (FixedMul(lines[i].v1->x, sinecomponent) % MAXFLATSIZE) + (FixedMul(lines[i].v1->y, cosinecomponent) % MAXFLATSIZE); // Ditto.
 					}
-				}
-				else // Do offsets
-				{
-					if (!(lines[i].flags & ML_BLOCKMONSTERS)) // Align floor unless BLOCKMONSTERS flag is set
+ 
+					for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
 					{
-						for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
+						if (!(lines[i].flags & ML_NOSONIC)) // Modify floor flat alignment unless NOSONIC flag is set
 						{
-							sectors[s].floor_xoffs += lines[i].dx;
-							sectors[s].floor_yoffs += lines[i].dy;
+							sectors[s].spawn_flrpic_angle = sectors[s].floorpic_angle = flatangle;
+							sectors[s].floor_xoffs += xoffs;
+							sectors[s].floor_yoffs += yoffs;
 							// saved for netgames
 							sectors[s].spawn_flr_xoffs = sectors[s].floor_xoffs;
 							sectors[s].spawn_flr_yoffs = sectors[s].floor_yoffs;
 						}
-					}
-
-					if (!(lines[i].flags & ML_NOCLIMB)) // Align ceiling unless NOCLIMB flag is set
-					{
-						for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
+ 
+						if (!(lines[i].flags & ML_NOTAILS)) // Modify ceiling flat alignment unless NOTAILS flag is set
 						{
-							sectors[s].ceiling_xoffs += lines[i].dx;
-							sectors[s].ceiling_yoffs += lines[i].dy;
+							sectors[s].spawn_ceilpic_angle = sectors[s].ceilingpic_angle = flatangle;
+							sectors[s].ceiling_xoffs += xoffs;
+							sectors[s].ceiling_yoffs += yoffs;
 							// saved for netgames
 							sectors[s].spawn_ceil_xoffs = sectors[s].ceiling_xoffs;
 							sectors[s].spawn_ceil_yoffs = sectors[s].ceiling_yoffs;
 						}
 					}
 				}
+				else // Otherwise, print a helpful warning. Can I do no less?
+					CONS_Alert(CONS_WARNING,
+					M_GetText("Flat alignment linedef (tag %d) doesn't have anything to do.\nConsider changing the linedef's flag configuration or removing it entirely.\n"),
+					lines[i].tag);
 				break;
-
+ 
 			case 8: // Sector Parameters
 				for (s = -1; (s = P_FindSectorFromLineTag(lines + i, s)) >= 0 ;)
 				{
@@ -6976,7 +7047,9 @@ void T_Friction(friction_t *f)
 		// apparently, all I had to do was comment out part of the next line and
 		// friction works for all mobj's
 		// (or at least MF_PUSHABLEs, which is all I care about anyway)
-		if (!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz)
+		if ((!(thing->flags & (MF_NOGRAVITY | MF_NOCLIP)) && thing->z == thing->floorz) && (thing->player 
+			&& (thing->player->kartstuff[k_startimer] && thing->player->kartstuff[k_bootaketimer] 
+			&& thing->player->kartstuff[k_mushroomtimer] && thing->player->kartstuff[k_growshrinktimer] <= 0)))
 		{
 			if (f->roverfriction)
 			{
diff --git a/src/p_user.c b/src/p_user.c
index 06f7ca804..59d529a21 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -4571,9 +4571,9 @@ static void P_3dMovement(player_t *player)
 	}
 	else
 	{
-		if (player->kartstuff[k_drift] == 1)
+		if (player->kartstuff[k_drift] >= 1)
 			movepushangle = player->mo->angle+ANGLE_45;
-		else if (player->kartstuff[k_drift] == -1)
+		else if (player->kartstuff[k_drift] <= -1)
 			movepushangle = player->mo->angle-ANGLE_45;
 		else
 			movepushangle = player->mo->angle;
@@ -4715,7 +4715,11 @@ static void P_3dMovement(player_t *player)
 		&& cmd->forwardmove != 0 && !(player->pflags & PF_GLIDING || player->exiting
 		|| (P_PlayerInPain(player) && !onground)))
 	{
-		movepushforward = cmd->forwardmove * (thrustfactor * acceleration);
+		//movepushforward = cmd->forwardmove * (thrustfactor * acceleration);
+		if (cmd->forwardmove > 0)
+			movepushforward = K_3dKartMovement(player, onground);
+		else
+			movepushforward = -(K_3dKartMovement(player, onground));
 
 		// allow very small movement while in air for gameplay
 		if (!onground)
@@ -4764,7 +4768,11 @@ static void P_3dMovement(player_t *player)
 			// (Why was it so complicated before? ~Red)
 			controldirection = R_PointToAngle2(0, 0, cmd->forwardmove*FRACUNIT, -cmd->sidemove*FRACUNIT)+movepushangle;
 
-			movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
+			//movepushforward = max(abs(cmd->sidemove), abs(cmd->forwardmove)) * (thrustfactor * acceleration);
+			if (max(abs(cmd->sidemove), abs(cmd->forwardmove)) > 0)
+				movepushforward = K_3dKartMovement(player, onground);
+			else
+				movepushforward = -(K_3dKartMovement(player, onground));
 
 			// allow very small movement while in air for gameplay
 			if (!onground)
@@ -4800,7 +4808,11 @@ static void P_3dMovement(player_t *player)
 	}
 	else if (cmd->sidemove && !(player->pflags & PF_GLIDING) && !player->exiting && !P_PlayerInPain(player))
 	{
-		movepushside = cmd->sidemove * (thrustfactor * acceleration);
+		//movepushside = cmd->sidemove * (thrustfactor * acceleration);
+		if (cmd->sidemove > 0)
+			movepushside = K_3dKartMovement(player, onground);
+		else
+			movepushside = -(K_3dKartMovement(player, onground));
 
 		if (!onground)
 		{
@@ -6664,10 +6676,12 @@ static void P_MovePlayer(player_t *player)
 		// Drifting sound
 		{
 			// Start looping the sound now.
-			if (leveltime % 50 == 0 && ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && onground))
+			if (leveltime % 50 == 0 && onground
+			&& ((player->kartstuff[k_drift] >= 1 && player->kartstuff[k_drift] <= 3)
+			|| (player->kartstuff[k_drift] <= -1 && player->kartstuff[k_drift] >= -3)))
 				S_StartSound(player->mo, sfx_mkdrft);
 			// Leveltime being 50 might take a while at times. We'll start it up once, isntantly.
-			else if ((player->kartstuff[k_drift] == 1 || player->kartstuff[k_drift] == -1) && !S_SoundPlaying(player->mo, sfx_mkdrft) && onground)
+			else if ((player->kartstuff[k_drift] >= 1 || player->kartstuff[k_drift] <= -1) && !S_SoundPlaying(player->mo, sfx_mkdrft) && onground)
 				S_StartSound(player->mo, sfx_mkdrft);
 			// Ok, we'll stop now.
 			else if ((player->kartstuff[k_drift] == 0)
@@ -7906,11 +7920,13 @@ static void P_DeathThink(player_t *player)
 				countdown2 = 1*TICRATE;
 				skipstats = true;
 
+				/* // SRB2kart 010217 - Score doesn't need to be reset in Kart.
 				for (i = 0; i < MAXPLAYERS; i++)
 				{
 					if (playeringame[i])
 						players[i].score = 0;
 				}
+				*/
 
 				//emeralds = 0;
 				tokenbits = 0;
@@ -9037,7 +9053,7 @@ void P_PlayerThink(player_t *player)
 	// Make sure spectators always have a score and ring count of 0.
 	if (player->spectator)
 	{
-		player->score = 0;
+		//player->score = 0;
 		player->mo->health = 1;
 		player->health = 1;
 	}
@@ -9052,12 +9068,17 @@ void P_PlayerThink(player_t *player)
 	if (player == &players[displayplayer])
 		playerdeadview = false;
 
+	// SRB2kart 010217
+	if (gametype == GT_RACE && leveltime < 4*TICRATE)
+		player->powers[pw_nocontrol] = 2;
+	/*
 	if ((gametype == GT_RACE || gametype == GT_COMPETITION) && leveltime < 4*TICRATE)
 	{
-		cmd->buttons &= BT_BRAKE; // Remove all buttons except BT_BRAKE // TODO: ?
+		cmd->buttons &= BT_BRAKE; // Remove all buttons except BT_BRAKE
 		cmd->forwardmove = 0;
 		cmd->sidemove = 0;
 	}
+	*/
 
 	// Synchronizes the "real" amount of time spent in the level.
 	if (!player->exiting)
diff --git a/src/r_main.c b/src/r_main.c
index 97d6876e1..1655a5667 100644
--- a/src/r_main.c
+++ b/src/r_main.c
@@ -139,7 +139,7 @@ static void FlipCam2_OnChange(void);
 void SendWeaponPref(void);
 void SendWeaponPref2(void);
 
-consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
+consvar_t cv_tailspickup = {"tailspickup", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_chasecam = {"chasecam", "On", CV_CALL, CV_OnOff, ChaseCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_chasecam2 = {"chasecam2", "On", CV_CALL, CV_OnOff, ChaseCam2_OnChange, 0, NULL, NULL, 0, 0, NULL};
 consvar_t cv_flipcam = {"flipcam", "No", CV_SAVE|CV_CALL|CV_NOINIT, CV_YesNo, FlipCam_OnChange, 0, NULL, NULL, 0, 0, NULL};
diff --git a/src/r_things.c b/src/r_things.c
index 44883f2ce..331ff7261 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2279,6 +2279,11 @@ static void Sk_SetDefaultValue(skin_t *skin)
 	skin->starttranscolor = 160;
 	skin->prefcolor = SKINCOLOR_GREEN;
 
+	// SRB2kart
+	skin->kartspeed = 7;
+	skin->kartweight = 5;
+	//
+
 	skin->normalspeed = 36<<FRACBITS;
 	skin->runspeed = 28<<FRACBITS;
 	skin->thrustfactor = 5;
@@ -2422,6 +2427,11 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
 		player->mindash = skin->mindash;
 		player->maxdash = skin->maxdash;
 
+		// SRB2kart
+		player->kartspeed = skin->kartspeed;
+		player->kartweight = skin->kartweight;
+		//
+
 		player->normalspeed = skin->normalspeed;
 		player->runspeed = skin->runspeed;
 		player->thrustfactor = skin->thrustfactor;
@@ -2644,6 +2654,10 @@ void R_AddSkins(UINT16 wadnum)
 #undef GETSPEED
 
 #define GETINT(field) else if (!stricmp(stoken, #field)) skin->field = atoi(value);
+			// SRB2kart
+			GETINT(kartspeed)
+			GETINT(kartweight)
+			//
 			GETINT(thrustfactor)
 			GETINT(accelstart)
 			GETINT(acceleration)
diff --git a/src/r_things.h b/src/r_things.h
index 483db7e99..e634b5274 100644
--- a/src/r_things.h
+++ b/src/r_things.h
@@ -86,6 +86,11 @@ typedef struct
 	fixed_t mindash;
 	fixed_t maxdash;
 
+	// SRB2kart
+	UINT8 kartspeed; // Normal ground
+	UINT8 kartweight; // Normal ground
+	//
+
 	fixed_t normalspeed; // Normal ground
 	fixed_t runspeed; // Speed that you break into your run animation
 
diff --git a/src/s_sound.c b/src/s_sound.c
index 5a6546495..e19f92654 100644
--- a/src/s_sound.c
+++ b/src/s_sound.c
@@ -1159,7 +1159,7 @@ void S_StartSoundName(void *mo, const char *soundname)
 /// ------------------------
 
 #ifdef MUSICSLOT_COMPATIBILITY
-const char *compat_special_music_slots[16] =
+const char *compat_special_music_slots[21] =
 {
 	"titles", // 1036  title screen
 	"read_m", // 1037  intro
@@ -1176,6 +1176,12 @@ const char *compat_special_music_slots[16] =
 	"credit", // 1048  credits
 	"racent", // 1049  Race Results
 	"stjr",   // 1050  Sonic Team Jr. Presents
+	// SRB2kart 040217
+	"finlap", // 1051  Sonic Team Jr. Presents
+	"karwin", // 1052  Sonic Team Jr. Presents
+	"karok",  // 1053  Sonic Team Jr. Presents
+	"karlos", // 1054  Sonic Team Jr. Presents
+	"mega",   // 1055  Sonic Team Jr. Presents
 	""
 };
 #endif
diff --git a/src/s_sound.h b/src/s_sound.h
index bcc7979a1..1f308447f 100644
--- a/src/s_sound.h
+++ b/src/s_sound.h
@@ -142,7 +142,7 @@ void S_StopSoundByNum(sfxenum_t sfxnum);
 #ifdef MUSICSLOT_COMPATIBILITY
 // For compatibility with code/scripts relying on older versions
 // This is a list of all the "special" slot names and their associated numbers
-const char *compat_special_music_slots[16];
+const char *compat_special_music_slots[21];
 #endif
 
 #endif
diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg
index f309f7db1..a064dc38e 100644
--- a/src/win32/Makefile.cfg
+++ b/src/win32/Makefile.cfg
@@ -57,9 +57,9 @@ endif
 
 	# name of the exefile
 ifdef SDL
-	EXENAME?=srb2win.exe
+	EXENAME?=srb2kart.exe
 else
-	EXENAME?=srb2dd.exe
+	EXENAME?=srb2kartdd.exe
 endif
 
 ifdef SDL
diff --git a/src/win32/Srb2win.ico b/src/win32/Srb2win.ico
index 700276fd4b9ac2810a6981eb054921f3708c702b..6e667b61c84414bc9758ea57721bb07d85a62083 100644
GIT binary patch
literal 82992
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

literal 372798
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
G1OE?SzcGja

diff --git a/src/y_inter.c b/src/y_inter.c
index e5ff97ede..74f6978f3 100644
--- a/src/y_inter.c
+++ b/src/y_inter.c
@@ -114,6 +114,9 @@ typedef union
 		patch_t *redflag; // int_ctf uses this struct too.
 		INT32 numplayers; // Number of players being displayed
 		char levelstring[40]; // holds levelnames up to 32 characters
+		// SRB2kart
+		int increase[MAXPLAYERS]; //how much did the score increase by?
+		int time[MAXPLAYERS]; //Tournament Time
 	} match;
 
 	struct
@@ -151,10 +154,12 @@ static INT32 endtic = -1;
 
 intertype_t intertype = int_none;
 
-static void Y_AwardCoopBonuses(void);
-static void Y_AwardSpecialStageBonus(void);
+//static void Y_AwardCoopBonuses(void);
+//static void Y_AwardSpecialStageBonus(void);
+static void Y_CalculateTournamentPoints(void); // SRB2kart
+
 static void Y_CalculateCompetitionWinners(void);
-static void Y_CalculateTimeRaceWinners(void);
+//static void Y_CalculateTimeRaceWinners(void);
 static void Y_CalculateMatchWinners(void);
 static void Y_FollowIntermission(void);
 static void Y_UnloadData(void);
@@ -199,34 +204,32 @@ void Y_IntermissionDrawer(void)
 	else
 		V_DrawPatchFill(bgtile);
 
-	if (intertype == int_coop)
+	// SRB2kart 290117 - compeltely replaced this block.
+	if (intertype == int_timeattack)
 	{
-		INT32 bonusy;
-
-		// draw score
-		V_DrawScaledPatch(hudinfo[HUD_SCORE].x, hudinfo[HUD_SCORE].y, V_SNAPTOLEFT, sboscore);
-		V_DrawTallNum(hudinfo[HUD_SCORENUM].x, hudinfo[HUD_SCORENUM].y, V_SNAPTOLEFT, data.coop.score);
-
 		// draw time
 		V_DrawScaledPatch(hudinfo[HUD_TIME].x, hudinfo[HUD_TIME].y, V_SNAPTOLEFT, sbotime);
-		if (cv_timetic.value == 1)
+		if (cv_timetic.value)
 			V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT, data.coop.tics);
 		else
 		{
-			// we should show centiseconds on the intermission screen too, if the conditions are right.
-			if (modeattacking || cv_timetic.value == 2)
-			{
-				V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT,
-					G_TicsToCentiseconds(data.coop.tics), 2);
-				V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod);
-			}
-
-			V_DrawPaddedTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, V_SNAPTOLEFT,
-				G_TicsToSeconds(data.coop.tics), 2);
-			V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, V_SNAPTOLEFT, sbocolon);
-			V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, V_SNAPTOLEFT,
-				G_TicsToMinutes(data.coop.tics, false));
+			if (G_TicsToSeconds(data.coop.tics) < 10)
+				V_DrawTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, 0, 0);
+			V_DrawTallNum(hudinfo[HUD_SECONDS].x, hudinfo[HUD_SECONDS].y, 0, G_TicsToSeconds(data.coop.tics));
+			V_DrawTallNum(hudinfo[HUD_MINUTES].x, hudinfo[HUD_MINUTES].y, 0, G_TicsToMinutes(data.coop.tics, false));
+			V_DrawScaledPatch(hudinfo[HUD_TIMECOLON].x, hudinfo[HUD_TIMECOLON].y, 0, sbocolon);
+			V_DrawTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, 0, (int)((data.coop.tics%TICRATE) * (100.00f/TICRATE)));
+			V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, 0, sbocolon);
 		}
+		
+		/* // SRB2kart - pulled from old coop block, just in case we need it
+		// we should show centiseconds on the intermission screen too, if the conditions are right.
+		if (modeattacking || cv_timetic.value == 2)
+		{
+			V_DrawPaddedTallNum(hudinfo[HUD_TICS].x, hudinfo[HUD_TICS].y, V_SNAPTOLEFT,
+				G_TicsToCentiseconds(data.coop.tics), 2);
+			V_DrawScaledPatch(hudinfo[HUD_TIMETICCOLON].x, hudinfo[HUD_TIMETICCOLON].y, V_SNAPTOLEFT, sboperiod);
+		}*/
 
 		// draw the "got through act" lines and act number
 		V_DrawLevelTitle(data.coop.passedx1, 49, 0, data.coop.passed1);
@@ -235,114 +238,141 @@ void Y_IntermissionDrawer(void)
 		if (mapheaderinfo[gamemap-1]->actnum)
 			V_DrawScaledPatch(244, 57, 0, data.coop.ttlnum);
 
-		bonusy = 150;
-		// Total
-		V_DrawScaledPatch(152, bonusy, 0, data.coop.ptotal);
-		V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.total);
-		bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1;
+		//if (gottimebonus && endtic != -1)
+		//	V_DrawCenteredString(BASEVIDWIDTH/2, 172, V_YELLOWMAP, "TIME BONUS UNLOCKED!");
+
+		V_DrawString(70, 106, V_YELLOWMAP, "LAP 1");
+		V_DrawString(70, 116, V_YELLOWMAP, "LAP 2");
+		V_DrawString(70, 126, V_YELLOWMAP, "LAP 3");
 
-		// Draw bonuses
-		for (i = 3; i >= 0; --i)
 		{
-			if (data.coop.bonuses[i].display)
-			{
-				V_DrawScaledPatch(152, bonusy, 0, data.coop.bonuspatches[i]);
-				V_DrawTallNum(BASEVIDWIDTH - 68, bonusy + 1, 0, data.coop.bonuses[i].points);
-			}
-			bonusy -= (3*SHORT(tallnum[0]->height)/2) + 1;
+			INT32 laptime;
+			laptime = stplyr->checkpointtimes[(numstarposts+1) - 1];
+			V_DrawRightAlignedString(250, 106, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE))));
+			laptime = stplyr->checkpointtimes[((numstarposts+1)*2) - 1] - stplyr->checkpointtimes[(numstarposts+1) - 1];
+			V_DrawRightAlignedString(250, 116, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE))));
+			laptime = stplyr->realtime - stplyr->checkpointtimes[((numstarposts+1)*2) - 1];
+			V_DrawRightAlignedString(250, 126, 0, va("%d:%02d.%02d", laptime/(60*TICRATE), laptime/TICRATE % 60, (int)((laptime%TICRATE) * (100.00f/TICRATE))));
 		}
 	}
-	else if (intertype == int_spec)
+	else if (intertype == int_race)
 	{
-		static tic_t animatetic = 0;
-		INT32 ttheight = 16;
-		INT32 xoffset1 = 0; // Line 1 x offset
-		INT32 xoffset2 = 0; // Line 2 x offset
-		INT32 xoffset3 = 0; // Line 3 x offset
-		UINT8 drawsection = 0;
+		INT32 i = 0, j = 0;
+		INT32 x = 4;
+		INT32 y = 48;
+		char name[MAXPLAYERNAME+1];
 
-		// draw the header
-		if (intertic <= TICRATE)
-			animatetic = 0;
-		else if (!animatetic && data.spec.bonus.points == 0 && data.spec.passed3[0] != '\0')
-			animatetic = intertic;
+		boolean completed[MAXPLAYERS];
+		memset(completed, 0, sizeof (completed));
 
-		if (animatetic)
-		{
-			INT32 animatetimer = (intertic - animatetic);
-			if (animatetimer <= 8)
-			{
-				xoffset1 = -(animatetimer     * 40);
-				xoffset2 = -((animatetimer-2) * 40);
-				if (xoffset2 > 0) xoffset2 = 0;
-			}
-			else if (animatetimer <= 19)
-			{
-				drawsection = 1;
-				xoffset1 = (16-animatetimer) * 40;
-				xoffset2 = (18-animatetimer) * 40;
-				xoffset3 = (20-animatetimer) * 40;
-				if (xoffset1 < 0) xoffset1 = 0;
-				if (xoffset2 < 0) xoffset2 = 0;
-			}
-			else
-				drawsection = 1;
-		}
+		// draw the level name
+		V_DrawCenteredString(BASEVIDWIDTH/2, 20, 0, data.match.levelstring);
+		V_DrawFill(4, 42, 312, 1, 0);
 
-		if (drawsection == 1)
+		if (data.match.numplayers > 8)
 		{
-			ttheight = 16;
-			V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
-			ttheight += V_LevelNameHeight(data.spec.passed3) + 2;
-			V_DrawLevelTitle(data.spec.passedx3 + xoffset2, ttheight, 0, data.spec.passed3);
-			ttheight += V_LevelNameHeight(data.spec.passed4) + 2;
-			V_DrawLevelTitle(data.spec.passedx4 + xoffset3, ttheight, 0, data.spec.passed4);
+			V_DrawFill(160, 32, 1, 152, 0);
+
+			V_DrawCenteredString(x+6+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "#");
+			V_DrawString(x+36+(BASEVIDWIDTH/2), 32, V_YELLOWMAP, "NAME");
+
+			V_DrawRightAlignedString(x+110, 32, V_YELLOWMAP, "TIME");
+
+			V_DrawRightAlignedString(x+152, 32, V_YELLOWMAP, "SCORE");
 		}
-		else if (data.spec.passed1[0] != '\0')
+
+		V_DrawCenteredString(x+6, 32, V_YELLOWMAP, "#");
+		V_DrawString(x+36, 32, V_YELLOWMAP, "NAME");
+
+		if (data.match.numplayers > 8)
 		{
-			ttheight = 24;
-			V_DrawLevelTitle(data.spec.passedx1 + xoffset1, ttheight, 0, data.spec.passed1);
-			ttheight += V_LevelNameHeight(data.spec.passed2) + 2;
-			V_DrawLevelTitle(data.spec.passedx2 + xoffset2, ttheight, 0, data.spec.passed2);
+			V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+110, 32, V_YELLOWMAP, "TIME");
 		}
 		else
 		{
-			ttheight = 24 + (V_LevelNameHeight(data.spec.passed2)/2) + 2;
-			V_DrawLevelTitle(data.spec.passedx2 + xoffset1, ttheight, 0, data.spec.passed2);
+			V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+62, 32, V_YELLOWMAP, "TIME");
 		}
 
-		// draw the emeralds
-		if (intertic & 1)
+		V_DrawRightAlignedString(x+(BASEVIDWIDTH/2)+152, 32, V_YELLOWMAP, "SCORE");
+
+		for (i = 0; i < data.match.numplayers; i++)
 		{
-			INT32 emeraldx = 80;
-			for (i = 0; i < 7; ++i)
+			char strtime[10];
+
+			if (data.match.spectator[i])
+				continue;
+
+			V_DrawCenteredString(x+6, y, 0, va("%d", j+1));
+			j++; //We skip spectators, but not their number.
+
+			if (playeringame[data.match.num[i]])
 			{
-				if (emeralds & (1 << i))
-					V_DrawScaledPatch(emeraldx, 74, 0, emeraldpics[i]);
-				emeraldx += 24;
-			}
-		}
+				if (data.match.color[i] == 0)
+					V_DrawSmallScaledPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]]);
+				else
+				{
+					UINT8 *colormap = R_GetTranslationColormap(*data.match.character[i], *data.match.color[i], GTC_CACHE);
+					V_DrawSmallMappedPatch(x+16, y-4, 0,faceprefix[*data.match.character[i]], colormap);
+				}
 
-		V_DrawScaledPatch(152, 108, 0, data.spec.bonuspatch);
-		V_DrawTallNum(BASEVIDWIDTH - 68, 109, 0, data.spec.bonus.points);
-		V_DrawScaledPatch(152, 124, 0, data.spec.pscore);
-		V_DrawTallNum(BASEVIDWIDTH - 68, 125, 0, data.spec.score);
+				if (data.match.numplayers > 8)
+				{
+					strlcpy(name, data.match.name[i], 6);
+				}
+				else
+					STRBUFCPY(name, data.match.name[i]);
 
-		// Draw continues!
-		if (!multiplayer /* && (data.spec.continues & 0x80) */) // Always draw outside of netplay
-		{
-			UINT8 continues = data.spec.continues & 0x7F;
+				V_DrawString(x+36, y, V_ALLOWLOWERCASE, name);
 
-			V_DrawScaledPatch(152, 150, 0, data.spec.pcontinues);
-			for (i = 0; i < continues; ++i)
+				snprintf(strtime, sizeof strtime, "%d", data.match.scores[i]-data.match.increase[i]);
+
+				if (data.match.numplayers > 8)
+				{
+					V_DrawRightAlignedString(x+152, y, V_YELLOWMAP, strtime);
+				}
+				else
+				{
+					V_DrawRightAlignedString(x+152+BASEVIDWIDTH/2, y, V_YELLOWMAP, strtime);
+				}
+
+				if (data.match.increase[i] > 9)
+					snprintf(strtime, sizeof strtime, "(+%02d)", data.match.increase[i]);
+				else
+					snprintf(strtime, sizeof strtime, "(+  %d)", data.match.increase[i]);
+
+				if (data.match.numplayers <= 8) // Only draw this with less than 8 players, otherwise we won't be able to fit the times in
+				{
+					V_DrawString(x+84+BASEVIDWIDTH/2, y, 0, strtime);
+				}
+
+				snprintf(strtime, sizeof strtime, "%i:%02i.%02i", G_TicsToMinutes(data.match.time[i], true),
+				G_TicsToSeconds(data.match.time[i]), G_TicsToCentiseconds(data.match.time[i]));
+
+				strtime[sizeof strtime - 1] = '\0';
+
+				if (data.match.numplayers > 8)
+				{
+					V_DrawRightAlignedString(x+134, y, 0, strtime);
+				}
+				else
+				{
+					V_DrawRightAlignedString(x+80+BASEVIDWIDTH/2, y, 0, strtime);
+				}
+
+
+				completed[i] = true;
+			}
+
+			y += 16;
+
+			if (y > 160)
 			{
-				if ((data.spec.continues & 0x80) && i == continues-1 && (endtic < 0 || intertic%20 < 10))
-					break;
-				V_DrawContinueIcon(246 - (i*12), 162, 0, *data.spec.playerchar, *data.spec.playercolor);
+				y = 48;
+				x += BASEVIDWIDTH/2;
 			}
 		}
 	}
-	else if (intertype == int_match || intertype == int_race)
+	else if (intertype == int_match)
 	{
 		INT32 j = 0;
 		INT32 x = 4;
@@ -671,6 +701,7 @@ void Y_Ticker(void)
 	if (endtic != -1)
 		return; // tally is done
 
+	/* // SRB2kart
 	if (intertype == int_coop) // coop or single player, normal level
 	{
 		INT32 i;
@@ -798,6 +829,39 @@ void Y_Ticker(void)
 			--data.spec.gotlife;
 		}
 	}
+	*/
+	if (intertype == int_timeattack)
+	{
+		if (!intertic)
+			endtic = intertic + 10*TICRATE; // 10 second pause after end of tally
+	}
+	else if (intertype == int_race)
+	{
+		INT32 q=0,r=0;
+
+		/* // SRB2kart - removed temporarily.
+		if (!intertic) {
+			if (!((music_playing == "karwin") // Mario Kart Win
+			|| (music_playing == "karok") // Mario Kart Ok
+			|| (music_playing == "karlos"))) // Mario Kart Lose
+				S_ChangeMusicInternal("racent", true); // Backup Plan
+		}*/
+
+		if (intertic < TICRATE || intertic % 8)
+			return;
+
+		for (q = 0; q < data.match.numplayers; q++)
+		{
+			if (data.match.increase[q]) {
+				data.match.increase[q]--;
+				r++;
+			}
+		}
+		if (r)
+			S_StartSound(NULL, sfx_menu1);
+		else
+			endtic = intertic + 3*TICRATE; // 3 second pause after end of tally
+	}
 	else if (intertype == int_match || intertype == int_ctf || intertype == int_teammatch) // match
 	{
 		if (!intertic) // first time only
@@ -924,10 +988,16 @@ void Y_StartIntermission(void)
 	{
 		timer = 0;
 
+		/*
 		if (G_IsSpecialStage(gamemap))
 			intertype = (maptol & TOL_NIGHTS) ? int_nightsspec : int_spec;
 		else
 			intertype = (maptol & TOL_NIGHTS) ? int_nights : int_coop;
+		*/
+		if (modeattacking)
+			intertype = int_timeattack;
+		else
+			intertype = int_race;
 	}
 	else
 	{
@@ -941,6 +1011,7 @@ void Y_StartIntermission(void)
 				timer = 1;
 		}
 
+		/* // SRB2kart
 		if (gametype == GT_COOP)
 		{
 			// Nights intermission is single player only
@@ -950,7 +1021,8 @@ void Y_StartIntermission(void)
 			else
 				intertype = int_coop;
 		}
-		else if (gametype == GT_TEAMMATCH)
+		else */
+		if (gametype == GT_TEAMMATCH)
 			intertype = int_teammatch;
 		else if (gametype == GT_MATCH
 		 || gametype == GT_TAG
@@ -985,11 +1057,11 @@ void Y_StartIntermission(void)
 			}
 
 			// fall back into the coop intermission for now
-			intertype = int_coop;
-		case int_coop: // coop or single player, normal level
+			intertype = int_timeattack;
+		case int_timeattack: // coop or single player, normal level // SRB2kart 230117 - replaced int_coop
 		{
 			// award time and ring bonuses
-			Y_AwardCoopBonuses();
+			// Y_AwardCoopBonuses();
 
 			// setup time data
 			data.coop.tics = players[consoleplayer].realtime;
@@ -1079,6 +1151,7 @@ void Y_StartIntermission(void)
 			break;
 		}
 
+		/*	// SRB2kart 230117 - removed
 		case int_nightsspec:
 			if (modeattacking && stagefailed)
 			{
@@ -1144,7 +1217,7 @@ void Y_StartIntermission(void)
 				data.spec.headx = 48;
 				data.spec.nowsuper = NULL;
 			} */
-
+/*
 			// Super form stuff (normally blank)
 			data.spec.passed3[0] = '\0';
 			data.spec.passed4[0] = '\0';
@@ -1190,7 +1263,7 @@ void Y_StartIntermission(void)
 			data.spec.passedx3 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed3))/2;
 			data.spec.passedx4 = (BASEVIDWIDTH - V_LevelNameWidth(data.spec.passed4))/2;
 			break;
-		}
+		}*/
 
 		case int_match:
 		{
@@ -1224,7 +1297,7 @@ void Y_StartIntermission(void)
 		case int_race: // (time-only race)
 		{
 			// Calculate who won
-			Y_CalculateTimeRaceWinners();
+			Y_CalculateTournamentPoints();
 
 			// set up the levelstring
 			if (mapheaderinfo[prevmap]->actnum)
@@ -1241,7 +1314,7 @@ void Y_StartIntermission(void)
 			data.match.levelstring[sizeof data.match.levelstring - 1] = '\0';
 
 			// get RESULT header
-			data.match.result = W_CachePatchName("RESULT", PU_STATIC);
+			//data.match.result = W_CachePatchName("RESULT", PU_STATIC);
 
 			bgtile = W_CachePatchName("SRB2BACK", PU_STATIC);
 			usetile = true;
@@ -1360,6 +1433,7 @@ static void Y_CalculateMatchWinners(void)
 	}
 }
 
+/*
 //
 // Y_CalculateTimeRaceWinners
 //
@@ -1403,6 +1477,7 @@ static void Y_CalculateTimeRaceWinners(void)
 		data.match.numplayers++;
 	}
 }
+*/
 
 //
 // Y_CalculateCompetitionWinners
@@ -1665,7 +1740,7 @@ bonus_f bonuses_list[4][4] = {
 };
 
 
-
+/*  // SRB2kart 230117 - Replaced with Y_CalculateTournamentPoints
 //
 // Y_AwardCoopBonuses
 //
@@ -1759,6 +1834,86 @@ static void Y_AwardSpecialStageBonus(void)
 		}
 	}
 }
+*/
+
+//
+// Y_CalculateTournamentPoints
+//
+static void Y_CalculateTournamentPoints(void)
+{
+	INT32 i, j;
+	boolean completed[MAXPLAYERS];
+	INT32 numplayersingame = 0;
+	INT32 zz1  = 0, zz2  = 0, zz3  = 0, zz4  = 0, zz5  = 0, zz6  = 0, zz7  = 0, zz8  = 0,
+		  zz9  = 0, zz10 = 0, zz11 = 0, zz12 = 0, zz13 = 0, zz14 = 0, zz15 = 0, zz16 = 0;
+
+	for (i = 0; i < MAXPLAYERS; i++)
+	{
+		if (playeringame[i])
+			numplayersingame++;
+	}
+
+	zz1 = numplayersingame;		zz2 = numplayersingame-1;	zz3 = numplayersingame-2;	zz4 = numplayersingame-3;
+	zz5 = numplayersingame-4;	zz6 = numplayersingame-5;	zz7 = numplayersingame-6;	zz8 = numplayersingame-7;
+	zz9 = numplayersingame-8;	zz10= numplayersingame-9;	zz11= numplayersingame-10;	zz12= numplayersingame-11;
+	zz13= numplayersingame-12;	zz14= numplayersingame-13;	zz15= numplayersingame-14;	zz16= numplayersingame-15;
+	
+	if (zz1 < 0) zz1 = 0;	if (zz2 < 0) zz2 = 0;	if (zz3 < 0) zz3 = 0;	if (zz4 < 0) zz4 = 0;
+	if (zz5 < 0) zz5 = 0;	if (zz6 < 0) zz6 = 0;	if (zz7 < 0) zz7 = 0;	if (zz8 < 0) zz8 = 0;
+	if (zz9 < 0) zz9 = 0;	if (zz10< 0) zz10= 0;	if (zz11< 0) zz11= 0;	if (zz12< 0) zz12= 0;
+	if (zz13< 0) zz13= 0;	if (zz14< 0) zz14= 0;	if (zz15< 0) zz15= 0;	if (zz16< 0) zz16= 0;
+
+	INT32 increase[MAXPLAYERS] = {zz1,zz2,zz3,zz4,zz5,zz6,zz7,zz8,zz9,zz10,zz11,zz12,zz13,zz14,zz15,zz16};
+
+	// Initialize variables
+
+	for (j = 0; j < MAXPLAYERS; j++)
+		data.match.scores[j] = INT32_MAX;
+
+	memset(data.match.time, 0, sizeof (data.match.time));
+	memset(data.match.color, 0, sizeof (data.match.color));
+	memset(data.match.character, 0, sizeof (data.match.character));
+	memset(data.match.spectator, 0, sizeof (data.match.spectator));
+	memset(data.match.increase, 0, sizeof (data.match.increase));
+	memset(completed, 0, sizeof (completed));
+	data.match.numplayers = 0;
+	i = j = 0;
+
+	for (j = 0; j < MAXPLAYERS; j++)
+	{
+		if (!playeringame[j])
+			continue;
+
+		for (i = 0; i < MAXPLAYERS; i++)
+		{
+			if (!playeringame[i])
+				continue;
+
+			if (players[i].realtime <= data.match.scores[data.match.numplayers] && completed[i] == false)
+			{
+				data.match.time[data.match.numplayers] = players[i].realtime;
+				data.match.scores[data.match.numplayers] = players[i].realtime;
+				data.match.color[data.match.numplayers] = &players[i].skincolor;
+				data.match.character[data.match.numplayers] = &players[i].skin;
+				data.match.name[data.match.numplayers] = player_names[i];
+				data.match.spectator[data.match.numplayers] = players[i].spectator;
+				data.match.num[data.match.numplayers] = i;
+			}
+		}
+		completed[data.match.num[data.match.numplayers]] = true;
+		if (!(players[data.match.num[data.match.numplayers]].pflags & PF_TIMEOVER
+		|| players[data.match.num[data.match.numplayers]].spectator))
+			data.match.increase[data.match.numplayers] = increase[data.match.numplayers];
+		players[data.match.num[data.match.numplayers]].score += data.match.increase[data.match.numplayers];
+		data.match.scores[data.match.numplayers] = players[data.match.num[data.match.numplayers]].score;
+
+		//players[data.match.num[data.match.numplayers]].newfloorz = 0;
+		players[data.match.num[data.match.numplayers]].kartstuff[k_lakitu] = 0;
+		//players[data.match.num[data.match.numplayers]].airtime = 0;
+
+		data.match.numplayers++;
+	}
+}
 
 // ======
 
@@ -1853,6 +2008,7 @@ static void Y_UnloadData(void)
 
 	switch (intertype)
 	{
+		/*
 		case int_coop:
 			// unload the coop and single player patches
 			UNLOAD(data.coop.ttlnum);
@@ -1870,6 +2026,7 @@ static void Y_UnloadData(void)
 			UNLOAD(data.spec.pscore);
 			UNLOAD(data.spec.pcontinues);
 			break;
+		*/
 		case int_match:
 		case int_race:
 			UNLOAD(data.match.result);
diff --git a/src/y_inter.h b/src/y_inter.h
index 9fe95fcc4..358debf7b 100644
--- a/src/y_inter.h
+++ b/src/y_inter.h
@@ -20,15 +20,15 @@ void Y_EndGame(void);
 typedef enum
 {
 	int_none,
-	int_coop,     // Single Player/Cooperative
-	int_match,    // Match
-	int_teammatch,// Team Match
-//	int_tag,      // Tag
-	int_ctf,      // CTF
-	int_spec,     // Special Stage
-	int_nights,   // NiGHTS into Dreams
-	int_nightsspec,// NiGHTS special stage
-	int_race,     // Race
+	int_timeattack,  // Time Attack
+	int_match,       // Match
+	int_teammatch,   // Team Match
+//	int_tag,         // Tag
+	int_ctf,         // CTF
+	int_spec,        // Special Stage
+	int_nights,      // NiGHTS into Dreams
+	int_nightsspec,  // NiGHTS special stage
+	int_race,        // Race
 	int_classicrace, // Competition
 } intertype_t;
 extern intertype_t intertype;
-- 
GitLab