1 // Copyright (C) 2008, 2010, 2011, 2014, 2015, 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 #include <sigc++/functors/mem_fun.h>
19
20 #include "cityset.h"
21 #include "File.h"
22 #include "xmlhelper.h"
23 #include "gui/image-helpers.h"
24 #include "city.h"
25 #include "ruin.h"
26 #include "temple.h"
27 #include "tarhelper.h"
28 #include "Configuration.h"
29 #include "file-compat.h"
30 #include "ucompose.hpp"
31
32 Glib::ustring Cityset::d_tag = "cityset";
33 Glib::ustring Cityset::file_extension = CITYSET_EXT;
34
35 #include <iostream>
36 //#define debug(x) {std::cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<std::endl<<std::flush;}
37 #define debug(x)
38
39 #define DEFAULT_CITY_TILE_SIZE 40
Cityset(guint32 id,Glib::ustring name)40 Cityset::Cityset(guint32 id, Glib::ustring name)
41 : Set(CITYSET_EXT, id, name, DEFAULT_CITY_TILE_SIZE)
42 {
43 d_cities_filename = "";
44 d_razedcities_filename = "";
45 d_port_filename = "";
46 d_signpost_filename = "";
47 d_ruins_filename = "";
48 d_temples_filename = "";
49 d_towers_filename = "";
50 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
51 citypics[i] = NULL;
52 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
53 razedcitypics[i] = NULL;
54 port = NULL;
55 signpost = NULL;
56 for (unsigned int i = 0; i < RUIN_TYPES; i++)
57 ruinpics[i] = NULL;
58 for (unsigned int i = 0; i < TEMPLE_TYPES; i++)
59 templepics[i] = NULL;
60 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
61 towerpics[i] = NULL;
62
63 d_city_tile_width = 2;
64 d_temple_tile_width = 1;
65 d_ruin_tile_width = 1;
66 }
67
Cityset(const Cityset & c)68 Cityset::Cityset(const Cityset& c)
69 : sigc::trackable(c), Set(c), d_cities_filename(c.d_cities_filename),
70 d_razedcities_filename(c.d_razedcities_filename),
71 d_port_filename(c.d_port_filename),
72 d_signpost_filename(c.d_signpost_filename),
73 d_ruins_filename(c.d_ruins_filename),
74 d_temples_filename(c.d_temples_filename),
75 d_towers_filename(c.d_towers_filename)
76 {
77 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
78 {
79 if (c.citypics[i] != NULL)
80 citypics[i] = c.citypics[i]->copy();
81 else
82 citypics[i] = NULL;
83 }
84 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
85 {
86 if (c.razedcitypics[i] != NULL)
87 razedcitypics[i] = c.razedcitypics[i]->copy();
88 else
89 razedcitypics[i] = NULL;
90 }
91 if (c.port != NULL)
92 port = c.port->copy();
93 else
94 port = NULL;
95 if (c.signpost != NULL)
96 signpost = c.signpost->copy();
97 else
98 signpost = NULL;
99
100 for (unsigned int i = 0; i < RUIN_TYPES; i++)
101 {
102 if (c.ruinpics[i] != NULL)
103 ruinpics[i] = c.ruinpics[i]->copy();
104 else
105 ruinpics[i] = NULL;
106 }
107 for (unsigned int i = 0; i < TEMPLE_TYPES; i++)
108 {
109 if (c.templepics[i] != NULL)
110 templepics[i] = c.templepics[i]->copy();
111 else
112 templepics[i] = NULL;
113 }
114 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
115 {
116 if (c.towerpics[i] != NULL)
117 towerpics[i] = c.towerpics[i]->copy();
118 else
119 towerpics[i] = NULL;
120 }
121
122 d_city_tile_width = c.d_city_tile_width;
123 d_temple_tile_width = c.d_temple_tile_width;
124 d_ruin_tile_width = c.d_ruin_tile_width;
125 }
126
Cityset(XML_Helper * helper,Glib::ustring directory)127 Cityset::Cityset(XML_Helper *helper, Glib::ustring directory)
128 : Set(CITYSET_EXT, helper)
129 {
130 setDirectory(directory);
131 guint32 ts;
132 helper->getData(ts, "tilesize");
133 setTileSize(ts);
134 helper->getData(d_cities_filename, "cities");
135 File::add_png_if_no_ext (d_cities_filename);
136 helper->getData(d_razedcities_filename, "razed_cities");
137 File::add_png_if_no_ext (d_razedcities_filename);
138 helper->getData(d_port_filename, "port");
139 File::add_png_if_no_ext (d_port_filename);
140 helper->getData(d_signpost_filename, "signpost");
141 File::add_png_if_no_ext (d_signpost_filename);
142 helper->getData(d_ruins_filename, "ruins");
143 File::add_png_if_no_ext (d_ruins_filename);
144 helper->getData(d_temples_filename, "temples");
145 File::add_png_if_no_ext (d_temples_filename);
146 helper->getData(d_towers_filename, "towers");
147 File::add_png_if_no_ext (d_towers_filename);
148 helper->getData(d_city_tile_width, "city_tile_width");
149 helper->getData(d_temple_tile_width, "temple_tile_width");
150 helper->getData(d_ruin_tile_width, "ruin_tile_width");
151 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
152 citypics[i] = NULL;
153 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
154 razedcitypics[i] = NULL;
155 for (unsigned int i = 0; i < RUIN_TYPES; i++)
156 ruinpics[i] = NULL;
157 for (unsigned int i = 0; i < TEMPLE_TYPES; i++)
158 templepics[i] = NULL;
159 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
160 towerpics[i] = NULL;
161 port = NULL;
162 signpost = NULL;
163 }
164
~Cityset()165 Cityset::~Cityset()
166 {
167 uninstantiateImages();
168 clean_tmp_dir();
169 }
170
171 //! Helper class for making a new Cityset object from a cityset file.
172 class CitysetLoader
173 {
174 public:
CitysetLoader(Glib::ustring filename,bool & broken,bool & unsupported)175 CitysetLoader(Glib::ustring filename, bool &broken, bool &unsupported)
176 {
177 unsupported_version = false;
178 cityset = NULL;
179 dir = File::get_dirname(filename);
180 file = File::get_basename(filename);
181 if (File::nameEndsWith(filename, Cityset::file_extension) == false)
182 filename += Cityset::file_extension;
183 Tar_Helper t(filename, std::ios::in, broken);
184 if (broken)
185 return;
186 Glib::ustring lwcfilename =
187 t.getFirstFile(Cityset::file_extension, broken);
188 if (broken)
189 return;
190 XML_Helper helper(lwcfilename, std::ios::in);
191 helper.registerTag(Cityset::d_tag, sigc::mem_fun((*this), &CitysetLoader::load));
192 if (!helper.parseXML())
193 {
194 unsupported = unsupported_version;
195 std::cerr << String::ucompose(_("Error! can't load cityset `%1'."), filename) << std::endl;
196 if (cityset != NULL)
197 delete cityset;
198 cityset = NULL;
199 }
200 helper.close();
201 File::erase(lwcfilename);
202 t.Close();
203 };
load(Glib::ustring tag,XML_Helper * helper)204 bool load(Glib::ustring tag, XML_Helper* helper)
205 {
206 if (tag == Cityset::d_tag)
207 {
208 if (helper->getVersion() == LORDSAWAR_CITYSET_VERSION)
209 {
210 cityset = new Cityset(helper, dir);
211 cityset->setBaseName(file);
212 return true;
213 }
214 else
215 {
216 unsupported_version = true;
217 return false;
218 }
219 }
220 return false;
221 };
222 Glib::ustring dir;
223 Glib::ustring file;
224 Cityset *cityset;
225 bool unsupported_version;
226 };
227
create(Glib::ustring file,bool & unsupported_version)228 Cityset *Cityset::create(Glib::ustring file, bool &unsupported_version)
229 {
230 bool broken = false;
231 CitysetLoader d(file, broken, unsupported_version);
232 if (broken)
233 return NULL;
234 return d.cityset;
235 }
236
save(Glib::ustring filename,Glib::ustring ext) const237 bool Cityset::save(Glib::ustring filename, Glib::ustring ext) const
238 {
239 bool broken = false;
240 Glib::ustring goodfilename = File::add_ext_if_necessary(filename, ext);
241 Glib::ustring tmpfile = File::get_tmp_file();
242 XML_Helper helper(tmpfile, std::ios::out);
243 helper.begin(LORDSAWAR_CITYSET_VERSION);
244 broken = !save(&helper);
245 helper.close();
246 if (broken == true)
247 return false;
248 return saveTar(tmpfile, tmpfile + ".tar", goodfilename);
249 }
250
save(XML_Helper * helper) const251 bool Cityset::save(XML_Helper *helper) const
252 {
253 bool retval = true;
254
255 retval &= helper->openTag(d_tag);
256 retval &= Set::save(helper);
257 retval &= helper->saveData("tilesize", getUnscaledTileSize());
258 retval &= helper->saveData("cities", d_cities_filename);
259 retval &= helper->saveData("razed_cities", d_razedcities_filename);
260 retval &= helper->saveData("port", d_port_filename);
261 retval &= helper->saveData("signpost", d_signpost_filename);
262 retval &= helper->saveData("ruins", d_ruins_filename);
263 retval &= helper->saveData("temples", d_temples_filename);
264 retval &= helper->saveData("towers", d_towers_filename);
265 retval &= helper->saveData("city_tile_width", d_city_tile_width);
266 retval &= helper->saveData("temple_tile_width", d_temple_tile_width);
267 retval &= helper->saveData("ruin_tile_width", d_ruin_tile_width);
268 retval &= helper->closeTag();
269 return retval;
270 }
271
uninstantiateImages()272 void Cityset::uninstantiateImages()
273 {
274 if (getPortImage() != NULL)
275 {
276 delete getPortImage();
277 setPortImage(NULL);
278 }
279 if (getSignpostImage() != NULL)
280 {
281 delete getSignpostImage();
282 setSignpostImage(NULL);
283 }
284 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
285 {
286 if (getCityImage(i) != NULL)
287 {
288 delete getCityImage(i);
289 setCityImage(i, NULL);
290 }
291 }
292 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
293 {
294 if (getRazedCityImage(i) != NULL)
295 {
296 delete getRazedCityImage(i);
297 setRazedCityImage(i, NULL);
298 }
299 }
300 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
301 {
302 if (getTowerImage(i) != NULL)
303 {
304 delete getTowerImage(i);
305 setTowerImage(i, NULL);
306 }
307 }
308 for (unsigned int i = 0; i < RUIN_TYPES; i++)
309 {
310 if (getRuinImage(i) != NULL)
311 {
312 delete getRuinImage(i);
313 setRuinImage(i, NULL);
314 }
315 }
316 for (unsigned int i = 0; i < TEMPLE_TYPES; i++)
317 {
318 if (getTempleImage(i) != NULL)
319 {
320 delete getTempleImage(i);
321 setTempleImage(i, NULL);
322 }
323 }
324 }
325
instantiateImages(Glib::ustring port_filename,Glib::ustring signpost_filename,Glib::ustring cities_filename,Glib::ustring razed_cities_filename,Glib::ustring towers_filename,Glib::ustring ruins_filename,Glib::ustring temples_filename,bool scale,bool & broken)326 void Cityset::instantiateImages(Glib::ustring port_filename,
327 Glib::ustring signpost_filename,
328 Glib::ustring cities_filename,
329 Glib::ustring razed_cities_filename,
330 Glib::ustring towers_filename,
331 Glib::ustring ruins_filename,
332 Glib::ustring temples_filename,
333 bool scale, bool &broken)
334 {
335 if (port_filename.empty() == false && !broken)
336 setPortImage (PixMask::create(port_filename, broken));
337 if (signpost_filename.empty() == false && !broken)
338 setSignpostImage (PixMask::create(signpost_filename, broken));
339
340 int citysize = getUnscaledTileSize() * d_city_tile_width;
341 if (cities_filename.empty() == false && !broken)
342 {
343 std::vector<PixMask* > pics;
344 pics = disassemble_row(cities_filename, MAX_PLAYERS + 1, broken);
345 if (!broken)
346 {
347 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
348 {
349 if (scale)
350 {
351 if (pics[i]->get_width() != citysize)
352 PixMask::scale(pics[i], citysize, citysize);
353 }
354 setCityImage(i, pics[i]);
355 }
356 }
357 }
358
359 if (razed_cities_filename.empty() == false && !broken)
360 {
361 std::vector<PixMask* > pics;
362 pics = disassemble_row(razed_cities_filename, MAX_PLAYERS, broken);
363 if (!broken)
364 {
365 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
366 {
367 if (scale)
368 {
369 if (pics[i]->get_width() != citysize)
370 PixMask::scale(pics[i], citysize, citysize);
371 }
372 setRazedCityImage(i, pics[i]);
373 }
374 }
375 }
376
377 if (towers_filename.empty() == false && !broken)
378 {
379 std::vector<PixMask* > pics = disassemble_row(towers_filename,
380 MAX_PLAYERS, broken);
381 if (!broken)
382 {
383 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
384 {
385 if (scale)
386 {
387 if (pics[i]->get_width() != (int)getUnscaledTileSize())
388 PixMask::scale(pics[i], getUnscaledTileSize(),
389 getUnscaledTileSize());
390 }
391 setTowerImage(i, pics[i]);
392 }
393 }
394 }
395
396 if (ruins_filename.empty() == false && !broken)
397 {
398 std::vector<PixMask* > pics = disassemble_row(ruins_filename,
399 RUIN_TYPES, broken);
400 if (!broken)
401 {
402 int ruinsize = getUnscaledTileSize() * d_ruin_tile_width;
403 for (unsigned int i = 0; i < RUIN_TYPES ; i++)
404 {
405 if (scale)
406 {
407 if (pics[i]->get_width() != ruinsize)
408 PixMask::scale(pics[i], ruinsize, ruinsize);
409 }
410 setRuinImage(i, pics[i]);
411 }
412 }
413 }
414
415 if (temples_filename.empty() == false && !broken)
416 {
417 std::vector<PixMask* > pics;
418 pics = disassemble_row(temples_filename, TEMPLE_TYPES, broken);
419 if (!broken)
420 {
421 int templesize = getUnscaledTileSize() * d_temple_tile_width;
422 for (unsigned int i = 0; i < TEMPLE_TYPES ; i++)
423 {
424 if (scale)
425 {
426 if (pics[i]->get_width() != templesize)
427 PixMask::scale(pics[i], templesize, templesize);
428 }
429 setTempleImage(i, pics[i]);
430 }
431 }
432 }
433 }
434
instantiateImages(bool scale,bool & broken)435 void Cityset::instantiateImages(bool scale, bool &broken)
436 {
437 debug("Loading images for cityset " << getName());
438 uninstantiateImages();
439 broken = false;
440 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
441 if (broken)
442 return;
443 Glib::ustring port_filename = "";
444 Glib::ustring signpost_filename = "";
445 Glib::ustring cities_filename = "";
446 Glib::ustring razed_cities_filename = "";
447 Glib::ustring towers_filename = "";
448 Glib::ustring ruins_filename = "";
449 Glib::ustring temples_filename = "";
450
451 if (getPortFilename().empty() == false && !broken)
452 port_filename = t.getFile(getPortFilename(), broken);
453 if (getSignpostFilename().empty() == false && !broken)
454 signpost_filename = t.getFile(getSignpostFilename(), broken);
455 if (getCitiesFilename().empty() == false && !broken)
456 cities_filename = t.getFile(getCitiesFilename(), broken);
457 if (getRazedCitiesFilename().empty() == false && !broken)
458 razed_cities_filename = t.getFile(getRazedCitiesFilename(), broken);
459 if (getTowersFilename().empty() == false && !broken)
460 towers_filename = t.getFile(getTowersFilename(), broken);
461 if (getRuinsFilename().empty() == false && !broken)
462 ruins_filename = t.getFile(getRuinsFilename(), broken);
463 if (getTemplesFilename().empty() == false && !broken)
464 temples_filename = t.getFile(getTemplesFilename(), broken);
465 if (!broken)
466 instantiateImages(port_filename, signpost_filename, cities_filename,
467 razed_cities_filename, towers_filename, ruins_filename,
468 temples_filename, scale, broken);
469 if (port_filename != "")
470 File::erase(port_filename);
471 if (signpost_filename != "")
472 File::erase(signpost_filename);
473 if (cities_filename != "")
474 File::erase(cities_filename);
475 if (razed_cities_filename != "")
476 File::erase(razed_cities_filename);
477 if (towers_filename != "")
478 File::erase(towers_filename);
479 if (ruins_filename != "")
480 File::erase(ruins_filename);
481 if (temples_filename != "")
482 File::erase(temples_filename);
483 t.Close();
484 }
485
validate()486 bool Cityset::validate()
487 {
488 bool valid = true;
489 if (String::utrim (getName ()) == "")
490 return false;
491 if (validateCitiesFilename() == false)
492 return false;
493 if (validateRazedCitiesFilename() == false)
494 return false;
495 if (validatePortFilename() == false)
496 return false;
497 if (validateSignpostFilename() == false)
498 return false;
499 if (validateRuinsFilename() == false)
500 return false;
501 if (validateTemplesFilename() == false)
502 return false;
503 if (validateTowersFilename() == false)
504 return false;
505 if (validateCityTileWidth() == false)
506 return false;
507 if (validateRuinTileWidth() == false)
508 return false;
509 if (validateTempleTileWidth() == false)
510 return false;
511 return valid;
512 }
513
validateCitiesFilename()514 bool Cityset::validateCitiesFilename()
515 {
516 if (getCitiesFilename().empty() == true)
517 return false;
518 return true;
519 }
520
validateRazedCitiesFilename()521 bool Cityset::validateRazedCitiesFilename()
522 {
523 if (getRazedCitiesFilename().empty() == true)
524 return false;
525 return true;
526 }
527
validateSignpostFilename()528 bool Cityset::validateSignpostFilename()
529 {
530 if (getSignpostFilename().empty() == true)
531 return false;
532 return true;
533 }
534
validatePortFilename()535 bool Cityset::validatePortFilename()
536 {
537 if (getPortFilename().empty() == true)
538 return false;
539 return true;
540 }
541
validateRuinsFilename()542 bool Cityset::validateRuinsFilename()
543 {
544 if (getRuinsFilename().empty() == true)
545 return false;
546 return true;
547 }
548
validateTemplesFilename()549 bool Cityset::validateTemplesFilename()
550 {
551 if (getTemplesFilename().empty() == true)
552 return false;
553 return true;
554 }
555
validateTowersFilename()556 bool Cityset::validateTowersFilename()
557 {
558 if (getTowersFilename().empty() == true)
559 return false;
560 return true;
561 }
562
validateCityTileWidth()563 bool Cityset::validateCityTileWidth()
564 {
565 if (getCityTileWidth() <= 0)
566 return false;
567 return true;
568 }
569
validateRuinTileWidth()570 bool Cityset::validateRuinTileWidth()
571 {
572 if (getRuinTileWidth() <= 0)
573 return false;
574 return true;
575 }
576
validateTempleTileWidth()577 bool Cityset::validateTempleTileWidth()
578 {
579 if (getTempleTileWidth() <= 0)
580 return false;
581 return true;
582 }
583
tileWidthsEqual(Cityset * cityset)584 bool Cityset::tileWidthsEqual(Cityset *cityset)
585 {
586 if (getCityTileWidth() == cityset->getCityTileWidth() &&
587 getRuinTileWidth() == cityset->getRuinTileWidth() &&
588 getTempleTileWidth() == cityset->getTempleTileWidth())
589 return true;
590 return false;
591 }
592
reload(bool & broken)593 void Cityset::reload(bool &broken)
594 {
595 broken = false;
596 bool unsupported_version = false;
597 CitysetLoader d(getConfigurationFile(), broken, unsupported_version);
598 if (!broken && d.cityset && d.cityset->validate())
599 {
600 //steal the values from d.cityset and then don't delete it.
601 uninstantiateImages();
602 Glib::ustring basename = getBaseName();
603 *this = *d.cityset;
604 instantiateImages(true, broken);
605 setBaseName(basename);
606 }
607 }
608
calculate_preferred_tile_size(guint32 & ts) const609 bool Cityset::calculate_preferred_tile_size(guint32 &ts) const
610 {
611 guint32 tilesize = 0;
612 std::map<guint32, guint32> sizecounts;
613
614 if (citypics[0])
615 sizecounts[citypics[0]->get_unscaled_width() / d_city_tile_width]++;
616 if (razedcitypics[0])
617 sizecounts[razedcitypics[0]->get_unscaled_width() / d_city_tile_width]++;
618 if (port)
619 sizecounts[port->get_unscaled_width()]++;
620 if (signpost)
621 sizecounts[signpost->get_unscaled_width()]++;
622 if (ruinpics[0])
623 sizecounts[ruinpics[0]->get_unscaled_width() / d_ruin_tile_width]++;
624 if (templepics[0])
625 sizecounts[templepics[0]->get_unscaled_width() / d_temple_tile_width]++;
626 if (towerpics[0])
627 sizecounts[towerpics[0]->get_unscaled_width()]++;
628
629 guint32 maxcount = 0;
630 for (std::map<guint32, guint32>::iterator it = sizecounts.begin();
631 it != sizecounts.end(); it++)
632 {
633 if ((*it).second > maxcount)
634 {
635 maxcount = (*it).second;
636 tilesize = (*it).first;
637 }
638 }
639 bool ret = true;
640 if (tilesize == 0)
641 {
642 ts = DEFAULT_CITY_TILE_SIZE;
643 ret = false;
644 }
645 else
646 ts = tilesize;
647 return ret;
648 }
649
countEmptyImageNames() const650 guint32 Cityset::countEmptyImageNames() const
651 {
652 guint32 count = 0;
653 if (d_cities_filename.empty() == true)
654 count++;
655 if (d_razedcities_filename.empty() == true)
656 count++;
657 if (d_port_filename.empty() == true)
658 count++;
659 if (d_signpost_filename.empty() == true)
660 count++;
661 if (d_ruins_filename.empty() == true)
662 count++;
663 if (d_temples_filename.empty() == true)
664 count++;
665 if (d_towers_filename.empty() == true)
666 count++;
667 return count;
668 }
669
upgrade(Glib::ustring filename,Glib::ustring old_version,Glib::ustring new_version)670 bool Cityset::upgrade(Glib::ustring filename, Glib::ustring old_version, Glib::ustring new_version)
671 {
672 return FileCompat::getInstance()->upgrade(filename, old_version, new_version,
673 FileCompat::CITYSET, d_tag);
674 }
675
support_backward_compatibility()676 void Cityset::support_backward_compatibility()
677 {
678 FileCompat::getInstance()->support_type (FileCompat::CITYSET, file_extension,
679 d_tag, true);
680 FileCompat::getInstance()->support_version
681 (FileCompat::CITYSET, "0.2.0", LORDSAWAR_CITYSET_VERSION,
682 sigc::ptr_fun(&Cityset::upgrade));
683 }
684
copy(const Cityset * cityset)685 Cityset* Cityset::copy(const Cityset *cityset)
686 {
687 if (!cityset)
688 return NULL;
689 return new Cityset(*cityset);
690 }
691
clearCitiesImage(bool clear_name)692 void Cityset::clearCitiesImage (bool clear_name)
693 {
694 if (clear_name)
695 setCitiesFilename ("");
696
697 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
698 {
699 PixMask *p = getCityImage (i);
700 delete p;
701 setCityImage (i, NULL);
702 }
703 }
704
instantiateCityImages()705 bool Cityset::instantiateCityImages ()
706 {
707 clearCitiesImage (false);
708 bool broken = false;
709 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
710 if (broken)
711 return broken;
712 Glib::ustring imgname = getCitiesFilename();
713 if (imgname.empty() == false)
714 {
715 Glib::ustring filename = t.getFile(imgname, broken);
716 if (!broken)
717 {
718 std::vector<PixMask* > pics;
719 pics = disassemble_row(filename, MAX_PLAYERS + 1, broken);
720 if (!broken)
721 {
722 for (unsigned int i = 0; i < MAX_PLAYERS + 1; i++)
723 setCityImage(i, pics[i]);
724 }
725 }
726 }
727 return broken;
728 }
729
clearRazedCitiesImage(bool clear_name)730 void Cityset::clearRazedCitiesImage (bool clear_name)
731 {
732 if (clear_name)
733 setRazedCitiesFilename ("");
734
735 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
736 {
737 PixMask *p = getRazedCityImage (i);
738 delete p;
739 setRazedCityImage (i, NULL);
740 }
741 }
742
instantiateRazedCityImages()743 bool Cityset::instantiateRazedCityImages ()
744 {
745 clearRazedCitiesImage (false);
746 bool broken = false;
747 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
748 if (broken)
749 return broken;
750 Glib::ustring imgname = getRazedCitiesFilename();
751 if (imgname.empty() == false)
752 {
753 Glib::ustring filename = t.getFile(imgname, broken);
754 if (!broken)
755 {
756 std::vector<PixMask* > pics;
757 pics = disassemble_row(filename, MAX_PLAYERS, broken);
758 if (!broken)
759 {
760 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
761 setRazedCityImage(i, pics[i]);
762 }
763 }
764 }
765 return broken;
766 }
767
clearPortImage(bool clear_name)768 void Cityset::clearPortImage (bool clear_name)
769 {
770 if (clear_name)
771 setPortFilename ("");
772
773 PixMask *p = getPortImage ();
774 if (p)
775 delete p;
776 setPortImage (NULL);
777 }
778
instantiatePortImage()779 bool Cityset::instantiatePortImage ()
780 {
781 clearPortImage (false);
782 bool broken = false;
783 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
784 if (broken)
785 return broken;
786 Glib::ustring imgname = getPortFilename();
787 if (imgname.empty() == false)
788 {
789 Glib::ustring filename = t.getFile(imgname, broken);
790 if (!broken)
791 setPortImage (PixMask::create(filename, broken));
792 }
793 return broken;
794 }
795
clearSignpostImage(bool clear_name)796 void Cityset::clearSignpostImage (bool clear_name)
797 {
798 if (clear_name)
799 setSignpostFilename ("");
800
801 PixMask *p = getSignpostImage ();
802 if (p)
803 delete p;
804 setSignpostImage (NULL);
805 }
806
instantiateSignpostImage()807 bool Cityset::instantiateSignpostImage ()
808 {
809 clearSignpostImage (false);
810 bool broken = false;
811 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
812 if (broken)
813 return broken;
814 Glib::ustring imgname = getSignpostFilename();
815 if (imgname.empty() == false)
816 {
817 Glib::ustring filename = t.getFile(imgname, broken);
818 if (!broken)
819 setSignpostImage (PixMask::create(filename, broken));
820 }
821 return broken;
822 }
823
clearRuinsImage(bool clear_name)824 void Cityset::clearRuinsImage (bool clear_name)
825 {
826 if (clear_name)
827 setRuinsFilename ("");
828
829 for (unsigned int i = 0; i < RUIN_TYPES; i++)
830 {
831 PixMask *p = getRuinImage (i);
832 delete p;
833 setRuinImage (i, NULL);
834 }
835 }
836
instantiateRuinImages()837 bool Cityset::instantiateRuinImages ()
838 {
839 clearRuinsImage (false);
840 bool broken = false;
841 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
842 if (broken)
843 return broken;
844 Glib::ustring imgname = getRuinsFilename();
845 if (imgname.empty() == false)
846 {
847 Glib::ustring filename = t.getFile(imgname, broken);
848 if (!broken)
849 {
850 std::vector<PixMask* > pics =
851 disassemble_row(filename, RUIN_TYPES, broken);
852 if (!broken)
853 {
854 for (unsigned int i = 0; i < RUIN_TYPES ; i++)
855 setRuinImage(i, pics[i]);
856 }
857 }
858 }
859 return broken;
860 }
861
clearTemplesImage(bool clear_name)862 void Cityset::clearTemplesImage (bool clear_name)
863 {
864 if (clear_name)
865 setTemplesFilename ("");
866
867 for (unsigned int i = 0; i < TEMPLE_TYPES; i++)
868 {
869 PixMask *p = getTempleImage (i);
870 delete p;
871 setTempleImage (i, NULL);
872 }
873 }
874
instantiateTempleImages()875 bool Cityset::instantiateTempleImages ()
876 {
877 clearTemplesImage (false);
878 bool broken = false;
879 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
880 if (broken)
881 return broken;
882 Glib::ustring imgname = getTemplesFilename();
883 if (imgname.empty() == false)
884 {
885 Glib::ustring filename = t.getFile(imgname, broken);
886 if (!broken)
887 {
888 std::vector<PixMask* > pics;
889 pics = disassemble_row(filename, TEMPLE_TYPES, broken);
890 if (!broken)
891 {
892 for (unsigned int i = 0; i < TEMPLE_TYPES ; i++)
893 setTempleImage(i, pics[i]);
894 }
895 }
896 }
897 return broken;
898 }
899
clearTowersImage(bool clear_name)900 void Cityset::clearTowersImage (bool clear_name)
901 {
902 if (clear_name)
903 setTowersFilename ("");
904
905 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
906 {
907 PixMask *p = getTowerImage (i);
908 delete p;
909 setTowerImage (i, NULL);
910 }
911 }
912
instantiateTowerImages()913 bool Cityset::instantiateTowerImages ()
914 {
915 clearTowersImage (false);
916 bool broken = false;
917 Tar_Helper t(getConfigurationFile(), std::ios::in, broken);
918 if (broken)
919 return broken;
920 Glib::ustring imgname = getTowersFilename();
921 if (imgname.empty() == false)
922 {
923 Glib::ustring filename = t.getFile(imgname, broken);
924 if (!broken)
925 {
926 std::vector<PixMask* > pics =
927 disassemble_row(filename, MAX_PLAYERS, broken);
928 if (!broken)
929 {
930 for (unsigned int i = 0; i < MAX_PLAYERS; i++)
931 setTowerImage(i, pics[i]);
932 }
933 }
934 }
935 return broken;
936 }
937
get_default_tile_size()938 guint32 Cityset::get_default_tile_size ()
939 {
940 Cityset *c = new Cityset (1, "");
941 guint32 ts = c->getUnscaledTileSize ();
942 delete c;
943 return ts;
944 }
945
uninstantiateSameNamedImages(Glib::ustring name)946 void Cityset::uninstantiateSameNamedImages (Glib::ustring name)
947 {
948 if (getCitiesFilename() == name)
949 clearCitiesImage ();
950 if (getRazedCitiesFilename() == name)
951 clearRazedCitiesImage ();
952 if (getPortFilename() == name)
953 clearPortImage ();
954 if (getSignpostFilename() == name)
955 clearSignpostImage ();
956 if (getRuinsFilename() == name)
957 clearRuinsImage ();
958 if (getTemplesFilename() == name)
959 clearTemplesImage ();
960 if (getTowersFilename() == name)
961 clearTowersImage ();
962 }
963 // End of file
964