Mercurial > repos > IBDev-IBBoard.WarFoundry.API
annotate API/Objects/Race.cs @ 496:00d6cf940c3c
Re #420: Saved army does not save "contained" structure
* Add loading of nesting from .army files
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Sat, 01 Sep 2012 15:28:26 +0100 |
parents | 95c1b68a600b |
children |
rev | line source |
---|---|
357 | 1 // This file (Race.cs) is a part of the IBBoard.WarFoundry.API project and is copyright 2007, 2008, 2009 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 using System.IO; | |
7 using System.Xml; | |
8 using IBBoard.IO; | |
9 using IBBoard.WarFoundry.API.Factories; | |
10 using IBBoard.WarFoundry.API.Objects.Requirement; | |
11 | |
12 namespace IBBoard.WarFoundry.API.Objects | |
13 { | |
14 public class Race : WarFoundryStagedLoadingObject | |
15 { | |
16 public static string SYSTEM_DEFAULT_RACE_ID = "GameDefault"; | |
17 | |
18 private string subID; | |
19 private GameSystem system; | |
20 private string defaultArmyName = ""; | |
21 private Dictionary<Category, Dictionary<string, UnitType>> unitTypesByCat; | |
22 private Dictionary<string, UnitType> unitTypes = new Dictionary<string,UnitType>(); | |
23 private Dictionary<string, EquipmentItem> equipment = new Dictionary<string,EquipmentItem>(); | |
24 private Dictionary<string, Ability> abilities = new Dictionary<string,Ability>(); | |
25 private Dictionary<string, Category> categories = new Dictionary<string,Category>(); | |
26 private Dictionary<string, UnitMemberType> memberTypes = new Dictionary<string, UnitMemberType>(); | |
27 | |
28 public Race(string raceID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : this(raceID, "", raceName, gameSystem, creatingFactory) | |
29 { | |
30 } | |
31 | |
32 public Race(string raceID, string raceSubID, string raceName, GameSystem gameSystem, IWarFoundryFactory creatingFactory) : base(raceID + (raceSubID != "" ? "_" + raceSubID : ""), raceName, creatingFactory) | |
33 { | |
468
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
34 subID = raceSubID ?? ""; |
357 | 35 system = gameSystem; |
36 } | |
37 | |
38 public override bool Equals (object obj) | |
39 { | |
40 if (obj == null) | |
41 { | |
42 return false; | |
43 } | |
44 else if (!(obj is Race)) | |
45 { | |
46 return false; | |
47 } | |
48 else | |
49 { | |
50 Race other = (Race)obj; | |
51 | |
52 if (!ID.Equals(other.ID) || !SubID.Equals(other.SubID) || !GameSystem.Equals(other.GameSystem)) | |
53 { | |
54 return false; | |
55 } | |
56 else | |
57 { | |
58 return true; | |
59 } | |
60 } | |
61 } | |
62 | |
419 | 63 public override int GetHashCode() |
64 { | |
65 return ID.GetHashCode() + SubID.GetHashCode() + GameSystem.GetHashCode() + ArmyDefaultName.GetHashCode(); | |
66 } | |
67 | |
357 | 68 public string SubID |
69 { | |
70 get { return subID; } | |
71 set { subID = (value == null ? "" : value.Trim()); } | |
72 } | |
73 | |
74 public GameSystem GameSystem | |
75 { | |
76 get { return system; } | |
77 set | |
78 { | |
79 if (value == null) | |
80 { | |
81 throw new ArgumentException("Game system for a race cannot be null"); | |
82 } | |
83 | |
84 system = value; | |
85 } | |
86 } | |
87 | |
88 public string ArmyDefaultName | |
89 { | |
90 get { return defaultArmyName; } | |
91 set | |
92 { | |
93 if (value == null) | |
94 { | |
95 throw new ArgumentException("No default army name"); | |
96 } | |
97 | |
98 defaultArmyName = value; | |
99 } | |
100 } | |
101 | |
102 public void AddCategory(Category cat) | |
103 { | |
104 categories[cat.ID] = cat; | |
105 } | |
106 | |
107 /// <summary> | |
108 /// Gets a category from its ID. Attempts to get the category from the race's overrides, or else it falls back to getting the Game System's category with that ID. | |
109 /// </summary> | |
110 /// <param name="id"> | |
111 /// The ID of the category to get | |
112 /// </param> | |
113 /// <returns> | |
114 /// The <code>Category</code> with the specified ID, or null if one doesn't exist. | |
115 /// </returns> | |
116 public Category GetCategory(string id) | |
117 { | |
118 EnsureFullyLoaded(); | |
119 Category cat = null; | |
120 categories.TryGetValue(id, out cat); | |
121 | |
122 if (cat == null) | |
123 { | |
124 cat = GameSystem.GetCategory(id); | |
125 } | |
126 | |
127 return cat; | |
128 } | |
129 | |
130 public Category[] Categories | |
131 { | |
132 get | |
133 { | |
134 EnsureFullyLoaded(); | |
135 Category[] cats; | |
136 | |
137 if (!HasCategoryOverrides()) | |
138 { | |
139 cats = GameSystem.Categories; | |
140 } | |
141 else | |
142 { | |
143 cats = DictionaryUtils.ToArray<string, Category>(categories); | |
144 } | |
145 | |
146 return cats; | |
147 } | |
148 } | |
149 | |
150 public bool HasCategoryOverrides() | |
151 { | |
152 EnsureFullyLoaded(); | |
153 return categories.Count > 0; | |
154 } | |
155 | |
156 public void AddEquipmentItem(EquipmentItem item) | |
157 { | |
158 //TODO: Throw DuplicateItemException | |
159 equipment.Add(item.ID, item); | |
160 } | |
161 | |
162 public EquipmentItem GetEquipmentItem(string id) | |
163 { | |
164 EnsureFullyLoaded(); | |
165 return DictionaryUtils.GetValue(equipment, id); | |
166 } | |
167 | |
168 public List<EquipmentItem> GetEquipmentList() | |
169 { | |
170 EnsureFullyLoaded(); | |
171 List<EquipmentItem> items = new List<EquipmentItem>(); | |
172 | |
173 foreach (EquipmentItem item in equipment.Values) | |
174 { | |
175 items.Add(item); | |
176 } | |
177 | |
178 return items; | |
179 } | |
180 | |
181 public void AddUnitType(UnitType type) | |
182 { | |
183 CacheUnitType(type); | |
184 unitTypes.Add(type.ID, type); | |
185 } | |
186 | |
187 public UnitType[] GetUnitTypes(Category cat) | |
188 { | |
189 EnsureFullyLoaded(); | |
190 BuildUnitTypesByCategoryCache(); | |
191 Dictionary<string, UnitType> unitTypesDictionary; | |
192 unitTypesByCat.TryGetValue(cat, out unitTypesDictionary); | |
193 UnitType[] unitTypesArray; | |
194 | |
195 if (unitTypesDictionary == null) | |
196 { | |
197 unitTypesArray = new UnitType[0]; | |
198 } | |
199 else | |
200 { | |
201 unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary); | |
202 } | |
203 | |
204 return unitTypesArray; | |
205 } | |
206 | |
207 private void CacheUnitType(UnitType unit) | |
208 { | |
468
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
209 if (unit.IsContainedOnly) |
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
210 { |
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
211 return; |
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
212 } |
95c1b68a600b
Re #359: Add "only contained" attribute to unit types
IBBoard <dev@ibboard.co.uk>
parents:
419
diff
changeset
|
213 |
357 | 214 BuildUnitTypesByCategoryCache(); |
215 | |
216 foreach (Category cat in unit.Categories) | |
217 { | |
218 Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat); | |
219 | |
220 if (catUnitTypes == null) | |
221 { | |
222 throw new InvalidFileException(String.Format("Unit type {0} with name {1} is a unit of an undefined category ({2})", unit.ID, unit.Name, cat.ID)); | |
223 } | |
224 | |
225 catUnitTypes.Add(unit.ID, unit); | |
226 } | |
227 } | |
228 | |
229 private void BuildUnitTypesByCategoryCache() | |
230 { | |
231 if (unitTypesByCat == null) | |
232 { | |
233 DoBuildUnitTypesByCategoryCache(); | |
234 } | |
235 } | |
236 | |
237 private void DoBuildUnitTypesByCategoryCache() | |
238 { | |
239 unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>(); | |
240 | |
241 foreach (Category category in Categories) | |
242 { | |
243 unitTypesByCat.Add(category, new Dictionary<string, UnitType>()); | |
244 } | |
245 | |
246 foreach (UnitType unit in unitTypes.Values) | |
247 { | |
248 CacheUnitType(unit); | |
249 } | |
250 } | |
251 | |
252 public UnitType GetUnitType(string id) | |
253 { | |
254 EnsureFullyLoaded(); | |
255 return DictionaryUtils.GetValue(unitTypes, id); | |
256 } | |
257 | |
258 public List<Ability> GetAbilityList() | |
259 { | |
260 EnsureFullyLoaded(); | |
261 List<Ability> items = new List<Ability>(); | |
262 items.AddRange(abilities.Values); | |
263 return items; | |
264 } | |
265 | |
266 public void AddAbility(Ability newAbility) | |
267 { | |
268 //TODO: Throw DuplicateItemException | |
269 abilities.Add(newAbility.ID, newAbility); | |
270 } | |
271 | |
272 public Ability GetAbility(string id) | |
273 { | |
274 EnsureFullyLoaded(); | |
275 return DictionaryUtils.GetValue(abilities, id); | |
276 } | |
277 | |
278 protected virtual Dictionary<string, UnitType> RaceUnitTypes | |
279 { | |
280 get { return RaceRawUnitTypes; } | |
281 set { RaceRawUnitTypes = value; } | |
282 } | |
283 | |
284 protected virtual Dictionary<string, EquipmentItem> RaceEquipment | |
285 { | |
286 get { return RaceRawEquipment; } | |
287 set { RaceRawEquipment = value; } | |
288 } | |
289 | |
290 protected virtual Dictionary<string, Ability> RaceAbilities | |
291 { | |
292 get { return RaceRawAbilities; } | |
293 set { RaceRawAbilities = value; } | |
294 } | |
295 | |
296 protected Dictionary<string, UnitType> RaceRawUnitTypes | |
297 { | |
298 get { return unitTypes; } | |
299 set { unitTypes = value; } | |
300 } | |
301 | |
302 protected Dictionary<string, EquipmentItem> RaceRawEquipment | |
303 { | |
304 get { return equipment; } | |
305 set { equipment = value; } | |
306 } | |
307 | |
308 protected Dictionary<string, Ability> RaceRawAbilities | |
309 { | |
310 get { return abilities; } | |
311 set { abilities = value; } | |
312 } | |
313 | |
314 public void AddUnitMemberType(UnitMemberType memberType) | |
315 { | |
316 memberTypes[memberType.ID] = memberType; | |
317 } | |
318 | |
319 /// <summary> | |
320 /// Gets a unit member type by its ID. | |
321 /// </summary> | |
322 /// <param name="id"> | |
323 /// The ID of the unit member type to get | |
324 /// </param> | |
325 /// <returns> | |
326 /// The <code>UnitMemberType</code> with the specified ID, or null if one doesn't exist. | |
327 /// </returns> | |
328 public UnitMemberType GetUnitMemberType(string id) | |
329 { | |
330 EnsureFullyLoaded(); | |
331 return DictionaryUtils.GetValue(memberTypes, id); | |
332 } | |
333 | |
334 public UnitMemberType[] UnitMemberTypes | |
335 { | |
336 get | |
337 { | |
338 EnsureFullyLoaded(); | |
339 return DictionaryUtils.ToArray(memberTypes); | |
340 } | |
341 } | |
342 | |
343 public ICollection<IRequirement> GetRequirements() | |
344 { | |
345 ICollection<IRequirement> reqs = new List<IRequirement>(); | |
346 | |
347 foreach (UnitType unitType in unitTypes.Values) | |
348 { | |
349 foreach (IRequirement requirement in unitType.GetRequirements()) | |
350 { | |
351 reqs.Add(requirement); | |
352 } | |
353 } | |
354 | |
355 return reqs; | |
356 } | |
357 } | |
358 } |