changeset 431:c8002429ab45

Re #366: Rewrite equipment handling and limits * Remove code added for #356 and work without limiting * Move "Calculate number taken" method to util class
author IBBoard <dev@ibboard.co.uk>
date Sat, 12 Nov 2011 20:35:15 +0000
parents 7e95b880f9cc
children f64a52e2f8b1
files API/Commands/AbstractSetUnitEquipmentAmountCommand.cs API/Commands/SetUnitEquipmentRatioAmountCommand.cs API/Objects/AbstractUnitEquipmentItemSelection.cs API/Objects/Unit.cs API/Objects/UnitEquipmentNumericSelection.cs API/Objects/UnitEquipmentRatioSelection.cs API/Util/UnitEquipmentUtil.cs
diffstat 7 files changed, 225 insertions(+), 258 deletions(-) [+]
line wrap: on
line diff
--- a/API/Commands/AbstractSetUnitEquipmentAmountCommand.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Commands/AbstractSetUnitEquipmentAmountCommand.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -65,7 +65,7 @@
 		/// </returns>
 		protected string GetOldAmountString()
 		{
-			return oldAmountWasRatio ? GetRatioAmountString(oldAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, oldAmount)) : GetNumberAmountString((int)oldAmount);
+			return oldAmountWasRatio ? GetRatioAmountString(oldAmount, UnitEquipmentUtil.CalculateEquipmentAmountTakenFromRatio(Unit, EquipItem, oldAmount)) : GetNumberAmountString((int)oldAmount);
 		}
 
 		protected string GetNumberAmountString(int number)
--- a/API/Commands/SetUnitEquipmentRatioAmountCommand.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Commands/SetUnitEquipmentRatioAmountCommand.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -6,6 +6,7 @@
 using IBBoard.Commands;
 using IBBoard.Lang;
 using IBBoard.WarFoundry.API.Objects;
+using IBBoard.WarFoundry.API.Util;
 
 namespace IBBoard.WarFoundry.API.Commands
 {
@@ -21,9 +22,9 @@
 			newAmount = amount;
 		}
 
-		protected override string GetNewAmountString ()
+		protected override string GetNewAmountString()
 		{
-			return GetRatioAmountString(newAmount, UnitEquipmentRatioSelection.CalculateNumberTaken(Unit, EquipItem, newAmount));
+			return GetRatioAmountString(newAmount, UnitEquipmentUtil.CalculateEquipmentAmountTakenFromRatio(Unit, EquipItem, newAmount));
 		}
 
 		public override void Redo()
--- a/API/Objects/AbstractUnitEquipmentItemSelection.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Objects/AbstractUnitEquipmentItemSelection.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -85,23 +85,15 @@
 		}
 
 		/// <summary>
-		/// Gets the number taken as a whole number of times the item was taken. This number may be altered by the limits
-		/// placed on the equipment item (e.g. reduced if there is a lower maximum limit)
+		/// Gets the number taken as a whole number of times the item was taken. This number will not be altered by the limits
+		/// placed on the equipment item, which are instead used to raise validation warnings.
 		/// </summary>
 		/// <value>
-		/// The number of times the item was taken, modified by any limits.
+		/// The number of times the item was taken.
 		/// </value>
 		public abstract int NumberTaken
 		{
 			 get;
 		}
-
-		/// <summary>
-		/// Gets the raw amount taken as a whole number of times the item was taken.
-		/// </summary>
-		/// <value>
-		/// The unmodified number of times the item was taken.
-		/// </value>
-		public abstract int RawNumberTaken { get; }
 	}
 }
--- a/API/Objects/Unit.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Objects/Unit.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -511,7 +511,7 @@
 			
 			foreach (AbstractUnitEquipmentItemSelection selection in selections)
 			{
-				amount += selection.RawNumberTaken;
+				amount += selection.NumberTaken;
 			}
 			
 			return amount;
--- a/API/Objects/UnitEquipmentNumericSelection.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Objects/UnitEquipmentNumericSelection.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -23,14 +23,6 @@
 		{
 			get
 			{
-				return RawNumberTaken;
-			}
-		}
-
-		public override int RawNumberTaken
-		{
-			get
-			{
 				return (int)AmountTaken;
 			}
 		}
