diff --git a/src/dehacked.c b/src/dehacked.c
index b1ec8605511d6b489687548002ae0b0e9e15a0d3..a512e1029f9b4ab0ee1108d0ad41d4273133d6a4 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -3859,6 +3859,50 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	// Level end sign (uses player sprite)
 	"S_PLAY_SIGN",
 
+	// NiGHTS character (uses player sprite)
+	"S_PLAY_NIGHTS_TRANS",
+	"S_PLAY_NIGHTS_TRANS2",
+	"S_PLAY_NIGHTS_TRANS3",
+	"S_PLAY_NIGHTS_TRANS4",
+	"S_PLAY_NIGHTS_TRANS5",
+	"S_PLAY_NIGHTS_TRANS6",
+	"S_PLAY_NIGHTS_TRANS7",
+	"S_PLAY_NIGHTS_TRANS8",
+	"S_PLAY_NIGHTS_TRANS9",
+
+	"S_PLAY_NIGHTS_STAND",
+	"S_PLAY_NIGHTS_FLOAT",
+	"S_PLAY_NIGHTS_PAIN",
+	"S_PLAY_NIGHTS_PULL",
+	"S_PLAY_NIGHTS_ATTACK",
+
+	"S_PLAY_NIGHTS_FLY0",
+	"S_PLAY_NIGHTS_DRILL0",
+	"S_PLAY_NIGHTS_FLY1",
+	"S_PLAY_NIGHTS_DRILL1",
+	"S_PLAY_NIGHTS_FLY2",
+	"S_PLAY_NIGHTS_DRILL2",
+	"S_PLAY_NIGHTS_FLY3",
+	"S_PLAY_NIGHTS_DRILL3",
+	"S_PLAY_NIGHTS_FLY4",
+	"S_PLAY_NIGHTS_DRILL4",
+	"S_PLAY_NIGHTS_FLY5",
+	"S_PLAY_NIGHTS_DRILL5",
+	"S_PLAY_NIGHTS_FLY6",
+	"S_PLAY_NIGHTS_DRILL6",
+	"S_PLAY_NIGHTS_FLY7",
+	"S_PLAY_NIGHTS_DRILL7",
+	"S_PLAY_NIGHTS_FLY8",
+	"S_PLAY_NIGHTS_DRILL8",
+	"S_PLAY_NIGHTS_FLY9",
+	"S_PLAY_NIGHTS_DRILL9",
+	"S_PLAY_NIGHTS_FLYA",
+	"S_PLAY_NIGHTS_DRILLA",
+	"S_PLAY_NIGHTS_FLYB",
+	"S_PLAY_NIGHTS_DRILLB",
+	"S_PLAY_NIGHTS_FLYC",
+	"S_PLAY_NIGHTS_DRILLC",
+
 	// Blue Crawla
 	"S_POSS_STND",
 	"S_POSS_RUN1",
@@ -5854,93 +5898,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_NIGHTSGOAL3",
 	"S_NIGHTSGOAL4",
 
-	"S_NIGHTSFLY1A",
-	"S_NIGHTSFLY1B",
-	"S_NIGHTSDRILL1A",
-	"S_NIGHTSDRILL1B",
-	"S_NIGHTSDRILL1C",
-	"S_NIGHTSDRILL1D",
-	"S_NIGHTSFLY2A",
-	"S_NIGHTSFLY2B",
-	"S_NIGHTSDRILL2A",
-	"S_NIGHTSDRILL2B",
-	"S_NIGHTSDRILL2C",
-	"S_NIGHTSDRILL2D",
-	"S_NIGHTSFLY3A",
-	"S_NIGHTSFLY3B",
-	"S_NIGHTSDRILL3A",
-	"S_NIGHTSDRILL3B",
-	"S_NIGHTSDRILL3C",
-	"S_NIGHTSDRILL3D",
-	"S_NIGHTSFLY4A",
-	"S_NIGHTSFLY4B",
-	"S_NIGHTSDRILL4A",
-	"S_NIGHTSDRILL4B",
-	"S_NIGHTSDRILL4C",
-	"S_NIGHTSDRILL4D",
-	"S_NIGHTSFLY5A",
-	"S_NIGHTSFLY5B",
-	"S_NIGHTSDRILL5A",
-	"S_NIGHTSDRILL5B",
-	"S_NIGHTSDRILL5C",
-	"S_NIGHTSDRILL5D",
-	"S_NIGHTSFLY6A",
-	"S_NIGHTSFLY6B",
-	"S_NIGHTSDRILL6A",
-	"S_NIGHTSDRILL6B",
-	"S_NIGHTSDRILL6C",
-	"S_NIGHTSDRILL6D",
-	"S_NIGHTSFLY7A",
-	"S_NIGHTSFLY7B",
-	"S_NIGHTSDRILL7A",
-	"S_NIGHTSDRILL7B",
-	"S_NIGHTSDRILL7C",
-	"S_NIGHTSDRILL7D",
-	"S_NIGHTSFLY8A",
-	"S_NIGHTSFLY8B",
-	"S_NIGHTSDRILL8A",
-	"S_NIGHTSDRILL8B",
-	"S_NIGHTSDRILL8C",
-	"S_NIGHTSDRILL8D",
-	"S_NIGHTSFLY9A",
-	"S_NIGHTSFLY9B",
-	"S_NIGHTSDRILL9A",
-	"S_NIGHTSDRILL9B",
-	"S_NIGHTSDRILL9C",
-	"S_NIGHTSDRILL9D",
-	"S_NIGHTSHURT1",
-	"S_NIGHTSHURT2",
-	"S_NIGHTSHURT3",
-	"S_NIGHTSHURT4",
-	"S_NIGHTSHURT5",
-	"S_NIGHTSHURT6",
-	"S_NIGHTSHURT7",
-	"S_NIGHTSHURT8",
-	"S_NIGHTSHURT9",
-	"S_NIGHTSHURT10",
-	"S_NIGHTSHURT11",
-	"S_NIGHTSHURT12",
-	"S_NIGHTSHURT13",
-	"S_NIGHTSHURT14",
-	"S_NIGHTSHURT15",
-	"S_NIGHTSHURT16",
-	"S_NIGHTSHURT17",
-	"S_NIGHTSHURT18",
-	"S_NIGHTSHURT19",
-	"S_NIGHTSHURT20",
-	"S_NIGHTSHURT21",
-	"S_NIGHTSHURT22",
-	"S_NIGHTSHURT23",
-	"S_NIGHTSHURT24",
-	"S_NIGHTSHURT25",
-	"S_NIGHTSHURT26",
-	"S_NIGHTSHURT27",
-	"S_NIGHTSHURT28",
-	"S_NIGHTSHURT29",
-	"S_NIGHTSHURT30",
-	"S_NIGHTSHURT31",
-	"S_NIGHTSHURT32",
-
 	"S_NIGHTSPARKLE1",
 	"S_NIGHTSPARKLE2",
 	"S_NIGHTSPARKLE3",
@@ -6037,16 +5994,6 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit
 	"S_CRUMBLE1",
 	"S_CRUMBLE2",
 
-	"S_SUPERTRANS1",
-	"S_SUPERTRANS2",
-	"S_SUPERTRANS3",
-	"S_SUPERTRANS4",
-	"S_SUPERTRANS5",
-	"S_SUPERTRANS6",
-	"S_SUPERTRANS7",
-	"S_SUPERTRANS8",
-	"S_SUPERTRANS9",
-
 	// Spark
 	"S_SPRK1",
 	"S_SPRK2",
@@ -6603,7 +6550,6 @@ static const char *const MOBJTYPE_LIST[] = {  // array length left dynamic for s
 	"MT_AXISTRANSFERLINE",
 	"MT_NIGHTSDRONE",
 	"MT_NIGHTSGOAL",
-	"MT_NIGHTSCHAR",
 	"MT_NIGHTSPARKLE",
 	"MT_NIGHTSLOOPHELPER",
 	"MT_NIGHTSBUMPER", // NiGHTS Bumper
diff --git a/src/info.c b/src/info.c
index 51b25e4b799686cfdb1a56fb1cee413b70047d86..aeba7dcabe173ea34b103d48afe9ed751d588837 100644
--- a/src/info.c
+++ b/src/info.c
@@ -96,7 +96,7 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SRUN",
 	"SPEE",
 	"SPAN",
-	"SMSL",
+	"SSTN",
 	"SDTH",
 	"SDRN",
 	"SSPN",
@@ -106,7 +106,42 @@ char spr2names[NUMPLAYERSPRITES][5] =
 	"SFAL",
 	"SEDG",
 	"SRID",
-	"SFLT"
+	"SFLT",
+
+	"NTRN",
+	"NSTD",
+	"NFLT",
+	"NPAN",
+	"NPUL",
+	"NATK",
+
+	"NGT0",
+	"NGT1",
+	"NGT2",
+	"NGT3",
+	"NGT4",
+	"NGT5",
+	"NGT6",
+	"NGT7",
+	"NGT8",
+	"NGT9",
+	"NGTA",
+	"NGTB",
+	"NGTC",
+
+	"DRL0",
+	"DRL1",
+	"DRL2",
+	"DRL3",
+	"DRL4",
+	"DRL5",
+	"DRL6",
+	"DRL7",
+	"DRL8",
+	"DRL9",
+	"DRLA",
+	"DRLB",
+	"DRLC"
 };
 enum playersprite free_spr2 = SPR2_FIRSTFREESLOT;
 
