diff --git a/specs/udmf_zdoom.txt b/specs/udmf_zdoom.txt
index bdd70322eb..4fc57f8565 100644
--- a/specs/udmf_zdoom.txt
+++ b/specs/udmf_zdoom.txt
@@ -186,6 +186,7 @@ Note: All <bool> fields default to false unless mentioned otherwise.
       soundsequence = <string>;       // The sound sequence to play when this sector moves. Placing a
                                       // sound sequence thing in the sector will override this property.
       hidden = <bool>;                // if true this sector will not be drawn on the textured automap.
+      waterzone = <bool>;             // Sector is under water and swimmable
       
       * Note about dropactors
 
@@ -328,6 +329,9 @@ Added back locknumber property.
 1.20 25.02.2012
 Added arg0str thing property.
 
+1.21 09.08.2013
+Added waterzone sector property.
+
 ===============================================================================
 EOF
 ===============================================================================
diff --git a/src/d_player.h b/src/d_player.h
index 892adeebf1..75ed533d90 100644
--- a/src/d_player.h
+++ b/src/d_player.h
@@ -141,6 +141,7 @@ public:
 	FNameNoInit	MorphWeapon;
 	fixed_t		AttackZOffset;			// attack height, relative to player center
 	fixed_t		UseRange;				// [NS] Distance at which player can +use
+	fixed_t		AirCapacity;			// Multiplier for air supply underwater.
 	const PClass *FlechetteType;
 
 	// [CW] Fades for when you are being damaged.
diff --git a/src/g_doom/a_archvile.cpp b/src/g_doom/a_archvile.cpp
index e2fb689c2a..8fce33324f 100644
--- a/src/g_doom/a_archvile.cpp
+++ b/src/g_doom/a_archvile.cpp
@@ -101,15 +101,20 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileTarget)
 //
 // A_VileAttack
 //
+
+// A_VileAttack flags
+#define VAF_DMGTYPEAPPLYTODIRECT 1
+
 DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
 {		
-	ACTION_PARAM_START(6);
+	ACTION_PARAM_START(7);
 	ACTION_PARAM_SOUND(snd,0);
 	ACTION_PARAM_INT(dmg,1);
 	ACTION_PARAM_INT(blastdmg,2);
 	ACTION_PARAM_INT(blastrad,3);
 	ACTION_PARAM_FIXED(thrust,4);
 	ACTION_PARAM_NAME(dmgtype,5);
+	ACTION_PARAM_INT(flags,6);
 
 	AActor *fire, *target;
 	angle_t an;
@@ -123,7 +128,15 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_VileAttack)
 		return;
 
 	S_Sound (self, CHAN_WEAPON, snd, 1, ATTN_NORM);
-	int newdam = P_DamageMobj (target, self, self, dmg, NAME_None);
+
+	int newdam;
+
+	if (flags & VAF_DMGTYPEAPPLYTODIRECT)
+		newdam = P_DamageMobj (target, self, self, dmg, dmgtype);
+
+	else
+		newdam = P_DamageMobj (target, self, self, dmg, NAME_None);
+
 	P_TraceBleed (newdam > 0 ? newdam : dmg, target);
 		
 	an = self->angle >> ANGLETOFINESHIFT;
diff --git a/src/namedef.h b/src/namedef.h
index 44fe35e79a..f2d601eb5a 100644
--- a/src/namedef.h
+++ b/src/namedef.h
@@ -442,6 +442,7 @@ xx(Alphafloor)
 xx(Alphaceiling)
 xx(Renderstylefloor)
 xx(Renderstyleceiling)
+xx(Waterzone)
 
 xx(offsetx_top)
 xx(offsety_top)
diff --git a/src/p_acs.cpp b/src/p_acs.cpp
index d061d451ae..4cb949539e 100644
--- a/src/p_acs.cpp
+++ b/src/p_acs.cpp
@@ -3512,6 +3512,8 @@ enum
 	APROP_Radius		= 36,
 	APROP_ReactionTime  = 37,
 	APROP_MeleeRange	= 38,
+	APROP_ViewHeight	= 39,
+	APROP_AttackZOffset	= 40
 };
 
 // These are needed for ACS's APROP_RenderStyle
@@ -3727,6 +3729,16 @@ void DLevelScript::DoSetActorProperty (AActor *actor, int property, int value)
 		actor->reactiontime = value;
 		break;
 
+	case APROP_ViewHeight:
+		if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
+			static_cast<APlayerPawn *>(actor)->ViewHeight = value;
+		break;
+
+	case APROP_AttackZOffset:
+		if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
+			static_cast<APlayerPawn *>(actor)->AttackZOffset = value;
+		break;
+
 	default:
 		// do nothing.
 		break;
