view API/Objects/Requirement/RequiresNoMoreThanNOfUnitTypeRequirement.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 159dc9be36c2
children e0641e0eb86c
line source
1 // This file (RequiresNoMoreThanNOfUnitTypeRequirement.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2011 IBBoard
2 //
3 // 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.
4 using System;
5 using IBBoard.WarFoundry.API.Objects;
6 using System.Collections.Generic;
7 using System.Text;
9 namespace IBBoard.WarFoundry.API.Objects.Requirement
10 {
11 /// <summary>
12 /// A requirement where a WarFoundryObject cannot be taken in an army if more than N of a UnitType will be in the army.
13 /// </summary>
14 public abstract class RequiresNoMoreThanNOfUnitTypeRequirement<OBJECT_TYPE> : AbstractUnitRequirement<OBJECT_TYPE> where OBJECT_TYPE : IWarFoundryObject
15 {
16 public static readonly string REQUIREMENT_ID = "RequiresNoMoreThanNUnits";
18 public RequiresNoMoreThanNOfUnitTypeRequirement(OBJECT_TYPE allowedObject, params UnitType[] limitedUnitTypes) : base(allowedObject, limitedUnitTypes)
19 {
20 //Do nothing special
21 }
23 public override string RequirementID
24 {
25 get
26 {
27 return REQUIREMENT_ID;
28 }
29 }
31 protected override bool IsApplicable(Army toArmy, AddingContext context)
32 {
33 return false;
34 }
36 protected override bool IsApplicable(IWarFoundryObject toObject, AddingContext context)
37 {
38 bool isApplicable = false;
39 UnitType unitType = GetUnitTypeFromObject(toObject);
41 if (unitType != null)
42 {
43 isApplicable = IsApplicable(unitType);
44 }
46 return isApplicable;
47 }
49 private bool IsApplicable(UnitType unitType)
50 {
51 bool isApplicable = false;
52 foreach (UnitCountRequirementData requirement in ConstraintTypes)
53 {
54 if (requirement.UnitType.Equals(unitType))
55 {
56 isApplicable = true;
57 break;
58 }
59 }
60 return isApplicable;
61 }
63 protected override Validation CheckAllowsAdding(IWarFoundryObject wfObject, Army toArmy, AddingContext context)
64 {
65 Validation canAdd = Validation.Passed;
67 foreach (UnitCountRequirementData limit in ConstraintTypes)
68 {
69 if (GetUnitTypeCount(toArmy, limit.UnitType, wfObject) > limit.Count)
70 {
71 canAdd = Validation.Failed;
72 break;
73 }
74 }
76 return canAdd;
77 }
79 private int GetUnitTypeCount(Army toArmy, UnitType unitType, WarFoundryObject wfObject)
80 {
81 return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType);
82 }
84 private int GetCountFromObject(WarFoundryObject wfObject, UnitType limitedType)
85 {
86 return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0;
87 }
89 /// <summary>
90 /// Adds a requirement for there to be no more than maxCount of a given UnitType
91 /// </summary>
92 /// <param name='unitType'>
93 /// The unit type to limit.
94 /// </param>
95 /// <param name='minCount'>
96 /// The maximum number of that type that must exist.
97 /// </param>
98 public void AddUnitTypeRequirement(UnitType unitType, int maxCount)
99 {
100 ConstraintTypes.Add(new UnitCountRequirementData(unitType, maxCount));
101 }
103 /// <summary>
104 /// Adds a requirement for there to be none of a given UnitType
105 /// </summary>
106 /// <param name='unitType'>
107 /// The unit type to limit.
108 /// </param>
109 public override void AddUnitTypeRequirement(UnitType unitType)
110 {
111 AddUnitTypeRequirement(unitType, 0);
112 }
114 /// <summary>
115 /// Checks whether the supplied army is currently valid according to this requirement.
116 /// </summary>
117 /// <returns>
118 /// A <code>Validation</code> enum to show the result of the validation
119 /// </returns>
120 /// <param name='toValidate'>
121 /// The army to validate
122 /// </param>
123 public override Validation ValidatesArmy(Army army)
124 {
125 Validation canAdd = Validation.NotApplicable;
126 int allowedTypeCount = GetObjectCountFromArmy(army, AllowedObject);
128 if (allowedTypeCount > 0)
129 {
130 canAdd = Validation.Passed;
132 foreach (UnitCountRequirementData limit in ConstraintTypes)
133 {
134 if (army.GetUnitTypeCount(limit.UnitType) > limit.Count)
135 {
136 canAdd = Validation.Failed;
137 break;
138 }
139 }
140 }
141 else
142 {
143 canAdd = Validation.NotApplicable;
144 }
146 return canAdd;
147 }
149 protected override string ValidationFailedMessage
150 {
151 get
152 {
153 return "Army cannot contain more than: {0}.";
154 }
155 }
157 protected override string GetFailedRequirementsString(Army army)
158 {
159 return String.Join("; ", GetFailedRequirements(army).ToArray());
160 }
162 private List<string> GetFailedRequirements(Army army)
163 {
164 List<string> failures = new List<string>();
166 foreach (UnitCountRequirementData requirement in ConstraintTypes)
167 {
168 int unitCount = army.GetUnitTypeCount(requirement.UnitType);
170 if (unitCount > requirement.Count)
171 {
172 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (have " + unitCount + ")");
173 }
174 }
176 return failures;
177 }
179 protected override string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy)
180 {
181 return String.Join("; ", GetFailedAddingRequirements(toAdd, toArmy).ToArray());
182 }
184 private List<string> GetFailedAddingRequirements(IWarFoundryObject toAdd, Army army)
185 {
186 List<string> failures = new List<string>();
188 foreach (UnitCountRequirementData requirement in ConstraintTypes)
189 {
190 int unitCount = GetUnitTypeCount(army, requirement.UnitType, toAdd);
192 if (unitCount > requirement.Count)
193 {
194 failures.Add(requirement.Count + " × " + requirement.UnitType.Name + " (would have " + unitCount + ")");
195 }
196 }
198 return failures;
199 }
201 protected override int GetObjectCountFromArmy(Army toArmy)
202 {
203 return 0;
204 }
205 }
206 }