@@ -176,7 +211,7 @@ state_t states[NUMSTATES] =
 	{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_SSTN,  -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
 	{SPR_PLAY, SPR2_SDRN,   4, {NULL}, 0, 0, S_PLAY_SUPER_DRWN}, // S_PLAY_SUPER_DRWN
 	{SPR_PLAY, SPR2_SSPN,   1, {NULL}, 0, 0, S_PLAY_SUPER_SPIN}, // S_PLAY_SUPER_SPIN
@@ -192,12 +227,12 @@ state_t states[NUMSTATES] =
 	{SPR_PLAY, SPR2_TRNS,                4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS2}, // S_PLAY_SUPER_TRANS
 	{SPR_PLAY, SPR2_TRNS,                4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS3}, // S_PLAY_SUPER_TRANS2
 	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  4, {NULL}, 0, 0, S_PLAY_SUPER_TRANS4}, // S_PLAY_SUPER_TRANS3
-	{SPR_PLAY, SPR2_TRNS,                3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
-	{SPR_PLAY, SPR2_TRNS,                3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
-	{SPR_PLAY, SPR2_TRNS,                3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
-	{SPR_PLAY, SPR2_TRNS,                3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
-	{SPR_PLAY, SPR2_TRNS,                3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
-	{SPR_PLAY, SPR2_TRNS,               16, {NULL}, 0, 0, S_PLAY_WALK},         // S_PLAY_SUPER_TRANS9
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS5}, // S_PLAY_SUPER_TRANS4
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS6}, // S_PLAY_SUPER_TRANS5
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS7}, // S_PLAY_SUPER_TRANS6
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS8}, // S_PLAY_SUPER_TRANS7
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT,  3, {NULL}, 0, 0, S_PLAY_SUPER_TRANS9}, // S_PLAY_SUPER_TRANS8
+	{SPR_PLAY, SPR2_TRNS|FF_FULLBRIGHT, 16, {NULL}, 0, 0, S_PLAY_WALK},         // S_PLAY_SUPER_TRANS9
 
 	{SPR_NULL, 0, -1, {NULL}, 0, 0, S_OBJPLACE_DUMMY}, //S_OBJPLACE_DUMMY
 
@@ -211,6 +246,52 @@ state_t states[NUMSTATES] =
 	// Level end sign (uses player sprite)
 	{SPR_PLAY, SPR2_SIGN, 1, {NULL}, 0, 24, S_PLAY_SIGN},         // S_PLAY_SIGN
 
