// This file (UnitRequiresAtLeastNUnitsRequirement.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;
using IBBoard.WarFoundry.API.Objects;
using System.Text;
namespace IBBoard.WarFoundry.API.Objects.Requirement
{
///
/// A requirement where a WarFoundryObject requires at least N units of any of the specified unit types before any number of that object can be taken in an army.
///
/// The definition for how this requirement is built from a data file is defined in the class.
///
public class RequiresAtLeastNUnitsRequirement : AbstractUnitRequirement where OBJECT_TYPE : IWarFoundryObject
{
public static readonly string REQUIREMENT_ID = "RequiresAtLeastNUnits";
public RequiresAtLeastNUnitsRequirement(OBJECT_TYPE requirementOn, params UnitType[] requiredUnitTypes) : base(requirementOn, requiredUnitTypes)
{
//Do nothing
}
public override string RequirementID
{
get
{
return REQUIREMENT_ID;
}
}
protected override bool TypeEquals(object obj)
{
RequiresAtLeastNUnitsRequirement otherReq = obj as RequiresAtLeastNUnitsRequirement;
if (!Collections.Collections.AreEqual(RequiredTypes, otherReq.RequiredTypes))
{
return false;
}
else
{
return true;
}
}
public override int GetHashCode()
{
int hash = 0;
foreach (UnitCountRequirementData req in RequiredTypes)
{
hash += req.UnitType.GetHashCode();
}
return hash;
}
///
/// Checks whether the supplied WarFoundryObject can be added to the supplied army.
///
///
/// A Validation
enum to show the result of the validation
///
///
/// The object that we want to add. This may be involved in the check, or it may not affect the evaluation of the requirement
///
///
/// The army to add the object to.
///
public override Validation AllowsAdding(IWarFoundryObject wfObject, Army toArmy)
{
return IsApplicable(wfObject, toArmy) ? CheckAllowsAdding(wfObject, toArmy) : Validation.NotApplicable;
}
protected override bool IsApplicable(Army toArmy)
{
return false;
}
protected override bool IsApplicable(IWarFoundryObject toObject)
{
bool isApplicable = false;
UnitType unitType = GetUnitTypeFromObject(toObject);
if (unitType != null)
{
isApplicable = IsApplicable(unitType);
}
return isApplicable;
}
private bool IsApplicable(UnitType unitType)
{
bool isApplicable = false;
foreach (UnitCountRequirementData requirement in RequiredTypes)
{
if (requirement.UnitType.Equals(unitType))
{
isApplicable = true;
break;
}
}
return isApplicable;
}
private Validation CheckAllowsAdding(IWarFoundryObject wfObject, Army toArmy)
{
Validation isValid = Validation.Passed;
foreach (UnitCountRequirementData requirement in RequiredTypes)
{
if (GetUnitTypeCount(toArmy, requirement.UnitType, wfObject) < requirement.Count)
{
isValid = Validation.Failed;
break;
}
}
return isValid;
}
///
/// Adds a requirement for there to be at least minCount of a given UnitType
///
///
/// The unit type to require.
///
///
/// The minimum number of that type that must exist.
///
public void AddUnitTypeRequirement(UnitType unitType, int minCount)
{
RequiredTypes.Add(new UnitCountRequirementData(unitType, minCount));
}
///
/// Adds a requirement for there to be one or more of a given UnitType
///
///
/// The unit type to require.
///
public override void AddUnitTypeRequirement(UnitType unitType)
{
AddUnitTypeRequirement(unitType, 1);
}
///
/// Checks whether the supplied army is currently valid according to this requirement.
///
///
/// A Validation
enum to show the result of the validation
///
///
/// The army to validate
///
public override Validation ValidatesArmy(Army toValidate)
{
Validation isValid = Validation.Passed;
foreach (UnitCountRequirementData requirement in RequiredTypes)
{
if (toValidate.GetUnitTypeCount(requirement.UnitType) < requirement.Count)
{
isValid = Validation.Failed;
break;
}
}
return isValid;
}
protected override string GetFailedRequirementsString(Army army)
{
return String.Join("; ", GetFailedRequirements(army).ToArray());
}
private List GetFailedRequirements(Army army)
{
List failures = new List();
foreach (UnitCountRequirementData requirement in RequiredTypes)
{
int unitCount = army.GetUnitTypeCount(requirement.UnitType);
if (unitCount < requirement.Count)
{
failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")");
}
}
return failures;
}
protected override string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy)
{
return String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray());
}
private List GetFailedAddingRequirements(IWarFoundryObject toAdd, Army army)
{
List failures = new List();
foreach (UnitCountRequirementData requirement in RequiredTypes)
{
int unitCount = GetUnitTypeCount(army, requirement.UnitType, toAdd);
if (unitCount < requirement.Count)
{
failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")");
}
}
return failures;
}
protected override int GetObjectCountFromArmy(Army toArmy)
{
return 0;
}
}
}