diff --git a/extras/conf/udb/Includes/SRB222_misc.cfg b/extras/conf/udb/Includes/SRB222_misc.cfg
index 6d64aea813acdd5f0bf35318577fa8304b6243d4..52cd22322f1c93086462302c31291f7dcaf8aed4 100644
--- a/extras/conf/udb/Includes/SRB222_misc.cfg
+++ b/extras/conf/udb/Includes/SRB222_misc.cfg
@@ -79,6 +79,7 @@ sectorflags
 	triggerspecial_touch = "Trigger on Edge Touch";
 	triggerspecial_headbump = "Trigger on Headbump";
 	invertprecip = "Invert Precipitation";
+	heatwave = "Heat Wave";
 }
 
 thingflags
diff --git a/src/deh_lua.c b/src/deh_lua.c
index ae062695c0c985bc15bfcc395983692b6d3c6b9a..28030052a86eacdda0a1c89a78b8cb9eade97a48 100644
--- a/src/deh_lua.c
+++ b/src/deh_lua.c
@@ -340,7 +340,7 @@ static inline int lib_getenum(lua_State *L)
 	}
 	else if (fastncmp("MSF_", word, 3)) {
 		p = word + 4;
-		for (i = 0; i < 4; i++)
+		for (i = 0; i < 5; i++)
 			if (MSF_LIST[i] && fastcmp(p, MSF_LIST[i])) {
 				lua_pushinteger(L, ((lua_Integer)1 << i));
 				return 1;
diff --git a/src/deh_tables.c b/src/deh_tables.c
index 73cf7068eb826fbb0bc0d88e97441222f4b61af4..b6a9e02254ff422c5b457dd5f372e2cb34cb3279 100644
--- a/src/deh_tables.c
+++ b/src/deh_tables.c
@@ -4472,11 +4472,12 @@ const char *const ML_LIST[16] = {
 };
 
 // Sector flags
-const char *const MSF_LIST[4] = {
+const char *const MSF_LIST[5] = {
 	"FLIPSPECIAL_FLOOR",
 	"FLIPSPECIAL_CEILING",
 	"TRIGGERSPECIAL_TOUCH",
 	"TRIGGERSPECIAL_HEADBUMP",
+	"HEATWAVE",
 };
 
 const char *COLOR_ENUMS[] = {
diff --git a/src/deh_tables.h b/src/deh_tables.h
index 77260d50711abdc52cbb51c610ec6b54795b1e58..982c6ff4a3dccb4985b0bef5ba80714aab73c34b 100644
--- a/src/deh_tables.h
+++ b/src/deh_tables.h
@@ -65,7 +65,7 @@ extern const char *const MAPTHINGFLAG_LIST[4];
 extern const char *const PLAYERFLAG_LIST[];
 extern const char *const GAMETYPERULE_LIST[];
 extern const char *const ML_LIST[16]; // Linedef flags
-extern const char* const MSF_LIST[4]; // Sector flags
+extern const char* const MSF_LIST[5]; // Sector flags
 extern const char *COLOR_ENUMS[];
 extern const char *const POWERS_LIST[];
 extern const char *const HUDITEMS_LIST[];
diff --git a/src/p_mobj.c b/src/p_mobj.c
index 47a70233b0988a058caa5d5911c57df2de76bdb9..428274679e5c373368d4eb923fdb99aff562f848 100644
--- a/src/p_mobj.c
+++ b/src/p_mobj.c
@@ -3551,19 +3551,16 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
 {
 	sector_t *sector;
 	fixed_t halfheight = thiscam->z + (thiscam->height >> 1);
-	size_t i;
 
 	// see if we are in water
 	sector = thiscam->subsector->sector;
 
-	for (i = 0; i < sector->tags.count; i++)
-		if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1)
-			return true;
+	if (sector->flags & MSF_HEATWAVE)
+		return true;
 
 	if (sector->ffloors)
 	{
 		ffloor_t *rover;
-		size_t j;
 
 		for (rover = sector->ffloors; rover; rover = rover->next)
 		{
@@ -3575,8 +3572,7 @@ static boolean P_CameraCheckHeat(camera_t *thiscam)
 			if (halfheight <= P_GetFFloorBottomZAt(rover, thiscam->x, thiscam->y))
 				continue;
 
-			for (j = 0; j < rover->master->frontsector->tags.count; j++)
-			if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1)
+			if (rover->master->frontsector->flags & MSF_HEATWAVE)
 				return true;
 		}
 	}
diff --git a/src/p_setup.c b/src/p_setup.c
index 987f4f6f5a0ac6823413b6262decfbba065a9a3a..ec35ad824ab5c29b050ef3d66f0b7b5f95350850 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -1672,6 +1672,8 @@ static void ParseTextmapSectorParameter(UINT32 i, char *param, char *val)
 		sectors[i].flags |= MSF_TRIGGERSPECIAL_HEADBUMP;
 	else if (fastcmp(param, "invertprecip") && fastcmp("true", val))
 		sectors[i].flags |= MSF_INVERTPRECIP;
+	else if (fastcmp(param, "heatwave") && fastcmp("true", val))
+		sectors[i].flags |= MSF_HEATWAVE;
 }
 
 static void ParseTextmapSidedefParameter(UINT32 i, char *param, char *val)
@@ -3282,6 +3284,15 @@ static void P_ConvertBinaryMap(void)
 			lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
 			lines[i].args[2] = !!(lines[i].flags & ML_EFFECT1);
 			break;
+		case 13: //Heat wave effect
+		{
+			INT32 s;
+
+			TAG_ITER_SECTORS(tag, s)
+				sectors[s].flags |= MSF_HEATWAVE;
+
+			break;
+		}
 		case 14: //Bustable block parameters
 			lines[i].args[0] = sides[lines[i].sidenum[0]].textureoffset >> FRACBITS;
 			lines[i].args[1] = sides[lines[i].sidenum[0]].rowoffset >> FRACBITS;
diff --git a/src/p_user.c b/src/p_user.c
index 60000afa0a8b8d14a2fb5c80fa8c5da17853307d..8adb6ef9b672f0ee0f8d25bfe8f4a8efb34f79e8 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -10466,7 +10466,6 @@ static void P_CalcPostImg(player_t *player)
 	postimg_t *type;
 	INT32 *param;
 	fixed_t pviewheight;
-	size_t i;
 
 	if (player->mo->eflags & MFE_VERTICALFLIP)
 		pviewheight = player->mo->z + player->mo->height - player->viewheight;
@@ -10491,45 +10490,30 @@ static void P_CalcPostImg(player_t *player)
 	}
 
 	// see if we are in heat (no, not THAT kind of heat...)
-	for (i = 0; i < sector->tags.count; i++)
+	if (sector->flags & MSF_HEATWAVE)
+		*type = postimg_heat;
+	else if (sector->ffloors)
 	{
-		if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1)
-		{
-			*type = postimg_heat;
-			break;
-		}
-		else if (sector->ffloors)
-		{
-			ffloor_t *rover;
-			fixed_t topheight;
-			fixed_t bottomheight;
-			boolean gotres = false;
-
-			for (rover = sector->ffloors; rover; rover = rover->next)
-			{
-				size_t j;
+		ffloor_t *rover;
+		fixed_t topheight;
+		fixed_t bottomheight;
 
-				if (!(rover->flags & FF_EXISTS))
-					continue;
+		for (rover = sector->ffloors; rover; rover = rover->next)
+		{
+			if (!(rover->flags & FF_EXISTS))
+				continue;
 
-				topheight    = P_GetFFloorTopZAt   (rover, player->mo->x, player->mo->y);
-				bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
+			topheight    = P_GetFFloorTopZAt   (rover, player->mo->x, player->mo->y);
+			bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
 
-				if (pviewheight >= topheight || pviewheight <= bottomheight)
-					continue;
+			if (pviewheight >= topheight || pviewheight <= bottomheight)
+				continue;
 
-				for (j = 0; j < rover->master->frontsector->tags.count; j++)
-				{
-					if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1)
-					{
-						*type = postimg_heat;
-						gotres = true;
-						break;
-					}
-				}
-			}
-			if (gotres)
+			if (rover->master->frontsector->flags & MSF_HEATWAVE)
+			{
+				*type = postimg_heat;
 				break;
+			}
 		}
 	}
 
diff --git a/src/r_defs.h b/src/r_defs.h
index c10428431a55cf81754e3c88346039395d79e687..16c4ad64f7b9b821074adf97a4278feab387c613 100644
--- a/src/r_defs.h
+++ b/src/r_defs.h
@@ -284,6 +284,7 @@ typedef enum
 	MSF_TRIGGERSPECIAL_HEADBUMP =  1<<3,
 	// invertprecip - inverts presence of precipitation
 	MSF_INVERTPRECIP            =  1<<4,
+	MSF_HEATWAVE                =  1<<5, // heat wave effect
 } sectorflags_t;