+	// NiGHTS Player, transforming
+	{SPR_PLAY, SPR2_NTRN,                4, {A_Scream}, 0, 0, S_PLAY_NIGHTS_TRANS2}, // S_PLAY_NIGHTS_TRANS
+	{SPR_PLAY, SPR2_NTRN,                4, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS3}, // S_PLAY_NIGHTS_TRANS2
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  4, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS4}, // S_PLAY_NIGHTS_TRANS3
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  3, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS5}, // S_PLAY_NIGHTS_TRANS4
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  3, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS6}, // S_PLAY_NIGHTS_TRANS5
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  3, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS7}, // S_PLAY_NIGHTS_TRANS6
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  3, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS8}, // S_PLAY_NIGHTS_TRANS7
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT,  3, {NULL},     0, 0, S_PLAY_NIGHTS_TRANS9}, // S_PLAY_NIGHTS_TRANS8
+	{SPR_PLAY, SPR2_NTRN|FF_FULLBRIGHT, 16, {NULL},     0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_TRANS9
+
+	// NiGHTS Player, Stand, Floating, Pain, Pull and Attack
+	{SPR_PLAY, SPR2_NSTD, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_STAND}, // S_PLAY_NIGHTS_STAND
+	{SPR_PLAY, SPR2_NFLT, 7, {NULL}, 0, 0, S_PLAY_NIGHTS_FLOAT}, // S_PLAY_NIGHTS_FLOAT
+	{SPR_PLAY, SPR2_NPAN, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_PAIN}, // S_PLAY_NIGHTS_PAIN
+	{SPR_PLAY, SPR2_NPUL, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_PULL}, // S_PLAY_NIGHTS_PULL
+	{SPR_PLAY, SPR2_NATK, 1, {NULL}, 0, 0, S_PLAY_NIGHTS_ATTACK}, // S_PLAY_NIGHTS_ATTACK
+
+	// NiGHTS Player, Flying and Drilling
+	{SPR_PLAY, SPR2_NGT0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY0},  // S_PLAY_NIGHTS_FLY0
+	{SPR_PLAY, SPR2_DRL0, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL0},  // S_PLAY_NIGHTS_DRILL0
+	{SPR_PLAY, SPR2_NGT1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY1},  // S_PLAY_NIGHTS_FLY1
+	{SPR_PLAY, SPR2_DRL1, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL1},  // S_PLAY_NIGHTS_DRILL1
+	{SPR_PLAY, SPR2_NGT2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY2},  // S_PLAY_NIGHTS_FLY2
+	{SPR_PLAY, SPR2_DRL2, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL2},  // S_PLAY_NIGHTS_DRILL2
+	{SPR_PLAY, SPR2_NGT3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY3},  // S_PLAY_NIGHTS_FLY3
+	{SPR_PLAY, SPR2_DRL3, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL3},  // S_PLAY_NIGHTS_DRILL3
+	{SPR_PLAY, SPR2_NGT4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY4},  // S_PLAY_NIGHTS_FLY4
+	{SPR_PLAY, SPR2_DRL4, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL4},  // S_PLAY_NIGHTS_DRILL4
+	{SPR_PLAY, SPR2_NGT5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY5},  // S_PLAY_NIGHTS_FLY5
+	{SPR_PLAY, SPR2_DRL5, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL5},  // S_PLAY_NIGHTS_DRILL5
+	{SPR_PLAY, SPR2_NGT6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY6},  // S_PLAY_NIGHTS_FLY6
+	{SPR_PLAY, SPR2_DRL6, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL6},  // S_PLAY_NIGHTS_DRILL6
+	{SPR_PLAY, SPR2_NGT7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY7},  // S_PLAY_NIGHTS_FLY7
+	{SPR_PLAY, SPR2_DRL7, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL7},  // S_PLAY_NIGHTS_DRILL7
+	{SPR_PLAY, SPR2_NGT8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY8},  // S_PLAY_NIGHTS_FLY8
+	{SPR_PLAY, SPR2_DRL8, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL8},  // S_PLAY_NIGHTS_DRILL8
+	{SPR_PLAY, SPR2_NGT9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLY9},  // S_PLAY_NIGHTS_FLY9
+	{SPR_PLAY, SPR2_DRL9, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILL9},  // S_PLAY_NIGHTS_DRILL9
+	{SPR_PLAY, SPR2_NGTA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYA},  // S_PLAY_NIGHTS_FLYA
+	{SPR_PLAY, SPR2_DRLA, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLA},  // S_PLAY_NIGHTS_DRILLA
+	{SPR_PLAY, SPR2_NGTB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYB},  // S_PLAY_NIGHTS_FLYB
+	{SPR_PLAY, SPR2_DRLB, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLB},  // S_PLAY_NIGHTS_DRILLB
+	{SPR_PLAY, SPR2_NGTC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_FLYC},  // S_PLAY_NIGHTS_FLYC
+	{SPR_PLAY, SPR2_DRLC, 2, {NULL}, 0, 0, S_PLAY_NIGHTS_DRILLC},  // S_PLAY_NIGHTS_DRILLC
+
 	// Blue Crawla
 	{SPR_POSS, 0, 5, {A_Look}, 0, 0, S_POSS_STND},   // S_POSS_STND
 	{SPR_POSS, 0, 3, {A_Chase}, 0, 0, S_POSS_RUN2},   // S_POSS_RUN1
@@ -2266,96 +2347,6 @@ state_t states[NUMSTATES] =
 	{SPR_GOAL, 2, 4, {NULL}, 0, 0, S_NIGHTSGOAL4}, // S_NIGHTSGOAL3
 	{SPR_GOAL, 3, 4, {NULL}, 0, 0, S_NIGHTSGOAL1}, // S_NIGHTSGOAL4
 
-	// Nights Player, Flying and Drilling
-	{SPR_SUPE, 0, 1, {NULL}, 0, 0, S_NIGHTSFLY1B},  // S_NIGHTSFLY1A
-	{SPR_SUPE, 1, 1, {NULL}, 0, 0, S_NIGHTSFLY1A},  // S_NIGHTSFLY1B
-	{SPR_NDRL, 0, 2, {NULL}, 0, 0, S_NIGHTSDRILL1B},  // S_NIGHTSDRILL1A
-	{SPR_NDRL, 1, 2, {NULL}, 0, 0, S_NIGHTSDRILL1C},  // S_NIGHTSDRILL1B
-	{SPR_NDRL, 2, 2, {NULL}, 0, 0, S_NIGHTSDRILL1D},  // S_NIGHTSDRILL1C
-	{SPR_NDRL, 3, 2, {NULL}, 0, 0, S_NIGHTSDRILL1A},  // S_NIGHTSDRILL1D
-	{SPR_SUPE, 2, 1, {NULL}, 0, 0, S_NIGHTSFLY2B},  // S_NIGHTSFLY2A
-	{SPR_SUPE, 3, 1, {NULL}, 0, 0, S_NIGHTSFLY2A},  // S_NIGHTSFLY2B
-	{SPR_NDRL, 4, 2, {NULL}, 0, 0, S_NIGHTSDRILL2B},  // S_NIGHTSDRILL2A
-	{SPR_NDRL, 5, 2, {NULL}, 0, 0, S_NIGHTSDRILL2C},  // S_NIGHTSDRILL2B
-	{SPR_NDRL, 6, 2, {NULL}, 0, 0, S_NIGHTSDRILL2D},  // S_NIGHTSDRILL2C
-	{SPR_NDRL, 7, 2, {NULL}, 0, 0, S_NIGHTSDRILL2A},  // S_NIGHTSDRILL2D
-	{SPR_SUPE, 4, 1, {NULL}, 0, 0, S_NIGHTSFLY3B},  // S_NIGHTSFLY3A
-	{SPR_SUPE, 5, 1, {NULL}, 0, 0, S_NIGHTSFLY3A},  // S_NIGHTSFLY3B
-	{SPR_NDRL, 8, 2, {NULL}, 0, 0, S_NIGHTSDRILL3B},  // S_NIGHTSDRILL3A
-	{SPR_NDRL, 9, 2, {NULL}, 0, 0, S_NIGHTSDRILL3C},  // S_NIGHTSDRILL3B
-	{SPR_NDRL, 10, 2, {NULL}, 0, 0, S_NIGHTSDRILL3D}, // S_NIGHTSDRILL3C
-	{SPR_NDRL, 11, 2, {NULL}, 0, 0, S_NIGHTSDRILL3A}, // S_NIGHTSDRILL3D
-	{SPR_SUPE, 6, 1, {NULL}, 0, 0, S_NIGHTSFLY4B},  // S_NIGHTSFLY4A
-	{SPR_SUPE, 7, 1, {NULL}, 0, 0, S_NIGHTSFLY4A},  // S_NIGHTSFLY4B
-	{SPR_NDRL, 12, 2, {NULL}, 0, 0, S_NIGHTSDRILL4B}, // S_NIGHTSDRILL4A
-	{SPR_NDRL, 13, 2, {NULL}, 0, 0, S_NIGHTSDRILL4C}, // S_NIGHTSDRILL4B
-	{SPR_NDRL, 14, 2, {NULL}, 0, 0, S_NIGHTSDRILL4D}, // S_NIGHTSDRILL4C
-	{SPR_NDRL, 15, 2, {NULL}, 0, 0, S_NIGHTSDRILL4A}, // S_NIGHTSDRILL4D
-	{SPR_SUPE, 8, 1, {NULL}, 0, 0, S_NIGHTSFLY5B},  // S_NIGHTSFLY5A
-	{SPR_SUPE, 9, 1, {NULL}, 0, 0, S_NIGHTSFLY5A},  // S_NIGHTSFLY5B
-	{SPR_NDRL, 16, 2, {NULL}, 0, 0, S_NIGHTSDRILL5B}, // S_NIGHTSDRILL5A
-	{SPR_NDRL, 17, 2, {NULL}, 0, 0, S_NIGHTSDRILL5C}, // S_NIGHTSDRILL5B
-	{SPR_NDRL, 18, 2, {NULL}, 0, 0, S_NIGHTSDRILL5D}, // S_NIGHTSDRILL5C
-	{SPR_NDRL, 19, 2, {NULL}, 0, 0, S_NIGHTSDRILL5A}, // S_NIGHTSDRILL5D
-	{SPR_SUPE, 10, 1, {NULL}, 0, 0, S_NIGHTSFLY6B}, // S_NIGHTSFLY6A
-	{SPR_SUPE, 11, 1, {NULL}, 0, 0, S_NIGHTSFLY6A}, // S_NIGHTSFLY6B
-	{SPR_NDRL, 20, 2, {NULL}, 0, 0, S_NIGHTSDRILL6B}, // S_NIGHTSDRILL6A
-	{SPR_NDRL, 21, 2, {NULL}, 0, 0, S_NIGHTSDRILL6C}, // S_NIGHTSDRILL6B
-	{SPR_NDRL, 22, 2, {NULL}, 0, 0, S_NIGHTSDRILL6D}, // S_NIGHTSDRILL6C
-	{SPR_NDRL, 23, 2, {NULL}, 0, 0, S_NIGHTSDRILL6A}, // S_NIGHTSDRILL6D
-	{SPR_SUPE, 12, 1, {NULL}, 0, 0, S_NIGHTSFLY7B}, // S_NIGHTSFLY7A
-	{SPR_SUPE, 13, 1, {NULL}, 0, 0, S_NIGHTSFLY7A}, // S_NIGHTSFLY7B
-	{SPR_NDRL, 24, 2, {NULL}, 0, 0, S_NIGHTSDRILL7B}, // S_NIGHTSDRILL7A
-	{SPR_NDRL, 25, 2, {NULL}, 0, 0, S_NIGHTSDRILL7C}, // S_NIGHTSDRILL7B
-	{SPR_NDRL, 26, 2, {NULL}, 0, 0, S_NIGHTSDRILL7D}, // S_NIGHTSDRILL7C
-	{SPR_NDRL, 27, 2, {NULL}, 0, 0, S_NIGHTSDRILL7A}, // S_NIGHTSDRILL7D
-	{SPR_SUPE, 14, 1, {NULL}, 0, 0, S_NIGHTSFLY8B}, // S_NIGHTSFLY8A
-	{SPR_SUPE, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY8A}, // S_NIGHTSFLY8B
-	{SPR_NDRL, 28, 2, {NULL}, 0, 0, S_NIGHTSDRILL8B}, // S_NIGHTSDRILL8A
-	{SPR_NDRL, 29, 2, {NULL}, 0, 0, S_NIGHTSDRILL8C}, // S_NIGHTSDRILL8B
-	{SPR_NDRL, 30, 2, {NULL}, 0, 0, S_NIGHTSDRILL8D}, // S_NIGHTSDRILL8C
-	{SPR_NDRL, 31, 2, {NULL}, 0, 0, S_NIGHTSDRILL8A}, // S_NIGHTSDRILL8D
-	{SPR_SUPE, 16, 1, {NULL}, 0, 0, S_NIGHTSFLY9B}, // S_NIGHTSFLY9A
-	{SPR_SUPE, 17, 1, {NULL}, 0, 0, S_NIGHTSFLY9A}, // S_NIGHTSFLY9B
-	{SPR_NDRL, 32, 2, {NULL}, 0, 0, S_NIGHTSDRILL9B}, // S_NIGHTSDRILL9A
-	{SPR_NDRL, 33, 2, {NULL}, 0, 0, S_NIGHTSDRILL9C}, // S_NIGHTSDRILL9B
-	{SPR_NDRL, 34, 2, {NULL}, 0, 0, S_NIGHTSDRILL9D}, // S_NIGHTSDRILL9C
-	{SPR_NDRL, 35, 2, {NULL}, 0, 0, S_NIGHTSDRILL9A}, // S_NIGHTSDRILL9D
-
-	// Nights Player, Falling
-	{SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT2},   // S_NIGHTSHURT1
-	{SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT3},   // S_NIGHTSHURT2
-	{SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT4},   // S_NIGHTSHURT3
-	{SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT5},   // S_NIGHTSHURT4
-	{SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT6},   // S_NIGHTSHURT5
-	{SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT7},   // S_NIGHTSHURT6
-	{SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT8},   // S_NIGHTSHURT7
-	{SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT9},   // S_NIGHTSHURT8
-	{SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT10},  // S_NIGHTSHURT9
-	{SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT11},  // S_NIGHTSHURT10
-	{SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT12}, // S_NIGHTSHURT11
-	{SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT13}, // S_NIGHTSHURT12
-	{SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT14}, // S_NIGHTSHURT13
-	{SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT15}, // S_NIGHTSHURT14
-	{SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT16}, // S_NIGHTSHURT15
-	{SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSHURT17}, // S_NIGHTSHURT16
-	{SPR_SUPZ, 0, 1, {NULL}, 0, 0, S_NIGHTSHURT18},  // S_NIGHTSHURT17
-	{SPR_SUPZ, 1, 1, {NULL}, 0, 0, S_NIGHTSHURT19},  // S_NIGHTSHURT18
-	{SPR_SUPZ, 2, 1, {NULL}, 0, 0, S_NIGHTSHURT20},  // S_NIGHTSHURT19
-	{SPR_SUPZ, 3, 1, {NULL}, 0, 0, S_NIGHTSHURT21},  // S_NIGHTSHURT20
-	{SPR_SUPZ, 4, 1, {NULL}, 0, 0, S_NIGHTSHURT22},  // S_NIGHTSHURT21
-	{SPR_SUPZ, 5, 1, {NULL}, 0, 0, S_NIGHTSHURT23},  // S_NIGHTSHURT22
-	{SPR_SUPZ, 6, 1, {NULL}, 0, 0, S_NIGHTSHURT24},  // S_NIGHTSHURT23
-	{SPR_SUPZ, 7, 1, {NULL}, 0, 0, S_NIGHTSHURT25},  // S_NIGHTSHURT24
-	{SPR_SUPZ, 8, 1, {NULL}, 0, 0, S_NIGHTSHURT26},  // S_NIGHTSHURT25
-	{SPR_SUPZ, 9, 1, {NULL}, 0, 0, S_NIGHTSHURT27},  // S_NIGHTSHURT26
-	{SPR_SUPZ, 10, 1, {NULL}, 0, 0, S_NIGHTSHURT28}, // S_NIGHTSHURT27
-	{SPR_SUPZ, 11, 1, {NULL}, 0, 0, S_NIGHTSHURT29}, // S_NIGHTSHURT28
-	{SPR_SUPZ, 12, 1, {NULL}, 0, 0, S_NIGHTSHURT30}, // S_NIGHTSHURT29
-	{SPR_SUPZ, 13, 1, {NULL}, 0, 0, S_NIGHTSHURT31}, // S_NIGHTSHURT30
-	{SPR_SUPZ, 14, 1, {NULL}, 0, 0, S_NIGHTSHURT32}, // S_NIGHTSHURT31
-	{SPR_SUPZ, 15, 1, {NULL}, 0, 0, S_NIGHTSFLY1A},  // S_NIGHTSHURT32
-
 	// Nights Sparkle
 	{SPR_NSPK, FF_FULLBRIGHT, 140, {NULL}, 0, 0, S_NIGHTSPARKLE2},   // S_NIGHTSPARKLE1
 	{SPR_NSPK, FF_FULLBRIGHT|1, 7, {NULL}, 0, 0, S_NIGHTSPARKLE3},   // S_NIGHTSPARKLE2
@@ -2458,16 +2449,6 @@ state_t states[NUMSTATES] =
 	{SPR_NULL, 0, 35, {NULL}, 0, 0, S_CRUMBLE2},  // S_CRUMBLE1
 	{SPR_NULL, 0, 105, {A_Scream}, 0, 0, S_NULL}, // S_CRUMBLE2
 
-	{SPR_SUPT,               0,  4, {A_Scream}, 0, 0,  S_SUPERTRANS2}, // S_SUPERTRANS1
-	{SPR_SUPT,               1,  4, {NULL}, 0, 0,  S_SUPERTRANS3}, // S_SUPERTRANS2
-	{SPR_SUPT, FF_FULLBRIGHT|2,  4, {NULL}, 0, 0,  S_SUPERTRANS4}, // S_SUPERTRANS3
-	{SPR_SUPT,               3,  3, {NULL}, 0, 0,  S_SUPERTRANS5}, // S_SUPERTRANS4
-	{SPR_SUPT,               4,  3, {NULL}, 0, 0,  S_SUPERTRANS6}, // S_SUPERTRANS5
-	{SPR_SUPT,               5,  3, {NULL}, 0, 0,  S_SUPERTRANS7}, // S_SUPERTRANS6
-	{SPR_SUPT,               6,  3, {NULL}, 0, 0,  S_SUPERTRANS8}, // S_SUPERTRANS7
-	{SPR_SUPT,               7,  3, {NULL}, 0, 0,  S_SUPERTRANS9}, // S_SUPERTRANS8
-	{SPR_SUPT,               8, 16, {NULL}, 0, 0, S_NIGHTSDRONE1}, // S_SUPERTRANS9
-
 	// Spark
 	{SPR_SPRK, FF_TRANS40  , 1, {NULL}, 0, 0, S_SPRK2},  // S_SPRK1
 	{SPR_SPRK, FF_TRANS50|1, 1, {NULL}, 0, 0, S_SPRK3},  // S_SPRK2
@@ -12185,33 +12166,6 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
 		S_NULL          // raisestate
 	},
 