@@ -3799,6 +3811,23 @@ int DLevelScript::GetActorProperty (int tid, int property, const SDWORD *stack,
 	case APROP_Radius:		return actor->radius;
 	case APROP_ReactionTime:return actor->reactiontime;
 	case APROP_MeleeRange:	return actor->meleerange;
+	case APROP_ViewHeight:	if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
+							{
+								return static_cast<APlayerPawn *>(actor)->ViewHeight;
+							}
+							else
+							{
+								return 0;
+							}
+	case APROP_AttackZOffset:
+							if (actor->IsKindOf (RUNTIME_CLASS (APlayerPawn)))
+							{
+								return static_cast<APlayerPawn *>(actor)->AttackZOffset;
+							}
+							else
+							{
+								return 0;
+							}
 
 	case APROP_SeeSound:	return GlobalACSStrings.AddString(actor->SeeSound, stack, stackdepth);
 	case APROP_AttackSound:	return GlobalACSStrings.AddString(actor->AttackSound, stack, stackdepth);
@@ -3851,6 +3880,8 @@ int DLevelScript::CheckActorProperty (int tid, int property, int value)
 		case APROP_Radius:
 		case APROP_ReactionTime:
 		case APROP_MeleeRange:
+		case APROP_ViewHeight:
+		case APROP_AttackZOffset:
 			return (GetActorProperty(tid, property, NULL, 0) == value);
 
 		// Boolean values need to compare to a binary version of value
diff --git a/src/p_udmf.cpp b/src/p_udmf.cpp
index c1d18fd4c7..91e4c85650 100644
--- a/src/p_udmf.cpp
+++ b/src/p_udmf.cpp
@@ -1326,7 +1326,11 @@ public:
 					continue;
 
 				case NAME_hidden:
-					sec->MoreFlags |= SECF_HIDDEN;
+					Flag(sec->MoreFlags, SECF_HIDDEN, key);
+					break;
+
+				case NAME_Waterzone:
+					Flag(sec->MoreFlags, SECF_UNDERWATER, key);
 					break;
 
 				default:
diff --git a/src/p_user.cpp b/src/p_user.cpp
index c427353a5b..e2c8b80c96 100644
--- a/src/p_user.cpp
+++ b/src/p_user.cpp
@@ -477,6 +477,10 @@ void APlayerPawn::Serialize (FArchive &arc)
 	{
 		arc << UseRange;
 	}
+	if (SaveVersion >= 4503)
+	{
+		arc << AirCapacity;
+	}
 }
 
 //===========================================================================
@@ -1066,7 +1070,7 @@ bool APlayerPawn::ResetAirSupply (bool playgasp)
 	{
 		S_Sound (this, CHAN_VOICE, "*gasp", 1, ATTN_NORM);
 	}
-	if (level.airsupply> 0) player->air_finished = level.time + level.airsupply;
+	if (level.airsupply> 0 && player->mo->AirCapacity > 0) player->air_finished = level.time + FixedMul(level.airsupply, player->mo->AirCapacity);
 	else player->air_finished = INT_MAX;
 	return wasdrowning;
 }
diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp
index 7b922df027..34234e5838 100644
--- a/src/thingdef/thingdef_properties.cpp
+++ b/src/thingdef/thingdef_properties.cpp
@@ -2419,6 +2419,15 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, userange, F, PlayerPawn)
 	defaults->UseRange = z;
 }
 
+//==========================================================================
+//
+//==========================================================================
+DEFINE_CLASS_PROPERTY_PREFIX(player, aircapacity, F, PlayerPawn)
+{
+	PROP_FIXED_PARM(z, 0);
+	defaults->AirCapacity = z;
+}
+
 //==========================================================================
 //
 //==========================================================================
diff --git a/src/version.h b/src/version.h
index a5bf7be29b..4a2cc07019 100644
--- a/src/version.h
+++ b/src/version.h
@@ -76,7 +76,7 @@ const char *GetVersionString();
 
 // Use 4500 as the base git save version, since it's higher than the
 // SVN revision ever got.
-#define SAVEVER 4502
+#define SAVEVER 4503
 
 #define SAVEVERSTRINGIFY2(x) #x
 #define SAVEVERSTRINGIFY(x) SAVEVERSTRINGIFY2(x)
diff --git a/wadsrc/static/actors/actor.txt b/wadsrc/static/actors/actor.txt
index c2fa8a0c72..0ea0184224 100644
--- a/wadsrc/static/actors/actor.txt
+++ b/wadsrc/static/actors/actor.txt
@@ -84,7 +84,7 @@ ACTOR Actor native //: Thinker
 	action native A_VileChase();
 	action native A_VileStart();
 	action native A_VileTarget(class<Actor> fire = "ArchvileFire");
-	action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire");
+	action native A_VileAttack(sound snd = "vile/stop", int initialdmg = 20, int blastdmg = 70, int blastradius = 70, float thrustfac = 1.0, name damagetype = "Fire", int flags = 0);
 	action native A_StartFire();
 	action native A_Fire(float spawnheight = 0);
 	action native A_FireCrackle();
diff --git a/wadsrc/static/actors/constants.txt b/wadsrc/static/actors/constants.txt
index 18f991e435..cd9b088ab9 100644
--- a/wadsrc/static/actors/constants.txt
+++ b/wadsrc/static/actors/constants.txt
@@ -4,6 +4,9 @@ const int PAF_NOSKULLATTACK = 1;
 const int PAF_AIMFACING = 2;
 const int PAF_NOTARGET = 4;
 
+// Flags for A_VileAttack
+const int VAF_DMGTYPEAPPLYTODIRECT = 1;
+
 // Flags for A_Saw
 const int SF_NORANDOM = 1;
 const int SF_RANDOMLIGHTMISS = 2;
diff --git a/wadsrc/static/actors/shared/player.txt b/wadsrc/static/actors/shared/player.txt
index 5457880a76..159d4cca94 100644
--- a/wadsrc/static/actors/shared/player.txt
+++ b/wadsrc/static/actors/shared/player.txt
@@ -32,6 +32,7 @@ Actor PlayerPawn : Actor native
 	Player.DamageScreenColor "ff 00 00"
 	Player.MugShotMaxHealth 0
 	Player.FlechetteType "ArtiPoisonBag3"
+	Player.AirCapacity 1
 	Obituary "$OB_MPDEFAULT"
 }