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
|
|
63 public string SubID
|
|
64 {
|
|
65 get { return subID; }
|
|
66 set { subID = (value == null ? "" : value.Trim()); }
|
|
67 }
|
|
68
|
|
69 public GameSystem GameSystem
|
|
70 {
|
|
71 get { return system; }
|
|
72 set
|
|
73 {
|
|
74 if (value == null)
|
|
75 {
|
|
76 throw new ArgumentException("Game system for a race cannot be null");
|
|
77 }
|
|
78
|
|
79 system = value;
|
|
80 }
|
|
81 }
|
|
82
|
|
83 public string ArmyDefaultName
|
|
84 {
|
|
85 get { return defaultArmyName; }
|
|
86 set
|
|
87 {
|
|
88 if (value == null)
|
|
89 {
|
|
90 throw new ArgumentException("No default army name");
|
|
91 }
|
|
92
|
|
93 defaultArmyName = value;
|
|
94 }
|
|
95 }
|
|
96
|
|
97 public void AddCategory(Category cat)
|
|
98 {
|
|
99 categories[cat.ID] = cat;
|
|
100 }
|
|
101
|
|
102 /// <summary>
|
|
103 /// 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.
|
|
104 /// </summary>
|
|
105 /// <param name="id">
|
|
106 /// The ID of the category to get
|
|
107 /// </param>
|
|
108 /// <returns>
|
|
109 /// The <code>Category</code> with the specified ID, or null if one doesn't exist.
|
|
110 /// </returns>
|
|
111 public Category GetCategory(string id)
|
|
112 {
|
|
113 EnsureFullyLoaded();
|
|
114 Category cat = null;
|
|
115 categories.TryGetValue(id, out cat);
|
|
116
|
|
117 if (cat == null)
|
|
118 {
|
|
119 cat = GameSystem.GetCategory(id);
|
|
120 }
|
|
121
|
|
122 return cat;
|
|
123 }
|
|
124
|
|
125 public Category[] Categories
|
|
126 {
|
|
127 get
|
|
128 {
|
|
129 EnsureFullyLoaded();
|
|
130 Category[] cats;
|
|
131
|
|
132 if (!HasCategoryOverrides())
|
|
133 {
|
|
134 cats = GameSystem.Categories;
|
|
135 }
|
|
136 else
|
|
137 {
|
|
138 cats = DictionaryUtils.ToArray<string, Category>(categories);
|
|
139 }
|
|
140
|
|
141 return cats;
|
|
142 }
|
|
143 }
|
|
144
|
|
145 public bool HasCategoryOverrides()
|
|
146 {
|
|
147 EnsureFullyLoaded();
|
|
148 return categories.Count > 0;
|
|
149 }
|
|
150
|
|
151 public void AddEquipmentItem(EquipmentItem item)
|
|
152 {
|
|
153 //TODO: Throw DuplicateItemException
|
|
154 equipment.Add(item.ID, item);
|
|
155 }
|
|
156
|
|
157 public EquipmentItem GetEquipmentItem(string id)
|
|
158 {
|
|
159 EnsureFullyLoaded();
|
|
160 return DictionaryUtils.GetValue(equipment, id);
|
|
161 }
|
|
162
|
|
163 public List<EquipmentItem> GetEquipmentList()
|
|
164 {
|
|
165 EnsureFullyLoaded();
|
|
166 List<EquipmentItem> items = new List<EquipmentItem>();
|
|
167
|
|
168 foreach (EquipmentItem item in equipment.Values)
|
|
169 {
|
|
170 items.Add(item);
|
|
171 }
|
|
172
|
|
173 return items;
|
|
174 }
|
|
175
|
|
176 public void AddUnitType(UnitType type)
|
|
177 {
|
|
178 CacheUnitType(type);
|
|
179 unitTypes.Add(type.ID, type);
|
|
180 }
|
|
181
|
|
182 public UnitType[] GetUnitTypes(Category cat)
|
|
183 {
|
|
184 EnsureFullyLoaded();
|
|
185 BuildUnitTypesByCategoryCache();
|
|
186 Dictionary<string, UnitType> unitTypesDictionary;
|
|
187 unitTypesByCat.TryGetValue(cat, out unitTypesDictionary);
|
|
188 UnitType[] unitTypesArray;
|
|
189
|
|
190 if (unitTypesDictionary == null)
|
|
191 {
|
|
192 unitTypesArray = new UnitType[0];
|
|
193 }
|
|
194 else
|
|
195 {
|
|
196 unitTypesArray = DictionaryUtils.ToArray<string, UnitType>(unitTypesDictionary);
|
|
197 }
|
|
198
|
|
199 return unitTypesArray;
|
|
200 }
|
|
201
|
|
202 private void CacheUnitType(UnitType unit)
|
|
203 {
|
|
204 BuildUnitTypesByCategoryCache();
|
|
205
|
|
206 foreach (Category cat in unit.Categories)
|
|
207 {
|
|
208 Dictionary<string, UnitType> catUnitTypes = DictionaryUtils.GetValue(unitTypesByCat, cat);
|
|
209
|
|
210 if (catUnitTypes == null)
|
|
211 {
|
|
212 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));
|
|
213 }
|
|
214
|
|
215 catUnitTypes.Add(unit.ID, unit);
|
|
216 }
|
|
217 }
|
|
218
|
|
219 private void BuildUnitTypesByCategoryCache()
|
|
220 {
|
|
221 if (unitTypesByCat == null)
|
|
222 {
|
|
223 DoBuildUnitTypesByCategoryCache();
|
|
224 }
|
|
225 }
|
|
226
|
|
227 private void DoBuildUnitTypesByCategoryCache()
|
|
228 {
|
|
229 unitTypesByCat = new Dictionary<Category,Dictionary<string,UnitType>>();
|
|
230
|
|
231 foreach (Category category in Categories)
|
|
232 {
|
|
233 unitTypesByCat.Add(category, new Dictionary<string, UnitType>());
|
|
234 }
|
|
235
|
|
236 foreach (UnitType unit in unitTypes.Values)
|
|
237 {
|
|
238 CacheUnitType(unit);
|
|
239 }
|
|
240 }
|
|
241
|
|
242 public UnitType GetUnitType(string id)
|
|
243 {
|
|
244 EnsureFullyLoaded();
|
|
245 return DictionaryUtils.GetValue(unitTypes, id);
|
|
246 }
|
|
247
|
|
248 public List<Ability> GetAbilityList()
|
|
249 {
|
|
250 EnsureFullyLoaded();
|
|
251 List<Ability> items = new List<Ability>();
|
|
252 items.AddRange(abilities.Values);
|
|
253 return items;
|
|
254 }
|
|
255
|
|
256 public void AddAbility(Ability newAbility)
|
|
257 {
|
|
258 //TODO: Throw DuplicateItemException
|
|
259 abilities.Add(newAbility.ID, newAbility);
|
|
260 }
|
|
261
|
|
262 public Ability GetAbility(string id)
|
|
263 {
|
|
264 EnsureFullyLoaded();
|
|
265 return DictionaryUtils.GetValue(abilities, id);
|
|
266 }
|
|
267
|
|
268 protected virtual Dictionary<string, UnitType> RaceUnitTypes
|
|
269 {
|
|
270 get { return RaceRawUnitTypes; }
|
|
271 set { RaceRawUnitTypes = value; }
|
|
272 }
|
|
273
|
|
274 protected virtual Dictionary<string, EquipmentItem> RaceEquipment
|
|
275 {
|
|
276 get { return RaceRawEquipment; }
|
|
277 set { RaceRawEquipment = value; }
|
|
278 }
|
|
279
|
|
280 protected virtual Dictionary<string, Ability> RaceAbilities
|
|
281 {
|
|
282 get { return RaceRawAbilities; }
|
|
283 set { RaceRawAbilities = value; }
|
|
284 }
|
|
285
|
|
286 protected Dictionary<string, UnitType> RaceRawUnitTypes
|
|
287 {
|
|
288 get { return unitTypes; }
|
|
289 set { unitTypes = value; }
|
|
290 }
|
|
291
|
|
292 protected Dictionary<string, EquipmentItem> RaceRawEquipment
|
|
293 {
|
|
294 get { return equipment; }
|
|
295 set { equipment = value; }
|
|
296 }
|
|
297
|
|
298 protected Dictionary<string, Ability> RaceRawAbilities
|
|
299 {
|
|
300 get { return abilities; }
|
|
301 set { abilities = value; }
|
|
302 }
|
|
303
|
|
304 public void AddUnitMemberType(UnitMemberType memberType)
|
|
305 {
|
|
306 memberTypes[memberType.ID] = memberType;
|
|
307 }
|
|
308
|
|
309 /// <summary>
|
|
310 /// Gets a unit member type by its ID.
|
|
311 /// </summary>
|
|
312 /// <param name="id">
|
|
313 /// The ID of the unit member type to get
|
|
314 /// </param>
|
|
315 /// <returns>
|
|
316 /// The <code>UnitMemberType</code> with the specified ID, or null if one doesn't exist.
|
|
317 /// </returns>
|
|
318 public UnitMemberType GetUnitMemberType(string id)
|
|
319 {
|
|
320 EnsureFullyLoaded();
|
|
321 return DictionaryUtils.GetValue(memberTypes, id);
|
|
322 }
|
|
323
|
|
324 public UnitMemberType[] UnitMemberTypes
|
|
325 {
|
|
326 get
|
|
327 {
|
|
328 EnsureFullyLoaded();
|
|
329 return DictionaryUtils.ToArray(memberTypes);
|
|
330 }
|
|
331 }
|
|
332
|
|
333 public ICollection<IRequirement> GetRequirements()
|
|
334 {
|
|
335 ICollection<IRequirement> reqs = new List<IRequirement>();
|
|
336
|
|
337 foreach (UnitType unitType in unitTypes.Values)
|
|
338 {
|
|
339 foreach (IRequirement requirement in unitType.GetRequirements())
|
|
340 {
|
|
341 reqs.Add(requirement);
|
|
342 }
|
|
343 }
|
|
344
|
|
345 return reqs;
|
|
346 }
|
|
347 }
|
|
348 }
|