# HG changeset patch # User IBBoard # Date 1256590504 0 # Node ID 36adabb1c3ea100cb2def423788354cc1f267094 # Parent 6fe336109128a61007d27f95a035fdd29fa63c3e Re #198: Add slots with counts to units * Remove old Min/MaxNumber/Percentage for equipment and replace with limits * Refactor equipment selections and remove "numeric for ratio" as the limits handle the upper/lower limit differences * Stop equipment selections taking an amount of 0 for out of range amounts * Add "IsValid" property for selections * Removed use of "-1" as an 'infinity' limit - now use 100% as a more correct value * Change "unlimitedSize" limit in schema to "unitSizeLimit" diff -r 6fe336109128 -r 36adabb1c3ea IBBoard.WarFoundry.API.csproj --- a/IBBoard.WarFoundry.API.csproj Sat Oct 24 18:59:04 2009 +0000 +++ b/IBBoard.WarFoundry.API.csproj Mon Oct 26 20:55:04 2009 +0000 @@ -137,7 +137,6 @@ - diff -r 6fe336109128 -r 36adabb1c3ea api/Factories/Xml/WarFoundryXmlRaceFactory.cs --- a/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Mon Oct 26 20:55:04 2009 +0000 @@ -166,14 +166,20 @@ private static void LoadEquipmentSlotForUnitType (UnitType type, XmlElement equipSlot) { string slotName = equipSlot.GetAttribute ("name"); - XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); - AbstractLimit limit = GetLimitFromElement(limitElem); + AbstractLimit limit = GetMaxLimit (equipSlot); if (limit!=null) { type.AddEquipmentSlot (slotName, limit); } } + + private static AbstractLimit GetMaxLimit (XmlElement equipSlot) + { + XmlElement limitElem = WarFoundryXmlFactoryUtils.SelectSingleElement(equipSlot, "race:maxLimit/*[1]"); + return GetLimitFromElement(limitElem); + } + private static AbstractLimit GetLimitFromElement(XmlElement limitElem) { @@ -192,8 +198,8 @@ case "absoluteLimit": limit = new AbsoluteNumericLimit(XmlTools.GetIntValueFromAttribute(limitElem, "limit")); break; - case "unlimitedLimit": - limit = new UnlimitedLimit(); + case "unitSizeLimit": + limit = new NumericSizeConstrainedLimit(); break; default: //TODO: Warn of missing handler for when we've extended the limit list @@ -253,10 +259,9 @@ throw new InvalidFileException("Attribute 'equipmentSlot' of unit equipment item " + id + " for " + type.Name + " was not a valid slot name"); } } - + unitEquipItem.RoundNumberUp = equip.GetAttribute("roundDirection").Equals("up"); - try { unitEquipItem.IsRequired = bool.Parse(equip.GetAttribute("required")); @@ -268,42 +273,6 @@ try { - unitEquipItem.MaxNumber = int.Parse(equip.GetAttribute("maxNum")); - } - catch (FormatException e) - { - throw new InvalidFileException("Attribute 'maxNum' of unit equipment item " + id + " for " + type.Name + " was not a valid integer", e); - } - - try - { - unitEquipItem.MinNumber = int.Parse(equip.GetAttribute("minNum")); - } - catch (FormatException e) - { - throw new InvalidFileException("Attribute 'minNum' of unit equipment item " + id + " for " + type.Name + " was not a valid integer", e); - } - - try - { - unitEquipItem.MaxPercentage = double.Parse(equip.GetAttribute("maxPercentage")); - } - catch (FormatException e) - { - throw new InvalidFileException("Attribute 'maxPercentage' of unit equipment item " + id + " for " + type.Name + " was not a valid decimal number", e); - } - - try - { - unitEquipItem.MinPercentage = double.Parse(equip.GetAttribute("minPercentage")); - } - catch (FormatException e) - { - throw new InvalidFileException("Attribute 'minPercentage' of unit equipment item " + id + " for " + type.Name + " was not a valid decimal number", e); - } - - try - { unitEquipItem.CostMultiplier = double.Parse(equip.GetAttribute("costMultiplier")); } catch (FormatException e) diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/AbstractUnitEquipmentItemSelection.cs --- a/api/Objects/AbstractUnitEquipmentItemSelection.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Objects/AbstractUnitEquipmentItemSelection.cs Mon Oct 26 20:55:04 2009 +0000 @@ -46,23 +46,35 @@ } set { - if (IsValidValue(value)) - { - amountTaken = value; - } - else + amountTaken = value; + + if (!IsValidValue(value)) { //Fire validation failed event (once we have one) } } } - protected bool IsValidValue(double newValue) + public bool IsValid { - return IsInRange(newValue); + get + { + return IsValidValue(AmountTaken) && IsInRange(AmountTaken); + } } - protected abstract bool IsInRange(double newValue); + protected virtual bool IsValidValue(double newValue) + { + return true; + } + + protected bool IsInRange(double newValue) + { + int unitSize = EquipmentForUnit.Size; + int minLimit = EquipmentItem.MinLimit.GetLimit(unitSize); + int maxLimit = EquipmentItem.MaxLimit.GetLimit(unitSize); + return (minLimit <= newValue) && (newValue <= maxLimit); + } public double TotalCost { diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/Unit.cs --- a/api/Objects/Unit.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Objects/Unit.cs Mon Oct 26 20:55:04 2009 +0000 @@ -7,6 +7,7 @@ using System.Text; using System.Xml; using IBBoard.Lang; +using IBBoard.Limits; using IBBoard.WarFoundry.API.Util; namespace IBBoard.WarFoundry.API.Objects @@ -87,13 +88,15 @@ { if (CanEquipWithItem(unitEquip)) { - if (unitEquip.IsRatioLimit) + AbstractLimit minLimit = unitEquip.MinLimit; + + if (minLimit is IPercentageLimit) { - SetEquipmentRatio(unitEquip, unitEquip.MinPercentage); + SetEquipmentRatio(unitEquip, ((IPercentageLimit)minLimit).Percentage); } else { - SetEquipmentAmount(unitEquip, unitEquip.MinNumber); + SetEquipmentAmount(unitEquip, minLimit.GetLimit(this.Size)); } } } @@ -348,17 +351,7 @@ private void AddEquipmentAmount(UnitEquipmentItem equip, int amount) { - AbstractUnitEquipmentItemSelection newItem = null; - - if (equip.IsRatioLimit) - { - newItem = new UnitEquipmentNumericForRatioSelection(this, equip, amount); - } - else - { - newItem = new UnitEquipmentNumericSelection(this, equip, amount); - } - + AbstractUnitEquipmentItemSelection newItem = new UnitEquipmentNumericSelection(this, equip, amount); equipment[equip] = newItem; List selections = DictionaryUtils.GetValue(equipmentSlots, equip.SlotName); diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/UnitEquipmentItem.cs --- a/api/Objects/UnitEquipmentItem.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Objects/UnitEquipmentItem.cs Mon Oct 26 20:55:04 2009 +0000 @@ -4,6 +4,7 @@ using System; using IBBoard.CustomMath; +using IBBoard.Limits; using IBBoard.WarFoundry.API.Util; namespace IBBoard.WarFoundry.API.Objects @@ -16,15 +17,13 @@ private EquipmentItem item; private bool required; private bool roundUp; - private int minNum; - private int maxNum; - private double minPercentage; - private double maxPercentage; private double costMultiplier; private RoundType roundType; private string[] mutexGroups; private UnitType unitType; private string slotName = ""; + private AbstractLimit minLimit; + private AbstractLimit maxLimit; public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, new string[0]) @@ -126,92 +125,54 @@ public bool IsRatioLimit { - get { return minPercentage != 100 || maxPercentage != 100; } + get { return MinLimit is IPercentageLimit && MaxLimit is IPercentageLimit; } } - - public int MinNumber + + /// + /// Gets the Limit object for the minimum number of items that can be taken + /// + public AbstractLimit MinLimit { - get { return minNum; } + get + { + return (minLimit == null ? new UnlimitedLimit() : minLimit); + } set { - if (value >= 0 || value == WarFoundryCore.INFINITY) + if (value != null) { - minNum = value; - CheckMaxNumber(); + minLimit = value; + + if (maxLimit == null) + { + maxLimit = minLimit; + } } } } - private void CheckMaxNumber() + /// + /// Gets the Limit object for the maximum number of items that can be taken + /// + public AbstractLimit MaxLimit { - if (MaxNumber < MinNumber || MinNumber == WarFoundryCore.INFINITY) - { - MaxNumber = MinNumber; - } - } - - public int MaxNumber - { - get { return maxNum; } - set + get { - if (value >= 0 || value == WarFoundryCore.INFINITY) - { - maxNum = value; - CheckMinNumber(); - } + return (maxLimit == null ? new UnlimitedLimit() : maxLimit); } - } - - private void CheckMinNumber() - { - if ((MinNumber > MaxNumber && MaxNumber != WarFoundryCore.INFINITY) || (MinNumber == 0 && MaxNumber != 0)) - { - MinNumber = MaxNumber; - } - } - - public double MinPercentage - { - get { return minPercentage; } set { - if (value >= 0 && value <= 100) + if (value != null) { - minPercentage = value; - CheckMaxPercentage(); + maxLimit = value; + + if (minLimit == null) + { + minLimit = maxLimit; + } } } } - - private void CheckMaxPercentage() - { - if (MaxPercentage < MinPercentage) - { - MaxPercentage = MinPercentage; - } - } - - public double MaxPercentage - { - get { return maxPercentage; } - set - { - if (value >= 0 && value <= 100) - { - maxPercentage = value; - CheckMinPercentage(); - } - } - } - - private void CheckMinPercentage() - { - if (MinPercentage > MaxPercentage|| (MinPercentage == 0 && MaxPercentage != 0)) - { - MinPercentage = MaxPercentage; - } - } public EquipmentItem EquipmentItem { diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/UnitEquipmentNumericForRatioSelection.cs --- a/api/Objects/UnitEquipmentNumericForRatioSelection.cs Sat Oct 24 18:59:04 2009 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,33 +0,0 @@ -// This file (UnitEquipmentNumericForRatioSelection.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 IBBoard.CustomMath; - -namespace IBBoard.WarFoundry.API.Objects -{ - /// - /// An object to hold the selection of a unit's equipment where the selection was made as an absolute number and the - /// equipment item has a ratio limit - /// - public class UnitEquipmentNumericForRatioSelection : UnitEquipmentNumericSelection - { - public UnitEquipmentNumericForRatioSelection(Unit unit, UnitEquipmentItem item, double amount) : base(unit, item, amount) - { - } - - public UnitEquipmentNumericForRatioSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, IBBMath.Round(unit.Size * item.MinPercentage, item.RoundNumberUp)) - { - } - - protected override bool IsInRange (double newValue) - { - int minLimit = (int) IBBMath.Round(EquipmentForUnit.Size * EquipmentItem.MinPercentage / 100, EquipmentItem.RoundNumberUp); - int maxLimit = (int) IBBMath.Round(EquipmentForUnit.Size * EquipmentItem.MaxPercentage / 100, EquipmentItem.RoundNumberUp); - newValue = (newValue == WarFoundryCore.INFINITY ? EquipmentForUnit.Size : newValue); - bool isInRange = (minLimit <= newValue) && (newValue <= maxLimit); - return isInRange && IsWholeNumber(newValue); - } - } -} diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/UnitEquipmentNumericSelection.cs --- a/api/Objects/UnitEquipmentNumericSelection.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Objects/UnitEquipmentNumericSelection.cs Mon Oct 26 20:55:04 2009 +0000 @@ -15,7 +15,7 @@ { } - public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, item.MinNumber) + public UnitEquipmentNumericSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, item.MinLimit.GetLimit(unit.Size)) { } @@ -23,7 +23,7 @@ { get { - return (AmountTaken == WarFoundryCore.INFINITY ? EquipmentForUnit.Size : (int) AmountTaken); + return (int) AmountTaken; } } @@ -32,22 +32,9 @@ return newValue == Math.Round(newValue); } - protected override bool IsInRange(double newValue) + protected override bool IsValidValue (double newValue) { - bool isInRange = IsWholeNumber(newValue); - - if (newValue == WarFoundryCore.INFINITY) - { - isInRange = (EquipmentItem.MaxNumber == WarFoundryCore.INFINITY); - } - else if (isInRange) - { - int minLimit = (EquipmentItem.MinNumber == WarFoundryCore.INFINITY ? EquipmentForUnit.Size : EquipmentItem.MinNumber); - int maxLimit = (EquipmentItem.MaxNumber == WarFoundryCore.INFINITY ? EquipmentForUnit.Size : EquipmentItem.MaxNumber); - isInRange = (minLimit <= newValue) && (newValue <= maxLimit); - } - - return isInRange; + return base.IsValidValue(newValue) && IsWholeNumber(newValue); } public override string GetEquipmentAmountString () @@ -66,18 +53,7 @@ /// public static string GetEquipmentAmountString(double amount) { - string amountString; - - if (amount == WarFoundryCore.INFINITY) - { - amountString = "all"; //TODO: Translate - } - else - { - amountString = amount.ToString(); - } - - return amountString; + return amount.ToString(); } } } diff -r 6fe336109128 -r 36adabb1c3ea api/Objects/UnitEquipmentRatioSelection.cs --- a/api/Objects/UnitEquipmentRatioSelection.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Objects/UnitEquipmentRatioSelection.cs Mon Oct 26 20:55:04 2009 +0000 @@ -3,6 +3,7 @@ // 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 IBBoard.Limits; namespace IBBoard.WarFoundry.API.Objects { @@ -16,7 +17,7 @@ { } - public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, item.MinPercentage) + public UnitEquipmentRatioSelection(Unit unit, UnitEquipmentItem item) : base(unit, item, ((IPercentageLimit)item.MinLimit).Percentage) { } @@ -28,11 +29,6 @@ return (int) (EquipmentItem.RoundNumberUp ? Math.Ceiling(numberTaken) : Math.Floor(numberTaken)); } } - - protected override bool IsInRange (double newValue) - { - return (EquipmentItem.MinPercentage <= newValue) && (newValue <= EquipmentItem.MaxPercentage); - } public override string GetEquipmentAmountString () { diff -r 6fe336109128 -r 36adabb1c3ea api/Util/UnitEquipmentUtil.cs --- a/api/Util/UnitEquipmentUtil.cs Sat Oct 24 18:59:04 2009 +0000 +++ b/api/Util/UnitEquipmentUtil.cs Mon Oct 26 20:55:04 2009 +0000 @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Text; +using IBBoard.Limits; using IBBoard.WarFoundry.API.Objects; namespace IBBoard.WarFoundry.API.Util @@ -101,7 +102,16 @@ public static int GetMaxEquipmentCount (Unit unit, UnitEquipmentItem equip) { - return equip.MaxNumber; + int max = equip.MaxLimit.GetLimit(unit.Size); + AbstractLimit limit = unit.UnitType.GetEquipmentSlotLimit(equip.SlotName); + + if (!(limit is UnlimitedLimit)) + { + int slotMax = limit.GetLimit(unit.Size) - unit.GetEquipmentAmountInSlot(equip.SlotName); + max = Math.Min(slotMax, max); + } + + return max; } } } diff -r 6fe336109128 -r 36adabb1c3ea dtds/race.xsd --- a/dtds/race.xsd Sat Oct 24 18:59:04 2009 +0000 +++ b/dtds/race.xsd Mon Oct 26 20:55:04 2009 +0000 @@ -34,7 +34,8 @@ - + + @@ -48,16 +49,17 @@ + + + + + - - - - diff -r 6fe336109128 -r 36adabb1c3ea dtds/warfoundry-core.xsd --- a/dtds/warfoundry-core.xsd Sat Oct 24 18:59:04 2009 +0000 +++ b/dtds/warfoundry-core.xsd Mon Oct 26 20:55:04 2009 +0000 @@ -29,7 +29,7 @@ - +