diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 556d8638433dfe9b83580630dfcff9ce8726dbe5..01e94485d85696736fa334ecbe40225ba77b66da 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -513,6 +513,10 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
 	rsp->currentweapon = LONG(players[i].currentweapon);
 	rsp->ringweapons = LONG(players[i].ringweapons);
 
+	rsp->ammoremoval = (UINT16)SHORT(players[i].ammoremoval);
+	rsp->ammoremovaltimer = (tic_t)LONG(players[i].ammoremovaltimer);
+	rsp->ammoremovalweapon = LONG(players[i].ammoremovalweapon);
+
 	for (j = 0; j < NUMPOWERS; ++j)
 		rsp->powers[j] = (UINT16)SHORT(players[i].powers[j]);
 
@@ -644,6 +648,10 @@ static void resynch_read_player(resynch_pak *rsp)
 	players[i].currentweapon = LONG(rsp->currentweapon);
 	players[i].ringweapons = LONG(rsp->ringweapons);
 
+	players[i].ammoremoval = (UINT16)SHORT(rsp->ammoremoval);
+	players[i].ammoremovaltimer = (tic_t)LONG(rsp->ammoremovaltimer);
+	players[i].ammoremovalweapon = LONG(rsp->ammoremovalweapon);
+
 	for (j = 0; j < NUMPOWERS; ++j)
 		players[i].powers[j] = (UINT16)SHORT(rsp->powers[j]);
 
diff --git a/src/d_clisrv.h b/src/d_clisrv.h
index a6783fb3d120982ae61477f1f86f1b1cc5f57a6f..a2f140f330a2fad15e362cb7deb632f87ba667f6 100644
--- a/src/d_clisrv.h
+++ b/src/d_clisrv.h
@@ -164,6 +164,9 @@ typedef struct
 	angle_t aiming;
 	INT32 currentweapon;
 	INT32 ringweapons;
+	UINT16 ammoremoval;
+	tic_t ammoremovaltimer;
+	INT32 ammoremovalweapon;
 	UINT16 powers[NUMPOWERS];
 
 	// Score is resynched in the confirm resync packet
diff --git a/src/d_player.h b/src/d_player.h
index c133af7039cac5b02ef609be63b8f1fadbc19453..5860cf1de4b05f86b7567c4d87c3699475513c71 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -333,6 +333,10 @@ typedef struct player_s
 	INT32 currentweapon; // current weapon selected.
 	INT32 ringweapons; // weapons currently obtained.
 
+	UINT16 ammoremoval; // amount of ammo removed for the current weapon.
+	tic_t  ammoremovaltimer; // flashing counter for ammo used.
+	INT32  ammoremovalweapon; // weapon from which the ammo was removed.
+
 	// Power ups. invinc and invis are tic counters.
 	UINT16 powers[NUMPOWERS];
 
diff --git a/src/dehacked.c b/src/dehacked.c
index 04ac2ef4b5e3f4d455e416442f96cb1399633d93..5db61a5b5ea22eb508d097d1a6683d52bd5c3517 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -3347,6 +3347,10 @@ static void readmaincfg(MYFILE *f)
 			{
 				gameovertics = get_number(word2);
 			}
+			else if (fastcmp(word, "AMMOREMOVALTICS"))
+			{
+				ammoremovaltics = get_number(word2);
+			}
 			else if (fastcmp(word, "INTROTOPLAY"))
 			{
 				introtoplay = (UINT8)get_number(word2);
diff --git a/src/g_game.c b/src/g_game.c
index 576ea0c33579d9f562bebbb2c8565db59b939229..d5faf68468cc2b1b0f01a09083210a6cb7dd2da6 100644
--- a/src/g_game.c
+++ b/src/g_game.c
@@ -217,6 +217,8 @@ UINT16 nightslinktics = 2*TICRATE;
 
 INT32 gameovertics = 15*TICRATE;
 
+UINT8 ammoremovaltics = 2*TICRATE;
+
 UINT8 use1upSound = 0;
 UINT8 maxXtraLife = 2; // Max extra lives from rings
 
diff --git a/src/g_game.h b/src/g_game.h
index 4b63bc180afcb0908e5ffeefddb907cb07d098a7..e161bc8ed4a7cf11eefe93bbf6715825426b582c 100644
--- a/src/g_game.h
+++ b/src/g_game.h
@@ -51,6 +51,7 @@ extern tic_t levelstarttic;
 // for modding?
 extern INT16 prevmap, nextmap;
 extern INT32 gameovertics;
+extern UINT8 ammoremovaltics;
 extern tic_t timeinmap; // Ticker for time spent in level (used for levelcard display)
 extern INT16 rw_maximums[NUM_WEAPONS];
 extern INT32 pausedelay;
diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c
index b7bdaa1be87a078974490fe569e171c15906b319..addd707e16da8e86254cedb7393788091678744f 100644
--- a/src/lua_playerlib.c
+++ b/src/lua_playerlib.c
@@ -136,6 +136,12 @@ static int player_get(lua_State *L)
 		lua_pushinteger(L, plr->currentweapon);
 	else if (fastcmp(field,"ringweapons"))
 		lua_pushinteger(L, plr->ringweapons);
+	else if (fastcmp(field,"ammoremoval"))
+		lua_pushinteger(L, plr->ammoremoval);
+	else if (fastcmp(field,"ammoremovaltimer"))
+		lua_pushinteger(L, plr->ammoremovaltimer);
+	else if (fastcmp(field,"ammoremovalweapon"))
+		lua_pushinteger(L, plr->ammoremovalweapon);
 	else if (fastcmp(field,"powers"))
 		LUA_PushUserdata(L, plr->powers, META_POWERS);
 	else if (fastcmp(field,"pflags"))
@@ -428,6 +434,12 @@ static int player_set(lua_State *L)
 		plr->currentweapon = (INT32)luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"ringweapons"))
 		plr->ringweapons = (INT32)luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"ammoremoval"))
