Mercurial > repos > IBBoard.WarFoundry.API
diff API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirement.cs @ 487:248df19652f9
Re #410: Create "N units per M models in parent unit" requirement
* Add null adding context
* Add initial skeleton of "N units per M models in parent unit" requirement
* Update use of context
* Standardise some of "is applicable" testing
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 27 Jul 2012 20:31:12 +0100 |
parents | |
children | c082a312a741 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/API/Objects/Requirement/UnitRequiresNParentModelsForMUnitsRequirement.cs Fri Jul 27 20:31:12 2012 +0100 @@ -0,0 +1,183 @@ +// This file (UnitRequiresNoMoreThanNUnitsPerMModelsInParentUnitRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2012 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.WarFoundry.API.Objects.Requirement.Context; + +namespace IBBoard.WarFoundry.API.Objects.Requirement +{ + public class UnitRequiresNParentModelsForMUnitsRequirement : AbstractUnitRequirement<UnitType> + { + public static readonly string N_PER_M_IN_PARENT_REQUIREMENT_ID = "RequiresNoMoreThanNUnitsPerMModelsInParent"; + + public UnitRequiresNParentModelsForMUnitsRequirement(UnitType allowedObject, params UnitType[] limitedUnitTypes) : base(allowedObject, limitedUnitTypes) + { + //Do nothing special + } + + public override string RequirementID + { + get + { + return N_PER_M_IN_PARENT_REQUIREMENT_ID; + } + } + + protected override bool IsApplicable(IWarFoundryObject toObject, AddingContext context) + { + return GetCountFromContext(context) > 0 && IsApplicable(toObject); + } + + private bool IsApplicable(IWarFoundryObject toObject) + { + bool isApplicable = false; + UnitType unitType = GetUnitTypeFromObject(toObject); + + if (unitType != null) + { + isApplicable = this.AllowedObject.Equals(unitType) || IsApplicable(unitType); + } + + return isApplicable; + } + + private bool IsApplicable(UnitType unitType) + { + bool isApplicable = false; + foreach (UnitCountRequirementData requirement in ConstraintTypes) + { + if (requirement.UnitType.Equals(unitType)) + { + isApplicable = true; + break; + } + } + return isApplicable; + } + + protected override int GetObjectCountFromArmy(Army toArmy, UnitType obj) + { + return 0; + } + + protected override int GetObjectCountFromObject(IWarFoundryObject wfObject) + { + return base.GetObjectCountFromObject(wfObject); + } + + private int GetCountFromContext(AddingContext context) + { + AddingToParentContext parentContext = context as AddingToParentContext; + + if (parentContext == null || !IsUnitTypeLimited(parentContext.ParentUnit.UnitType)) + { + return 0; + } + else + { + return parentContext.ParentUnit.Size; + } + } + + public override void AddUnitTypeRequirement(UnitType unitType) + { + 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); + AddingToParentContext parentContext = context as AddingToParentContext; + + if (unitType != null && parentContext != null) + { + return GetFailedAddingRequirementsString(unitType, parentContext.ParentUnit, toArmy); + } + else + { + return ""; + } + } + + private string GetFailedAddingRequirementsString(UnitType unitType, Unit parentUnit, Army toArmy) + { + int allowedTypeCount = GetChildCountFromUnit(parentUnit); + + return String.Format("Army can only contain {0} × {1} as a sub-unit of each {2}, would have {3}", allowedTypeCount, unitType.Name, parentUnit.UnitType.Name, (allowedTypeCount + 1)); + } + + protected override string AllowsAddingFailedMessage + { + get + { + return "{0}"; + } + } + + protected override Validation CheckAllowsAdding(IWarFoundryObject wfObject, Army toArmy, AddingContext context) + { + AddingToParentContext parentContext = context as AddingToParentContext; + return parentContext == null ? Validation.Passed : CheckAllowsAdding(wfObject, toArmy, parentContext); + } + + private Validation CheckAllowsAdding(IWarFoundryObject obj, Army toArmy, AddingToParentContext context) + { + Validation canAdd = Validation.Passed; + Unit parentUnit = context.ParentUnit; + //Get count and add one because we're checking if this unit can be added, so it hasn't been added yet + int allowedTypeCount = GetChildCountFromUnit(parentUnit) + 1; + + foreach (UnitCountRequirementData limit in ConstraintTypes) + { + int limitedTypeCount = parentUnit.Size; + + if (!IsValidByRequirement(limit, allowedTypeCount, limitedTypeCount)) + { + canAdd = Validation.Failed; + break; + } + } + + return canAdd; + } + + private int GetChildCountFromUnit(Unit parentUnit) + { + int count = 0; + + foreach (Unit unit in parentUnit.ContainedUnits) + { + if (unit.UnitType.Equals(AllowedObject)) + { + count++; + } + } + + return count; + } + + private bool IsValidByRequirement(UnitCountRequirementData limit, int allowedTypeCount, int limitedTypeCount) + { + //Round down limited units to get only whole amounts + double normalisedLimited = Math.Floor(limitedTypeCount / (limit.Count * 1.0)); + double normalisedAllowed = allowedTypeCount / (limit.AllowsCount * 1.0); + return normalisedLimited >= 1 && normalisedAllowed <= normalisedLimited; + } + + public override Validation ValidatesArmy(Army army) + { + throw new System.NotImplementedException(); + } + + protected override int GetObjectCountFromArmy(Army toArmy) + { + return 0; + } + } +} +