-	{           // MT_NIGHTSCHAR
-		-1,             // doomednum
-		S_NIGHTSFLY1A,  // spawnstate
-		1000,           // spawnhealth
-		S_NULL,         // seestate
-		sfx_None,       // seesound
-		0,              // reactiontime
-		sfx_None,       // attacksound
-		S_NIGHTSFLY1A,  // painstate
-		255,            // painchance
-		sfx_None,       // painsound
-		S_NULL,         // meleestate
-		S_NULL,         // missilestate
-		S_NIGHTSFLY1A,  // deathstate
-		S_NULL,         // xdeathstate
-		sfx_None,       // deathsound
-		0,              // speed
-		16*FRACUNIT,    // radius
-		48*FRACUNIT,    // height
-		0,              // display offset
-		1000,           // mass
-		0,              // damage
-		sfx_None,       // activesound
-		MF_NOCLIP|MF_NOGRAVITY, // flags
-		S_NULL          // raisestate
-	},
-
 	{           // MT_NIGHTSPARKLE
 		-1,             // doomednum
 		S_NIGHTSPARKLE1,// spawnstate
diff --git a/src/info.h b/src/info.h
index 7a99d8b074473604e92e5848c5517f2dbb4a78a5..a700ad24edc09bea445932b7ec1e1ba24422a4c1 100644
--- a/src/info.h
+++ b/src/info.h
@@ -591,9 +591,9 @@ enum playersprite
 	SPR2_PEEL,
 	SPR2_PAIN,
 	SPR2_DEAD,
-	SPR2_DRWN,
+	SPR2_DRWN, // drown
 	SPR2_SPIN,
-	SPR2_DASH,
+	SPR2_DASH, // spindash charge
 	SPR2_GASP,
 	SPR2_JUMP,
 	SPR2_SPNG, // spring
@@ -601,38 +601,75 @@ enum playersprite
 	SPR2_EDGE,
 	SPR2_RIDE,
 
-	SPR2_SIGN,
-	SPR2_LIFE,
+	SPR2_SIGN, // end sign head
+	SPR2_LIFE, // life monitor icon
 
 	SPR2_FLY ,
 	SPR2_SWIM,
-	SPR2_TIRE,
-
-	SPR2_GLID,
-	SPR2_CLNG,
-	SPR2_CLMB,
-
-	SPR2_TWIN,
-
-	SPR2_MLEE,
-
-	SPR2_TRNS,
-	SPR2_SSTD,
-	SPR2_SWLK,
-	SPR2_SRUN,
-	SPR2_SPEE,
-	SPR2_SPAN,
-	SPR2_SMSL,
-	SPR2_SDTH,
-	SPR2_SDRN,
-	SPR2_SSPN,
-	SPR2_SGSP,
-	SPR2_SJMP,
-	SPR2_SSPG,
-	SPR2_SFAL,
-	SPR2_SEDG,
-	SPR2_SRID,
-	SPR2_SFLT,
+	SPR2_TIRE, // tired
+
+	SPR2_GLID, // glide
+	SPR2_CLNG, // cling
+	SPR2_CLMB, // climb
+
+	SPR2_TWIN, // twinspin
+
+	SPR2_MLEE, // melee
+
+	SPR2_TRNS, // super transformation
+	SPR2_SSTD, // super stand
+	SPR2_SWLK, // super walk
+	SPR2_SRUN, // super run
+	SPR2_SPEE, // super peelout
+	SPR2_SPAN, // super pain
+	SPR2_SSTN, // super stun
+	SPR2_SDTH, // super death
+	SPR2_SDRN, // super drown
+	SPR2_SSPN, // super spin
+	SPR2_SGSP, // super gasp
+	SPR2_SJMP, // super jump
+	SPR2_SSPG, // super spring
+	SPR2_SFAL, // super fall
+	SPR2_SEDG, // super edge
+	SPR2_SRID, // super ride
+	SPR2_SFLT, // super float
+
+	SPR2_NTRN, // NiGHTS transformation
+	SPR2_NSTD, // NiGHTS stand
+	SPR2_NFLT, // NiGHTS float
+	SPR2_NPAN, // NiGHTS pain
+	SPR2_NPUL, // NiGHTS pull
+	SPR2_NATK, // NiGHTS attack
+
+	// NiGHTS flight.
+	SPR2_NGT0,
+	SPR2_NGT1,
+	SPR2_NGT2,
+	SPR2_NGT3,
+	SPR2_NGT4,
+	SPR2_NGT5,
+	SPR2_NGT6,
+	SPR2_NGT7,
+	SPR2_NGT8,
+	SPR2_NGT9,
+	SPR2_NGTA,
+	SPR2_NGTB,
+	SPR2_NGTC,
+
+	// NiGHTS drill.
+	SPR2_DRL0,
+	SPR2_DRL1,
+	SPR2_DRL2,
+	SPR2_DRL3,
+	SPR2_DRL4,
+	SPR2_DRL5,
+	SPR2_DRL6,
+	SPR2_DRL7,
+	SPR2_DRL8,
+	SPR2_DRL9,
+	SPR2_DRLA,
+	SPR2_DRLB,
+	SPR2_DRLC,
 
 	SPR2_FIRSTFREESLOT,
 	SPR2_LASTFREESLOT = SPR2_FIRSTFREESLOT + NUMSPRITEFREESLOTS - 1,
@@ -733,6 +770,50 @@ typedef enum state
 	// Level end sign overlay (uses player sprite)
 	S_PLAY_SIGN,
 
+	// NiGHTS character (uses player sprite)
+	S_PLAY_NIGHTS_TRANS,
+	S_PLAY_NIGHTS_TRANS2,
+	S_PLAY_NIGHTS_TRANS3,
+	S_PLAY_NIGHTS_TRANS4,
+	S_PLAY_NIGHTS_TRANS5,
+	S_PLAY_NIGHTS_TRANS6,
+	S_PLAY_NIGHTS_TRANS7,
+	S_PLAY_NIGHTS_TRANS8,
+	S_PLAY_NIGHTS_TRANS9,
+
+	S_PLAY_NIGHTS_STAND,
+	S_PLAY_NIGHTS_FLOAT,
+	S_PLAY_NIGHTS_PAIN,
+	S_PLAY_NIGHTS_PULL,
+	S_PLAY_NIGHTS_ATTACK,
+
+	S_PLAY_NIGHTS_FLY0,
+	S_PLAY_NIGHTS_DRILL0,
+	S_PLAY_NIGHTS_FLY1,
+	S_PLAY_NIGHTS_DRILL1,
+	S_PLAY_NIGHTS_FLY2,
+	S_PLAY_NIGHTS_DRILL2,
+	S_PLAY_NIGHTS_FLY3,
+	S_PLAY_NIGHTS_DRILL3,
+	S_PLAY_NIGHTS_FLY4,
+	S_PLAY_NIGHTS_DRILL4,
+	S_PLAY_NIGHTS_FLY5,
+	S_PLAY_NIGHTS_DRILL5,
+	S_PLAY_NIGHTS_FLY6,
+	S_PLAY_NIGHTS_DRILL6,
+	S_PLAY_NIGHTS_FLY7,
+	S_PLAY_NIGHTS_DRILL7,
+	S_PLAY_NIGHTS_FLY8,
+	S_PLAY_NIGHTS_DRILL8,
+	S_PLAY_NIGHTS_FLY9,
+	S_PLAY_NIGHTS_DRILL9,
+	S_PLAY_NIGHTS_FLYA,
+	S_PLAY_NIGHTS_DRILLA,
+	S_PLAY_NIGHTS_FLYB,
+	S_PLAY_NIGHTS_DRILLB,
+	S_PLAY_NIGHTS_FLYC,
+	S_PLAY_NIGHTS_DRILLC,
+
 	// Blue Crawla
 	S_POSS_STND,
 	S_POSS_RUN1,
@@ -2728,93 +2809,6 @@ typedef enum state
 	S_NIGHTSGOAL3,
 	S_NIGHTSGOAL4,
 
-	S_NIGHTSFLY1A,
-	S_NIGHTSFLY1B,
-	S_NIGHTSDRILL1A,
-	S_NIGHTSDRILL1B,
-	S_NIGHTSDRILL1C,
-	S_NIGHTSDRILL1D,
-	S_NIGHTSFLY2A,
-	S_NIGHTSFLY2B,
-	S_NIGHTSDRILL2A,
-	S_NIGHTSDRILL2B,
-	S_NIGHTSDRILL2C,
-	S_NIGHTSDRILL2D,
-	S_NIGHTSFLY3A,
-	S_NIGHTSFLY3B,
-	S_NIGHTSDRILL3A,
-	S_NIGHTSDRILL3B,
-	S_NIGHTSDRILL3C,
-	S_NIGHTSDRILL3D,
-	S_NIGHTSFLY4A,
-	S_NIGHTSFLY4B,
-	S_NIGHTSDRILL4A,
-	S_NIGHTSDRILL4B,
-	S_NIGHTSDRILL4C,
-	S_NIGHTSDRILL4D,
-	S_NIGHTSFLY5A,
-	S_NIGHTSFLY5B,
-	S_NIGHTSDRILL5A,
-	S_NIGHTSDRILL5B,
-	S_NIGHTSDRILL5C,
-	S_NIGHTSDRILL5D,
-	S_NIGHTSFLY6A,
-	S_NIGHTSFLY6B,
-	S_NIGHTSDRILL6A,
-	S_NIGHTSDRILL6B,
-	S_NIGHTSDRILL6C,
-	S_NIGHTSDRILL6D,
-	S_NIGHTSFLY7A,
-	S_NIGHTSFLY7B,
-	S_NIGHTSDRILL7A,
-	S_NIGHTSDRILL7B,
-	S_NIGHTSDRILL7C,
-	S_NIGHTSDRILL7D,
-	S_NIGHTSFLY8A,
-	S_NIGHTSFLY8B,
-	S_NIGHTSDRILL8A,
-	S_NIGHTSDRILL8B,
-	S_NIGHTSDRILL8C,
-	S_NIGHTSDRILL8D,
-	S_NIGHTSFLY9A,
-	S_NIGHTSFLY9B,
-	S_NIGHTSDRILL9A,
-	S_NIGHTSDRILL9B,
-	S_NIGHTSDRILL9C,
-	S_NIGHTSDRILL9D,
-	S_NIGHTSHURT1,
-	S_NIGHTSHURT2,
-	S_NIGHTSHURT3,
-	S_NIGHTSHURT4,
-	S_NIGHTSHURT5,
-	S_NIGHTSHURT6,
-	S_NIGHTSHURT7,
-	S_NIGHTSHURT8,
-	S_NIGHTSHURT9,
-	S_NIGHTSHURT10,
-	S_NIGHTSHURT11,
-	S_NIGHTSHURT12,
-	S_NIGHTSHURT13,
-	S_NIGHTSHURT14,
-	S_NIGHTSHURT15,
-	S_NIGHTSHURT16,
-	S_NIGHTSHURT17,
-	S_NIGHTSHURT18,
-	S_NIGHTSHURT19,
-	S_NIGHTSHURT20,
-	S_NIGHTSHURT21,
-	S_NIGHTSHURT22,
-	S_NIGHTSHURT23,
-	S_NIGHTSHURT24,
-	S_NIGHTSHURT25,
-	S_NIGHTSHURT26,
-	S_NIGHTSHURT27,
-	S_NIGHTSHURT28,
-	S_NIGHTSHURT29,
-	S_NIGHTSHURT30,
-	S_NIGHTSHURT31,
-	S_NIGHTSHURT32,
-
 	S_NIGHTSPARKLE1,
 	S_NIGHTSPARKLE2,
 	S_NIGHTSPARKLE3,
@@ -2911,16 +2905,6 @@ typedef enum state
 	S_CRUMBLE1,
 	S_CRUMBLE2,
 
-	S_SUPERTRANS1,
-	S_SUPERTRANS2,
-	S_SUPERTRANS3,
-	S_SUPERTRANS4,
-	S_SUPERTRANS5,
-	S_SUPERTRANS6,
-	S_SUPERTRANS7,
-	S_SUPERTRANS8,
-	S_SUPERTRANS9,
-
 	// Spark
 	S_SPRK1,
 	S_SPRK2,
@@ -3496,7 +3480,6 @@ typedef enum mobj_type
 	MT_AXISTRANSFERLINE,
 	MT_NIGHTSDRONE,
 	MT_NIGHTSGOAL,
-	MT_NIGHTSCHAR,
 	MT_NIGHTSPARKLE,
 	MT_NIGHTSLOOPHELPER,
 	MT_NIGHTSBUMPER, // NiGHTS Bumper
diff --git a/src/lua_skinlib.c b/src/lua_skinlib.c
index 7ff21151c7250c9cad3e5bf204a1cd4198700311..f93513c49c52677b585616968f1ce59c550bd9ff 100644
--- a/src/lua_skinlib.c
+++ b/src/lua_skinlib.c
@@ -51,6 +51,7 @@ enum skin {
 	skin_camerascale,
 	skin_starttranscolor,
 	skin_prefcolor,
+	skin_supercolor,
 	skin_prefoppositecolor,
 	skin_highresscale,
 	skin_soundsid,
@@ -88,6 +89,7 @@ static const char *const skin_opt[] = {
 	"camerascale",
 	"starttranscolor",
 	"prefcolor",
+	"supercolor",
 	"prefoppositecolor",
 	"highresscale",
 	"soundsid",
@@ -208,6 +210,9 @@ static int skin_get(lua_State *L)
 	case skin_prefcolor:
 		lua_pushinteger(L, skin->prefcolor);
 		break;
+	case skin_supercolor:
+		lua_pushinteger(L, skin->supercolor);
+		break;
 	case skin_prefoppositecolor:
 		lua_pushinteger(L, skin->prefoppositecolor);
 		break;
diff --git a/src/p_enemy.c b/src/p_enemy.c
index aa38c9818ec0530fcd7cf866da3dc4a9b9144859..07246d69b18edf915692cb63d1c50a7f7b834028 100644
--- a/src/p_enemy.c
+++ b/src/p_enemy.c
@@ -8039,7 +8039,7 @@ void A_OrbitNights(mobj_t* actor)
 #endif
 
 	if (!actor->target || !actor->target->player ||
-	    !actor->target->tracer || !actor->target->player->nightstime
+	    !(actor->target->player->pflags & PF_NIGHTSMODE) || !actor->target->player->nightstime
 	    // Also remove this object if they no longer have a NiGHTS helper
 		|| (ishelper && !actor->target->player->powers[pw_nights_helper]))
 	{
@@ -8058,14 +8058,21 @@ void A_OrbitNights(mobj_t* actor)
 			const fixed_t fh = FixedMul(FINECOSINE(ofa),FixedMul(20*FRACUNIT, actor->scale));
 			const fixed_t fs = FixedMul(FINESINE(fa),FixedMul(32*FRACUNIT, actor->scale));
 
-			actor->x = actor->target->tracer->x + fc;
-			actor->y = actor->target->tracer->y + fs;
-			actor->z = actor->target->tracer->z + fh + FixedMul(16*FRACUNIT, actor->scale);
+			actor->x = actor->target->x + fc;
+			actor->y = actor->target->y + fs;
+			actor->z = actor->target->z + fh + FixedMul(16*FRACUNIT, actor->scale);
 
 			// Semi-lazy hack
 			actor->angle = (angle_t)actor->extravalue1 + ANGLE_90;
 		}
 		P_SetThingPosition(actor);
+
+		if (ishelper // Flash a helper that's about to be removed.
+		&& (actor->target->player->powers[pw_nights_helper] < TICRATE)
+		&& (actor->target->player->powers[pw_nights_helper] & 1))
+			actor->flags2 |= MF2_DONTDRAW;
+		else
+			actor->flags2 &= ~MF2_DONTDRAW;
 	}
 }
 
diff --git a/src/p_inter.c b/src/p_inter.c
index 5f538ee8d2f3273f1ab9853536b5c9855915799c..936747ce6601aa81a229013ef81b1428a945894d 100644
--- a/src/p_inter.c
+++ b/src/p_inter.c
@@ -652,16 +652,16 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
 				if (G_IsSpecialStage(gamemap)) //After-mare bonus time/emerald reward in special stages.
 				{
 					// only allow the player with the emerald in-hand to leave.
-					if (toucher->tracer && toucher->tracer->target
-					&& toucher->tracer->target->type == MT_GOTEMERALD)
+					if (toucher->tracer
+					&& toucher->tracer->type == MT_GOTEMERALD)
 					{
 					}
 					else // Make sure that SOMEONE has the emerald, at least!
 					{
 						for (i = 0; i < MAXPLAYERS; i++)
 							if (playeringame[i] && players[i].playerstate == PST_LIVE
-							&& players[i].mo->tracer && players[i].mo->tracer->target
-							&& players[i].mo->tracer->target->type == MT_GOTEMERALD)
+							&& players[i].mo->tracer
+							&& players[i].mo->tracer->type == MT_GOTEMERALD)
 								return;
 						// Well no one has an emerald, so exit anyway!
 					}
@@ -2487,7 +2487,7 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source)
 		}
 
 		player->powers[pw_flashing] = flashingtics;
