diff --git a/src/d_player.h b/src/d_player.h
index 0e4c5ec516471f8f158d3b82c46b5f2c600b1c1c..4a5d0e702b860ba3103f6800f854e213662a4183 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -165,6 +165,7 @@ typedef enum
 	PA_EDGE,
 	PA_WALK,
 	PA_RUN,
+	PA_PEEL,
 	PA_PAIN,
 	PA_ROLL,
 	PA_SPRING,
diff --git a/src/dehacked.c b/src/dehacked.c
index 37584c6e1a875bb55a1c5187cdfa1e48ec600031..57496d20c081b0e83427e2da36244833a2a24dfb 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -3794,6 +3794,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_PLAY_WAIT",
 	"S_PLAY_WALK",
 	"S_PLAY_RUN",
+	"S_PLAY_PEEL",
 	"S_PLAY_PAIN",
 	"S_PLAY_DEAD",
 	"S_PLAY_DRWN",
@@ -3819,6 +3820,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_PLAY_SUPER_STND",
 	"S_PLAY_SUPER_WALK",
 	"S_PLAY_SUPER_RUN",
+	"S_PLAY_SUPER_PEEL",
 	"S_PLAY_SUPER_PAIN",
 	"S_PLAY_SUPER_STUN",
 	"S_PLAY_SUPER_DEAD",
@@ -7188,6 +7190,7 @@ struct {
 	{"PA_EDGE",PA_EDGE},
 	{"PA_WALK",PA_WALK},
 	{"PA_RUN",PA_RUN},
+	{"PA_PEEL",PA_PEEL},
 	{"PA_PAIN",PA_PAIN},
 	{"PA_ROLL",PA_ROLL},
 	{"PA_SPRING",PA_SPRING},
diff --git a/src/info.c b/src/info.c
index dc71ad1632af933268cf6db2c8fd5c119dce3596..8eec2481871c6b3c6be345a77a5bec4a3dd3cc1b 100644
--- a/src/info.c
+++ b/src/info.c
@@ -62,6 +62,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"WAIT",
 	"WALK",
 	"RUN_",
+	"PEEL",
 	"PAIN",
 	"DEAD",
 	"DRWN",
@@ -88,6 +89,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SSTD",
 	"SWLK",
 	"SRUN",
+	"SPEE",
 	"SPAN",
 	"SMSL",
 	"SDTH",
@@ -132,6 +134,7 @@ state_t states[NUMSTATES] =
 	{SPR_PLAY, SPR2_WAIT,  16, {NULL}, 0, 0, S_PLAY_WAIT}, // S_PLAY_WAIT
 	{SPR_PLAY, SPR2_WALK,   4, {NULL}, 0, 0, S_PLAY_WALK}, // S_PLAY_WALK
 	{SPR_PLAY, SPR2_RUN ,   2, {NULL}, 0, 0, S_PLAY_RUN},  // S_PLAY_RUN
+	{SPR_PLAY, SPR2_PEEL,   2, {NULL}, 0, 0, S_PLAY_PEEL}, // S_PLAY_PEEL
 	{SPR_PLAY, SPR2_PAIN, 350, {NULL}, 0, 0, S_PLAY_FALL}, // S_PLAY_PAIN
 	{SPR_PLAY, SPR2_DEAD,   4, {NULL}, 0, 0, S_PLAY_DEAD}, // S_PLAY_DEAD
 	{SPR_PLAY, SPR2_DRWN,   4, {NULL}, 0, 0, S_PLAY_DRWN}, // S_PLAY_DRWN
@@ -157,6 +160,7 @@ state_t states[NUMSTATES] =
 	{SPR_PLAY, SPR2_SSTD,   7, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STND
 	{SPR_PLAY, SPR2_SWLK,   7, {NULL}, 0, 0, S_PLAY_SUPER_WALK}, // S_PLAY_SUPER_WALK
 	{SPR_PLAY, SPR2_SRUN,   7, {NULL}, 0, 0, S_PLAY_SUPER_RUN},  // S_PLAY_SUPER_RUN
+	{SPR_PLAY, SPR2_SPEE,   7, {NULL}, 0, 0, S_PLAY_SUPER_PEEL}, // S_PLAY_SUPER_PEEL
 	{SPR_PLAY, SPR2_SPAN,  -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_PAIN
 	{SPR_PLAY, SPR2_SMSL,  -1, {NULL}, 0, 0, S_PLAY_SUPER_STND}, // S_PLAY_SUPER_STUN
 	{SPR_PLAY, SPR2_SDTH,   4, {NULL}, 0, 0, S_PLAY_SUPER_DEAD}, // S_PLAY_SUPER_DEAD
diff --git a/src/info.h b/src/info.h
index 46fdde46ba3fb9af5898394b264719fbb012bf98..46b76096b7999e5777d3fe4c2c7fdb7206f12b45 100644
--- a/src/info.h
+++ b/src/info.h
@@ -581,6 +581,7 @@ enum playersprite
 	SPR2_WAIT,
 	SPR2_WALK,
 	SPR2_RUN ,
+	SPR2_PEEL,
 	SPR2_PAIN,
 	SPR2_DEAD,
 	SPR2_DRWN,
@@ -607,6 +608,7 @@ enum playersprite
 	SPR2_SSTD,
 	SPR2_SWLK,
 	SPR2_SRUN,
+	SPR2_SPEE,
 	SPR2_SPAN,
 	SPR2_SMSL,
 	SPR2_SDTH,
@@ -645,6 +647,7 @@ typedef enum state
 	S_PLAY_WAIT,
 	S_PLAY_WALK,
 	S_PLAY_RUN,
+	S_PLAY_PEEL,
 	S_PLAY_PAIN,
 	S_PLAY_DEAD,
 	S_PLAY_DRWN,
@@ -670,6 +673,7 @@ typedef enum state
 	S_PLAY_SUPER_STND,
 	S_PLAY_SUPER_WALK,
 	S_PLAY_SUPER_RUN,
+	S_PLAY_SUPER_PEEL,
 	S_PLAY_SUPER_PAIN,
 	S_PLAY_SUPER_STUN,
 	S_PLAY_SUPER_DEAD,
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 5fb3c81d747c511fcbf718de5071ec31817062c3..bffa796dde567c2bbc8b446be605c90402a0bf81 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -175,6 +175,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 			return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_WALK);
 		case S_PLAY_RUN:
 			return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_RUN);
+		case S_PLAY_PEEL:
+			return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PEEL);
 		case S_PLAY_PAIN:
 			return P_SetPlayerMobjState(mobj, S_PLAY_SUPER_PAIN);
 		case S_PLAY_DEAD:
