# HG changeset patch # User IBBoard # Date 1321130115 0 # Node ID c8002429ab452d197e42d119d1bd1d3f78116798 # Parent 7e95b880f9ccc19f1d9893632ca469db5d37f7b5 Re #366: Rewrite equipment handling and limits * Remove code added for #356 and work without limiting * Move "Calculate number taken" method to util class diff -r 7e95b880f9cc -r c8002429ab45 API/Commands/AbstractSetUnitEquipmentAmountCommand.cs --- 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 @@ /// 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) diff -r 7e95b880f9cc -r c8002429ab45 API/Commands/SetUnitEquipmentRatioAmountCommand.cs --- 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() diff -r 7e95b880f9cc -r c8002429ab45 API/Objects/AbstractUnitEquipmentItemSelection.cs --- 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 @@ } /// - /// 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. /// /// - /// The number of times the item was taken, modified by any limits. + /// The number of times the item was taken. /// public abstract int NumberTaken { get; } - - /// - /// Gets the raw amount taken as a whole number of times the item was taken. - /// - /// - /// The unmodified number of times the item was taken. - /// - public abstract int RawNumberTaken { get; } } } diff -r 7e95b880f9cc -r c8002429ab45 API/Objects/Unit.cs --- 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; diff -r 7e95b880f9cc -r c8002429ab45 API/Objects/UnitEquipmentNumericSelection.cs --- 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; } } diff -r 7e95b880f9cc -r c8002429ab45 API/Objects/UnitEquipmentRatioSelection.cs --- 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); diff -r 7e95b880f9cc -r c8002429ab45 API/Util/UnitEquipmentUtil.cs --- 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 - { - /// - /// Gets an array of allowed s based on the current selections of the unit, taking in to account Mutex groups and other limits. - /// - /// The to get equipment items for - /// The array of allowed s - public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit) - { - List list = new List(); - 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; - } - - /// - /// Gets a list of all s that would stop the unit taking item because of mutex groups. - /// - /// The unit that wants to take the equipment item - /// The item to check blocking items for - /// a list of all s that would stop the unit taking item - public static List GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item) - { - List items = new List(); - 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 + { + /// + /// Gets an array of allowed s based on the current selections of the unit, taking in to account Mutex groups and other limits. + /// + /// The to get equipment items for + /// The array of allowed s + public static UnitEquipmentItem[] GetAllowedEquipmentItems(Unit unit) + { + List list = new List(); + 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; + } + + /// + /// Gets a list of all s that would stop the unit taking item because of mutex groups. + /// + /// The unit that wants to take the equipment item + /// The item to check blocking items for + /// a list of all s that would stop the unit taking item + public static List GetBlockingEquipmentItems(Unit unit, UnitEquipmentItem item) + { + List items = new List(); + 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); + } + } +}