comparison API/Objects/Requirement/AbstractUnitRequirement.cs @ 455:afc6410e4efc

Re #379: Fix validation of requirements to check for unit * Move to "Unit" requirements, since we assume things depend on units * Rename some classes to more meaningful names from unit-based change * Rename "requires N for M" requirement as we can make it more flexible
author IBBoard <dev@ibboard.co.uk>
date Wed, 22 Feb 2012 20:45:39 +0000
parents
children 52baffdd2ab9
comparison
equal deleted inserted replaced
454:def5d333c5e8 455:afc6410e4efc
1 // This file (AbstractRequirement.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 System.Collections.Generic;
6
7 namespace IBBoard.WarFoundry.API.Objects.Requirement
8 {
9 public abstract class AbstractUnitRequirement<OBJECT_TYPE> : IRequirement where OBJECT_TYPE : IWarFoundryObject
10 {
11 private List<UnitCountRequirementData> requiredTypes;
12 private OBJECT_TYPE allowedObject;
13
14 public AbstractUnitRequirement(OBJECT_TYPE allowedObject, params UnitType[] requiredUnitTypes)
15 {
16 this.allowedObject = allowedObject;
17 requiredTypes = new List<UnitCountRequirementData>();
18
19 foreach (UnitType unitType in requiredUnitTypes)
20 {
21 AddUnitTypeRequirement(unitType);
22 }
23 }
24
25 public abstract string RequirementID { get; }
26
27 protected List<UnitCountRequirementData> RequiredTypes { get { return requiredTypes; } }
28
29 public abstract void AddUnitTypeRequirement(UnitType unitType);
30
31 public override bool Equals(object obj)
32 {
33 if (obj == null)
34 {
35 return false;
36 }
37 else if (obj.GetType().Equals(this.GetType()))
38 {
39 return TypeEquals(obj);
40 }
41 else
42 {
43 return false;
44 }
45 }
46
47 public override abstract int GetHashCode();
48
49 /// <summary>
50 /// Type-specific equality checking - must be implemented by each class
51 /// </summary>
52 /// <returns>
53 /// <code>true</code> if this object is equal to <code>obj</code>, else <code>false</code>
54 /// </returns>
55 /// <param name='obj'>
56 /// The object to compare to
57 /// </param>
58 protected abstract bool TypeEquals(object obj);
59
60 protected virtual bool IsApplicable(IWarFoundryObject toObjectAdded, Army toArmy)
61 {
62 return IsApplicable(toArmy) || IsApplicable(toObjectAdded);
63 }
64
65 protected virtual bool IsApplicable(Army toArmy)
66 {
67 return true;
68 }
69
70 protected virtual bool IsApplicable(IWarFoundryObject toObject)
71 {
72 return true;
73 }
74
75 public string GetValidationMessage(Army army)
76 {
77 string message = "";
78
79 Validation result = ValidatesArmy(army);
80 if (!Validates.AsOkay(result))
81 {
82 message = GetValidationFailedMessage(army);
83 }
84
85 return message;
86 }
87
88 protected virtual string ValidationFailedMessage { get { return "Army must contain: {0}."; } }
89
90 private string GetValidationFailedMessage(Army army)
91 {
92 return String.Format(ValidationFailedMessage, GetFailedRequirementsString(army));
93 }
94
95 protected abstract string GetFailedRequirementsString(Army army);
96
97 public string GetAllowsAddingMessage(IWarFoundryObject toAdd, Army toArmy)
98 {
99 string message = "";
100
101 Validation result = AllowsAdding(toAdd, toArmy);
102 if (!Validates.AsOkay(result))
103 {
104 message = GetAllowsAddingFailedMessage(toAdd, toArmy);
105 }
106
107 return message;
108 }
109
110 protected virtual string AllowsAddingFailedMessage { get { return ValidationFailedMessage; } }
111
112 protected string GetAllowsAddingFailedMessage(IWarFoundryObject toAdd, Army toArmy)
113 {
114 return String.Format(AllowsAddingFailedMessage, GetFailedAddingRequirementsString(toAdd, toArmy));
115 }
116
117 protected abstract string GetFailedAddingRequirementsString(IWarFoundryObject toAdd, Army toArmy);
118
119 public abstract Validation AllowsAdding(IWarFoundryObject wfObject, Army toArmy);
120
121 public abstract Validation ValidatesArmy(Army army);
122
123 protected UnitType GetUnitTypeFromObject(IWarFoundryObject toObject)
124 {
125 UnitType unitType = null;
126
127 if (toObject is UnitType)
128 {
129 unitType = (UnitType)toObject;
130 }
131 else if (toObject is Unit)
132 {
133 unitType = ((Unit)toObject).UnitType;
134 }
135
136 return unitType;
137 }
138
139 protected int GetUnitTypeCount(Army toArmy, UnitType unitType, IWarFoundryObject wfObject)
140 {
141 return toArmy.GetUnitTypeCount(unitType) + GetCountFromObject(wfObject, unitType);
142 }
143
144 protected int GetCountFromObject(IWarFoundryObject wfObject, UnitType limitedType)
145 {
146 return (limitedType.Equals(wfObject) || (wfObject is Unit && ((Unit)wfObject).UnitType.Equals(limitedType))) ? 1 : 0;
147 }
148
149 protected int GetObjectCount(Army toArmy, IWarFoundryObject wfObject)
150 {
151 return GetObjectCountFromArmy(toArmy) + GetObjectCountFromObject(wfObject);
152 }
153
154 protected abstract int GetObjectCountFromArmy(Army toArmy);
155
156 protected virtual int GetObjectCountFromObject(IWarFoundryObject wfObject)
157 {
158 return allowedObject.Equals(wfObject) ? 1 : 0;
159 }
160
161 public OBJECT_TYPE AllowedObject { get { return allowedObject; } }
162 }
163 }
164