# HG changeset patch # User IBBoard # Date 1343572269 -3600 # Node ID aac77204ae0ead0219db11c91536a3c983e4cd58 # Parent c082a312a7412fe82c44884339fcd6ac949eb450 Re #410: Create "N units per M models in parent unit" requirement * Add methods to Army and ArmyCategory to get units of a given type * Implement validation on "N models in parent for M units" requirement diff -r c082a312a741 -r aac77204ae0e API/Objects/Army.cs --- a/API/Objects/Army.cs Sun Jul 29 14:16:14 2012 +0100 +++ b/API/Objects/Army.cs Sun Jul 29 15:31:09 2012 +0100 @@ -67,7 +67,7 @@ { get { - if (categories==null) + if (categories == null) { categories = new Dictionary(); Category[] raceCats = Race.Categories; @@ -79,9 +79,9 @@ Category raceCat = raceCats[i]; cat = new ArmyCategory(this, raceCat); categories[raceCat] = cat; - cat.PointsValueChanged+= PointsValueChangedMethod; - cat.UnitAdded+=new ObjectAddDelegate(Army_UnitAdded); - cat.UnitRemoved+=new ObjectRemoveDelegate(Army_UnitRemoved); + cat.PointsValueChanged += PointsValueChangedMethod; + cat.UnitAdded += new ObjectAddDelegate(Army_UnitAdded); + cat.UnitRemoved += new ObjectRemoveDelegate(Army_UnitRemoved); } } @@ -91,7 +91,7 @@ public ArmyCategory[] Categories { - get + get { return DictionaryUtils.ToArray(ArmyCategories); } @@ -104,7 +104,7 @@ public GameSystem GameSystem { - get { return (armyRace!=null ? armyRace.GameSystem : null); } + get { return (armyRace != null ? armyRace.GameSystem : null); } } protected void OnUnitAdded(Unit unit) @@ -117,7 +117,7 @@ protected void OnUnitRemoved(Unit unit) { - if (UnitRemoved!=null) + if (UnitRemoved != null) { UnitRemoved(unit); } @@ -125,7 +125,7 @@ private void OnPointsValueChanged(double oldValue, double newValue) { - if (PointsValueChanged!=null) + if (PointsValueChanged != null) { PointsValueChanged(this, oldValue, newValue); } @@ -139,7 +139,7 @@ double oldPoints = pointsTotal; pointsTotal = value; - if (oldPoints!=pointsTotal) + if (oldPoints != pointsTotal) { OnPointsValueChanged(oldPoints, pointsTotal); } @@ -192,7 +192,7 @@ { List fullList = new List(); - foreach(ArmyCategory cat in Categories) + foreach (ArmyCategory cat in Categories) { fullList.AddRange(cat.GetUnits()); } @@ -200,17 +200,29 @@ return fullList.ToArray(); } + public Unit[] GetUnits(UnitType unitType) + { + List fullList = new List(); + + foreach (ArmyCategory cat in Categories) + { + fullList.AddRange(cat.GetUnits(unitType)); + } + + return fullList.ToArray(); + } + public int MaxPoints { get { return maxPoints; } - set + set { if (value > 0) { int oldPoints = maxPoints; maxPoints = value; - if (MaxPointsValueChanged != null) + if (MaxPointsValueChanged != null) { MaxPointsValueChanged(this, oldPoints, maxPoints); } @@ -231,7 +243,7 @@ foreach (ArmyCategory cat in Categories) { - points+= cat.Points; + points += cat.Points; } TotalPoints = points; @@ -244,7 +256,7 @@ foreach (ArmyCategory cat in Categories) { - count+= cat.GetUnitTypeCount(unitType); + count += cat.GetUnitTypeCount(unitType); } return count; @@ -268,17 +280,17 @@ unit.UnitSizeChanged -= HandleUnitUnitSizeChanged; } - private void HandleUnitUnitEquipmentAmountChanged (WarFoundryObject obj, double oldValue, double newValue) + private void HandleUnitUnitEquipmentAmountChanged(WarFoundryObject obj, double oldValue, double newValue) { OnArmyCompositionChanged(); } - private void HandleUnitUnitSizeChanged (WarFoundryObject obj, int oldValue, int newValue) + private void HandleUnitUnitSizeChanged(WarFoundryObject obj, int oldValue, int newValue) { OnArmyCompositionChanged(); } - public ICollection GetRequirements () + public ICollection GetRequirements() { return Race.GetRequirements(); } diff -r c082a312a741 -r aac77204ae0e API/Objects/ArmyCategory.cs --- a/API/Objects/ArmyCategory.cs Sun Jul 29 14:16:14 2012 +0100 +++ b/API/Objects/ArmyCategory.cs Sun Jul 29 15:31:09 2012 +0100 @@ -26,7 +26,7 @@ { parentArmy = army; category = cat; - cat.NameChanged+=new StringValChangedDelegate(cat_NameChanged); + cat.NameChanged += new StringValChangedDelegate(cat_NameChanged); PointsValueChangedMethod = new DoubleValChangedDelegate(PointsValueChangedHandler); units = new List(); unitTypes = new Dictionary(); @@ -57,7 +57,7 @@ public override string Name { get { return category.Name; } - set + set { category.Name = value; } @@ -69,11 +69,11 @@ //List failedReqs = ParentArmy.CanAddUnit(unit); units.Add(unit); unit.Category = this; - unit.PointsValueChanged+= PointsValueChangedMethod; + unit.PointsValueChanged += PointsValueChangedMethod; int unitTypeCount; unitTypes.TryGetValue(unit.UnitType.ID, out unitTypeCount); - unitTypes[unit.UnitType.ID] = (int)unitTypeCount + 1; - TotalPoints+= unit.Points; + unitTypes[unit.UnitType.ID] = unitTypeCount + 1; + TotalPoints += unit.Points; OnUnitAdded(unit); } @@ -82,15 +82,15 @@ //TODO: Put back a similar check //List failedReqs = ParentArmy.CanRemoveUnit(unit); units.Remove(unit); - unitTypes[unit.UnitType.ID] = ((int)unitTypes[unit.UnitType.ID])-1; - TotalPoints-= unit.Points; - unit.PointsValueChanged-= PointsValueChangedMethod; + unitTypes[unit.UnitType.ID] = unitTypes[unit.UnitType.ID] - 1; + TotalPoints -= unit.Points; + unit.PointsValueChanged -= PointsValueChangedMethod; OnUnitRemoved(unit); } public int GetUnitTypeCount(UnitType unitType) { - return unitTypes.ContainsKey(unitType.ID) ? (int)unitTypes[unitType.ID] : 0; + return unitTypes.ContainsKey(unitType.ID) ? unitTypes[unitType.ID] : 0; } public Unit[] GetUnits() @@ -98,6 +98,19 @@ return units.ToArray(); } + public Unit[] GetUnits(UnitType unitType) + { + List filteredUnits = new List(); + foreach (Unit unit in units) + { + if (unit.UnitType.Equals(unitType)) + { + filteredUnits.Add(unit); + } + } + return filteredUnits.ToArray(); + } + public Unit[] GetMainUnits() { List mainUnits = new List(); @@ -116,12 +129,12 @@ private double TotalPoints { get { return pointsTotal; } - set + set { double oldVal = pointsTotal; pointsTotal = value; - if (oldVal!=pointsTotal) + if (oldVal != pointsTotal) { OnPointsValueChanged(oldVal, pointsTotal); } @@ -138,7 +151,7 @@ if (obj is Unit) { double diff = newVal - oldVal; - TotalPoints+= diff; + TotalPoints += diff; } } @@ -160,7 +173,7 @@ protected virtual void OnPointsValueChanged(double oldValue, double newValue) { - if (PointsValueChanged!=null) + if (PointsValueChanged != null) { PointsValueChanged(this, oldValue, newValue); } diff -r c082a312a741 -r aac77204ae0e API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirement.cs --- a/API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirement.cs Sun Jul 29 14:16:14 2012 +0100 +++ b/API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirement.cs Sun Jul 29 15:31:09 2012 +0100 @@ -3,6 +3,8 @@ // 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.WarFoundry.API.Objects.Requirement.Context; +using System.Collections.Generic; +using IBBoard.Collections; namespace IBBoard.WarFoundry.API.Objects.Requirement { @@ -84,11 +86,6 @@ this.ConstraintTypes.Add(new UnitCountRequirementData(unitType, 1, 1)); } - protected override string GetFailedRequirementsString(Army army) - { - return ""; - } - protected override string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy, AddingContext context) { UnitType unitType = GetUnitTypeFromObject(toAdd); @@ -171,7 +168,79 @@ public override Validation ValidatesArmy(Army army) { - throw new System.NotImplementedException(); + bool isApplicable = false; + Validation result = Validation.Passed; + + foreach (Unit unit in army.GetUnits(AllowedObject)) + { + Unit parentUnit = unit.ParentUnit; + isApplicable = isApplicable || (parentUnit != null && IsUnitTypeLimited(parentUnit.UnitType)); + if (isApplicable && !ValidatesUnitInArmy(unit, parentUnit, army)) + { + result = Validation.Failed; + break; + } + } + + return isApplicable ? result : Validation.NotApplicable; + } + + private bool ValidatesUnitInArmy(Unit unit, Unit parentUnit, Army army) + { + bool isValid = true; + int allowedTypeCount = GetChildCountFromUnit(parentUnit); + + foreach (UnitCountRequirementData limit in ConstraintTypes) + { + int limitedTypeCount = parentUnit.Size; + + if (!IsValidByRequirement(limit, allowedTypeCount, limitedTypeCount)) + { + isValid = false; + break; + } + } + + return isValid; + } + + protected override string ValidationFailedMessage + { + get + { + List parentsList = new List(); + + foreach (UnitCountRequirementData limit in ConstraintTypes) + { + parentsList.Add(String.Format("{0} × {1} for every {2} model in a parent unit of {3}", limit.AllowsCount, AllowedObject.Name, limit.Count, limit.UnitType.Name)); + } + + return String.Format("Army can only contain {0}: {{0}}.", String.Join(", ", parentsList.ToArray())); + } + } + + protected override string GetFailedRequirementsString(Army army) + { + return String.Join("; ", GetFailedValidationRequirements(army).ToArray()); + } + + private List GetFailedValidationRequirements(Army army) + { + List failures = new List(); + SimpleSet parentUnits = new SimpleSet(); + + foreach (Unit unit in army.GetUnits(AllowedObject)) + { + Unit parentUnit = unit.ParentUnit; + if (parentUnit != null && !parentUnits.Contains(parentUnit) && IsUnitTypeLimited(parentUnit.UnitType) && !ValidatesUnitInArmy(unit, parentUnit, army)) + { + parentUnits.Add(parentUnit); + int allowedTypeCount = GetChildCountFromUnit(parentUnit); + failures.Add(String.Format("{0} has {1} for {2}", parentUnit.Name, allowedTypeCount, parentUnit.Size)); + } + } + + return failures; } protected override int GetObjectCountFromArmy(Army toArmy)