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 SHIELDSET_H 20 #define SHIELDSET_H 21 22 #include <gtkmm.h> 23 #include <map> 24 #include <vector> 25 #include <sigc++/trackable.h> 26 27 #include "shield.h" 28 #include "tartan.h" 29 #include "set.h" 30 #include "defs.h" 31 32 class XML_Helper; 33 class ShieldStyle; 34 35 //! A list of Shield graphic objects in a shield theme. 36 /** 37 * Every scenario has a shield set; it is the theme of the shield graphics 38 * within the game. Shields come in three sizes -- small, medium and large. 39 * Small shields appear on the OverviewMap. Medium shields appear in the turn 40 * indicator in the top right of the GameWindow. Large shields appear in many 41 * dialogs, chiefly the FightWindow, and DiplomacyDialog. 42 * Every shield belongs to one of 9 players (the ninth is the Neutral player). 43 * The players aren't Player objects in this case; instead it refers to a 44 * Shield::ShieldColour. e.g. Not `The Sirians' but rather the `White player' 45 * of the scenario. 46 * 47 * The Shieldset dictates the dimensions of these three sizes of shields. 48 * 49 * Shieldsets are referred to by their basename. This is the last part of the 50 * filename, minus the file extension. 51 * 52 * The shieldset configuration file is a tar file that contains an XML file, 53 * and a set of png files. Filenames have the following form: 54 * shield/${Shieldset::d_basename}.lws. 55 */ 56 class Shieldset: public std::list<Shield *>, public sigc::trackable, public Set 57 { 58 public: 59 60 //! The xml tag of this object in a shieldset configuration file. 61 static Glib::ustring d_tag; 62 63 //! The file extension for shieldset files. It includes the dot. 64 static Glib::ustring file_extension; 65 66 67 //! Default constructor. 68 /** 69 * Make a new shieldset given a unique id and a basename name. 70 */ 71 Shieldset(guint32 id, Glib::ustring name); 72 73 //! Copy constructor. 74 Shieldset(const Shieldset& s); 75 76 //! Load a Shieldset from an opened shieldset configuration file. 77 /** 78 * Make a new Shieldset object by reading it in from the shieldset 79 * configuration file. 80 * 81 * @param helper The opened shieldset configuration file to load the 82 * Shieldset from. 83 */ 84 Shieldset(XML_Helper* helper, Glib::ustring directory); 85 86 //! Destructor. 87 ~Shieldset(); 88 89 // Get Methods 90 91 //! Return the mask colour for the given player. 92 Gdk::RGBA getColor(guint32 owner) const; 93 94 //! Return the number of pixels high the small shields are. getSmallHeight()95 guint32 getSmallHeight() const {return d_small_height;} 96 97 //! Return the number of pixels wide the small shields are. getSmallWidth()98 guint32 getSmallWidth() const {return d_small_width;} 99 100 //! Return the number of pixels high the medium shields are. getMediumHeight()101 guint32 getMediumHeight() const {return d_medium_height;} 102 103 //! Return the number of pixels wide the medium shields are. getMediumWidth()104 guint32 getMediumWidth() const {return d_medium_width;} 105 106 //! Return the number of pixels the large shields are. getLargeHeight()107 guint32 getLargeHeight() const {return d_large_height;} 108 109 //! Return the number of pixels wide the large shields are. getLargeWidth()110 guint32 getLargeWidth() const {return d_large_width;} 111 112 //! Return the total number of shields in this shieldset. getSize()113 guint32 getSize() const {return size();} 114 115 bool isAnyHeightAndWidthSet(); 116 bool isSmallHeightAndWidthSet(); 117 bool isMediumHeightAndWidthSet(); 118 bool isLargeHeightAndWidthSet(); 119 120 // Set Methods 121 122 //! Return the number of pixels high the small shields are. setSmallHeight(guint32 n)123 void setSmallHeight(guint32 n) {d_small_height = n;} 124 125 //! Set how wide in pixels small shields are scaled to. setSmallWidth(guint32 n)126 void setSmallWidth(guint32 n) {d_small_width = n;} 127 128 //! Set how high in pixels medium shields are scaled to. setMediumHeight(guint32 n)129 void setMediumHeight(guint32 n) {d_medium_height = n;} 130 131 //! Set how wide in pixels medium shields are scaled to. setMediumWidth(guint32 n)132 void setMediumWidth(guint32 n) {d_medium_width = n;} 133 134 //! Set how high in pixels large shields are scaled to. setLargeHeight(guint32 n)135 void setLargeHeight(guint32 n) {d_large_height = n;} 136 137 //! Set how wide in pixels large shields are scaled to. setLargeWidth(guint32 n)138 void setLargeWidth(guint32 n) {d_large_width = n;} 139 140 //! Load the shieldset again. 141 void reload(bool &broken); 142 143 //! Set the dimensions based on the largest image of that shieldstyle. 144 void setHeightsAndWidthsFromImages(ShieldStyle *s); 145 void setHeightsAndWidthsFromImages(); 146 void setSmallHeightsAndWidthsFromImages(); 147 void setMediumHeightsAndWidthsFromImages(); 148 void setLargeHeightsAndWidthsFromImages(); 149 150 // Methods that operate on the class data but do not modify the class. 151 152 bool save(XML_Helper *helper) const; 153 154 bool save(Glib::ustring filename, Glib::ustring extension) const; 155 156 //! Find the shield of a given size and colour in this Shieldset. 157 /** 158 * Scan through all Shield objects in this set for first one that is 159 * the desired size, and for the desired player. 160 * 161 * @param type One of the values in Shield::ShieldType. 162 * @param colour One of the values in Shield::ShieldColour. 163 * 164 * @return A pointer to the shield that matches the size and player. 165 * If no Shield object could be found that matches the given 166 * parameters, NULL is returned. 167 */ 168 ShieldStyle* lookupShieldByTypeAndColour(guint32 type, guint32 colour) const; 169 Shield* lookupShieldByColour(guint32 colour) const; 170 171 //! Get the image and mask associated with the shield of a given colour. 172 /** 173 * This gets the left tartan image and mask for a player denoted by 174 * colour. 175 */ 176 void lookupTartanImage(guint32 colour, Tartan::Type type, 177 PixMask **image, PixMask **mask); 178 179 //! Check to see if this shieldset can be used in the game. 180 bool validate() const; 181 182 //! Check to see if the number of shields is sufficient. 183 bool validateNumberOfShields() const; 184 185 //! Check to see if the images for the shields are supplied. 186 bool validateShieldImages(Shield::Colour c) const; 187 188 //! Check to see if the images for the tartans are supplied. 189 bool validateTartanImages(Shield::Colour c) const; 190 191 guint32 countEmptyImageNames() const; 192 193 // Methods that operate on the class data and also modify the class. 194 195 //! Load the images associated with this shieldset. 196 /** 197 * Go get the image files from the shieldset file and create the 198 * various pixmask objects. 199 * 200 * @param scale The images are clamped to the sizes held in 201 * d_small_width, d_small_height (for the small 202 * shields) and so on. 203 * @param broken True when couldn't read the shieldset file. 204 */ 205 void instantiateImages(bool scale, bool &broken); 206 207 //! Destroy images associated with this shieldset. 208 void uninstantiateImages(); 209 210 //! destroy any image that has this name 211 void uninstantiateSameNamedImages (Glib::ustring imgname); 212 213 // Static Methods 214 215 //! Create a shieldset from the given shieldset configuration file. 216 static Shieldset *create(Glib::ustring filename, bool &unsupported); 217 218 static Shieldset *copy (const Shieldset *orig); 219 220 //! rewrite old shieldset files. 221 static bool upgrade(Glib::ustring filename, Glib::ustring old_version, Glib::ustring new_version); 222 static void support_backward_compatibility(); 223 224 private: 225 226 //! Callback function to load Shield objects into the Shieldset. 227 bool loadShield(Glib::ustring tag, XML_Helper* helper); 228 229 // DATA 230 231 //! The number of pixels high the small shield images are scaled to. 232 /** 233 * Equates to the shieldset.d_small_height XML entity in the shieldset 234 * configuration file. 235 */ 236 guint32 d_small_height; 237 238 //! The number of pixels wide the small shield images are scaled to. 239 /** 240 * Equates to the shieldset.d_small_width XML entity in the shieldset 241 * configuration file. 242 */ 243 guint32 d_small_width; 244 245 //! The number of pixels high the medium shield images are scaled to. 246 /** 247 * Equates to the shieldset.d_medium_height XML entity in the shieldset 248 * configuration file. 249 */ 250 guint32 d_medium_height; 251 252 //! The number of pixels wide the medium shield images are scaled to. 253 /** 254 * Equates to the shieldset.d_medium_width XML entity in the shieldset 255 * configuration file. 256 */ 257 guint32 d_medium_width; 258 259 //! The number of pixels high the large shield images are scaled to. 260 /** 261 * Equates to the shieldset.d_large_height XML entity in the shieldset 262 * configuration file. 263 */ 264 guint32 d_large_height; 265 266 //! The number of pixels wide the large shield images are scaled to. 267 /** 268 * Equates to the shieldset.d_large_width XML entity in the shieldset 269 * configuration file. 270 */ 271 guint32 d_large_width; 272 }; 273 274 #endif // SHIELDSET_H 275 276