-		P_SetMobjState(target->tracer, S_NIGHTSHURT1);
+		P_SetPlayerMobjState(target, S_PLAY_NIGHTS_PAIN);
 		S_StartSound(target, sfx_nghurt);
 
 		if (oldnightstime > 10*TICRATE
diff --git a/src/p_mobj.c b/src/p_mobj.c
index f006cb53dd3f293c3618da021d76e0d3d872a716..730af9003a3b1152287db696d909a1a73f2a515c 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -173,10 +173,6 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 	else if (state == S_PLAY_SWIM && !(player->mo->eflags & MFE_UNDERWATER))
 		return P_SetPlayerMobjState(player->mo, S_PLAY_FLY);
 
-	// Catch melee into goop
-	//if (state == S_PLAY_MELEE && player->mo->eflags & MFE_GOOWATER)
-		//return P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
-
 	// Catch state changes for Super Sonic
 	if (player->powers[pw_super] && (player->charflags & SF_SUPERANIMS))
 	{
@@ -439,7 +435,7 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 				case SPR2_SPAN:
 					spr2 = SPR2_PAIN;
 					break;
-				case SPR2_SMSL:
+				case SPR2_SSTN:
 					spr2 = SPR2_SPAN;
 					break;
 				case SPR2_SDTH:
@@ -473,6 +469,81 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 					spr2 = SPR2_SWLK;
 					break;
 
+				// NiGHTS sprites.
+				case SPR2_NTRN:
+					spr2 = SPR2_TRNS;
+					break;
+				case SPR2_NSTD:
+					spr2 = SPR2_SSTD;
+					break;
+				case SPR2_NFLT:
+					spr2 = (skin->flags & SF_SUPERANIMS) ? SPR2_SFLT : SPR2_FALL; // This is skin-exclusive so the default NiGHTS skin changing system plays nice.
+					break;
+				case SPR2_NPUL:
+					spr2 = SPR2_NFLT;
+					break;
+				case SPR2_NPAN:
+					spr2 = SPR2_NPUL;
+					break;
+				case SPR2_NATK:
+					spr2 = SPR2_SSPN;
+					break;
+				/*case SPR2_NGT0:
+					spr2 = SPR2_STND;
+					break;*/
+				case SPR2_NGT1:
+				case SPR2_NGT7:
+				case SPR2_DRL0:
+					spr2 = SPR2_NGT0;
+					break;
+				case SPR2_NGT2:
+				case SPR2_DRL1:
+					spr2 = SPR2_NGT1;
+					break;
+				case SPR2_NGT3:
+				case SPR2_DRL2:
+					spr2 = SPR2_NGT2;
+					break;
+				case SPR2_NGT4:
+				case SPR2_DRL3:
+					spr2 = SPR2_NGT3;
+					break;
+				case SPR2_NGT5:
+				case SPR2_DRL4:
+					spr2 = SPR2_NGT4;
+					break;
+				case SPR2_NGT6:
+				case SPR2_DRL5:
+					spr2 = SPR2_NGT5;
+					break;
+				case SPR2_DRL6:
+					spr2 = SPR2_NGT6;
+					break;
+				case SPR2_NGT8:
+				case SPR2_DRL7:
+					spr2 = SPR2_NGT7;
+					break;
+				case SPR2_NGT9:
+				case SPR2_DRL8:
+					spr2 = SPR2_NGT8;
+					break;
+				case SPR2_NGTA:
+				case SPR2_DRL9:
+					spr2 = SPR2_NGT9;
+					break;
+				case SPR2_NGTB:
+				case SPR2_DRLA:
+					spr2 = SPR2_NGTA;
+					break;
+				case SPR2_NGTC:
+				case SPR2_DRLB:
+					spr2 = SPR2_NGTB;
+					break;
+				case SPR2_DRLC:
+					spr2 = SPR2_NGTC;
+					break;
+
+
 				// Sprites for non-player objects? There's nothing we can do.
 				case SPR2_SIGN:
 				case SPR2_LIFE:
@@ -526,6 +597,8 @@ boolean P_SetPlayerMobjState(mobj_t *mobj, statenum_t state)
 
 			mobj->sprite2 = spr2;
 			mobj->frame = frame|(st->frame&~FF_FRAMEMASK);
+			if (mobj->color > MAXSKINCOLORS) // Super colours? Super bright!
+				mobj->frame |= FF_FULLBRIGHT;
 		}
 		// Regular sprites
 		else
diff --git a/src/p_user.c b/src/p_user.c
index e694d08a1666b12a222c0b38900779fcd1941e49..cf265b645e3a72c5bf06d8441602c084cc828db2 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -576,9 +576,6 @@ static void P_DeNightserizePlayer(player_t *player)
 
 	player->pflags &= ~PF_NIGHTSMODE;
 
-	//if (player->mo->tracer)
-		//P_RemoveMobj(player->mo->tracer);
-
 	player->powers[pw_underwater] = 0;
 	player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING|PF_TRANSFERTOCLOSEST);
 	player->secondjump = 0;
