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 diff
     1.1 --- a/api/Factories/Xml/WarFoundryXmlRaceFactory.cs	Sat Sep 26 18:48:36 2009 +0000
     1.2 +++ b/api/Factories/Xml/WarFoundryXmlRaceFactory.cs	Sat Sep 26 19:51:11 2009 +0000
     1.3 @@ -154,8 +154,32 @@
     1.4  				
     1.5  				if (equipItem!=null)
     1.6  				{
     1.7 -					string mutexGroup = equip.GetAttribute("exclusivityGroup");
     1.8 -					UnitEquipmentItem unitEquipItem = new UnitEquipmentItem(equipItem, type, mutexGroup);
     1.9 +					string mutexGroupString = equip.GetAttribute("exclusivityGroups");
    1.10 +					string[] mutexGroups;
    1.11 +
    1.12 +					if (mutexGroupString == "")
    1.13 +					{
    1.14 +						mutexGroupString = equip.GetAttribute("exclusivityGroup");
    1.15 +					}
    1.16 +
    1.17 +					if (mutexGroupString != "")
    1.18 +					{
    1.19 +						string[] groups = mutexGroupString.Split(',');
    1.20 +						int groupCount = groups.Length;
    1.21 +
    1.22 +						for (int i = 0; i < groupCount; i++)
    1.23 +						{
    1.24 +							groups[i] = groups[i].Trim();
    1.25 +						}
    1.26 +
    1.27 +						mutexGroups = groups;
    1.28 +					}
    1.29 +					else
    1.30 +					{
    1.31 +						mutexGroups = new string[0];
    1.32 +					}
    1.33 +
    1.34 +					UnitEquipmentItem unitEquipItem = new UnitEquipmentItem(equipItem, type, mutexGroups);
    1.35  					unitEquipItem.RoundNumberUp = equip.GetAttribute("roundDirection").Equals("up");
    1.36  					
    1.37  					
     2.1 --- a/api/Objects/Unit.cs	Sat Sep 26 18:48:36 2009 +0000
     2.2 +++ b/api/Objects/Unit.cs	Sat Sep 26 19:51:11 2009 +0000
     2.3 @@ -433,22 +433,39 @@
     2.4  		
     2.5  		public bool CanEquipWithItem(UnitEquipmentItem item)
     2.6  		{
     2.7 -			string mutex = item.MutexGroup;
     2.8 -
     2.9 -			if (mutex == "")
    2.10 -			{
    2.11 -				return true;
    2.12 +			string[] mutexes = item.MutexGroups;
    2.13 +			bool canEquip = false;
    2.14 +
    2.15 +			if (mutexes.Length == 0)
    2.16 +			{
    2.17 +				canEquip = true;
    2.18 +			}
    2.19 +			else
    2.20 +			{
    2.21 +				canEquip = GetBlockingEquipmentItems(item).Count == 0;
    2.22  			}
    2.23  
    2.24 -			foreach (UnitEquipmentItem unitItem in GetEquipment())
    2.25 -			{
    2.26 -				if (unitItem.MutexGroup == mutex)
    2.27 -				{
    2.28 -					return false;
    2.29 -				}
    2.30 -			}
    2.31 -
    2.32 -			return true;
    2.33 +			return canEquip;
    2.34 +		}
    2.35 +
    2.36 +		/// <summary>
    2.37 +		/// Gets a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code> because of mutex groups.
    2.38 +		/// </summary>
    2.39 +		/// <param name="item">The item to check blocking items for</param>
    2.40 +		/// <returns>a list of all <see cref="UnitEquipmentItem"/>s that would stop the unit taking <code>item</code></returns>
    2.41 +		public List<UnitEquipmentItem> GetBlockingEquipmentItems(UnitEquipmentItem item)
    2.42 +		{
    2.43 +			List<UnitEquipmentItem> items = new List<UnitEquipmentItem>();
    2.44 +
    2.45 +			foreach (UnitEquipmentItem unitItem in GetEquipment())
    2.46 +			{
    2.47 +				if (unitItem.IsMutuallyExclusive(item))
    2.48 +				{
    2.49 +					items.Add(unitItem);
    2.50 +				}
    2.51 +			}
    2.52 +
    2.53 +			return items;
    2.54  		}
    2.55  
    2.56  		public bool CanEquipWithItem(string equipID)
     3.1 --- a/api/Objects/UnitEquipmentItem.cs	Sat Sep 26 18:48:36 2009 +0000
     3.2 +++ b/api/Objects/UnitEquipmentItem.cs	Sat Sep 26 19:51:11 2009 +0000
     3.3 @@ -3,7 +3,6 @@
     3.4  // 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.
     3.5  
     3.6  using System;
     3.7 -using System.Xml;
     3.8  using IBBoard.Lang;
     3.9  
    3.10  namespace IBBoard.WarFoundry.API.Objects
    3.11 @@ -21,22 +20,22 @@
    3.12  		private double minPercentage;
    3.13  		private double maxPercentage;
    3.14  		private double costMultiplier;
    3.15 -		private RoundType roundType;
    3.16 -		private string mutexGroup;
    3.17 +		private RoundType roundType;
    3.18 +		private string[] mutexGroups;
    3.19  		private UnitType unitType;
    3.20  
    3.21 -		public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, "")
    3.22 +		public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor) : this(equipmentItem, equipmentFor, new string[0])
    3.23  		{
    3.24  			//Do nothing extra
    3.25  		}
    3.26  		
    3.27 -		public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, string mutexGroup)
    3.28 +		public UnitEquipmentItem(EquipmentItem equipmentItem, UnitType equipmentFor, params string[] mutexGroups)
    3.29  		{
    3.30  			item = equipmentItem;
    3.31  			unitType = equipmentFor;
    3.32 -			this.mutexGroup = mutexGroup;
    3.33 +			this.mutexGroups = mutexGroups;
    3.34  			unitType.AddEquipmentItem(this);
    3.35 -		}
    3.36 +		}
    3.37  		
    3.38  		public override string Name
    3.39  		{
    3.40 @@ -105,9 +104,15 @@
    3.41  			set { roundUp = value; }
    3.42  		}
    3.43  
    3.44 +		[Obsolete("Use MutexGroups instead for greater flexibility")]
    3.45  		public string MutexGroup
    3.46  		{
    3.47 -			get { return mutexGroup; }
    3.48 +			get { return (mutexGroups.Length == 0 ? "" : mutexGroups[0]); }
    3.49 +		}
    3.50 +
    3.51 +		public String[] MutexGroups
    3.52 +		{
    3.53 +			get { return (string[]) mutexGroups.Clone(); }
    3.54  		}
    3.55  
    3.56  		public UnitType EquipmentForUnit
    3.57 @@ -184,7 +189,7 @@
    3.58  
    3.59  		public bool HasAlternatives()
    3.60  		{
    3.61 -			if (MutexGroup=="")
    3.62 +			if (MutexGroups.Length == 0)
    3.63  			{
    3.64  				return false;
    3.65  			}
    3.66 @@ -195,7 +200,7 @@
    3.67  			else
    3.68  			{
    3.69  				//If the number of items in the MutEx group is greater than one then it must be this item plus another
    3.70 -				return EquipmentForUnit.GetEquipmentItemsByExclusionGroup(MutexGroup).Length > 1;
    3.71 +				return EquipmentForUnit.GetEquipmentItemsByExclusionGroups(MutexGroups).Length > 1;
    3.72  			}
    3.73  		}
    3.74  
    3.75 @@ -222,6 +227,31 @@
    3.76  		public bool CanBeUsedWithArmourType(ArmourType otherItemType)
    3.77  		{
    3.78  			return EquipmentItem.CanBeUsedWithArmourType(otherItemType);
    3.79 -		}
    3.80 +		}
    3.81 +
    3.82 +		/// <summary>
    3.83 +		/// 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)
    3.84 +		/// </summary>
    3.85 +		/// <param name="item">the item to check against</param>
    3.86 +		/// <returns><code>true</code> if the two items share at least one mutex group, else <code>false</code></returns>
    3.87 +		public bool IsMutuallyExclusive(UnitEquipmentItem item)
    3.88 +		{
    3.89 +			bool areMutex = false;
    3.90 +
    3.91 +			foreach (string mutex in MutexGroups)
    3.92 +			{
    3.93 +				foreach (string otherMutex in item.MutexGroups)
    3.94 +				{
    3.95 +					if (mutex.Equals(otherMutex))
    3.96 +					{
    3.97 +						areMutex = true;
    3.98 +						goto postLoop;
    3.99 +					}
   3.100 +				}
   3.101 +			}
   3.102 +			postLoop:
   3.103 +
   3.104 +			return areMutex;
   3.105 +		}
   3.106  	}
   3.107  }
     4.1 --- a/api/Objects/UnitType.cs	Sat Sep 26 18:48:36 2009 +0000
     4.2 +++ b/api/Objects/UnitType.cs	Sat Sep 26 19:51:11 2009 +0000
     4.3 @@ -233,15 +233,15 @@
     4.4  			{
     4.5  				equipment.Add(item.ID, item);
     4.6  				equipmentKeyOrder.Add(item.ID);
     4.7 -				AddToMutexGroup(item);
     4.8 +				AddToMutexGroups(item);
     4.9  			}
    4.10  		}
    4.11  		
    4.12 -		private void AddToMutexGroup(UnitEquipmentItem item)
    4.13 +		private void AddToMutexGroups(UnitEquipmentItem item)
    4.14  		{
    4.15 -			string mutexGroup = item.MutexGroup;
    4.16 +			string[] mutexGroups = item.MutexGroups;
    4.17  			
    4.18 -			if (mutexGroup!="" && mutexGroup!=null)
    4.19 +			foreach (string mutexGroup in mutexGroups)
    4.20  			{
    4.21  				List<UnitEquipmentItem> items = DictionaryUtils.GetValue(equipmentExclusionGroups, mutexGroup);
    4.22  				
    4.23 @@ -295,17 +295,25 @@
    4.24  		}
    4.25  
    4.26  		public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroup(string group)
    4.27 +		{
    4.28 +			return GetEquipmentItemsByExclusionGroups(new string[] { group });
    4.29 +		}
    4.30 +
    4.31 +		public UnitEquipmentItem[] GetEquipmentItemsByExclusionGroups(string[] groups)
    4.32  		{
    4.33 -			List<UnitEquipmentItem> list = DictionaryUtils.GetValue(equipmentExclusionGroups, group);
    4.34 -
    4.35 -			if (list == null)
    4.36 -			{
    4.37 -				return new UnitEquipmentItem[0];
    4.38 -			}
    4.39 -			else
    4.40 -			{
    4.41 -				return list.ToArray();
    4.42 -			}
    4.43 +			List<UnitEquipmentItem> list = new List<UnitEquipmentItem>();
    4.44 +
    4.45 +			foreach (string group in groups)
    4.46 +			{
    4.47 +				List<UnitEquipmentItem> groupList = DictionaryUtils.GetValue(equipmentExclusionGroups, group);
    4.48 +
    4.49 +				if (groupList != null)
    4.50 +				{
    4.51 +					list.AddRange(groupList);
    4.52 +				}
    4.53 +			}
    4.54 +
    4.55 +			return list.ToArray();
    4.56  		}
    4.57  		
    4.58  		public bool IsRatioLimitedEquipmentItem(EquipmentItem item)
     5.1 --- a/dtds/race.xsd	Sat Sep 26 18:48:36 2009 +0000
     5.2 +++ b/dtds/race.xsd	Sat Sep 26 19:51:11 2009 +0000
     5.3 @@ -35,7 +35,9 @@
     5.4  													<xs:complexType>
     5.5  														<xs:attribute name="id" type="xs:IDREF" />
     5.6  														<xs:attribute name="required" type="xs:boolean" default="false"/>
     5.7 +														<!-- exclusivityGroup is deprecated in favour of the comma-separated exclusivityGroups -->
     5.8  														<xs:attribute name="exclusivityGroup" type="xs:string" default=""/>
     5.9 +														<xs:attribute name="exclusivityGroups" type="xs:string" default=""/>
    5.10  														<xs:attribute name="minNum" type="core:nonNegativeOrInfiniteInteger" default="-1"/>
    5.11  														<xs:attribute name="maxNum" type="core:nonNegativeOrInfiniteInteger" default="-1"/>
    5.12  														<xs:attribute name="minPercentage" type="core:percentage" default="100"/>