diff --git a/src/g_shared/sbarinfo.cpp b/src/g_shared/sbarinfo.cpp
index 23733efcfd..2fcc29b050 100644
--- a/src/g_shared/sbarinfo.cpp
+++ b/src/g_shared/sbarinfo.cpp
@@ -206,67 +206,31 @@ class SBarInfoCommandFlowControl : public SBarInfoCommand
 {
 	public:
 		SBarInfoCommandFlowControl(SBarInfo *script) : SBarInfoCommand(script), truth(false) {}
-		~SBarInfoCommandFlowControl()
-		{
-			for(unsigned int i = 0;i < 2;i++)
-			{
-				for(unsigned int j = 0;j < commands[i].Size();j++)
-					delete commands[i][j];
-			}
-		}
 
 		void	Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
 		{
-			for(unsigned int i = 0;i < commands[truth].Size();i++)
-				commands[truth][i]->Draw(block, statusBar);
+			for(auto command : commands[truth])
+				command->Draw(block, statusBar);
 		}
 		int		NumCommands() const { return commands[truth].Size(); }
 		void	Parse(FScanner &sc, bool fullScreenOffsets)
 		{
-			bool elseBlock = false;
-			SBarInfoCommand *cmd = NULL;
-			// Should loop no more than twice.
-			while(true)
-			{
-				if(sc.CheckToken('{'))
-				{
-					while((cmd = NextCommand(sc)) != NULL)
-					{
-						cmd->Parse(sc, fullScreenOffsets);
-						commands[!elseBlock].Push(cmd);
-					}
-				}
-				else
-				{
-					if((cmd = NextCommand(sc)) != NULL)
-					{
-						cmd->Parse(sc, fullScreenOffsets);
-						commands[!elseBlock].Push(cmd);
-					}
-					else
-						sc.ScriptError("Missing command for flow control statement.");
-				}
-
-				if(!elseBlock && sc.CheckToken(TK_Else))
-				{
-					elseBlock = true;
-					continue;
-				}
-				break;
-			}
+			ParseBlock(commands[1], sc, fullScreenOffsets);
+			if(sc.CheckToken(TK_Else))
+				ParseBlock(commands[0], sc, fullScreenOffsets);
 		}
 		void	Reset()
 		{
 			for(unsigned int i = 0;i < 2;i++)
 			{
-				for(unsigned int j = 0;j < commands[i].Size();j++)
-					commands[i][j]->Reset();
+				for(auto command : commands[i])
+					command->Reset();
 			}
 		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			for(unsigned int i = 0;i < commands[truth].Size();i++)
-				commands[truth][i]->Tick(block, statusBar, hudChanged);
+			for(auto command : commands[truth])
+				command->Tick(block, statusBar, hudChanged);
 		}
 
 	protected:
@@ -283,11 +247,65 @@ class SBarInfoCommandFlowControl : public SBarInfoCommand
 				Tick(block, statusBar, true);
 		}
 
+		void Negate()
+		{
+			swapvalues(commands[0], commands[1]);
+		}
+
 	private:
+		void ParseBlock(TDeletingArray<SBarInfoCommand *> &commands, FScanner &sc, bool fullScreenOffsets)
+		{
+			if(sc.CheckToken('{'))
+			{
+				while(SBarInfoCommand *cmd = NextCommand(sc))
+				{
+					cmd->Parse(sc, fullScreenOffsets);
+					commands.Push(cmd);
+				}
+			}
+			else
+			{
+				if(SBarInfoCommand *cmd = NextCommand(sc))
+				{
+					cmd->Parse(sc, fullScreenOffsets);
+					commands.Push(cmd);
+				}
+				else
+					sc.ScriptError("Missing command for flow control statement.");
+			}
+		}
+
 		SBarInfoCommand	*NextCommand(FScanner &sc);
 
