diff --git a/src/dehacked.c b/src/dehacked.c
index 8d240326d8f937349e8f4035d2a1346baf4954d5..7e4c0e35720c3829c48450a6559099ef2d5280f8 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -9081,6 +9081,7 @@ struct {
 	{"TC_ALLWHITE",TC_ALLWHITE},
 	{"TC_RAINBOW",TC_RAINBOW},
 	{"TC_BLINK",TC_BLINK},
+	{"TC_DASHMODE",TC_DASHMODE},
 #endif
 
 	{NULL,0}
diff --git a/src/r_draw.c b/src/r_draw.c
index 1754403c44141a2ca599bddcc28d0ca6ed90ca80..bb70a319f0a5137d3f95740e10b77efda06eeed7 100644
--- a/src/r_draw.c
+++ b/src/r_draw.c
@@ -130,10 +130,11 @@ UINT32 nflatxshift, nflatyshift, nflatshiftup, nflatmask;
 #define ALLWHITE_TT_CACHE_INDEX (MAXSKINS + 3)
 #define RAINBOW_TT_CACHE_INDEX (MAXSKINS + 4)
 #define BLINK_TT_CACHE_INDEX (MAXSKINS + 5)
+#define DASHMODE_TT_CACHE_INDEX (MAXSKINS + 6)
 #define DEFAULT_STARTTRANSCOLOR 96
 #define NUM_PALETTE_ENTRIES 256
 
-static UINT8** translationtablecache[MAXSKINS + 6] = {NULL};
+static UINT8** translationtablecache[MAXSKINS + 7] = {NULL};
 
 const UINT8 Color_Index[MAXTRANSLATIONS-1][16] = {
 	// {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, // SKINCOLOR_NONE
@@ -569,6 +570,40 @@ static void R_GenerateTranslationColormap(UINT8 *dest_colormap, INT32 skinnum, U
 				dest_colormap[Color_Index[SKINCOLOR_BLUE-1][12-i]] = Color_Index[SKINCOLOR_BLUE-1][i];
 			dest_colormap[159] = dest_colormap[253] = dest_colormap[254] = 0;
 		}
+		else if (skinnum == TC_DASHMODE) // This is a long one, because MotorRoach basically hand-picked the indices
+		{
+			// greens -> ketchups
+			dest_colormap[96] = dest_colormap[97] = 48;
+			dest_colormap[98] = 49;
+			dest_colormap[99] = 51;
+			dest_colormap[100] = 52;
+			dest_colormap[101] = dest_colormap[102] = 54;
+			dest_colormap[103] = 34;
+			dest_colormap[104] = 37;
+			dest_colormap[105] = 39;
+			dest_colormap[106] = 41;
+			for (i = 0; i < 5; i++)
+				dest_colormap[107 + i] = 43 + i;
+
+			// reds -> steel blues
+			dest_colormap[32] = 146;
+			dest_colormap[33] = 147;
+			dest_colormap[34] = dest_colormap[35] = 170;
+			dest_colormap[36] = 171;
+			dest_colormap[37] = dest_colormap[38] = 172;
+			dest_colormap[39] = dest_colormap[40] = dest_colormap[41] = 173;
+			dest_colormap[42] = dest_colormap[43] = dest_colormap[44] = 174;
+			dest_colormap[45] = dest_colormap[46] = dest_colormap[47] = 175;
+			dest_colormap[71] = 139;
+
+			// steel blues -> oranges
+			dest_colormap[170] = 52;
+			dest_colormap[171] = 54;
+			dest_colormap[172] = 56;
+			dest_colormap[173] = 42;
+			dest_colormap[174] = 45;
+			dest_colormap[175] = 47;
+		}
 		return;
 	}
 	else if (color == SKINCOLOR_NONE)
@@ -628,6 +663,7 @@ UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags)
 		case TC_ALLWHITE:   skintableindex = ALLWHITE_TT_CACHE_INDEX; break;
 		case TC_RAINBOW:    skintableindex = RAINBOW_TT_CACHE_INDEX; break;
 		case TC_BLINK:      skintableindex = BLINK_TT_CACHE_INDEX; break;
+		case TC_DASHMODE:   skintableindex = DASHMODE_TT_CACHE_INDEX; break;
 		     default:       skintableindex = skinnum; break;
 	}
 
diff --git a/src/r_draw.h b/src/r_draw.h
index 3c142972257c446a29e32fd1c36a810e47c63bc0..a0ab748480930d6f06191b6de78adfefdb539ce5 100644
--- a/src/r_draw.h
+++ b/src/r_draw.h
@@ -109,6 +109,7 @@ extern lumpnum_t viewborderlump[8];
 #define TC_ALLWHITE   -4 // For Cy-Brak-demon
 #define TC_RAINBOW    -5 // For single colour
 #define TC_BLINK      -6 // For item blinking, according to kart
+#define TC_DASHMODE   -7 // For Metal Sonic's dashmode
 
 // Initialize color translation tables, for player rendering etc.
 void R_InitTranslationTables(void);
diff --git a/src/r_things.c b/src/r_things.c
index 5c99edcec3d74e135a605fd591ff55b3f0166fcb..3233e96506df927db7119bdad95f14f9d03ee714 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -753,6 +753,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
 		dc_transmap = vis->transmap;
 		if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
 			dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
+		else if (!(vis->cut & SC_PRECIP)
+			&& vis->mobj->player && vis->mobj->player->dashmode >= 108 && vis->mobj->player->charflags & SF_MACHINE
+			&&((leveltime/2) & 1))
+		{
+			dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
+		}
 		else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // MT_GHOST LOOKS LIKE A PLAYER SO USE THE PLAYER TRANSLATION TABLES. >_>
 		{
 			size_t skinnum = (skin_t*)vis->mobj->skin-skins;
@@ -774,6 +780,12 @@ static void R_DrawVisSprite(vissprite_t *vis)
 		// New colormap stuff for skins Tails 06-07-2002
 		if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized)
 			dc_translation = R_GetTranslationColormap(TC_RAINBOW, vis->mobj->color, GTC_CACHE);
+		else if (!(vis->cut & SC_PRECIP)
+			&& vis->mobj->player && vis->mobj->player->dashmode >= 108 && vis->mobj->player->charflags & SF_MACHINE
+			&&((leveltime/2) & 1))
+		{
+			dc_translation = R_GetTranslationColormap(TC_DASHMODE, 0, GTC_CACHE);
+		}
 		else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player!
 		{
 			size_t skinnum = (skin_t*)vis->mobj->skin-skins;