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 {
|
|
34 subID = (raceSubID == null ? "" : raceSubID);
|
|
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 {
|
|
209 BuildUnitTypesByCategoryCache();
|
|
210
|
|
211 foreach (Category cat in unit.Categories)
|
|
212 {
|
|
213 Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat);
|
|
214
|
|
215 if (catUnitTypes == null)
|
|
216 {
|
|
217 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));
|
|
218 }
|
|
219
|
|
220 catUnitTypes.Add(unit.ID, unit);
|
|
221 }
|
|
222 }
|
|
223
|
|
224 private void BuildUnitTypesByCategoryCache()
|
|
225 {
|
|
226 if (unitTypesByCat == null)
|
|
227 {
|
|
228 DoBuildUnitTypesByCategoryCache();
|
|
229 }
|
|
230 }
|
|
231
|
|
232 private void DoBuildUnitTypesByCategoryCache()
|
|
233 {
|
|
234 unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>();
|
|
235
|
|
236 foreach (Category category in Categories)
|
|
237 {
|
|
238 unitTypesByCat.Add(category, new Dictionary<string, UnitType>());
|
|
239 }
|
|
240
|
|
241 foreach (UnitType unit in unitTypes.Values)
|
|
242 {
|
|
243 CacheUnitType(unit);
|
|
244 }
|
|
245 }
|
|
246
|
|
247 public UnitType GetUnitType(string id)
|
|
248 {
|
|
249 EnsureFullyLoaded();
|
|
250 return DictionaryUtils.GetValue(unitTypes, id);
|
|
251 }
|
|
252
|
|
253 public List<Ability> GetAbilityList()
|
|
254 {
|
|
255 EnsureFullyLoaded();
|
|
256 List<Ability> items = new List<Ability>();
|
|
257 items.AddRange(abilities.Values);
|
|
258 return items;
|
|
259 }
|
|
260
|
|
261 public void AddAbility(Ability newAbility)
|
|
262 {
|
|
263 //TODO: Throw DuplicateItemException
|
|
264 abilities.Add(newAbility.ID, newAbility);
|
|
265 }
|
|
266
|
|
267 public Ability GetAbility(string id)
|
|
268 {
|
|
269 EnsureFullyLoaded();
|
|
270 return DictionaryUtils.GetValue(abilities, id);
|
|
271 }
|
|
272
|
|
273 protected virtual Dictionary<string, UnitType> RaceUnitTypes
|
|
274 {
|
|
275 get { return RaceRawUnitTypes; }
|
|
276 set { RaceRawUnitTypes = value; }
|
|
277 }
|
|
278
|
|
279 protected virtual Dictionary<string, EquipmentItem> RaceEquipment
|
|
280 {
|
|
281 get { return RaceRawEquipment; }
|
|
282 set { RaceRawEquipment = value; }
|
|
283 }
|
|
284
|
|
285 protected virtual Dictionary<string, Ability> RaceAbilities
|
|
286 {
|
|
287 get { return RaceRawAbilities; }
|
|
288 set { RaceRawAbilities = value; }
|
|
289 }
|
|
290
|
|
291 protected Dictionary<string, UnitType> RaceRawUnitTypes
|
|
292 {
|
|
293 get { return unitTypes; }
|
|
294 set { unitTypes = value; }
|
|
295 }
|
|
296
|
|
297 protected Dictionary<string, EquipmentItem> RaceRawEquipment
|
|
298 {
|
|
299 get { return equipment; }
|
|
300 set { equipment = value; }
|
|
301 }
|
|
302
|
|
303 protected Dictionary<string, Ability> RaceRawAbilities
|
|
304 {
|
|
305 get { return abilities; }
|
|
306 set { abilities = value; }
|
|
307 }
|
|
308
|
|
309 public void AddUnitMemberType(UnitMemberType memberType)
|
|
310 {
|
|
311 memberTypes[memberType.ID] = memberType;
|
|
312 }
|
|
313
|
|
314 /// <summary>
|
|
315 /// Gets a unit member type by its ID.
|
|
316 /// </summary>
|
|
317 /// <param name="id">
|
|
318 /// The ID of the unit member type to get
|
|
319 /// </param>
|
|
320 /// <returns>
|
|
321 /// The <code>UnitMemberType</code> with the specified ID, or null if one doesn't exist.
|
|
322 /// </returns>
|
|
323 public UnitMemberType GetUnitMemberType(string id)
|
|
324 {
|
|
325 EnsureFullyLoaded();
|
|
326 return DictionaryUtils.GetValue(memberTypes, id);
|
|
327 }
|
|
328
|
|
329 public UnitMemberType[] UnitMemberTypes
|
|
330 {
|
|
331 get
|
|
332 {
|
|
333 EnsureFullyLoaded();
|
|
334 return DictionaryUtils.ToArray(memberTypes);
|
|
335 }
|
|
336 }
|
|
337
|
|
338 public ICollection<IRequirement> GetRequirements()
|
|
339 {
|
|
340 ICollection<IRequirement> reqs = new List<IRequirement>();
|
|
341
|
|
342 foreach (UnitType unitType in unitTypes.Values)
|
|
343 {
|
|
344 foreach (IRequirement requirement in unitType.GetRequirements())
|
|
345 {
|
|
346 reqs.Add(requirement);
|
|
347 }
|
|
348 }
|
|
349
|
|
350 return reqs;
|
|
351 }
|
|
352 }
|
|
353 }
|