-		bool						truth;
-		TArray<SBarInfoCommand *>	commands[2];
+		TDeletingArray<SBarInfoCommand *> commands[2];
+		bool truth;
+};
+
+class SBarInfoNegatableFlowControl : public SBarInfoCommandFlowControl
+{
+	public:
+		SBarInfoNegatableFlowControl(SBarInfo *script) : SBarInfoCommandFlowControl(script) {}
+
+		void Parse(FScanner &sc, bool fullScreenOffsets)
+		{
+			bool negate = false;
+			if(sc.CheckToken(TK_Identifier))
+			{
+				if(sc.Compare("not"))
+					negate = true;
+				else
+					sc.UnGet();
+			}
+
+			ParseNegatable(sc, fullScreenOffsets);
+
+			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
+
+			if(negate)
+				Negate();
+		}
+
+		virtual void ParseNegatable(FScanner &sc, bool fullScreenOffsets) {}
 };
 
 class SBarInfoMainBlock : public SBarInfoCommandFlowControl
diff --git a/src/g_shared/sbarinfo_commands.cpp b/src/g_shared/sbarinfo_commands.cpp
index e08fb1a20f..dcb0cd5442 100644
--- a/src/g_shared/sbarinfo_commands.cpp
+++ b/src/g_shared/sbarinfo_commands.cpp
@@ -1830,33 +1830,17 @@ const char* const CommandGameMode::modeNames[] =
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class CommandUsesAmmo : public SBarInfoCommandFlowControl
+class CommandUsesAmmo : public SBarInfoNegatableFlowControl
 {
 	public:
-		CommandUsesAmmo(SBarInfo *script)  : SBarInfoCommandFlowControl(script),
-			negate(false)
-		{
-		}
+		CommandUsesAmmo(SBarInfo *script)  : SBarInfoNegatableFlowControl(script) {}
 
-		void	Parse(FScanner &sc, bool fullScreenOffsets)
-		{
-			if(sc.CheckToken(TK_Identifier))
-			{
-				if(sc.Compare("not"))
-					negate = true;
-				else
-					sc.ScriptError("Expected 'not', but got '%s' instead.", sc.String);
-			}
-			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
-		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
+			SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
 
-			SetTruth((statusBar->CPlayer->ReadyWeapon != NULL && (statusBar->CPlayer->ReadyWeapon->AmmoType1 != NULL || statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL)) ^ negate, block, statusBar);
+			SetTruth(statusBar->CPlayer->ReadyWeapon != NULL && (statusBar->CPlayer->ReadyWeapon->AmmoType1 != NULL || statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL), block, statusBar);
 		}
-	protected:
-		bool	negate;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -1872,7 +1856,7 @@ class CommandUsesSecondaryAmmo : public CommandUsesAmmo
 		{
 			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
 
-			SetTruth((statusBar->CPlayer->ReadyWeapon != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType1 != statusBar->CPlayer->ReadyWeapon->AmmoType2) ^ negate, block, statusBar);
+			SetTruth(statusBar->CPlayer->ReadyWeapon != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType2 != NULL && statusBar->CPlayer->ReadyWeapon->AmmoType1 != statusBar->CPlayer->ReadyWeapon->AmmoType2, block, statusBar);
 		}
 };
 
