# HG changeset patch # User IBBoard # Date 1253994671 0 # Node ID 0c0e14f0378513a583277ca2247b25cf098c9e5a # Parent 1d13820b3d96fd49484f908c1c33a4a2357239c7 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 diff -r 1d13820b3d96 -r 0c0e14f03785 api/Factories/Xml/WarFoundryXmlRaceFactory.cs --- 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"); diff -r 1d13820b3d96 -r 0c0e14f03785 api/Objects/Unit.cs --- 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; + } + + /// + /// Gets a list of all s that would stop the unit taking item because of mutex groups. + /// + /// The item to check blocking items for + /// a list of all s that would stop the unit taking item + public List GetBlockingEquipmentItems(UnitEquipmentItem item) + { + List items = new List(); + + foreach (UnitEquipmentItem unitItem in GetEquipment()) + { + if (unitItem.IsMutuallyExclusive(item)) + { + items.Add(unitItem); + } + } + + return items; } public bool CanEquipWithItem(string equipID) diff -r 1d13820b3d96 -r 0c0e14f03785 api/Objects/UnitEquipmentItem.cs --- 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); - } + } + + /// + /// 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) + /// + /// the item to check against + /// true if the two items share at least one mutex group, else false + 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; + } } } diff -r 1d13820b3d96 -r 0c0e14f03785 api/Objects/UnitType.cs --- 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 items = DictionaryUtils.GetValue(equipmentExclusionGroups, mutexGroup); @@ -295,17 +295,25 @@ } public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroup(string group) - { - List 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 list = new List(); + + foreach (string group in groups) + { + List groupList = DictionaryUtils.GetValue(equipmentExclusionGroups, group); + + if (groupList != null) + { + list.AddRange(groupList); + } + } + + return list.ToArray(); } public bool IsRatioLimitedEquipmentItem(EquipmentItem item) diff -r 1d13820b3d96 -r 0c0e14f03785 dtds/race.xsd --- 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 @@ + +