@@ -592,7 +589,8 @@ static void P_DeNightserizePlayer(player_t *player)
 
 	player->mo->flags &= ~MF_NOGRAVITY;
 
-	player->mo->flags2 &= ~MF2_DONTDRAW;
+	player->mo->skin = &skins[player->skin];
+	player->mo->color = player->skincolor;
 
 	// Restore aiming angle
 	if (player == &players[consoleplayer])
@@ -603,8 +601,6 @@ static void P_DeNightserizePlayer(player_t *player)
 	// If you screwed up, kiss your score goodbye.
 	player->marescore = 0;
 
-	if (player->mo->tracer)
-		P_RemoveMobj(player->mo->tracer);
 	P_SetPlayerMobjState(player->mo, S_PLAY_FALL);
 	player->pflags |= PF_NIGHTSFALL;
 
@@ -638,6 +634,9 @@ static void P_DeNightserizePlayer(player_t *player)
 	// Restore from drowning music
 	P_RestoreMusic(player);
 }
+
+#define DEFAULTNIGHTSSKIN 0
+
 //
 // P_NightserizePlayer
 //
@@ -652,11 +651,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
 
 	if (!(player->pflags & PF_NIGHTSMODE))
 	{
-		P_SetTarget(&player->mo->tracer, P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z, MT_NIGHTSCHAR));
-		player->mo->tracer->destscale = player->mo->scale;
-		P_SetScale(player->mo->tracer, player->mo->scale);
-		player->mo->tracer->eflags = (player->mo->tracer->eflags & ~MFE_VERTICALFLIP)|(player->mo->eflags & MFE_VERTICALFLIP);
-		player->mo->height = player->mo->tracer->height;
+		player->mo->radius = 16*FRACUNIT;
+		player->mo->height = 48*FRACUNIT;
 	}
 
 	player->pflags &= ~(PF_USEDOWN|PF_JUMPDOWN|PF_ATTACKDOWN|PF_STARTDASH|PF_GLIDING|PF_JUMPED|PF_THOKKED|PF_SPINNING|PF_DRILLING);
