1 // Copyright (C) 2008, 2009, 2010, 2011, 2014, 2020 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 #pragma once
19 #ifndef CITYSET_H
20 #define CITYSET_H
21 
22 #include <vector>
23 #include <gtkmm.h>
24 #include <sigc++/trackable.h>
25 #include "PixMask.h"
26 #include "set.h"
27 
28 #include "defs.h"
29 
30 class XML_Helper;
31 
32 //! A list of city graphic objects in a city theme.
33 /**
34  * Every scenario has a city set; it is the theme of the city graphics
35  * within the game.
36  *
37  * The Cityset dictates the size of city images.
38  *
39  * Citysets are referred to by their base name.  The base name is the last
40  * part of the file's path minus the file extension.
41  *
42  * The cityset configuration file is a tar file that contains an XML file,
43  * and a set of png files.  Filenames have the following form:
44  * cityset/${Cityset::d_basename}.lwc.
45  */
46 class Cityset : public sigc::trackable, public Set
47 {
48     public:
49 	//! The xml tag of this object in a cityset configuration file.
50 	static Glib::ustring d_tag;
51 	static Glib::ustring file_extension;
52 
53 	//! Default constructor.
54 	/**
55 	 * Make a new Cityset.
56 	 *
57 	 * @param id    The unique Id of this Cityset among all other Cityset
58 	 *              objects.  Must be more than 0.
59 	 * @param name  The name of the Cityset.  Analagous to Cityset::d_name.
60 	 */
61 	Cityset(guint32 id, Glib::ustring name);
62 
63         //! Copy constructor.
64         Cityset(const Cityset& c);
65 
66 	//! Loading constructor.
67 	/**
68 	 * Make a new Cityset object by reading it in from the cityset
69 	 * configuration file.
70 	 *
71 	 * @param helper  The opened cityset configuration file to load the
72 	 *                Cityset from.
73 	 */
74         Cityset(XML_Helper* helper, Glib::ustring directory);
75 
76 	static Cityset *create(Glib::ustring file, bool &unsupported_version);
77 
78         static Cityset *copy (const Cityset *orig);
79 	//! Destructor.
80         ~Cityset();
81 
82 	bool save(XML_Helper *helper) const;
83 
84         bool save(Glib::ustring filename, Glib::ustring extension) const;
85 
86 
setCitiesFilename(Glib::ustring s)87 	void setCitiesFilename(Glib::ustring s) {d_cities_filename = s;};
getCitiesFilename()88 	Glib::ustring getCitiesFilename() {return d_cities_filename;};
setRazedCitiesFilename(Glib::ustring s)89 	void setRazedCitiesFilename(Glib::ustring s) {d_razedcities_filename = s;};
getRazedCitiesFilename()90 	Glib::ustring getRazedCitiesFilename() {return d_razedcities_filename;};
setPortFilename(Glib::ustring s)91 	void setPortFilename(Glib::ustring s) {d_port_filename = s;};
getPortFilename()92 	Glib::ustring getPortFilename() {return d_port_filename;};
setSignpostFilename(Glib::ustring s)93 	void setSignpostFilename(Glib::ustring s) {d_signpost_filename = s;};
getSignpostFilename()94 	Glib::ustring getSignpostFilename() {return d_signpost_filename;};
setRuinsFilename(Glib::ustring s)95 	void setRuinsFilename(Glib::ustring s) {d_ruins_filename = s;};
getRuinsFilename()96 	Glib::ustring getRuinsFilename() {return d_ruins_filename;};
setTemplesFilename(Glib::ustring s)97 	void setTemplesFilename(Glib::ustring s) {d_temples_filename = s;};
getTemplesFilename()98 	Glib::ustring getTemplesFilename() {return d_temples_filename;};
setTowersFilename(Glib::ustring s)99 	void setTowersFilename(Glib::ustring s) {d_towers_filename = s;};
getTowersFilename()100 	Glib::ustring getTowersFilename() {return d_towers_filename;};
101 
102         void clearCitiesImage(bool clear_name = true);
103         void clearRazedCitiesImage(bool clear_name = true);
104         void clearPortImage(bool clear_name = true);
105         void clearSignpostImage(bool clear_name = true);
106         void clearRuinsImage(bool clear_name = true);
107         void clearTemplesImage(bool clear_name = true);
108         void clearTowersImage(bool clear_name = true);
109 
setCityImage(guint32 i,PixMask * p)110 	void setCityImage(guint32 i, PixMask *p) {citypics[i] = p;};
getCityImage(guint32 i)111 	PixMask *getCityImage(guint32 i) {return citypics[i];};
setRazedCityImage(guint32 i,PixMask * p)112 	void setRazedCityImage(guint32 i, PixMask *p) {razedcitypics[i] = p;};
getRazedCityImage(guint32 i)113 	PixMask *getRazedCityImage(guint32 i) {return razedcitypics[i];};
getPortImage()114 	PixMask *getPortImage() {return port;};
setPortImage(PixMask * p)115 	void setPortImage(PixMask *p) {port = p;};
getSignpostImage()116 	PixMask *getSignpostImage() {return signpost;};
setSignpostImage(PixMask * p)117 	void setSignpostImage(PixMask *p) {signpost = p;};
setRuinImage(guint32 i,PixMask * p)118 	void setRuinImage(guint32 i, PixMask *p) {ruinpics[i] = p;};
getRuinImage(guint32 i)119 	PixMask *getRuinImage(guint32 i) {return ruinpics[i];};
setTempleImage(guint32 i,PixMask * p)120 	void setTempleImage(guint32 i, PixMask *p) {templepics[i] = p;};
getTempleImage(guint32 i)121 	PixMask *getTempleImage(guint32 i) {return templepics[i];};
setTowerImage(guint32 i,PixMask * p)122 	void setTowerImage(guint32 i, PixMask *p) {towerpics[i] = p;};
getTowerImage(guint32 i)123 	PixMask *getTowerImage(guint32 i) {return towerpics[i];};
124 
125         //! Load the images associated with this cityset.
126         /**
127          * Go get the image files from the cityset file and create the
128          * various pixmask objects.
129          *
130          * @param scale   The images are clamped to the tile size or not.
131          * @param broken  True when things went wrong reading the cityset file.
132          */
133 	void instantiateImages(bool scale, bool &broken);
134 	void instantiateImages(Glib::ustring port_filename,
135 			       Glib::ustring signpost_filename,
136 			       Glib::ustring cities_filename,
137 			       Glib::ustring razed_cities_filename,
138 			       Glib::ustring towers_filename,
139 			       Glib::ustring ruins_filename,
140 			       Glib::ustring temples_filename,
141                                bool scale, bool &broken);
142 
143         bool instantiateCityImages ();
144         bool instantiateRazedCityImages ();
145         bool instantiatePortImage ();
146         bool instantiateSignpostImage ();
147         bool instantiateRuinImages ();
148         bool instantiateTempleImages ();
149         bool instantiateTowerImages ();
150 	void uninstantiateImages();
151 
152         guint32 countEmptyImageNames() const;
getCityTileWidth()153 	guint32 getCityTileWidth() {return d_city_tile_width;};
setCityTileWidth(guint32 tiles)154 	void setCityTileWidth(guint32 tiles) {d_city_tile_width = tiles;};
getTempleTileWidth()155 	guint32 getTempleTileWidth() {return d_temple_tile_width;};
setTempleTileWidth(guint32 tiles)156 	void setTempleTileWidth(guint32 tiles) {d_temple_tile_width = tiles;};
getRuinTileWidth()157 	guint32 getRuinTileWidth() {return d_ruin_tile_width;};
setRuinTileWidth(guint32 tiles)158 	void setRuinTileWidth(guint32 tiles) {d_ruin_tile_width = tiles;};
159 	bool validate();
160 	bool validateCitiesFilename();
161 	bool validateRazedCitiesFilename();
162 	bool validateSignpostFilename();
163 	bool validatePortFilename();
164 	bool validateRuinsFilename();
165 	bool validateTemplesFilename();
166 	bool validateTowersFilename();
167 	bool validateCityTileWidth();
168 	bool validateRuinTileWidth();
169 	bool validateTempleTileWidth();
170 	bool tileWidthsEqual(Cityset *cityset);
171 
172         void uninstantiateSameNamedImages (Glib::ustring name);
173 
174         //! Callback to convert old files to new ones.
175         static bool upgrade(Glib::ustring filename, Glib::ustring old_version, Glib::ustring new_version);
176         static void support_backward_compatibility();
177 
178         static guint32 get_default_tile_size ();
179         //! Load the cityset again.
180         void reload(bool &broken);
181         bool calculate_preferred_tile_size(guint32 &ts) const;
182     private:
183 
184         // DATA
185 
186 	Glib::ustring d_cities_filename;
187 	Glib::ustring d_razedcities_filename;
188 	Glib::ustring d_port_filename;
189 	Glib::ustring d_signpost_filename;
190 	Glib::ustring d_ruins_filename;
191 	Glib::ustring d_temples_filename;
192 	Glib::ustring d_towers_filename;
193 	PixMask *citypics[MAX_PLAYERS + 1];
194 	PixMask *razedcitypics[MAX_PLAYERS];
195 	PixMask *port;
196 	PixMask *signpost;
197 	PixMask *ruinpics[RUIN_TYPES];
198 	PixMask *templepics[TEMPLE_TYPES];
199 	PixMask *towerpics[MAX_PLAYERS];
200 
201 	guint32 d_city_tile_width;
202 	guint32 d_temple_tile_width;
203 	guint32 d_ruin_tile_width;
204 };
205 
206 #endif // CITYSET_H
207 
208 // End of file
209