@@ -2890,28 +2874,18 @@ class CommandDrawBar : public SBarInfoCommand
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class CommandIsSelected : public SBarInfoCommandFlowControl
+class CommandIsSelected : public SBarInfoNegatableFlowControl
 {
 	public:
-		CommandIsSelected(SBarInfo *script) : SBarInfoCommandFlowControl(script),
-			negate(false)
+		CommandIsSelected(SBarInfo *script) : SBarInfoNegatableFlowControl(script)
 		{
 			weapon[0] = NULL;
 			weapon[1] = NULL;
 		}
 
-		void	Parse(FScanner &sc, bool fullScreenOffsets)
+		void	ParseNegatable(FScanner &sc, bool fullScreenOffsets)
 		{
-			if(sc.CheckToken(TK_Identifier))
-			{
-				if(sc.Compare("not"))
-				{
-					negate = true;
-					if(!sc.CheckToken(TK_StringConst))
-						sc.MustGetToken(TK_Identifier);
-				}
-			}
-			else
+			if(!sc.CheckToken(TK_Identifier))
 				sc.MustGetToken(TK_StringConst);
 			for(int i = 0;i < 2;i++)
 			{
@@ -2930,24 +2904,18 @@ class CommandIsSelected : public SBarInfoCommandFlowControl
 				else
 					break;
 			}
-			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
 		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
+			SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
 
 			if(statusBar->CPlayer->ReadyWeapon != NULL)
 			{
 				const PClass *readyWeapon = statusBar->CPlayer->ReadyWeapon->GetClass();
-				SetTruth(((weapon[1] != NULL) &&
-						((negate && (weapon[0] != readyWeapon && weapon[1] != readyWeapon)) ||
-						(!negate && (weapon[0] == readyWeapon || weapon[1] == readyWeapon)))) ||
-					((weapon[1] == NULL) &&
-						((!negate && weapon[0] == readyWeapon) || (negate && weapon[0] != readyWeapon))), block, statusBar);
+				SetTruth(weapon[0] == readyWeapon || (weapon[1] && weapon[1] == readyWeapon), block, statusBar);
 			}
 		}
 	protected:
-		bool			negate;
 		const PClass	*weapon[2];
 };
 