@@ -670,13 +666,17 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
 
 	player->mo->flags |= MF_NOGRAVITY;
 
-	player->mo->flags2 |= MF2_DONTDRAW;
+	if (skins[player->skin].sprites[SPR2_NGT0].numframes == 0) // If you don't have a sprite for flying horizontally, use the default NiGHTS skin.
+	{
+		player->mo->skin = &skins[DEFAULTNIGHTSSKIN];
+		player->mo->color = ((skin_t *)(player->mo->skin))->prefcolor;
+	}
 
 	player->nightstime = player->startedtime = nighttime*TICRATE;
 	player->bonustime = false;
 
 	P_RestoreMusic(player);
-	P_SetMobjState(player->mo->tracer, S_SUPERTRANS1);
+	P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS);
 
 	if (gametype == GT_RACE || gametype == GT_COMPETITION)
 	{
@@ -772,6 +772,8 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime)
 	player->pflags |= PF_NIGHTSMODE;
 }
 
+#undef DEFAULTNIGHTSSKIN
+
 //
 // P_PlayerInPain
 //
@@ -4999,13 +5001,13 @@ static void P_NightsTransferPoints(player_t *player, fixed_t xspeed, fixed_t rad
 		return;
 
 	// You're welcome, Rob. (Now with slightly less horrendous hacking  -Red
-	player->mo->tracer->flags &= ~MF_NOCLIP;
+	/*player->mo->tracer->flags &= ~MF_NOCLIP;
 	player->mo->tracer->z = player->mo->z;
 	if (!P_TryMove(player->mo->tracer, player->mo->x+player->mo->momx, player->mo->y+player->mo->momy, true)) {
 		player->mo->tracer->flags |= MF_NOCLIP;
 		return;
 	}
-	player->mo->tracer->flags |= MF_NOCLIP;
+	player->mo->tracer->flags |= MF_NOCLIP;*/
 	{
 		const INT32 sequence = player->mo->target->threshold;
 		mobj_t *transfer1 = NULL;
@@ -5395,10 +5397,6 @@ static void P_DoNiGHTSCapsule(player_t *player)
 {
 	INT32 i;
 
-	if ((player->pflags & PF_NIGHTSMODE) && (player->mo->tracer->state < &states[S_NIGHTSHURT1]
-		|| player->mo->tracer->state > &states[S_NIGHTSHURT32]))
-		P_SetMobjState(player->mo->tracer, S_NIGHTSHURT1);
-
 	if (abs(player->mo->x-player->capsule->x) <= 2*FRACUNIT)
 	{
 		P_UnsetThingPosition(player->mo);
@@ -5436,6 +5434,20 @@ static void P_DoNiGHTSCapsule(player_t *player)
 	else if (player->mo->z < player->capsule->z+(player->capsule->height/3))
 		player->mo->momz = 2*FRACUNIT;
 
+	if (player->pflags & PF_NIGHTSMODE)
+	{
+		if (player->mo->momx || player->mo->momy || player->mo->momz)
+		{
+			if (player->mo->state != &states[S_PLAY_NIGHTS_PULL])
+				P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_PULL);
+		}
+		else if (player->mo->state != &states[S_PLAY_NIGHTS_ATTACK])
+		{
+			S_StartSound(player->mo, sfx_spin);
+			P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_ATTACK);
+		}
+	}
+
 	if (G_IsSpecialStage(gamemap))
 	{ // In special stages, share rings. Everyone gives up theirs to the capsule player always, because we can't have any individualism here!
 		for (i = 0; i < MAXPLAYERS; i++)
@@ -5465,7 +5477,7 @@ static void P_DoNiGHTSCapsule(player_t *player)
 				S_StartSound(P_SpawnMobj(player->capsule->x + ((P_SignedRandom()/2)<<FRACBITS),
 				player->capsule->y + ((P_SignedRandom()/2)<<FRACBITS),
 				player->capsule->z + (player->capsule->height/2) + ((P_SignedRandom()/2)<<FRACBITS),
-				MT_EXPLODE),sfx_pop);
+				MT_BOSSEXPLODE),sfx_cybdth);
 
 			if (player->capsule->health <= 0)
 			{
@@ -5503,13 +5515,13 @@ static void P_DoNiGHTSCapsule(player_t *player)
 						P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
 					}*/
 
-					if (player->mo->tracer)
+					if (player->pflags & PF_NIGHTSMODE)
 					{
 						// Only give it to ONE person, and THAT player has to get to the goal!
 						emmo = P_SpawnMobj(player->mo->x, player->mo->y, player->mo->z + player->mo->info->height, MT_GOTEMERALD);
 						P_SetTarget(&emmo->target, player->mo);
 						P_SetMobjState(emmo, mobjinfo[MT_GOTEMERALD].meleestate + em);
-						P_SetTarget(&player->mo->tracer->target, emmo);
+						P_SetTarget(&player->mo->tracer, emmo);
 					}
 
 					// Okay, we're doing this down here because we're handling time weirdly for co-op special stages
@@ -5568,7 +5580,8 @@ static void P_NiGHTSMovement(player_t *player)
 	ticcmd_t *cmd = &player->cmd;
 	INT32 thrustfactor;
 	INT32 i;
-	statenum_t flystate = S_NIGHTSFLY1A;
+	statenum_t flystate;
+	UINT16 visangle;
 
 	player->pflags &= ~PF_DRILLING;
 
@@ -5587,7 +5600,7 @@ static void P_NiGHTSMovement(player_t *player)
 			player->drillmeter = TICRATE/10;
 	}
 
-	if (!player->mo->tracer)
+	if (!(player->pflags & PF_NIGHTSMODE))
 	{
 		P_DeNightserizePlayer(player);
 		return;
@@ -5602,13 +5615,14 @@ static void P_NiGHTSMovement(player_t *player)
 			&& (players[i].capsule && players[i].capsule->reactiontime))
 				capsule = true;
 		if (!capsule
-		&& !(player->mo->tracer->state >= &states[S_SUPERTRANS1]
-			&& player->mo->tracer->state <= &states[S_SUPERTRANS9])
+		&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+			&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
 		&& !player->exiting)
 			player->nightstime--;
 	}
 	else if (gametype != GT_RACE && gametype != GT_COMPETITION
-	&& !(player->mo->tracer->state >= &states[S_SUPERTRANS1] && player->mo->tracer->state <= &states[S_SUPERTRANS9])
+	&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+			&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
 	&& !(player->capsule && player->capsule->reactiontime)
 	&& !player->exiting)
 		player->nightstime--;
@@ -5693,8 +5707,6 @@ static void P_NiGHTSMovement(player_t *player)
 	radius = player->mo->target->radius;
 
 	player->mo->flags |= MF_NOGRAVITY;
-	player->mo->flags2 |= MF2_DONTDRAW;
-	P_SetScale(player->mo->tracer, player->mo->scale);
 
 	if (player->mo->eflags & MFE_VERTICALFLIP)
 		cmd->forwardmove = (SINT8)(-cmd->forwardmove);
@@ -5749,8 +5761,8 @@ static void P_NiGHTSMovement(player_t *player)
 		return;
 	}
 
-	if (player->mo->tracer->state >= &states[S_SUPERTRANS1]
-		&& player->mo->tracer->state <= &states[S_SUPERTRANS9])
+	if (player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+		&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9])
 	{
 		player->mo->momx = player->mo->momy = player->mo->momz = 0;
 		return;
@@ -5761,16 +5773,13 @@ static void P_NiGHTSMovement(player_t *player)
 		player->mo->momx = player->mo->momy = 0;
 
 		if (gametype != GT_RACE && gametype != GT_COMPETITION)
-			P_SetObjectMomZ(player->mo, 30*FRACUNIT, false);
-
-		player->mo->tracer->angle += ANGLE_11hh;
+			P_SetObjectMomZ(player->mo, FRACUNIT/2, true);
 
-		if (!(player->mo->tracer->state  >= &states[S_NIGHTSDRONE1]
-			&& player->mo->tracer->state <= &states[S_NIGHTSDRONE2]))
-			P_SetMobjState(player->mo->tracer, S_NIGHTSDRONE1);
+		if (player->mo->state  != &states[S_PLAY_NIGHTS_DRILL6])
+			P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_DRILL6);
 
-		player->mo->tracer->flags |= MF_NOCLIPHEIGHT;
 		player->mo->flags |= MF_NOCLIPHEIGHT;
+
 		return;
 	}
 