@@ -231,6 +233,10 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 	case S_PLAY_SUPER_RUN:
 		player->panim = PA_RUN;
 		break;
+	case S_PLAY_PEEL:
+	case S_PLAY_SUPER_PEEL:
+		player->panim = PA_PEEL;
+		break;
 	case S_PLAY_PAIN:
 	case S_PLAY_SUPER_PAIN:
 	case S_PLAY_SUPER_STUN:
@@ -316,7 +322,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 					else
 						mobj->tics = 4;
 				}
-				else if (player->panim == PA_RUN)
+				else if ((player->panim == PA_RUN) || (player->panim == PA_PEEL))
 				{
 					if (speed > 52<<FRACBITS)
 						mobj->tics = 1;
@@ -339,6 +345,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 			{
 				switch(spr2)
 				{
+				case SPR2_PEEL:
+					spr2 = SPR2_RUN;
+					break;
 				case SPR2_RUN:
 					spr2 = SPR2_WALK;
 					break;
@@ -393,6 +402,9 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 				case SPR2_SRUN:
 					spr2 = SPR2_RUN;
 					break;
+				case SPR2_SPEE:
+					spr2 = SPR2_PEEL;
+					break;
 				case SPR2_SPAN:
 					spr2 = SPR2_PAIN;
 					break;
@@ -2955,7 +2967,9 @@ static void P_PlayerZMovement(mobj_t *mo)
 					{
 						if (mo->player->cmomx || mo->player->cmomy)
 						{
-							if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
+							if (mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
+								P_SetPlayerMobjState(mo, S_PLAY_PEEL);
+							else if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
 								P_SetPlayerMobjState(mo, S_PLAY_RUN);
 							else if ((mo->player->rmomx || mo->player->rmomy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
 								P_SetPlayerMobjState(mo, S_PLAY_WALK);
@@ -2964,6 +2978,8 @@ static void P_PlayerZMovement(mobj_t *mo)
 						}
 						else
 						{
+							if (mo->player->dashmode >= 3*TICRATE && mo->player->panim != PA_PEEL)
+								P_SetPlayerMobjState(mo, S_PLAY_PEEL);
 							if (mo->player->speed >= FixedMul(mo->player->runspeed, mo->scale) && mo->player->panim != PA_RUN)
 								P_SetPlayerMobjState(mo, S_PLAY_RUN);
 							else if ((mo->momx || mo->momy) && (mo->player->panim != PA_WALK || mo->state-states == S_PLAY_SUPER_FLOAT))
diff --git a/src/p_user.c b/src/p_user.c
index 6b57bb7a969d873bb5ff42a637eeccdb9bda0faf..0eef60b1376794d6a64fd92cd2146990efdc5475 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3501,6 +3501,9 @@ static void P_DoSuperStuff(player_t *player)
 				case S_PLAY_SUPER_RUN:
 					P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
 					break;
+				case S_PLAY_SUPER_PEEL:
+					P_SetPlayerMobjState(player->mo, S_PLAY_PEEL);
+					break;
 				case S_PLAY_SUPER_PAIN:
 					P_SetPlayerMobjState(player->mo, S_PLAY_PAIN);
 					break;
@@ -6507,9 +6510,12 @@ static void P_MovePlayer(player_t *player)
 
 	if ((cmd->forwardmove != 0 || cmd->sidemove != 0) || (player->powers[pw_super] && !onground))
 	{
+		// If the player is in dashmode, here's their peelout.
+		if (player->charability == CA_DASHMODE && player->dashmode >= 3*TICRATE && player->panim == PA_RUN && !player->skidtime && (onground || player->powers[pw_super]))
+			P_SetPlayerMobjState (player->mo, S_PLAY_PEEL);
 		// If the player is moving fast enough,
 		// break into a run!
-		if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super]))
+		else if (player->speed >= runspd && player->panim == PA_WALK && !player->skidtime && (onground || player->powers[pw_super]))
 			P_SetPlayerMobjState (player->mo, S_PLAY_RUN);
 
 		// Super floating at slow speeds has its own special animation.
@@ -6521,6 +6527,11 @@ static void P_MovePlayer(player_t *player)
 			P_SetPlayerMobjState (player->mo, S_PLAY_WALK);
 	}
 
+	// If your peelout animation is playing, and you're
+	// going too slow, switch back to the run.
+	if (player->panim == PA_PEEL && player->dashmode < 3*TICRATE)
+		P_SetPlayerMobjState(player->mo, S_PLAY_RUN);
+
 	// If your running animation is playing, and you're
 	// going too slow, switch back to the walking frames.
 	if (player->panim == PA_RUN && player->speed < runspd)
@@ -6851,7 +6862,7 @@ static void P_MovePlayer(player_t *player)
 #endif
 		}
 		// Otherwise, face the direction you're travelling.
-		else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_ROLL
+		else if (player->panim == PA_WALK || player->panim == PA_RUN || player->panim == PA_PEEL || player->panim == PA_ROLL
 		|| (player->mo->state-states == S_PLAY_FLY || player->mo->state-states == S_PLAY_FLY_TIRED))
 			player->mo->angle = R_PointToAngle2(0, 0, player->rmomx, player->rmomy);
 
@@ -9173,7 +9184,7 @@ void P_PlayerThink(player_t *player)
 	// Dash mode ability for Metal Sonic
 	if ((player->charability == CA_DASHMODE) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho.
 	{
-		if (player->speed >= FixedMul(skins[player->skin].normalspeed - 5*FRACUNIT, player->mo->scale) || (player->pflags & PF_STARTDASH))
+		if (player->speed >= FixedMul(player->runspeed, player->mo->scale) || (player->pflags & PF_STARTDASH))
 		{
 			dashmode++; // Counter. Adds 1 to dash mode per tic in top speed.
 			if (dashmode == 3*TICRATE) // This isn't in the ">=" equation because it'd cause the sound to play infinitely.