initial commit, lordsawar source, slightly modified
[lordsawar] / src / armyset.h
1 //  Copyright (C) 2007, 2008, 2009 Ben Asselstine
2 //
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.
7 //
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.
12 //
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 
16 //  02110-1301, USA.
17
18 #ifndef ARMYSET_H
19 #define ARMYSET_H
20
21 #include <gtkmm.h>
22 #include <string>
23 #include <map>
24 #include <vector>
25 #include <sigc++/trackable.h>
26
27 #include "xmlhelper.h"
28 #include "armyproto.h"
29 #include "defs.h"
30 #include "shield.h"
31 #include "File.h"
32 #include "set.h"
33 #include "hero.h"
34
35 using namespace std;
36
37 //! A collection of Army prototype objects.
38 /**
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.
46  *
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.
50  *
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).
54  *
55  * Armyset objects are loaded from an armyset configuration file.
56  *
57  * Armyset objects are created by the armyset editor.
58  *
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.
61  *
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.
64  */
65 class Armyset: public std::list<ArmyProto *>, public sigc::trackable, public Set
66 {
67     public:
68
69         //! The xml tag of this object in an armyset configuration file.
70         static std::string d_tag; 
71         static std::string file_extension; 
72
73         //! Default constructor.
74         /**
75          * Make a new Armyset.
76          *
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.
80          */
81         Armyset(guint32 id, std::string name);
82         //! Loading constructor.
83         /**
84          * Load armyset XML entities from armyset configuration files.
85          */
86         Armyset(XML_Helper* helper, std::string directory);
87
88         static Armyset *create(std::string filename);
89
90         //! Destructor.
91         ~Armyset();
92
93         /**
94          * @param helper  An opened armyset configuration file.
95          */
96         //! Save the Armyset to an Armyset configuration file.
97         bool save(XML_Helper* helper);
98
99         //! Returns the size of this armyset.
100         /** 
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).
103          */
104         guint32 getSize() const {return size();}
105
106         //! Get the tile size of the Armyset.
107         /**
108          * The width and height of the Army graphic images as they appear
109          * on the screen.
110          * Analagous to the armyset.d_tilesize XML entity in the armyset 
111          * configuration file.
112          */
113         guint32 getTileSize() const {return d_tilesize;}
114
115         //! Get the unique identifier for this armyset.
116         /**
117          * Analagous to the armyset.d_id XML entity in the armyset 
118          * configuration file.
119          */
120         guint32 getId() const {return d_id;}
121
122         //! Set the unique identifier for this armyset.
123         void setId(guint32 id) {d_id = id;}
124
125         //! Returns the name of the armyset.
126         /** 
127          * Analagous to the armyset.d_name XML entity in the armyset 
128          * configuration file.
129          *
130          * @return The name or an empty string on error.
131          */
132         std::string getName() const {return _(d_name.c_str());}
133
134         //! Set the name of the armyset.
135         /**
136          * @note This method is only used in the armyset editor.
137          */
138         void setName(std::string name) {d_name = name;}
139
140         //! Get the copyright holders for this armyset.
141         std::string getCopyright() const {return d_copyright;};
142
143         //! Set the copyright holders on the armyset.
144         void setCopyright(std::string copy) {d_copyright = copy;};
145
146         //! Get the license of this armyset.
147         std::string getLicense() const {return d_license;};
148
149         //! Set the license for this armyset.
150         void setLicense(std::string license) {d_license = license;};
151
152         //! Get the subdirectory name of the armyset.
153         /**
154          * This value does not contain a path (e.g. no slashes).  It is the
155          * name of an armyset directory inside army/.
156          *
157          * @return The name of the subdirectory the Armyset is held in.
158          */
159         std::string getSubDir() const {return d_subdir;}
160
161         //! Set the subdirectory that the armyset is in.
162         void setSubDir(std::string dir) {d_subdir = dir;}
163
164         //! Get the image of the stack in a ship (minus the mask).
165         PixMask* getShipPic() const {return d_ship;}
166
167         //! Set the image of the stack in a ship
168         void setShipImage(PixMask* ship) {d_ship = ship;};
169
170         //! Get the mask portion of the image of the stack in a ship.
171         PixMask* getShipMask() const {return d_shipmask;}
172
173         //! Set the mask portion of the image of the stack in a ship.
174         void setShipMask(PixMask* shipmask) {d_shipmask = shipmask;};
175
176         //! Get the image of the bag.
177         PixMask* getBagPic() const {return d_bag;}
178
179         //! Set the image of the bag.
180         void setBagPic(PixMask* s) {d_bag = s;};
181
182         //! Get the image of the planted standard (minus the mask).
183         PixMask* getStandardPic() const {return d_standard;}
184
185         //! Set the image of the planted standard (minus the mask).
186         void setStandardPic(PixMask* s) {d_standard = s;};
187
188         //! Get the mask portion of the image of the planted standard.
189         PixMask* getStandardMask() const {return d_standard_mask;}
190
191         //! Set the mask portion of the image of the planted standard.
192         void setStandardMask(PixMask* s) {d_standard_mask = s;};
193
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;};
196
197         //! Get the name of the file holding the image of the stack in a boat.
198         std::string getShipImageName() {return d_stackship_name;};
199
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;};
202
203         //! Get the name of the file holding the image of the hero's flag.
204         std::string getStandardImageName() {return d_standard_name;};
205
206         //! Set the name of the file holding the image of the bag.
207         void setBagImageName(std::string n) {d_bag_name = n;};
208
209         //! Get the name of the file holding the image of the bag.
210         std::string getBagImageName() {return d_bag_name;};
211
212         //! Find an army with a type in this armyset.
213         /**
214          * Scan the Army prototype objects in this Armyset and return it.
215          *
216          * @note This is only used for the editor.  Most callers should use 
217          * Armysetlist::getArmy instead.
218          *
219          * @param army_type  The army type id of the Army prototype object
220          *                   to search for in this Armyset.
221          *
222          * @return The Army with the given army type id, or NULL if none
223          *         could be found.
224          */
225         ArmyProto * lookupArmyByType(guint32 army_type) const;
226
227         ArmyProto * lookupArmyByName(std::string name) const;
228
229         ArmyProto * lookupArmyByStrengthAndTurns(guint32 str, guint32 turns) const;
230
231         ArmyProto * lookupArmyByGender(Hero::Gender gender) const;
232
233         ArmyProto * lookupSimilarArmy(ArmyProto *army) const;
234         //! can this armyset be used within the game?
235         bool validate();
236         bool validateSize();
237         bool validateHero();
238         bool validatePurchasables();
239         bool validateRuinDefenders();
240         bool validateAwardables();
241         bool validateShip();
242         bool validateStandard();
243         bool validateBag();
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);
255
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;
264
265     private:
266
267         //! Callback function for the army tag (see XML_Helper)
268         bool loadArmyProto(std::string tag, XML_Helper* helper);
269         
270         //! The unique Id of this armyset.
271         /**
272          * This Id is unique among all other armysets.
273          * It is analgous to armyset.d_id in the armyset configuration files.
274          */
275         guint32 d_id;
276
277         //! The name of the Armyset.
278         /**
279          * This value appears in game configuration dialogs.
280          * It is analgous to armyset.d_name in the armyset configuration files.
281          */
282         std::string d_name;
283
284         //! The armyset has these copyright holders.
285         std::string d_copyright;
286
287         //! The license of the armyset.
288         std::string d_license;
289
290         //! The subdirectory of the Armyset.
291         /**
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.
295          */
296         std::string d_subdir;
297
298         //! The size of each army tile as rendered in the game.
299         /**
300          * The tile size represents the height and width in pixels of the 
301          * army picture.
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.
306          */
307         guint32 d_tilesize;
308
309         //! The unshaded picture of the stack when it's in a boat.
310         PixMask* d_ship;
311
312         //! The mask of what to shade with the player's colour on the boat.
313         PixMask* d_shipmask;
314
315         //! The unshaded picture of the planted standard.
316         PixMask* d_standard;
317
318         //! The mask of what to shade with the player's colour on the standard.
319         PixMask* d_standard_mask;
320
321         //! The picture of an item when it's lying on the ground.
322         PixMask *d_bag;
323
324         //! The name of the file that holds the picture of the hero's flag.
325         std::string d_standard_name;
326
327         //! The name of the file that holds the picture of stack on water.
328         std::string d_stackship_name;
329
330         //! The name of the file that holds the picture of the sack of items.
331         std::string d_bag_name;
332 };
333
334 #endif // ARMYSET_H
335