@@ -6036,74 +6045,41 @@ static void P_NiGHTSMovement(player_t *player)
 
 	// NiGHTS flying state
 	// Yep, I just ripped out almost 1000 lines of code.
-	if      ((player->anotherflyangle >=  12 && player->anotherflyangle <=  33)  // +x +y
-	      || (player->anotherflyangle >= 147 && player->anotherflyangle <= 168)) // -x +y
-		flystate = S_NIGHTSFLY2A;
-	else if ((player->anotherflyangle >=  34 && player->anotherflyangle <=  56)  // +x +y
-	      || (player->anotherflyangle >= 124 && player->anotherflyangle <= 146)) // -x +y
-		flystate = S_NIGHTSFLY3A;
-	else if ((player->anotherflyangle >=  57 && player->anotherflyangle <=  79)  // +x +y
-	      || (player->anotherflyangle >= 102 && player->anotherflyangle <= 123)) // -x +y
-		flystate = S_NIGHTSFLY4A;
-	else if  (player->anotherflyangle >=  80 && player->anotherflyangle <= 101)
-		flystate = S_NIGHTSFLY5A;
-	else if ((player->anotherflyangle >= 192 && player->anotherflyangle <= 213)  // -x -y
-	      || (player->anotherflyangle >= 327 && player->anotherflyangle <= 348)) // +x -y
-		flystate = S_NIGHTSFLY6A;
-	else if ((player->anotherflyangle >= 214 && player->anotherflyangle <= 236)  // -x -y
-	      || (player->anotherflyangle >= 305 && player->anotherflyangle <= 326)) // +x -y
-		flystate = S_NIGHTSFLY7A;
-	else if ((player->anotherflyangle >= 237 && player->anotherflyangle <= 258)  // -x -y
-	      || (player->anotherflyangle >= 282 && player->anotherflyangle <= 304)) // +x -y
-		flystate = S_NIGHTSFLY8A;
-	else if  (player->anotherflyangle >= 259 && player->anotherflyangle <= 281)
-		flystate = S_NIGHTSFLY9A;
+	// (and then toast revamped the entire thing again to be better, but not by much)
+	if (still)
+		flystate = (P_IsObjectOnGround(player->mo)) ? S_PLAY_NIGHTS_STAND : S_PLAY_NIGHTS_FLOAT;
 	else
-		flystate = S_NIGHTSFLY1A;
-
-	if (player->mo->eflags & MFE_VERTICALFLIP)
 	{
-		if (flystate >= S_NIGHTSFLY2A && flystate <= S_NIGHTSFLY5A)
-			flystate += 24; // shift to S_NIGHTSFLY6A
-		else if (flystate >= S_NIGHTSFLY6A && flystate <= S_NIGHTSFLY9A)
-			flystate -= 24; // shift to S_NIGHTSFLY2A
-	}
+		visangle = ((player->anotherflyangle + 7) % 360)/15;
+		if (visangle > 18) // Over 270 degrees.
+			visangle = 30 - visangle;
+		else if (visangle > 12) // Over 180 degrees.
+			visangle -= 6;
+		else if (visangle > 6) // Over 90 degrees.
+			visangle = 12 - visangle;
 
-	if (player->pflags & PF_DRILLING)
-	{
-		const statenum_t drillstate = flystate + 2;
-
-		if (!(player->mo->tracer->state >= &states[drillstate]
-		 && player->mo->tracer->state <= &states[drillstate+4]))
+		if (player->mo->eflags & MFE_VERTICALFLIP && visangle) // S_PLAY_NIGHTS_FLY0 stays the same, even in reverse gravity
 		{
-			if (!(player->mo->tracer->state >= &states[S_NIGHTSFLY1A]
-			 && player->mo->tracer->state <= &states[S_NIGHTSFLY9B]))
-			{
-				const INT32 framenum = player->mo->tracer->state->frame & 3;
-
-				if (framenum == 3) // Drilld special case
-					P_SetMobjStateNF(player->mo->tracer, drillstate);
-				else
-					P_SetMobjStateNF(player->mo->tracer, drillstate+framenum+1);
-			}
+			if (visangle > 6)
+				visangle -= 6; // shift to S_PLAY_NIGHTS_FLY1-6
 			else
-				P_SetMobjStateNF(player->mo->tracer, drillstate);
+				visangle += 6; // shift to S_PLAY_NIGHTS_FLY7-C
 		}
+
+		flystate = S_PLAY_NIGHTS_FLY0 + (visangle*2); // S_PLAY_FLY0-C - the *2 is to skip over drill states
+
+		if (player->pflags & PF_DRILLING)
+			flystate++; // shift to S_PLAY_NIGHTS_DRILL0-C
 	}
-	else
-		P_SetMobjStateNF(player->mo->tracer, leveltime & 1 ? flystate : flystate+1);
+
+	if (player->mo->state != &states[flystate])
+		P_SetPlayerMobjState(player->mo, flystate);
 
 	if (player == &players[consoleplayer])
 		localangle = player->mo->angle;
 	else if (player == &players[secondarydisplayplayer])
 		localangle2 = player->mo->angle;
 
-	if (still)
-	{
-		P_SetMobjStateNF(player->mo->tracer, S_NIGHTSDRONE1);
-		player->mo->tracer->angle = player->mo->angle;
-	}
-
 	// Check for crushing in our new location
 	if ((player->mo->ceilingz - player->mo->floorz < player->mo->height)
 		&& !(player->mo->flags & MF_NOCLIP))
@@ -6127,8 +6103,6 @@ static void P_NiGHTSMovement(player_t *player)
 	else if (player == &players[secondarydisplayplayer])
 		localaiming2 = movingangle;
 
-	player->mo->tracer->angle = player->mo->angle;
-
 	if ((player->pflags & PF_DRILLING) && !player->bumpertime)
 	{
 		if (firstdrill)
@@ -6433,6 +6407,15 @@ static void P_MovePlayer(player_t *player)
 	// Locate the capsule for this mare.
 	else if (maptol & TOL_NIGHTS)
 	{
+		if ((player->pflags & PF_NIGHTSMODE)
+		&& !(player->mo->state >= &states[S_PLAY_NIGHTS_TRANS]
+		&& player->mo->state <= &states[S_PLAY_NIGHTS_TRANS9]
+		&& !(player->exiting)))
+		{
+			skin_t *skin = ((skin_t *)(player->mo->skin));
+			player->mo->color = (skin->flags & SF_SUPER) ? skin->supercolor + (unsigned)abs(((signed)(leveltime >> 1) % 9) - 4) : player->mo->color; // This is where super flashing is handled.
+		}
+
 		if (!player->capsule && !player->bonustime)
 		{
 			thinker_t *th;
@@ -9063,19 +9046,6 @@ void P_PlayerThink(player_t *player)
 		else
 			player->pflags &= ~PF_USEDOWN;
 	}
-	else if (player->mo->tracer) // match tracer's position with yours when NiGHTS
-	{
-		P_UnsetThingPosition(player->mo->tracer);
-		player->mo->tracer->x = player->mo->x;
-		player->mo->tracer->y = player->mo->y;
-		if (player->mo->eflags & MFE_VERTICALFLIP)
-			player->mo->tracer->z = player->mo->z + player->mo->height - player->mo->tracer->height;
-		else
-			player->mo->tracer->z = player->mo->z;
-		player->mo->tracer->floorz = player->mo->floorz;
-		player->mo->tracer->ceilingz = player->mo->ceilingz;
-		P_SetThingPosition(player->mo->tracer);
-	}
 
 	// Counters, time dependent power ups.
 	// Time Bonus & Ring Bonus count settings
@@ -9172,20 +9142,10 @@ void P_PlayerThink(player_t *player)
 		player->losstime--;
 
 	// Flash player after being hit.
-	if (!(player->pflags & PF_NIGHTSMODE))
-	{
-		if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1))
-			player->mo->flags2 |= MF2_DONTDRAW;
-		else
-			player->mo->flags2 &= ~MF2_DONTDRAW;
-	}
-	else if (player->mo->tracer)
-	{
-		if (player->powers[pw_flashing] & 1)
-			player->mo->tracer->flags2 |= MF2_DONTDRAW;
-		else
-			player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
-	}
+	if (player->powers[pw_flashing] > 0 && player->powers[pw_flashing] < flashingtics && (leveltime & 1))
+		player->mo->flags2 |= MF2_DONTDRAW;
+	else
+		player->mo->flags2 &= ~MF2_DONTDRAW;
 
 	player->pflags &= ~PF_SLIDING;
 
diff --git a/src/r_things.c b/src/r_things.c
index 4ef67f18f4742df6bedff627550eb8c719a6df98..783304868f70e9db44fd0ed2264f81db2c6effa4 100644
--- a/src/r_things.c
+++ b/src/r_things.c
@@ -2357,7 +2357,7 @@ static void Sk_SetDefaultValue(skin_t *skin)
 	skin->jumpfactor = FRACUNIT;
 	skin->actionspd = 30<<FRACBITS;
 	skin->mindash = 15<<FRACBITS;
-	skin->maxdash = 90<<FRACBITS;
+	skin->maxdash = 70<<FRACBITS;
 
 	skin->radius = mobjinfo[MT_PLAYER].radius;
 	skin->height = mobjinfo[MT_PLAYER].height;