+		plr->ammoremoval = (UINT16)luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"ammoremovaltimer"))
+		plr->ammoremovaltimer = (tic_t)luaL_checkinteger(L, 3);
+	else if (fastcmp(field,"ammoremovalweapon"))
+		plr->ammoremovalweapon = (INT32)luaL_checkinteger(L, 3);
 	else if (fastcmp(field,"powers"))
 		return NOSET;
 	else if (fastcmp(field,"pflags"))
diff --git a/src/p_saveg.c b/src/p_saveg.c
index ea998b445e40c90135d0454ce412367373fc42d8..7c073b1514762b74ab6d352d2cdbebb755670ff1 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -125,6 +125,10 @@ static void P_NetArchivePlayers(void)
 		WRITEINT32(save_p, players[i].currentweapon);
 		WRITEINT32(save_p, players[i].ringweapons);
 
+		WRITEUINT16(save_p, players[i].ammoremoval);
+		WRITEUINT32(save_p, players[i].ammoremovaltimer);
+		WRITEINT32(save_p, players[i].ammoremovaltimer);
+
 		for (j = 0; j < NUMPOWERS; j++)
 			WRITEUINT16(save_p, players[i].powers[j]);
 
@@ -329,6 +333,10 @@ static void P_NetUnArchivePlayers(void)
 		players[i].currentweapon = READINT32(save_p);
 		players[i].ringweapons = READINT32(save_p);
 
+		players[i].ammoremoval = READUINT16(save_p);
+		players[i].ammoremovaltimer = READUINT32(save_p);
+		players[i].ammoremovalweapon = READINT32(save_p);
+
 		for (j = 0; j < NUMPOWERS; j++)
 			players[i].powers[j] = READUINT16(save_p);
 
diff --git a/src/p_user.c b/src/p_user.c
index 65f93a11cbb5d4f4e37f69aa6f0220842f03d2cd..09c8e36c07eacb4c1b781539d38f3af27642bb6f 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -3900,6 +3900,33 @@ static void P_SetWeaponDelay(player_t *player, INT32 delay)
 	}
 }
 
+//
+// P_DrainWeaponAmmo
+//
+// Reduces rings and weapon ammo. Also penalizes the player
+// for using weapon rings with no normal rings! >:V
+//
+static void P_DrainWeaponAmmo (player_t *player, INT32 power)
+{
+	player->powers[power]--;
+
+	if (player->rings < 1)
+	{
+		player->ammoremovalweapon = player->currentweapon;
+		player->ammoremovaltimer  = ammoremovaltics;
+
+		if (player->powers[power] > 0) // can't take a ring that doesn't exist
+		{
+			player->powers[power]--;
+			player->ammoremoval = 2;
+		}
+		else
+			player->ammoremoval = 1;
+	}
+	else
+		player->rings--;
+}
+
 //
 // P_DoFiring()
 //
@@ -3938,22 +3965,12 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 
 	player->pflags |= PF_ATTACKDOWN;
 
