Mercurial > repos > IBDev-IBBoard.WarFoundry.API
view API/Objects/Requirement/AbstractUnitRequirement.cs @ 479:f48c49b53738
Re #410: "N units per M models in parent" requirement
* Add a "context" object that will hold the parent unit (or possibly other stuff)
* Update all method signatures and calls
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Wed, 23 May 2012 20:56:27 +0100 |
parents | 7b9ff7b1df24 |
children | e0641e0eb86c |
line wrap: on
line source
// This file (AbstractRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 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 System.Collections.Generic; namespace IBBoard.WarFoundry.API.Objects.Requirement { public abstract class AbstractUnitRequirement<OBJECT_TYPE> : IRequirement where OBJECT_TYPE : IWarFoundryObject { private List<UnitCountRequirementData> requiredTypes; private OBJECT_TYPE allowedObject; public AbstractUnitRequirement(OBJECT_TYPE allowedObject, params UnitType[] requiredUnitTypes) { this.allowedObject = allowedObject; requiredTypes = new List<UnitCountRequirementData>(); foreach (UnitType unitType in requiredUnitTypes) { AddUnitTypeRequirement(unitType); } } public abstract string RequirementID { get; } protected List<UnitCountRequirementData> ConstraintTypes { get { return requiredTypes; } } public abstract void AddUnitTypeRequirement(UnitType unitType); public override bool Equals(object obj) { if (obj == null) { return false; } else if (obj.GetType().Equals(this.GetType())) { return TypeEquals((AbstractUnitRequirement<OBJECT_TYPE>)obj); } else { return false; } } protected virtual bool TypeEquals(AbstractUnitRequirement<OBJECT_TYPE> obj) { AbstractUnitRequirement<OBJECT_TYPE> otherReq = obj as AbstractUnitRequirement<OBJECT_TYPE>; if (!this.AllowedObject.Equals(otherReq.AllowedObject)) { return false; } else if (!Collections.Collections.AreEqual(ConstraintTypes, otherReq.ConstraintTypes)) { return false; } else { return true; } } public override int GetHashCode() { int hash = GetType().FullName.GetHashCode() + AllowedObject.GetHashCode(); foreach (UnitCountRequirementData limit in ConstraintTypes) { hash += limit.GetHashCode(); } return hash; } protected virtual bool IsApplicable(IWarFoundryObject toObjectAdded, Army toArmy, AddingContext context) { return IsApplicable(toArmy, context) || IsApplicable(toObjectAdded, context); } protected virtual bool IsApplicable(Army toArmy, AddingContext context) { return false; } protected virtual bool IsApplicable(IWarFoundryObject toObject, AddingContext context) { return false; } public string GetValidationMessage(Army army) { string message = ""; Validation result = ValidatesArmy(army); if (!Validates.AsOkay(result)) { message = GetValidationFailedMessage(army); } return message; } protected virtual string ValidationFailedMessage { get { return "Army must contain: {0}."; } } private string GetValidationFailedMessage(Army army) { return String.Format(ValidationFailedMessage, GetFailedRequirementsString(army)); } protected abstract string GetFailedRequirementsString(Army army); public string GetAllowsAddingMessage(IWarFoundryObject toAdd, Army toArmy) { string message = ""; Validation result = AllowsAdding(toAdd, toArmy); if (!Validates.AsOkay(result)) { message = GetAllowsAddingFailedMessage(toAdd, toArmy); } return message; } protected virtual string AllowsAddingFailedMessage { get { return ValidationFailedMessage; } } protected string GetAllowsAddingFailedMessage(IWarFoundryObject toAdd, Army toArmy) { return String.Format(AllowsAddingFailedMessage, GetFailedAddingRequirementsString(toAdd, toArmy)); } protected abstract string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy); /// <summary> /// Checks whether the supplied WarFoundryObject can be added to the supplied army. /// </summary> /// <returns> /// A <code>Validation</code> enum to show the result of the validation /// </returns> /// <param name='wfObject'> /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement /// </param> /// <param name='toArmy'> /// The army to add the object to. /// </param> public Validation AllowsAdding(IWarFoundryObject wfObject, Army toArmy) { return AllowsAdding(wfObject, toArmy, null); } /// <summary> /// Checks whether the supplied WarFoundryObject can be added to the supplied army. /// </summary> /// <returns> /// A <code>Validation</code> enum to show the result of the validation /// </returns> /// <param name='wfObject'> /// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement /// </param> /// <param name='toArmy'> /// The army to add the object to. /// </param> /// <param name='context'>The context for the action (may be null)</param> public Validation AllowsAdding(IWarFoundryObject wfObject, Army toArmy, AddingContext context) { return IsApplicable(wfObject, toArmy, context) ? CheckAllowsAdding(wfObject, toArmy, context) : Validation.NotApplicable; } protected abstract Validation CheckAllowsAdding(IWarFoundryObject wfObject, Army toArmy, AddingContext context); public abstract Validation ValidatesArmy(Army army); protected UnitType GetUnitTypeFromObject(IWarFoundryObject toObject) { UnitType unitType = null; if (toObject is UnitType) { unitType = (UnitType)toObject; } else if (toObject is Unit) { unitType = ((Unit)toObject).UnitType; } return unitType; } protected int GetUnitTypeCount(Army toArmy, UnitType unitType, IWarFoundryObject wfObject) { return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType); } protected int GetUnitTypesCount(Army army, UnitType[] unitTypes) { return GetUnitTypesCount(army, unitTypes, null); } protected int GetUnitTypesCount(Army toArmy, UnitType[] unitTypes, IWarFoundryObject wfObject) { int count = 0; foreach (UnitType unitType in unitTypes) { count += GetUnitTypeCount(toArmy, unitType, wfObject); } return count; } protected int GetCountFromObject(IWarFoundryObject wfObject, UnitType limitedType) { return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0; } protected int GetObjectCount(Army toArmy, IWarFoundryObject wfObject) { return GetObjectCountFromArmy(toArmy) + GetObjectCountFromObject(wfObject); } protected abstract int GetObjectCountFromArmy(Army toArmy); protected abstract int GetObjectCountFromArmy(Army toArmy, OBJECT_TYPE obj); protected virtual int GetObjectCountFromObject(IWarFoundryObject wfObject) { return allowedObject.Equals(wfObject) ? 1 : 0; } public OBJECT_TYPE AllowedObject { get { return allowedObject; } } protected string GetUnitTypeList(UnitCountRequirementData limit) { List<String> namesList = new List<String>(); foreach (UnitType unitType in limit.UnitTypes) { namesList.Add(unitType.Name); } string[] names = namesList.ToArray(); return String.Join(" or ", names); } } }