Mercurial > repos > IBBoard.WarFoundry.API
changeset 152:0c0e14f03785
Re #180: Add multiple mutex groups
* Add multiple mutex groups to UnitEquipmentItem
* Add new attribute to Race schema
* Make everywhere handle multiple groups instead of assuming one
* Make factory load new attribute then fall back to old (deprecated) attribute
* Add method to Unit to get the blocking items (useful for future UI work to say "replace X and Y with Z")
* Add IsMutuallyExclusive method to UnitEquipmentItem to determine whether mutex groups overlap
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 26 Sep 2009 19:51:11 +0000 |
parents | 1d13820b3d96 |
children | dd892567f054 |
files | api/Factories/Xml/WarFoundryXmlRaceFactory.cs api/Objects/Unit.cs api/Objects/UnitEquipmentItem.cs api/Objects/UnitType.cs dtds/race.xsd |
diffstat | 5 files changed, 122 insertions(+), 41 deletions(-) [+] |
line wrap: on
line diff
--- a/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sat Sep 26 18:48:36 2009 +0000 +++ b/api/Factories/Xml/WarFoundryXmlRaceFactory.cs Sat Sep 26 19:51:11 2009 +0000 @@ -154,8 +154,32 @@ if (equipItem!=null) { - string mutexGroup = equip.GetAttribute("exclusivityGroup"); - UnitEquipmentItem unitEquipItem = new UnitEquipmentItem(equipItem, type, mutexGroup); + string mutexGroupString = equip.GetAttribute("exclusivityGroups"); + string[] mutexGroups; + + if (mutexGroupString == "") + { + mutexGroupString = equip.GetAttribute("exclusivityGroup"); + } + + if (mutexGroupString != "") + { + string[] groups = mutexGroupString.Split(','); + int groupCount = groups.Length; + + for (int i = 0; i < groupCount; i++) + { + groups[i] = groups[i].Trim(); + } + + mutexGroups = groups; + } + else + { + mutexGroups = new string[0]; + } + + UnitEquipmentItem unitEquipItem = new UnitEquipmentItem(equipItem, type, mutexGroups); unitEquipItem.RoundNumberUp = equip.GetAttribute("roundDirection").Equals("up");
--- a/api/Objects/Unit.cs Sat Sep 26 18:48:36 2009 +0000 +++ b/api/Objects/Unit.cs Sat Sep 26 19:51:11 2009 +0000 @@ -433,22 +433,39 @@ public bool CanEquipWithItem(UnitEquipmentItem item) { - string mutex = item.MutexGroup; - - if (mutex == "") - { - return true; + string[] mutexes = item.MutexGroups; + bool canEquip = false; + + if (mutexes.Length == 0) + { + canEquip = true; + } + else + { + canEquip = GetBlockingEquipmentItems(item).Count == 0; } - foreach (UnitEquipmentItem unitItem in GetEquipment()) - { - if (unitItem.MutexGroup == mutex) - { - return false; - } - } - - return true; + return canEquip; + } + + /// <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="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 List<UnitEquipmentItem> GetBlockingEquipmentItems(UnitEquipmentItem item) + { + List<UnitEquipmentItem> items = new List<UnitEquipmentItem>(); + + foreach (UnitEquipmentItem unitItem in GetEquipment()) + { + if (unitItem.IsMutuallyExclusive(item)) + { + items.Add(unitItem); + } + } + + return items; } public bool CanEquipWithItem(string equipID)
--- a/api/Objects/UnitEquipmentItem.cs Sat Sep 26 18:48:36 2009 +0000 +++ b/api/Objects/UnitEquipmentItem.cs Sat Sep 26 19:51:11 2009 +0000 @@ -3,7 +3,6 @@ // 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.Xml; using IBBoard.Lang; namespace IBBoard.WarFoundry.API.Objects @@ -21,22 +20,22 @@ private double minPercentage; private double maxPercentage; private double costMultiplier; - private RoundType roundType; - private string mutexGroup; + private RoundType roundType; + private string[] mutexGroups; private UnitType unitType; - public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, "") + public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, new string[0]) { //Do nothing extra } - public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, string mutexGroup) + public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, params string[] mutexGroups) { item = equipmentItem; unitType = equipmentFor; - this.mutexGroup = mutexGroup; + this.mutexGroups = mutexGroups; unitType.AddEquipmentItem(this); - } + } public override string Name { @@ -105,9 +104,15 @@ set { roundUp = value; } } + [Obsolete("Use MutexGroups instead for greater flexibility")] public string MutexGroup { - get { return mutexGroup; } + get { return (mutexGroups.Length == 0 ? "" : mutexGroups[0]); } + } + + public String[] MutexGroups + { + get { return (string[]) mutexGroups.Clone(); } } public UnitType EquipmentForUnit @@ -184,7 +189,7 @@ public bool HasAlternatives() { - if (MutexGroup=="") + if (MutexGroups.Length == 0) { return false; } @@ -195,7 +200,7 @@ else { //If the number of items in the MutEx group is greater than one then it must be this item plus another - return EquipmentForUnit.GetEquipmentItemsByExclusionGroup(MutexGroup).Length > 1; + return EquipmentForUnit.GetEquipmentItemsByExclusionGroups(MutexGroups).Length > 1; } } @@ -222,6 +227,31 @@ public bool CanBeUsedWithArmourType(ArmourType otherItemType) { return EquipmentItem.CanBeUsedWithArmourType(otherItemType); - } + } + + /// <summary> + /// Checks the "mutex" (mutual exclusion) groups of the other item against its own and determines whether the two items are mutually exclusive (share at least one mutex group) + /// </summary> + /// <param name="item">the item to check against</param> + /// <returns><code>true</code> if the two items share at least one mutex group, else <code>false</code></returns> + public bool IsMutuallyExclusive(UnitEquipmentItem item) + { + bool areMutex = false; + + foreach (string mutex in MutexGroups) + { + foreach (string otherMutex in item.MutexGroups) + { + if (mutex.Equals(otherMutex)) + { + areMutex = true; + goto postLoop; + } + } + } + postLoop: + + return areMutex; + } } }
--- a/api/Objects/UnitType.cs Sat Sep 26 18:48:36 2009 +0000 +++ b/api/Objects/UnitType.cs Sat Sep 26 19:51:11 2009 +0000 @@ -233,15 +233,15 @@ { equipment.Add(item.ID, item); equipmentKeyOrder.Add(item.ID); - AddToMutexGroup(item); + AddToMutexGroups(item); } } - private void AddToMutexGroup(UnitEquipmentItem item) + private void AddToMutexGroups(UnitEquipmentItem item) { - string mutexGroup = item.MutexGroup; + string[] mutexGroups = item.MutexGroups; - if (mutexGroup!="" && mutexGroup!=null) + foreach (string mutexGroup in mutexGroups) { List<UnitEquipmentItem> items = DictionaryUtils.GetValue(equipmentExclusionGroups, mutexGroup); @@ -295,17 +295,25 @@ } public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroup(string group) - { - List<UnitEquipmentItem> list = DictionaryUtils.GetValue(equipmentExclusionGroups, group); + { + return GetEquipmentItemsByExclusionGroups(new string[] { group }); + } - if (list == null) - { - return new UnitEquipmentItem[0]; - } - else - { - return list.ToArray(); - } + public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroups(string[] groups) + { + List<UnitEquipmentItem> list = new List<UnitEquipmentItem>(); + + foreach (string group in groups) + { + List<UnitEquipmentItem> groupList = DictionaryUtils.GetValue(equipmentExclusionGroups, group); + + if (groupList != null) + { + list.AddRange(groupList); + } + } + + return list.ToArray(); } public bool IsRatioLimitedEquipmentItem(EquipmentItem item)
--- a/dtds/race.xsd Sat Sep 26 18:48:36 2009 +0000 +++ b/dtds/race.xsd Sat Sep 26 19:51:11 2009 +0000 @@ -35,7 +35,9 @@ <xs:complexType> <xs:attribute name="id" type="xs:IDREF" /> <xs:attribute name="required" type="xs:boolean" default="false"/> + <!-- exclusivityGroup is deprecated in favour of the comma-separated exclusivityGroups --> <xs:attribute name="exclusivityGroup" type="xs:string" default=""/> + <xs:attribute name="exclusivityGroups" type="xs:string" default=""/> <xs:attribute name="minNum" type="core:nonNegativeOrInfiniteInteger" default="-1"/> <xs:attribute name="maxNum" type="core:nonNegativeOrInfiniteInteger" default="-1"/> <xs:attribute name="minPercentage" type="core:percentage" default="100"/>