1 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
25 #include <sigc++/trackable.h>
27 #include "xmlhelper.h"
28 #include "armyproto.h"
37 //! A collection of Army prototype objects.
39 * An Armyset is a complete set of Army prototype objects. An Army prototype
40 * is a kind of Army, as opposed to an Army unit instance (e.g. on the game
41 * map). See the Army class for more information about what an Army prototype
42 * is. The Armyset describes the size of the graphic tiles that each Army
43 * graphic occupies on the screen (Army::d_tilesize).
44 * Two special images are kept with the Armyset: the ship picture, and the
45 * planted standard picture.
47 * The ship picture is what the Stack looks like when it is in a boat.
48 * The planted standard is what the player's standard looks like when it has
49 * been planted in the ground.
51 * Armysets are most often referred to by their Id (Armyset::d_id), but may
52 * sometimes be referred to by their name (Armyset::d_name) or subdirectory
53 * name (Armyset::d_subdir).
55 * Armyset objects are loaded from an armyset configuration file.
57 * Armyset objects are created by the armyset editor.
59 * Every Player has an Armyset that dictates the characteristics of the
60 * player's forces, but in practise there is only one Armyset per scenario.
62 * The armyset configuration file is a same named XML file inside the Armyset's
63 * directory. E.g. army/${Armyset::d_subdir}/${Armyset::d_subdir}.xml.
65 class Armyset: public std::list<ArmyProto *>, public sigc::trackable, public Set
69 //! The xml tag of this object in an armyset configuration file.
70 static std::string d_tag;
71 static std::string file_extension;
73 //! Default constructor.
77 * @param id The unique Id of this Armyset among all other Armyset
78 * objects. Must be more than 0.
79 * @param name The name of the Armyset. Analagous to Armyset::d_name.
81 Armyset(guint32 id, std::string name);
82 //! Loading constructor.
84 * Load armyset XML entities from armyset configuration files.
86 Armyset(XML_Helper* helper, std::string directory);
88 static Armyset *create(std::string filename);
94 * @param helper An opened armyset configuration file.
96 //! Save the Armyset to an Armyset configuration file.
97 bool save(XML_Helper* helper);
99 //! Returns the size of this armyset.
101 * @return The number of Army prototype objects in the armyset or 0
102 * on error (an armyset should never have a size of 0).
104 guint32 getSize() const {return size();}
106 //! Get the tile size of the Armyset.
108 * The width and height of the Army graphic images as they appear
110 * Analagous to the armyset.d_tilesize XML entity in the armyset
111 * configuration file.
113 guint32 getTileSize() const {return d_tilesize;}
115 //! Get the unique identifier for this armyset.
117 * Analagous to the armyset.d_id XML entity in the armyset
118 * configuration file.
120 guint32 getId() const {return d_id;}
122 //! Set the unique identifier for this armyset.
123 void setId(guint32 id) {d_id = id;}
125 //! Returns the name of the armyset.
127 * Analagous to the armyset.d_name XML entity in the armyset
128 * configuration file.
130 * @return The name or an empty string on error.
132 std::string getName() const {return _(d_name.c_str());}
134 //! Set the name of the armyset.
136 * @note This method is only used in the armyset editor.
138 void setName(std::string name) {d_name = name;}
140 //! Get the copyright holders for this armyset.
141 std::string getCopyright() const {return d_copyright;};
143 //! Set the copyright holders on the armyset.
144 void setCopyright(std::string copy) {d_copyright = copy;};
146 //! Get the license of this armyset.
147 std::string getLicense() const {return d_license;};
149 //! Set the license for this armyset.
150 void setLicense(std::string license) {d_license = license;};
152 //! Get the subdirectory name of the armyset.
154 * This value does not contain a path (e.g. no slashes). It is the
155 * name of an armyset directory inside army/.
157 * @return The name of the subdirectory the Armyset is held in.
159 std::string getSubDir() const {return d_subdir;}
161 //! Set the subdirectory that the armyset is in.
162 void setSubDir(std::string dir) {d_subdir = dir;}
164 //! Get the image of the stack in a ship (minus the mask).
165 PixMask* getShipPic() const {return d_ship;}
167 //! Set the image of the stack in a ship
168 void setShipImage(PixMask* ship) {d_ship = ship;};
170 //! Get the mask portion of the image of the stack in a ship.
171 PixMask* getShipMask() const {return d_shipmask;}
173 //! Set the mask portion of the image of the stack in a ship.
174 void setShipMask(PixMask* shipmask) {d_shipmask = shipmask;};
176 //! Get the image of the bag.
177 PixMask* getBagPic() const {return d_bag;}
179 //! Set the image of the bag.
180 void setBagPic(PixMask* s) {d_bag = s;};
182 //! Get the image of the planted standard (minus the mask).
183 PixMask* getStandardPic() const {return d_standard;}
185 //! Set the image of the planted standard (minus the mask).
186 void setStandardPic(PixMask* s) {d_standard = s;};
188 //! Get the mask portion of the image of the planted standard.
189 PixMask* getStandardMask() const {return d_standard_mask;}
191 //! Set the mask portion of the image of the planted standard.
192 void setStandardMask(PixMask* s) {d_standard_mask = s;};
194 //! Set the name of the file holding the image of the stack in a boat.
195 void setShipImageName(std::string n) {d_stackship_name = n;};
197 //! Get the name of the file holding the image of the stack in a boat.
198 std::string getShipImageName() {return d_stackship_name;};
200 //! Set the name of the file holding the image of the hero's flag.
201 void setStandardImageName(std::string n) {d_standard_name = n;};
203 //! Get the name of the file holding the image of the hero's flag.
204 std::string getStandardImageName() {return d_standard_name;};
206 //! Set the name of the file holding the image of the bag.
207 void setBagImageName(std::string n) {d_bag_name = n;};
209 //! Get the name of the file holding the image of the bag.
210 std::string getBagImageName() {return d_bag_name;};
212 //! Find an army with a type in this armyset.
214 * Scan the Army prototype objects in this Armyset and return it.
216 * @note This is only used for the editor. Most callers should use
217 * Armysetlist::getArmy instead.
219 * @param army_type The army type id of the Army prototype object
220 * to search for in this Armyset.
222 * @return The Army with the given army type id, or NULL if none
225 ArmyProto * lookupArmyByType(guint32 army_type) const;
227 ArmyProto * lookupArmyByName(std::string name) const;
229 ArmyProto * lookupArmyByStrengthAndTurns(guint32 str, guint32 turns) const;
231 ArmyProto * lookupArmyByGender(Hero::Gender gender) const;
233 ArmyProto * lookupSimilarArmy(ArmyProto *army) const;
234 //! can this armyset be used within the game?
238 bool validatePurchasables();
239 bool validateRuinDefenders();
240 bool validateAwardables();
242 bool validateStandard();
244 bool validateArmyUnitImages();
245 bool validateArmyUnitImage(ArmyProto *a, Shield::Colour &c);
246 bool validateArmyUnitNames();
247 bool validateArmyUnitName(ArmyProto *a);
248 //! get filenames in this armyset, excepting the configuration file.
249 void getFilenames(std::list<std::string> &files);
250 void instantiateImages();
251 void uninstantiateImages();
252 void loadStandardPic(std::string image_filename);
253 void loadShipPic(std::string image_filename);
254 void loadBagPic(std::string image_filename);
256 std::string getConfigurationFile();
257 static std::list<std::string> scanUserCollection();
258 static std::list<std::string> scanSystemCollection();
259 static void switchArmyset(Army *army, const Armyset *armyset);
260 static void switchArmyset(ArmyProdBase *army, const Armyset *armyset);
261 static void switchArmysetForRuinKeeper(Army *army, const Armyset *armyset);
262 const ArmyProto * getRandomRuinKeeper() const;
263 const ArmyProto *getRandomAwardableAlly() const;
267 //! Callback function for the army tag (see XML_Helper)
268 bool loadArmyProto(std::string tag, XML_Helper* helper);
270 //! The unique Id of this armyset.
272 * This Id is unique among all other armysets.
273 * It is analgous to armyset.d_id in the armyset configuration files.
277 //! The name of the Armyset.
279 * This value appears in game configuration dialogs.
280 * It is analgous to armyset.d_name in the armyset configuration files.
284 //! The armyset has these copyright holders.
285 std::string d_copyright;
287 //! The license of the armyset.
288 std::string d_license;
290 //! The subdirectory of the Armyset.
292 * This is the name of the subdirectory that the Armyset files are
293 * residing in. It does not contain a path (e.g. no slashes).
294 * Armyset files sit in the army/ directory.
296 std::string d_subdir;
298 //! The size of each army tile as rendered in the game.
300 * The tile size represents the height and width in pixels of the
302 * The actual army picture holds the unshaded image, and then the
303 * mask portion of the image to it's right.
304 * The tilesize is the height of the army image file, and it is also
305 * precisely equal to half of the image's width.
309 //! The unshaded picture of the stack when it's in a boat.
312 //! The mask of what to shade with the player's colour on the boat.
315 //! The unshaded picture of the planted standard.
318 //! The mask of what to shade with the player's colour on the standard.
319 PixMask* d_standard_mask;
321 //! The picture of an item when it's lying on the ground.
324 //! The name of the file that holds the picture of the hero's flag.
325 std::string d_standard_name;
327 //! The name of the file that holds the picture of stack on water.
328 std::string d_stackship_name;
330 //! The name of the file that holds the picture of the sack of items.
331 std::string d_bag_name;