diff --git a/src/d_player.h b/src/d_player.h
index 4b29785464c2ce023e52635dad676d240ddbe7bd..3bced1a8b6d1c11560ae4ccffd0278bc38a4beb2 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -38,6 +38,7 @@ typedef enum
 	SF_HIRES            = 1<<3, // Draw the sprite 2x as small?
 	SF_NOSKID           = 1<<4, // No skid particles etc
 	SF_NOSPEEDADJUST    = 1<<5, // Skin-specific version of disablespeedadjust
+	SF_RUNONWATER       = 1<<6, // Run on top of water FOFs?
 } skinflags_t;
 
 //Primary and secondary skin abilities
@@ -55,7 +56,8 @@ typedef enum
 	CA_TELEKINESIS,
 	CA_FALLSWITCH,
 	CA_JUMPBOOST,
-	CA_AIRDRILL
+	CA_AIRDRILL,
+	CA_JUMPTHOK
 } charability_t;
 
 //Secondary skin abilities
diff --git a/src/dehacked.c b/src/dehacked.c
index 9c2fe4d22a1c5bfffe3e0f595a7283ed0f2d3e38..37bd529504b18f06cef5631975997ec63532428c 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -7507,6 +7507,7 @@ struct {
 	{"SF_HIRES",SF_HIRES},
 	{"SF_NOSKID",SF_NOSKID},
 	{"SF_NOSPEEDADJUST",SF_NOSPEEDADJUST},
+	{"SF_RUNONWATER",SF_RUNONWATER},
 
 	// Character abilities!
 	// Primary
@@ -7523,6 +7524,7 @@ struct {
 	{"CA_FALLSWITCH",CA_FALLSWITCH},
 	{"CA_JUMPBOOST",CA_JUMPBOOST},
 	{"CA_AIRDRILL",CA_AIRDRILL},
+	{"CA_JUMPTHOK",CA_JUMPTHOK},
 	// Secondary
 	{"CA2_NONE",CA2_NONE}, // now slot 0!
 	{"CA2_SPINDASH",CA2_SPINDASH},
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 29ba5d04308e18e0d95e3adb6a3ba1dbb3ba5900..eaf57e57d39cd3774b7516739a74564da454abfd 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -2398,7 +2398,7 @@ static boolean P_SceneryZMovement(mobj_t *mo)
 boolean P_CanRunOnWater(player_t *player, ffloor_t *rover)
 {
 	if (!(player->pflags & PF_NIGHTSMODE) && !player->homing
-		&& (((player->charability == CA_SWIM) || player->powers[pw_super]) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
+		&& (((player->charability == CA_SWIM) || player->powers[pw_super] || player->charflags & SF_RUNONWATER) && player->mo->ceilingz-*rover->topheight >= player->mo->height)
 		&& (rover->flags & FF_SWIMMABLE) && !(player->pflags & PF_SPINNING) && player->speed > FixedMul(player->runspeed, player->mo->scale)
 		&& !(player->pflags & PF_SLIDING)
 		&& abs(player->mo->z - *rover->topheight) < FixedMul(30*FRACUNIT, player->mo->scale))
diff --git a/src/p_user.c b/src/p_user.c
index 57c8fac6ad72456355397785bb3c6655fe06b286..8549d51d59d99bc1523c716296fd4814ac10f54e 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3733,6 +3733,7 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
 			{
 				case CA_THOK:
 				case CA_HOMINGTHOK:
+				case CA_JUMPTHOK: // Credit goes to CZ64 and Sryder13 for the original
 					// Now it's Sonic's abilities turn!
 					if (player->pflags & PF_JUMPED)
 					{
@@ -3742,12 +3743,19 @@ static void P_DoJumpStuff(player_t *player, ticcmd_t *cmd)
 							P_DoSuperTransformation(player, false);
 						else // Otherwise, THOK!
 						{
-							if (!(player->pflags & PF_THOKKED) || (player->charability2 == CA2_MULTIABILITY))
+							if (!(player->pflags & PF_THOKKED) || ((player->charability2 == CA2_MULTIABILITY) && (!(player->charability == CA_JUMPTHOK))))
 							{
 								// Catapult the player
 								fixed_t actionspd = player->actionspd;
 								if (player->mo->eflags & MFE_UNDERWATER)
 									actionspd >>= 1;
+								if (player->charability == CA_JUMPTHOK)
+								{
+									if ((actionspd == 60*FRACUNIT) && (actionspd > player->normalspeed)) //Limit only at default
+										actionspd = player->normalspeed;
+									player->pflags &= ~PF_JUMPED;
+									P_DoJump(player, false);
+								}
 								P_InstaThrust(player->mo, player->mo->angle, FixedMul(actionspd, player->mo->scale));
 
 								if (maptol & TOL_2D)