@@ -3245,26 +3213,20 @@ FRandom CommandDrawGem::pr_chainwiggle; //use the same method of chain wiggling
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class CommandWeaponAmmo : public SBarInfoCommandFlowControl
+class CommandWeaponAmmo : public SBarInfoNegatableFlowControl
 {
 	public:
-		CommandWeaponAmmo(SBarInfo *script) : SBarInfoCommandFlowControl(script),
-			conditionAnd(false), negate(false)
+		CommandWeaponAmmo(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
+			conditionAnd(false)
 		{
 			ammo[0] = NULL;
 			ammo[1] = NULL;
 		}
 
-		void	Parse(FScanner &sc, bool fullScreenOffsets)
+		void	ParseNegatable(FScanner &sc, bool fullScreenOffsets)
 		{
 			if(!sc.CheckToken(TK_StringConst))
 				sc.MustGetToken(TK_Identifier);
-			if(sc.Compare("not") && sc.TokenType == TK_Identifier)
-			{
-				negate = true;
-				if(!sc.CheckToken(TK_StringConst))
-					sc.MustGetToken(TK_Identifier);
-			}
 			for(int i = 0;i < 2;i++)
 			{
 				ammo[i] = PClass::FindClass(sc.String);
@@ -3289,11 +3251,10 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
 				else
 					break;
 			}
-			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
 		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
+			SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
 
 			if(statusBar->CPlayer->ReadyWeapon != NULL)
 			{
@@ -3301,41 +3262,25 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
 				const PClass *AmmoType2 = statusBar->CPlayer->ReadyWeapon->AmmoType2;
 				bool usesammo1 = (AmmoType1 != NULL);
 				bool usesammo2 = (AmmoType2 != NULL);
-				if(negate && !usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble.
-				{
-					SetTruth(true, block, statusBar);
-					return;
-				}
+				//if(!usesammo1 && !usesammo2) //if the weapon doesn't use ammo don't go though the trouble.
+				//{
+				//	SetTruth(false, block, statusBar);
+				//	return;
+				//}
 				//Or means only 1 ammo type needs to match and means both need to match.
 				if(ammo[1] != NULL)
 				{
 					bool match1 = ((usesammo1 && (AmmoType1 == ammo[0] || AmmoType1 == ammo[1])) || !usesammo1);
 					bool match2 = ((usesammo2 && (AmmoType2 == ammo[0] || AmmoType2 == ammo[1])) || !usesammo2);
 					if((!conditionAnd && (match1 || match2)) || (conditionAnd && (match1 && match2)))
-					{
-						if(!negate)
-						{
-							SetTruth(true, block, statusBar);
-							return;
-						}
-					}
-					else if(negate)
 					{
 						SetTruth(true, block, statusBar);
 						return;
 					}
 				}
-				else //Every thing here could probably be one long if statement but then it would be more confusing.
+				else
 				{
 					if((usesammo1 && (AmmoType1 == ammo[0])) || (usesammo2 && (AmmoType2 == ammo[0])))
-					{
-						if(!negate)
-						{
-							SetTruth(true, block, statusBar);
-							return;
-						}
-					}
-					else if(negate)
 					{
 						SetTruth(true, block, statusBar);
 						return;
@@ -3345,33 +3290,26 @@ class CommandWeaponAmmo : public SBarInfoCommandFlowControl
 			SetTruth(false, block, statusBar);
 		}
 	protected:
-		bool			conditionAnd;
-		bool			negate;
 		const PClass	*ammo[2];
+		bool			conditionAnd;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class CommandInInventory : public SBarInfoCommandFlowControl
+class CommandInInventory : public SBarInfoNegatableFlowControl
 {
 	public:
-		CommandInInventory(SBarInfo *script) : SBarInfoCommandFlowControl(script),
-			conditionAnd(false), negate(false)
+		CommandInInventory(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
+			conditionAnd(false)
 		{
 			item[0] = item[1] = NULL;
 			amount[0] = amount[1] = 0;
 		}
 
-		void	Parse(FScanner &sc, bool fullScreenOffsets)
+		void	ParseNegatable(FScanner &sc, bool fullScreenOffsets)
 		{
 			if(!sc.CheckToken(TK_StringConst))
 				sc.MustGetToken(TK_Identifier);
-			if(sc.Compare("not") && sc.TokenType == TK_Identifier)
-			{
-				negate = true;
-				if(!sc.CheckToken(TK_StringConst))
-					sc.MustGetToken(TK_Identifier);
-			}
 			for(int i = 0;i < 2;i++)
 			{
 				item[i] = PClass::FindActor(sc.String);
@@ -3402,11 +3340,10 @@ class CommandInInventory : public SBarInfoCommandFlowControl
 				else
 					break;
 			}
-			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
 		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
+			SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
 
 			AInventory *invItem[2] = { statusBar->CPlayer->mo->FindInventory(item[0]), statusBar->CPlayer->mo->FindInventory(item[1]) };
 			if (invItem[0] != NULL && amount[0] > 0 && invItem[0]->Amount < amount[0]) invItem[0] = NULL;
@@ -3415,16 +3352,15 @@ class CommandInInventory : public SBarInfoCommandFlowControl
 			if (item[1])
 			{
 				if (conditionAnd)
-					SetTruth((invItem[0] && invItem[1]) != negate, block, statusBar);
+					SetTruth(invItem[0] && invItem[1], block, statusBar);
 				else
-					SetTruth((invItem[0] || invItem[1]) != negate, block, statusBar);
+					SetTruth(invItem[0] || invItem[1], block, statusBar);
 			}
 			else
-				SetTruth((invItem[0] != NULL) != negate, block, statusBar);
+				SetTruth(invItem[0] != NULL, block, statusBar);
 		}
 	protected:
 		bool			conditionAnd;
-		bool			negate;
 		PClassActor		*item[2];
 		int				amount[2];
 };
@@ -3459,42 +3395,31 @@ class CommandAlpha : public SBarInfoMainBlock
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class CommandIfHealth : public SBarInfoCommandFlowControl
+class CommandIfHealth : public SBarInfoNegatableFlowControl
 {
 	public:
-		CommandIfHealth(SBarInfo *script) : SBarInfoCommandFlowControl(script),
-			negate(false), percentage(false)
+		CommandIfHealth(SBarInfo *script) : SBarInfoNegatableFlowControl(script),
+			percentage(false)
 		{
 		}
 
-		void	Parse(FScanner &sc, bool fullScreenOffsets)
+		void	ParseNegatable(FScanner &sc, bool fullScreenOffsets)
 		{
-			if (sc.CheckToken(TK_Identifier))
-			{
-				if (sc.Compare("not"))
-					negate = true;
-				else
-					sc.ScriptError("Expected 'not', but got '%s' instead.", sc.String);
-			}
-
 			sc.MustGetToken(TK_IntConst);
 			percentage = sc.CheckToken('%');
 			hpamount = sc.Number;
-
-			SBarInfoCommandFlowControl::Parse(sc, fullScreenOffsets);
 		}
 		void	Tick(const SBarInfoMainBlock *block, const DSBarInfo *statusBar, bool hudChanged)
 		{
-			SBarInfoCommandFlowControl::Tick(block, statusBar, hudChanged);
+			SBarInfoNegatableFlowControl::Tick(block, statusBar, hudChanged);
 
 			int phealth = percentage ? statusBar->CPlayer->mo->health * 100 / statusBar->CPlayer->mo->GetMaxHealth() : statusBar->CPlayer->mo->health;
 
-			SetTruth((phealth >= hpamount) ^ negate, block, statusBar);
+			SetTruth(phealth >= hpamount, block, statusBar);
 		}
 	protected:
-		bool	negate;
-		bool	percentage;
 		int		hpamount;
+		bool	percentage;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/tarray.h b/src/tarray.h
index 7b9d5970bf..3ef4f2d990 100644
--- a/src/tarray.h
+++ b/src/tarray.h
@@ -39,6 +39,7 @@
 #include <assert.h>
 #include <string.h>
 #include <new>
+#include <utility>
 
 #if !defined(_WIN32)
 #include <inttypes.h>		// for intptr_t
@@ -137,11 +138,17 @@ public:
 		Count = 0;
 		Array = (T *)M_Malloc (sizeof(T)*max);
 	}
-	TArray (const TArray<T> &other)
+	TArray (const TArray<T,TT> &other)
 	{
 		DoCopy (other);
 	}
-	TArray<T> &operator= (const TArray<T> &other)
+	TArray (TArray<T,TT> &&other)
+	{
+		Array = other.Array; other.Array = NULL;
+		Most = other.Most; other.Most = 0;
+		Count = other.Count; other.Count = 0;
+	}
+	TArray<T,TT> &operator= (const TArray<T,TT> &other)
 	{
 		if (&other != this)
 		{
@@ -157,6 +164,21 @@ public:
 		}
 		return *this;
 	}
+	TArray<T,TT> &operator= (TArray<T,TT> &&other)
+	{
+		if (Array)
+		{
+			if (Count > 0)
+			{
+				DoDelete (0, Count-1);
+			}
+			M_Free (Array);
+		}
+		Array = other.Array; other.Array = NULL;
+		Most = other.Most; other.Most = 0;
+		Count = other.Count; other.Count = 0;
+		return *this;
+	}
 	~TArray ()
 	{
 		if (Array)
@@ -417,6 +439,14 @@ template<class T, class TT=T>
 class TDeletingArray : public TArray<T, TT>
 {
 public:
+	TDeletingArray() : TArray<T,TT>() {}
+	TDeletingArray(TDeletingArray<T,TT> &&other) : TArray<T,TT>(std::move(other)) {}
+	TDeletingArray<T,TT> &operator=(TDeletingArray<T,TT> &&other)
+	{
+		TArray<T,TT>::operator=(std::move(other));
+		return *this;
+	}
+
 	~TDeletingArray<T, TT> ()
 	{
 		for (unsigned int i = 0; i < TArray<T,TT>::Size(); ++i)
diff --git a/src/templates.h b/src/templates.h
index 4f75a961ae..0737fc4e91 100644
--- a/src/templates.h
+++ b/src/templates.h
@@ -40,6 +40,7 @@
 #endif
 
 #include <stdlib.h>
+#include <utility>
 
 //==========================================================================
 //
@@ -204,7 +205,7 @@ template<class T>
 inline
 void swapvalues (T &a, T &b)
 {
-	T temp = a; a = b; b = temp;
+	T temp = std::move(a); a = std::move(b); b = std::move(temp);
 }
 
 #endif //__TEMPLATES_H__