-#define TAKE_AMMO(player, power) \
-		player->powers[power]--; \
-		if (player->rings < 1) \
-		{ \
-			if (player->powers[power] > 0) \
-				player->powers[power]--; \
-		} \
-		else \
-			player->rings--;
-
 	if (cmd->buttons & BT_FIRENORMAL) // No powers, just a regular ring.
 		goto firenormal; //code repetition sucks.
 	// Bounce ring
 	else if (player->currentweapon == WEP_BOUNCE && player->powers[pw_bouncering])
 	{
-		TAKE_AMMO(player, pw_bouncering);
+		P_DrainWeaponAmmo(player, pw_bouncering);
 		P_SetWeaponDelay(player, TICRATE/4);
 
 		mo = P_SpawnPlayerMissile(player->mo, MT_THROWNBOUNCE, MF2_BOUNCERING);
@@ -3964,7 +3981,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 	// Rail ring
 	else if (player->currentweapon == WEP_RAIL && player->powers[pw_railring])
 	{
-		TAKE_AMMO(player, pw_railring);
+		P_DrainWeaponAmmo(player, pw_railring);
 		P_SetWeaponDelay(player, (3*TICRATE)/2);
 
 		mo = P_SpawnPlayerMissile(player->mo, MT_REDRING, MF2_RAILRING|MF2_DONTDRAW);
@@ -3975,7 +3992,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 	// Automatic
 	else if (player->currentweapon == WEP_AUTO && player->powers[pw_automaticring])
 	{
-		TAKE_AMMO(player, pw_automaticring);
+		P_DrainWeaponAmmo(player, pw_automaticring);
 		player->pflags &= ~PF_ATTACKDOWN;
 		P_SetWeaponDelay(player, 2);
 
@@ -3984,7 +4001,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 	// Explosion
 	else if (player->currentweapon == WEP_EXPLODE && player->powers[pw_explosionring])
 	{
-		TAKE_AMMO(player, pw_explosionring);
+		P_DrainWeaponAmmo(player, pw_explosionring);
 		P_SetWeaponDelay(player, (3*TICRATE)/2);
 
 		mo = P_SpawnPlayerMissile(player->mo, MT_THROWNEXPLOSION, MF2_EXPLOSION);
@@ -3992,7 +4009,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 	// Grenade
 	else if (player->currentweapon == WEP_GRENADE && player->powers[pw_grenadering])
 	{
-		TAKE_AMMO(player, pw_grenadering);
+		P_DrainWeaponAmmo(player, pw_grenadering);
 		P_SetWeaponDelay(player, TICRATE/3);
 
 		mo = P_SpawnPlayerMissile(player->mo, MT_THROWNGRENADE, MF2_EXPLOSION);
@@ -4011,7 +4028,7 @@ static void P_DoFiring(player_t *player, ticcmd_t *cmd)
 		angle_t shotangle = player->mo->angle;
 		angle_t oldaiming = player->aiming;
 
-		TAKE_AMMO(player, pw_scatterring);
+		P_DrainWeaponAmmo(player, pw_scatterring);
 		P_SetWeaponDelay(player, (2*TICRATE)/3);
 
 		// Center
@@ -4073,8 +4090,6 @@ firenormal:
 		}
 	}
 
-	#undef TAKE_AMMO
-
 	if (mo)
 	{
 		if (mo->flags & MF_MISSILE && mo->flags2 & MF2_RAILRING)
@@ -11332,6 +11347,12 @@ void P_PlayerThink(player_t *player)
 	// Counters, time dependent power ups.
 	// Time Bonus & Ring Bonus count settings
 
+	if (player->ammoremovaltimer)
+	{
+		if (--player->ammoremovaltimer == 0)
+			player->ammoremoval = 0;
+	}
+
 	// Strength counts up to diminish fade.
 	if (player->powers[pw_sneakers] && player->powers[pw_sneakers] < UINT16_MAX)
 		player->powers[pw_sneakers]--;
diff --git a/src/st_stuff.c b/src/st_stuff.c
index aefb4c53c70badbc2a9b85e178b4cdceb2b704dc..142cd3e61f8c261703d9b2121165b3b95960dc5e 100644
--- a/src/st_stuff.c
+++ b/src/st_stuff.c
@@ -1960,6 +1960,7 @@ static void ST_drawWeaponRing(powertype_t weapon, INT32 rwflag, INT32 wepflag, I
 
 static void ST_drawMatchHUD(void)
 {
+	char penaltystr[5];
 	const INT32 y = 176; // HUD_LIVES
 	INT32 offset = (BASEVIDWIDTH / 2) - (NUM_WEAPONS * 10) - 6;
 
@@ -1986,18 +1987,20 @@ static void ST_drawMatchHUD(void)
 				ST_drawWeaponSelect(offset, y);
 		}
 
-		offset += 20;
-		ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset, y, autoring);
-		offset += 20;
-		ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset, y, bouncering);
-		offset += 20;
-		ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset, y, scatterring);
-		offset += 20;
-		ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset, y, grenadering);
-		offset += 20;
-		ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset, y, explosionring);
-		offset += 20;
-		ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset, y, railring);
+		ST_drawWeaponRing(pw_automaticring, RW_AUTO, WEP_AUTO, offset + 20, y, autoring);
+		ST_drawWeaponRing(pw_bouncering, RW_BOUNCE, WEP_BOUNCE, offset + 40, y, bouncering);
+		ST_drawWeaponRing(pw_scatterring, RW_SCATTER, WEP_SCATTER, offset + 60, y, scatterring);
+		ST_drawWeaponRing(pw_grenadering, RW_GRENADE, WEP_GRENADE, offset + 80, y, grenadering);
+		ST_drawWeaponRing(pw_explosionring, RW_EXPLODE, WEP_EXPLODE, offset + 100, y, explosionring);
+		ST_drawWeaponRing(pw_railring, RW_RAIL, WEP_RAIL, offset + 120, y, railring);
+
+		if (stplyr->ammoremovaltimer && leveltime % 8 < 4)
+		{
+			sprintf(penaltystr, "-%d", stplyr->ammoremoval);
+			V_DrawString(offset + 8 + stplyr->ammoremovalweapon * 20, y,
+					V_REDMAP, penaltystr);
+		}
+
 	}
 }