--- a/API/Objects/UnitEquipmentRatioSelection.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Objects/UnitEquipmentRatioSelection.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -31,30 +31,7 @@
 			}
 		}
 
-		public override int RawNumberTaken
-		{
-			get
-			{
-				return CalculateRawNumberTaken(EquipmentForUnit, EquipmentItem, AmountTaken);
-			}
-		}
-
-		internal static int CalculateNumberTaken(Unit unit, UnitEquipmentItem item, double ratioTaken)
-		{
-			int wholeNumberTaken = CalculateRawNumberTaken(unit, item, ratioTaken);
-			int maxTaken = Int32.MaxValue;
-			int minTaken = 0;
-
-			if (wholeNumberTaken > 0)
-			{
-				maxTaken = UnitEquipmentUtil.GetMaxEquipmentCount(unit, item);
-			}
-
-			minTaken = UnitEquipmentUtil.GetMinEquipmentCount(unit, item);
-			return Math.Min(Math.Max(wholeNumberTaken, minTaken), maxTaken);
-		}
-
-		private static int CalculateRawNumberTaken (Unit unit, UnitEquipmentItem item, double ratioTaken)
+		private static int CalculateNumberTaken(Unit unit, UnitEquipmentItem item, double ratioTaken)
 		{
 			double exactNumberTaken = (ratioTaken / 100) * unit.Size;
 			return (int)IBBMath.Round(exactNumberTaken, item.RoundNumberUp);
--- a/API/Util/UnitEquipmentUtil.cs	Sun Nov 06 20:44:53 2011 +0000
+++ b/API/Util/UnitEquipmentUtil.cs	Sat Nov 12 20:35:15 2011 +0000
@@ -1,211 +1,216 @@
-// This file (UnitEquipmentUtil.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard.
-//
-// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-using IBBoard.CustomMath;
-using IBBoard.Limits;
-using IBBoard.WarFoundry.API.Objects;
-
-namespace IBBoard.WarFoundry.API.Util
-{
-	public class UnitEquipmentUtil
-	{
-		/// <summary>
-		/// Gets an array of allowed <see cref="UnitEquipmentItem"/>s based on the current selections of the unit, taking in to account Mutex groups and other limits.
-		/// </summary>
-		/// <param name="unit">The <see cref="Unit"/> to get equipment items for</param>
-		/// <returns>The array of allowed <see cref="UnitEquipmentItem"/>s</returns>
-		public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit)
-		{
-			List<UnitEquipmentItem> list = new List<UnitEquipmentItem>();
-			UnitEquipmentItem[] currItems = unit.GetEquipment();
-
-			foreach (UnitEquipmentItem item in GetAllEquipmentItems(unit))
-			{
-				bool allowed = IsAllowedByMutex(item, currItems);
-
-				if (allowed)
-				{
-					list.Add(item);
-				}
-			}
-
-			return list.ToArray();
-		}
-
-		private static bool IsAllowedByMutex(UnitEquipmentItem item, UnitEquipmentItem[] currItems)
-		{
-			bool allowed = true;
-
-			foreach (UnitEquipmentItem currItem in currItems)
-			{
-				if (ItemsAreMutuallyExclusive(currItem, item))
-				{
-					allowed = false;
-					break;
-				}
-			}
-
-			return allowed;
-		}
-
-		/// <summary>
-		/// Gets a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code> because of mutex groups.
-		/// </summary>
-		/// <param name="unit">The unit that wants to take the equipment item</param>
-		/// <param name="item">The item to check blocking items for</param>
-		/// <returns>a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code></returns>
-		public static List<UnitEquipmentItem> GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item)
-		{
-			List<UnitEquipmentItem> items = new List<UnitEquipmentItem>();
-			UnitEquipmentItem[] currItems = unit.GetEquipment();
-
-			foreach (UnitEquipmentItem unitItem in currItems)
-			{
-				if (ItemsAreMutuallyExclusive(unitItem, item))
-				{
-					items.Add(unitItem);
-				}
-			}
-
-			return items;
-		}
-
-		public static UnitEquipmentItem[] GetAllEquipmentItems(Unit unit)
-		{
-			return unit.UnitType.GetEquipmentItems();
-		}
-
-		public static bool ItemsAreMutuallyExclusive(UnitEquipmentItem item1, UnitEquipmentItem item2)
-		{
-			bool areMutex = false;
-			string[] item1mutex = item1.MutexGroups;
-			string[] item2mutex = item2.MutexGroups;
-
-			foreach (string mutex in item1mutex)
-			{
-				foreach (string otherMutex in item2mutex)
-				{
-					if (mutex.Equals(otherMutex))
-					{
-						areMutex = true;
-						goto postLoop;
-					}
-				}
-			}
-			postLoop:
-
-			return areMutex;
-		}
-
-		public static int GetMaxEquipmentCount (Unit unit, UnitEquipmentItem equip)
-		{
-			return GetEquipmentCountLimit (unit, equip.MaxLimit.GetLimit(unit.Size), equip);
-		}
-
-		private static int GetEquipmentCountLimit (Unit unit, int currLimit, UnitEquipmentItem equip)
-		{
-			int newLimit = currLimit;
-			ILimit limit = GetSlotLimitForItem(unit, equip);
-			
-			if (!(limit is UnlimitedLimit))
-			{
-				int slotMax = limit.GetLimit (unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip);
-				newLimit = Math.Min (slotMax, newLimit);
-			}
-			
-			return newLimit;
-		}
-
-		private static ILimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip)
-		{
-			return unit.UnitType.GetEquipmentSlotLimit(equip.SlotName);
-		}
-
-		
-		public static int GetMinEquipmentCount (Unit unit, UnitEquipmentItem equip)
-		{
-			return GetEquipmentCountLimit (unit, equip.MinLimit.GetLimit(unit.Size), equip);
-		}
-		
-		public static bool IsEquipmentRatioLimited(Unit unit, UnitEquipmentItem equip)
-		{
-			ILimit limit = GetSlotLimitForItem(unit, equip);
-			return equip.IsRatioLimit && (limit is IPercentageLimit || limit is UnlimitedLimit);
-		}
-		
-		public static double GetMaxEquipmentPercentage(Unit unit, UnitEquipmentItem equip)
-		{
-			return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MaxLimit, unit);
-		}
-		
-		private static double GetPercentageOfUnitSize(int number, Unit unit)
-		{
-			return IBBMath.Percentage(number, unit.Size);
-		}
-		
-		private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, ILimit equipLimit, Unit unit)
-		{			
-			double limit = 0;
-			ILimit slotLimit = GetSlotLimitForItem(unit, equip);
-			
-			if (slotLimit is IPercentageLimit)
-			{
-				limit = ((IPercentageLimit)slotLimit).Percentage - GetPercentageOfUnitSize(unit.GetEquipmentAmountInSlotExcludingItem(equip), unit);
-			}
-			else
-			{
-				int remaining = slotLimit.GetLimit(unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip);
-				limit = GetPercentageOfUnitSize(remaining, unit);
-			}
-			
-			if (equip.IsRatioLimit)
-			{
-				limit = Math.Min(limit, ((IPercentageLimit)equipLimit).Percentage);
-			}
-			else
-			{
-				limit = Math.Min(limit, GetPercentageOfUnitSize(equipLimit.GetLimit(unit.Size), unit));
-			}
-			
-			return limit;
-		}
-		
-		public static double GetMinEquipmentPercentage(Unit unit, UnitEquipmentItem equip)
-		{
-			return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MinLimit, unit);
-		}
-
-		public static double GetEquipmentAmount(Unit unit, UnitEquipmentItem item)
-		{
-			double amount = 0;
-			AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item);
-
-			if (selection != null)
-			{
-				amount = selection.AmountTaken;
-			}
-
-			return amount;
-		}
-
-		public static bool GetEquipmentAmountIsRatio(Unit unit, UnitEquipmentItem item)
-		{
-			return (unit.GetEquipmentSelection(item) is UnitEquipmentRatioSelection);
-		}
-
-		public static int GetEquipmentAmountTaken(Unit unit, UnitEquipmentItem item)
-		{
-			AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item);
-			return (selection == null ? 0 : selection.NumberTaken);
-		}
-		
-		public static bool CanEditEquipmentAmount(Unit unit, UnitEquipmentItem item)
-		{
-			return item !=null && (item.MaxLimit.GetLimit(unit.Size) != item.MinLimit.GetLimit(unit.Size));
-		}
-	}
-}
+// This file (UnitEquipmentUtil.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2009 IBBoard.
+//
+// The file and the library/program it is in are licensed and distributed, without warranty, under the GNU Affero GPL license, either version 3 of the License or (at your option) any later version. Please see COPYING for more information and the full license.
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using IBBoard.CustomMath;
+using IBBoard.Limits;
+using IBBoard.WarFoundry.API.Objects;
+
+namespace IBBoard.WarFoundry.API.Util
+{
+	public class UnitEquipmentUtil
+	{
+		/// <summary>
+		/// Gets an array of allowed <see cref="UnitEquipmentItem"/>s based on the current selections of the unit, taking in to account Mutex groups and other limits.
+		/// </summary>
+		/// <param name="unit">The <see cref="Unit"/> to get equipment items for</param>
+		/// <returns>The array of allowed <see cref="UnitEquipmentItem"/>s</returns>
+		public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit)
+		{
+			List<UnitEquipmentItem> list = new List<UnitEquipmentItem>();
+			UnitEquipmentItem[] currItems = unit.GetEquipment();
+
+			foreach (UnitEquipmentItem item in GetAllEquipmentItems(unit))
+			{
+				bool allowed = IsAllowedByMutex(item, currItems);
+
+				if (allowed)
+				{
+					list.Add(item);
+				}
+			}
+
+			return list.ToArray();
+		}
+
+		private static bool IsAllowedByMutex(UnitEquipmentItem item, UnitEquipmentItem[] currItems)
+		{
+			bool allowed = true;
+
+			foreach (UnitEquipmentItem currItem in currItems)
+			{
+				if (ItemsAreMutuallyExclusive(currItem, item))
+				{
+					allowed = false;
+					break;
+				}
+			}
+
+			return allowed;
+		}
+
+		/// <summary>
+		/// Gets a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code> because of mutex groups.
+		/// </summary>
+		/// <param name="unit">The unit that wants to take the equipment item</param>
+		/// <param name="item">The item to check blocking items for</param>
+		/// <returns>a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code></returns>
+		public static List<UnitEquipmentItem> GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item)
+		{
+			List<UnitEquipmentItem> items = new List<UnitEquipmentItem>();
+			UnitEquipmentItem[] currItems = unit.GetEquipment();
+
+			foreach (UnitEquipmentItem unitItem in currItems)
+			{
+				if (ItemsAreMutuallyExclusive(unitItem, item))
+				{
+					items.Add(unitItem);
+				}
+			}
+
+			return items;
+		}
+
+		public static UnitEquipmentItem[] GetAllEquipmentItems(Unit unit)
+		{
+			return unit.UnitType.GetEquipmentItems();
+		}
+
+		public static bool ItemsAreMutuallyExclusive(UnitEquipmentItem item1, UnitEquipmentItem item2)
+		{
+			bool areMutex = false;
+			string[] item1mutex = item1.MutexGroups;
+			string[] item2mutex = item2.MutexGroups;
+
+			foreach (string mutex in item1mutex)
+			{
+				foreach (string otherMutex in item2mutex)
+				{
+					if (mutex.Equals(otherMutex))
+					{
+						areMutex = true;
+						goto postLoop;
+					}
+				}
+			}
+			postLoop:
+
+			return areMutex;
+		}
+
+		public static int GetMaxEquipmentCount (Unit unit, UnitEquipmentItem equip)
+		{
+			return GetEquipmentCountLimit (unit, equip.MaxLimit.GetLimit(unit.Size), equip);
+		}
+
+		private static int GetEquipmentCountLimit (Unit unit, int currLimit, UnitEquipmentItem equip)
+		{
+			int newLimit = currLimit;
+			ILimit limit = GetSlotLimitForItem(unit, equip);
+			
+			if (!(limit is UnlimitedLimit))
+			{
+				int slotMax = limit.GetLimit (unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip);
+				newLimit = Math.Min (slotMax, newLimit);
+			}
+			
+			return newLimit;
+		}
+
+		private static ILimit GetSlotLimitForItem(Unit unit, UnitEquipmentItem equip)
+		{
+			return unit.UnitType.GetEquipmentSlotLimit(equip.SlotName);
+		}
+
+		
+		public static int GetMinEquipmentCount (Unit unit, UnitEquipmentItem equip)
+		{
+			return GetEquipmentCountLimit (unit, equip.MinLimit.GetLimit(unit.Size), equip);
+		}
+		
+		public static bool IsEquipmentRatioLimited(Unit unit, UnitEquipmentItem equip)
+		{
+			ILimit limit = GetSlotLimitForItem(unit, equip);
+			return equip.IsRatioLimit && (limit is IPercentageLimit || limit is UnlimitedLimit);
+		}
+		
+		public static double GetMaxEquipmentPercentage(Unit unit, UnitEquipmentItem equip)
+		{
+			return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MaxLimit, unit);
+		}
+		
+		private static double GetPercentageOfUnitSize(int number, Unit unit)
+		{
+			return IBBMath.Percentage(number, unit.Size);
+		}
+		
+		private static double GetMinOfSlotLimitAndEquipmentLimit(UnitEquipmentItem equip, ILimit equipLimit, Unit unit)
+		{			
+			double limit = 0;
+			ILimit slotLimit = GetSlotLimitForItem(unit, equip);
+			
+			if (slotLimit is IPercentageLimit)
+			{
+				limit = ((IPercentageLimit)slotLimit).Percentage - GetPercentageOfUnitSize(unit.GetEquipmentAmountInSlotExcludingItem(equip), unit);
+			}
+			else
+			{
+				int remaining = slotLimit.GetLimit(unit.Size) - unit.GetEquipmentAmountInSlotExcludingItem(equip);
+				limit = GetPercentageOfUnitSize(remaining, unit);
+			}
+			
+			if (equip.IsRatioLimit)
+			{
+				limit = Math.Min(limit, ((IPercentageLimit)equipLimit).Percentage);
+			}
+			else
+			{
+				limit = Math.Min(limit, GetPercentageOfUnitSize(equipLimit.GetLimit(unit.Size), unit));
+			}
+			
+			return limit;
+		}
+		
+		public static double GetMinEquipmentPercentage(Unit unit, UnitEquipmentItem equip)
+		{
+			return GetMinOfSlotLimitAndEquipmentLimit(equip, equip.MinLimit, unit);
+		}
+
+		public static double GetEquipmentAmount(Unit unit, UnitEquipmentItem item)
+		{
+			double amount = 0;
+			AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item);
+
+			if (selection != null)
+			{
+				amount = selection.AmountTaken;
+			}
+
+			return amount;
+		}
+
+		public static bool GetEquipmentAmountIsRatio(Unit unit, UnitEquipmentItem item)
+		{
+			return (unit.GetEquipmentSelection(item) is UnitEquipmentRatioSelection);
+		}
+
+		public static int GetEquipmentAmountTaken(Unit unit, UnitEquipmentItem item)
+		{
+			AbstractUnitEquipmentItemSelection selection = unit.GetEquipmentSelection(item);
+			return (selection == null ? 0 : selection.NumberTaken);
+		}
+		
+		public static bool CanEditEquipmentAmount(Unit unit, UnitEquipmentItem item)
+		{
+			return item !=null && (item.MaxLimit.GetLimit(unit.Size) != item.MinLimit.GetLimit(unit.Size));
+		}
+
+		public static int CalculateEquipmentAmountTakenFromRatio(Unit unit, UnitEquipmentItem equipItem, double newAmount)
+		{
+			return (int)IBBMath.Round(unit.Size * (newAmount / 100), equipItem.RoundNumberUp);
+		}
+	}
+}