1 /***************************************************************************
2                           onu.cpp  -  description
3                              -------------------
4     begin                : Wed Jul 18 2001
5     copyright            : (C) 2001-2006 by Gael de Chalendar (aka Kleag)
6     email                : kleag@free.fr
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either either version 2
14    of the License, or (at your option) any later version.of the License, or     *
15  *   (at your option) any later version.                                   *
16  *                                                                         *
17  *   You should have received a copy of the GNU General Public License
18  *   along with this program; if not, write to the Free Software
19  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  *   02110-1301, USA
21  ***************************************************************************/
22 #include "onu.h"
23 #include "Sprites/skinSpritesData.h"
24 #include "goal.h"
25 
26 #define KDE_NO_COMPAT
27 #include <QFile>
28 #include <qdom.h>
29 #include <QPainter>
30 #include <QPixmapCache>
31 #include <QFileInfo>
32 #include <QMenuBar>
33 #include <KLocalizedString>
34 #include "ksirk_debug.h"
35 #include <KMessageBox>
36 #include <KConfig>
37 #include <KConfigGroup>
38 
39 namespace Ksirk
40 {
41 
42 namespace GameLogic
43 {
44 
ONU(GameAutomaton * automaton,const QString & configFileName)45 ONU::ONU(GameAutomaton* automaton,
46   const QString& configFileName):
47   QObject(automaton),
48   m_automaton(automaton),
49   m_configFileName(configFileName),
50   countries(),
51   nationalities(),
52   m_continents(),
53   m_skin(),
54   m_zoom(1.0),
55   m_zoomArena(1.0),
56   m_nbZooms(0),
57   m_zoomFactorFinal(1)
58 {
59   qCDebug(KSIRK_LOG) << "ONU constructor: " << m_configFileName;
60   QFileInfo qfi(m_configFileName);
61   qCDebug(KSIRK_LOG) << "skin written at :" << qfi.lastModified().toSecsSinceEpoch();
62   //qCDebug(KSIRK_LOG) << "cache created at:" << m_automaton->pixmapCache().timestamp();
63 #pragma message("port to qt5")
64 #if 0
65   if (m_automaton->pixmapCache().timestamp() < qfi.lastModified().toSecsSinceEpoch())
66   {
67     m_automaton->pixmapCache().discard();
68   }
69 #endif
70   m_font.family = "URW Chancery L";
71   m_font.size = (int)(13*m_zoom);
72   m_font.weight = QFont::Bold;
73   m_font.italic = true;
74   m_font.foregroundColor = "black";
75   m_font.backgroundColor = "white";
76 
77   m_timerFast=new QTimer(this);		//instanciation of the timer
78   QObject::connect(m_timerFast,&QTimer::timeout, this, &ONU::changingZoom);	//connect the timer to the good slot
79 
80   Sprites::SkinSpritesData::changeable().init();
81 //   unsigned int nationalityId = 0;
82 //   unsigned int continentId = 0;
83   KConfig config(configFileName);
84 
85   KConfigGroup onugroup = config.group("onu");
86 
87   qCDebug(KSIRK_LOG) << "ONU XML format version: " << onugroup.readEntry("format-version");
88   QString formatVersion = onugroup.readEntry("format-version");
89 
90   if (formatVersion != ONU_FILE_FORMAT_VERSION)
91   {
92     qCCritical(KSIRK_LOG) << "Error - Invalid skin definition file format. Expected "<<QString(ONU_FILE_FORMAT_VERSION)<<" and got " << formatVersion << "in" << m_configFileName << ". You should remove this skin folder";
93 //     KMessageBox::error(0,
94 //                         i18n("Error - Invalid skin definition file format. Expected %1 and got %2",QString(ONU_FILE_FORMAT_VERSION),formatVersion) + "<br>" + m_configFileName,
95 //                         i18n("Fatal Error"));
96     return;
97   }
98 
99   m_name = onugroup.readEntry("name");
100   m_skin = onugroup.readEntry("skinpath");
101 
102   qCDebug(KSIRK_LOG) << "skin snapshot file: " << QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg");
103   if (!QPixmapCache::find(m_skin+"snapshot", &m_snapshot))
104   {
105     // Pixmap isn't in the cache, create it and insert to cache
106     m_snapshot = QPixmap(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg"));
107     if (m_snapshot.isNull())
108     {
109       qCCritical(KSIRK_LOG) << "Was not able to load the snapshot image: " << QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg");
110     }
111     QPixmapCache::insert(m_skin+"snapshot", m_snapshot);
112   }
113   m_width  = onugroup.readEntry("width",0);
114   m_height  = onugroup.readEntry("height",0);
115   m_description = onugroup.readEntry("desc");
116 //   countries.resize(onugroup.readEntry("nb-countries",0));
117 //   nationalities.resize(onugroup.readEntry("nb-nationalities",0));
118 //   m_continents.resize(onugroup.readEntry("nb-continents",0));
119 //    root.attribute("map");
120   QString poolString = onugroup.readEntry("pool");
121   qCDebug(KSIRK_LOG) << "Pool path: " << poolString;
122   qCDebug(KSIRK_LOG) << "Searching resource: " << (m_skin + '/' + poolString);
123 
124   QString poolFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + '/' + poolString);
125   qCDebug(KSIRK_LOG) << "Pool file name: " << poolFileName;
126   if (poolFileName.isEmpty())
127   {
128       KMessageBox::error(0,
129                          i18n("Pool filename not found\nProgram cannot continue"),
130                          i18n("Error!"));
131       exit(2);
132   }
133   m_map = QPixmap();
134   qCDebug(KSIRK_LOG) << m_skin << "before pool loading";
135   if (!m_automaton->rendererFor(m_skin).isValid())
136     m_automaton->rendererFor(m_skin).load(poolFileName);
137   if (m_automaton->svgDomFor(m_skin).svgFilename().isNull())
138     m_automaton->svgDomFor(m_skin).load(poolFileName);
139   qCDebug(KSIRK_LOG) << m_skin << "after pool loading";
140 
141   QString mapMaskFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + '/' + onugroup.readEntry("map-mask"));
142   qCDebug(KSIRK_LOG) << "Map mask file name: " << mapMaskFileName;
143   if (mapMaskFileName.isNull())
144   {
145       KMessageBox::error(0,
146                          i18n("Map mask image not found\nProgram cannot continue"),
147                          i18n("Error!"));
148       exit(2);
149   }
150   qCDebug(KSIRK_LOG) << "Loading map mask file: " << mapMaskFileName;
151   QPixmap countriesMaskPix;
152   if (!QPixmapCache::find(m_skin+"mapmask", &countriesMaskPix))
153   {
154     // Pixmap isn't in the cache, create it and insert to cache
155     countriesMaskPix = QPixmap(mapMaskFileName);
156     if (countriesMaskPix.isNull())
157     {
158       qCCritical(KSIRK_LOG) << "Was not able to load the map mask image: " << mapMaskFileName ;
159     }
160     QPixmapCache::insert(m_skin+"mapmask", countriesMaskPix);
161   }
162 //   countriesMask = QImage(mapMaskFileName);
163   countriesMask = countriesMaskPix.toImage();
164 
165   Sprites::SkinSpritesData::changeable().intData("width-between-flag-and-fighter", onugroup.readEntry("width-between-flag-and-fighter",0));
166 
167   Sprites::SkinSpritesData::changeable().intData("flag-width", config.group("flag").readEntry("width",0));
168   Sprites::SkinSpritesData::changeable().intData("flag-height", config.group("flag").readEntry("height",0));
169   Sprites::SkinSpritesData::changeable().intData("flag-frames", config.group("flag").readEntry("frames",0));
170   Sprites::SkinSpritesData::changeable().intData("flag-versions", config.group("flag").readEntry("versions",0));
171 
172 //   Sprites::SkinSpritesData::changeable().strData("infantry-id", config.group("infantry").readEntry("id"));
173   Sprites::SkinSpritesData::changeable().intData("infantry-width", config.group("infantry").readEntry("width",0));
174   Sprites::SkinSpritesData::changeable().intData("infantry-height", config.group("infantry").readEntry("height",0));
175   Sprites::SkinSpritesData::changeable().intData("infantry-frames", config.group("infantry").readEntry("frames",0));
176   Sprites::SkinSpritesData::changeable().intData("infantry-versions", config.group("infantry").readEntry("versions",0));
177 
178 //   Sprites::SkinSpritesData::changeable().strData("infantry1-id", config.group("infantry1").readEntry("id"));
179   Sprites::SkinSpritesData::changeable().intData("infantry1-width", config.group("infantry1").readEntry("width",0));
180   Sprites::SkinSpritesData::changeable().intData("infantry1-height", config.group("infantry1").readEntry("height",0));
181   Sprites::SkinSpritesData::changeable().intData("infantry1-frames", config.group("infantry1").readEntry("frames",0));
182   Sprites::SkinSpritesData::changeable().intData("infantry1-versions", config.group("infantry1").readEntry("versions",0));
183 
184 //   Sprites::SkinSpritesData::changeable().strData("infantry2-id", config.group("infantry2").readEntry("id"));
185   Sprites::SkinSpritesData::changeable().intData("infantry2-width", config.group("infantry2").readEntry("width",0));
186   Sprites::SkinSpritesData::changeable().intData("infantry2-height", config.group("infantry2").readEntry("height",0));
187   Sprites::SkinSpritesData::changeable().intData("infantry2-frames", config.group("infantry2").readEntry("frames",0));
188   Sprites::SkinSpritesData::changeable().intData("infantry2-versions", config.group("infantry2").readEntry("versions",0));
189 
190 //   Sprites::SkinSpritesData::changeable().strData("infantry3-id", config.group("infantry3").readEntry("id"));
191   Sprites::SkinSpritesData::changeable().intData("infantry3-width", config.group("infantry3").readEntry("width",0));
192   Sprites::SkinSpritesData::changeable().intData("infantry3-height", config.group("infantry3").readEntry("height",0));
193   Sprites::SkinSpritesData::changeable().intData("infantry3-frames", config.group("infantry3").readEntry("frames",0));
194   Sprites::SkinSpritesData::changeable().intData("infantry3-versions", config.group("infantry3").readEntry("versions",0));
195 
196 //   Sprites::SkinSpritesData::changeable().strData("cavalry-id", config.group("cavalry").readEntry("id"));
197   Sprites::SkinSpritesData::changeable().intData("cavalry-width", config.group("cavalry").readEntry("width",0));
198   Sprites::SkinSpritesData::changeable().intData("cavalry-height", config.group("cavalry").readEntry("height",0));
199   Sprites::SkinSpritesData::changeable().intData("cavalry-frames", config.group("cavalry").readEntry("frames",0));
200   Sprites::SkinSpritesData::changeable().intData("cavalry-versions", config.group("cavalry").readEntry("versions",0));
201 
202 //   Sprites::SkinSpritesData::changeable().strData("cannon-id", config.group("cannon").readEntry("id"));
203   Sprites::SkinSpritesData::changeable().intData("cannon-width", config.group("cannon").readEntry("width",0));
204   Sprites::SkinSpritesData::changeable().intData("cannon-height", config.group("cannon").readEntry("height",0));
205   Sprites::SkinSpritesData::changeable().intData("cannon-frames", config.group("cannon").readEntry("frames",0));
206   Sprites::SkinSpritesData::changeable().intData("cannon-versions", config.group("cannon").readEntry("versions",0));
207 
208 //   Sprites::SkinSpritesData::changeable().strData("firing-id", config.group("firing").readEntry("id"));
209   Sprites::SkinSpritesData::changeable().intData("firing-width", config.group("firing").readEntry("width",0));
210   Sprites::SkinSpritesData::changeable().intData("firing-height", config.group("firing").readEntry("height",0));
211   Sprites::SkinSpritesData::changeable().intData("firing-frames", config.group("firing").readEntry("frames",0));
212   Sprites::SkinSpritesData::changeable().intData("firing-versions", config.group("firing").readEntry("versions",0));
213 
214 //   Sprites::SkinSpritesData::changeable().strData("exploding-id", config.group("exploding").readEntry("id"));
215   Sprites::SkinSpritesData::changeable().intData("exploding-width", config.group("exploding").readEntry("width",0));
216   Sprites::SkinSpritesData::changeable().intData("exploding-height", config.group("cannon").readEntry("height",0));
217   Sprites::SkinSpritesData::changeable().intData("exploding-frames", config.group("exploding").readEntry("frames",0));
218   Sprites::SkinSpritesData::changeable().intData("exploding-versions", config.group("exploding").readEntry("versions",0));
219 
220   KConfigGroup fontgroup = config.group("font");
221   m_font.family = fontgroup.readEntry("family","URW Chancery L");
222   m_font.size = fontgroup.readEntry("size",(int)(13*m_zoom));
223   QString w = fontgroup.readEntry("weight", "bold");;
224   if (w == "normal")
225   {
226     m_font.weight = QFont::Normal;
227   }
228   else if (w == "light")
229   {
230     m_font.weight = QFont::Light;
231   }
232   else if (w == "demibold")
233   {
234     m_font.weight = QFont::DemiBold;
235   }
236   else if (w == "bold")
237   {
238     m_font.weight = QFont::Bold;
239   }
240   else if (w == "black")
241   {
242     m_font.weight = QFont::Black;
243   }
244   m_font.italic = fontgroup.readEntry("italic", true);
245   m_font.foregroundColor = fontgroup.readEntry("foreground-color", "black");
246   m_font.backgroundColor = fontgroup.readEntry("background-color", "white");
247 
248   QStringList countriesList = onugroup.readEntry("countries", QStringList());
249   foreach (const QString &country, countriesList)
250   {
251     KConfigGroup countryGroup = config.group(country);
252 //     unsigned int id = countryGroup.readEntry("id",0);
253     QString name = country;
254     QPointF anchorPoint = countryGroup.readEntry("anchor-point",QPointF())*m_zoom;
255     QPointF centralPoint = countryGroup.readEntry("central-point",QPointF())*m_zoom;
256     QPointF flagPoint = countryGroup.readEntry("flag-point",QPointF())*m_zoom;
257     QPointF cannonPoint = countryGroup.readEntry("cannon-point",QPointF())*m_zoom;
258     QPointF cavalryPoint = countryGroup.readEntry("cavalry-point",QPointF())*m_zoom;
259     QPointF infantryPoint = countryGroup.readEntry("infantry-point",QPointF())*m_zoom;
260 
261 //     qCDebug(KSIRK_LOG) << "Creating country " << name;
262 //     qCDebug(KSIRK_LOG) << "\tflag point: " << flagPoint;
263 //     qCDebug(KSIRK_LOG) << "\tcentral point: " << centralPoint;
264 //     qCDebug(KSIRK_LOG) << "\tcannon point: " << cannonPoint;
265 //     qCDebug(KSIRK_LOG) << "\tcavalry point: " << cavalryPoint;
266 //     qCDebug(KSIRK_LOG) << "\tinfantry point: " << infantryPoint;
267     countries.push_back(new Country(automaton, name, anchorPoint, centralPoint,
268         flagPoint, cannonPoint, cavalryPoint, infantryPoint));
269   }
270   QStringList nationalitiesList = onugroup.readEntry("nationalities", QStringList());
271   foreach (const QString &nationality, nationalitiesList)
272   {
273 //     qCDebug(KSIRK_LOG) << "Creating nationality " << nationality;
274     KConfigGroup nationalityGroup = config.group(nationality);
275     QString leader = nationalityGroup.readEntry("leader","");
276     QString flag = nationalityGroup.readEntry("flag","");
277 //         qCDebug(KSIRK_LOG) << "Creating nationality " << name << " ; flag: " << flag;
278     nationalities.push_back(new Nationality(nationality, flag, leader));
279 //     nationalityId++;
280   }
281 
282 
283   QStringList continentsList = onugroup.readEntry("continents", QStringList());
284   foreach (const QString &continent, continentsList)
285   {
286     KConfigGroup continentGroup = config.group(continent);
287 
288 //     unsigned int id = continentGroup.readEntry("id",0);
289     unsigned int bonus = continentGroup.readEntry("bonus",0);
290     QList<QString> countryIdList = continentGroup.readEntry("continent-countries",QList<QString>());
291 //     int countryId;
292     QList<Country*> continentList;
293     foreach(const QString& countryId, countryIdList)
294     {
295 //       qCDebug(KSIRK_LOG) << "Adding" << countryId << "to" << continent << "list";
296       Country *c = countryNamed(countryId);
297       if (c)
298       {
299         continentList.push_back(c);
300       }
301     }
302 //       qCDebug(KSIRK_LOG) << "Creating continent " << name;
303     m_continents.push_back(new Continent(continent, continentList, bonus));
304   }
305 
306   QStringList goalsList = onugroup.readEntry("goals", QStringList());
307   foreach (const QString &_goal, goalsList)
308   {
309 //     qCDebug(KSIRK_LOG) << "init goal " << _goal;
310     KConfigGroup goalGroup = config.group(_goal);
311 
312     Goal* goal = new Goal(automaton);
313     goal->description(goalGroup.readEntry("desc",""));
314     QString goalType = goalGroup.readEntry("type","");
315     if (goalType == "countries")
316     {
317       goal->type(Goal::Countries);
318       goal->nbCountries(goalGroup.readEntry("nbCountries",0));
319       goal->nbArmiesByCountry(goalGroup.readEntry("nbArmiesByCountry",0));
320 //       qCDebug(KSIRK_LOG) << "  nb countries: **********************************" << goal->nbCountries();
321 //       qCDebug(KSIRK_LOG) << "  nbarmies countries: **********************************" << goal->nbArmiesByCountry();
322     }
323     else if (goalType == "continents" )
324     {
325       goal->type(Goal::Continents);
326       QList<QString> contList = goalGroup.readEntry("continents",QList<QString>());
327       foreach(const QString& continentId, contList)
328       {
329         // Bug 308527. Use only known continents.
330         if (continentsList.contains(continentId))
331           goal->continents().push_back(continentId);
332         else
333         {
334           qCDebug(KSIRK_LOG) << "Unknown continent " << continentId << " in skin " << m_skin ;
335         }
336       }
337     }
338     else if (goalType == "player" )
339     {
340       goal->type(Goal::GoalPlayer);
341       unsigned int nb = goalGroup.readEntry("nbCountriesFallback",0);
342       goal->nbCountries(nb);
343     }
344     automaton->goals().push_back(goal);
345   }
346 
347   foreach (const QString &countryName, countriesList)
348   {
349     Country *country = countryNamed(countryName);
350 
351     if (!country)
352     {
353       continue;
354     }
355 
356 //     qCDebug(KSIRK_LOG) << "building neighbours list of " << countryName;
357     QList< Country* > theNeighbours;
358     KConfigGroup countryGroup = config.group(countryName);
359     QList<QString> theNeighboursIds = countryGroup.readEntry("neighbours",QList<QString>());
360 //     int neighbourId;
361     foreach(const QString& neighbourId, theNeighboursIds)
362     {
363       Country *c = countryNamed(neighbourId);
364       if (c)
365       {
366         theNeighbours.push_back(c);
367       }
368     }
369 
370     country-> neighbours(theNeighbours);
371   }
372   buildMap();
373 
374   qCDebug(KSIRK_LOG) << "OUT";
375 }
376 
~ONU()377 ONU::~ONU()
378 {
379   delete m_timerFast;
380 
381   QList<Country*>::iterator countriesIt, countriesIt_end;
382   countriesIt = countries.begin(); countriesIt_end = countries.end();
383   for (; countriesIt != countriesIt_end; countriesIt++)
384   {
385     delete *countriesIt;
386   }
387 
388   QList<Nationality*>::iterator nationalitiesIt, nationalitiesIt_end;
389   nationalitiesIt = nationalities.begin(); nationalitiesIt_end = nationalities.end();
390   for (; nationalitiesIt != nationalitiesIt_end; nationalitiesIt++)
391   {
392     delete *nationalitiesIt;
393   }
394 
395   QList<Continent*>::iterator continentsIt, continentsIt_end;
396   continentsIt = m_continents.begin(); continentsIt_end = m_continents.end();
397   for (; continentsIt != continentsIt_end; continentsIt++)
398   {
399     delete *continentsIt;
400   }
401 
402 }
403 
404 
405 /** This method returns a pointer to the country that contains the point (x,y).
406 If there is no country at (x,y), the functions returns 0. */
countryAt(const QPointF & point)407 Country* ONU::countryAt(const QPointF& point)
408 {
409 //    qCDebug(KSIRK_LOG) << "ONU::countryAt x y " << x << " " << y;
410     QPointF norm = point;
411     norm /= m_zoom;
412     if ( norm.x() < 0 || norm.x() >= countriesMask.width()
413       || norm.y() < 0 || norm.y() >= countriesMask.height() )
414       return 0;
415 
416     int index = qBlue(countriesMask.pixel(norm.toPoint()));
417 //    qCDebug(KSIRK_LOG) << "OUT ONU::countryAt: " << index;
418     if (index >= countries.size()) return 0;
419     return countries.at(index);
420 }
421 
reset()422 void ONU::reset()
423 {
424   qCDebug(KSIRK_LOG);
425   foreach (Country* country, countries)
426   {
427     country-> reset();
428   }
429 }
430 
431 
getCountries()432 QList<Country*>& ONU::getCountries()
433 {
434   return countries;
435 }
436 
getNationalities()437 QList<Nationality*>& ONU::getNationalities()
438 {
439   return nationalities;
440 }
441 
442 /** Read property of QList<Continent*> continents. */
getContinents() const443 const QList<Continent*>& ONU::getContinents() const
444 {
445   return m_continents;
446 }
447 
getContinents()448 QList<Continent*>& ONU::getContinents()
449 {
450   return m_continents;
451 }
452 
453 /**
454   * Returns the list of countries neighbours of this country that does not
455   * belongs to the argument player.
456   */
neighboursBelongingTo(const Country & country,const Player * player)457 QList<Country*> ONU::neighboursBelongingTo(const Country& country, const Player* player)
458 {
459   QList<Country*> list;
460   foreach (Country *c,  country.neighbours())
461   {
462     if ((country.communicateWith(c)) && (c-> owner() == player))
463       {list.push_back(c);}
464   }
465   return list;
466 }
467 
468 /**
469   * Returns the list of countries neighbours of this country that does not
470   * belongs to the argument player.
471   */
neighboursNotBelongingTo(const Country & country,const Player * player)472 QList<Country*> ONU::neighboursNotBelongingTo(const Country& country, const Player* player)
473 {
474   QList<Country*> list;
475   foreach (Country *c,  country.neighbours())
476   {
477     if ((country.communicateWith(c)) && (c-> owner() != player))
478       {list.push_back(c);}
479   }
480   return list;
481 }
482 
483 /**
484   * Returns the country named "name" ; 0 in case there is no such country
485   */
countryNamed(const QString & name)486 Country* ONU::countryNamed(const QString& name)
487 {
488   if (name.isEmpty())
489   {
490 //     qCDebug(KSIRK_LOG) << "request for country with empty name";
491     return 0;
492   }
493 
494   foreach (Country *c, countries)
495   {
496     if (c-> name() == name)
497       return c;
498   }
499 
500 //   qCDebug(KSIRK_LOG) << "request for country" << name << "which doesn't seem to exist.";
501   return 0;
502 }
503 
504 /** @return the number of countries in the world */
getNbCountries() const505 unsigned int ONU::getNbCountries() const
506 {
507     return(countries.size());
508 }
509 
saveXml(QTextStream & xmlStream)510 void ONU::saveXml(QTextStream& xmlStream)
511 {
512   xmlStream << "<ONU file=\"" << m_configFileName << "\" >";
513 
514   xmlStream << "<countries>";
515   foreach (Country *c, countries)
516   {
517       c->saveXml(xmlStream);
518   }
519   xmlStream << "</countries>";
520   xmlStream << "</ONU>";
521 }
522 
width() const523 unsigned int ONU::width() const
524 {
525   return m_width;
526 }
527 
height() const528 unsigned int ONU::height() const
529 {
530   return m_height;
531 }
532 
533 /** Returns the nation named "name" ; 0 in case there is no such nation */
nationNamed(const QString & name)534 Nationality* ONU::nationNamed(const QString& name)
535 {
536   foreach (Nationality *n, nationalities)
537   {
538     if (n->name() == name)
539     {
540       return n;
541     }
542   }
543   return 0;
544 }
545 
sendCountries(QDataStream & stream)546 void ONU::sendCountries(QDataStream& stream)
547 {
548   stream << quint32(countries.size());
549   foreach (Country* country, countries)
550   {
551 //     qCDebug(KSIRK_LOG) << "Sending country " << country->name();
552     country->send(stream);
553   }
554 }
555 
556 /*const Continent* ONU::continentWithId(const unsigned int id) const
557 {
558   for (unsigned int i = 0; i < m_continents.size(); i++)
559   {
560     if ( m_continents.at(i)->id() == id)
561     {
562       return m_continents.at(i);
563     }
564   }
565   return 0;
566 }
567 */
continentNamed(const QString & name)568 Continent* ONU::continentNamed(const QString& name)
569 {
570   foreach (Continent *c, m_continents)
571   {
572     if (c-> name() == name)
573       return c;
574   }
575   return 0;
576 }
577 
buildMap()578 void ONU::buildMap()
579 {
580   qCDebug(KSIRK_LOG) << "with zoom="<< m_zoom;
581   //QSize size((int)(m_automaton->rendererFor(m_skin).defaultSize().width()*m_zoom),(int)(m_automaton->rendererFor(m_skin).defaultSize().height()*m_zoom));
582   if (!QPixmapCache::find(m_skin+"map"+QString::number(m_width)+QString::number(m_height), &m_map))
583   {
584     // Pixmap isn't in the cache, create it and insert to cache
585     QSize size((int)(m_width),(int)(m_height));
586     QImage image(size, QImage::Format_ARGB32_Premultiplied);
587     image.fill(0);
588     QPainter p(&image);
589     m_automaton->rendererFor(m_skin).render(&p, "map");
590     m_map = QPixmap::fromImage(image);
591 
592 
593     QPainter painter(&m_map);
594     QFont foregroundFont(m_font.family, m_font.size, m_font.weight, m_font.italic);
595     QFont backgroundFont(m_font.family, m_font.size, QFont::Normal, m_font.italic);
596 
597     painter.drawPixmap(0,0,m_map);
598 
599     foreach (Country* country, countries)
600     {
601       const QString& countryName = i18n(country->name().toUtf8().data());
602       if (m_font.backgroundColor != "none")
603       {
604         painter.setPen(m_font.backgroundColor);
605         painter.setFont(backgroundFont);
606         QRect countryNameRect = painter.fontMetrics().boundingRect(countryName);
607         painter.drawText(
608           int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) + 1 ),
609          // HACK HACK see the same below
610           int( (country->centralPoint().y()*m_zoom) + 4/*(countryNameRect.height()/2)*/ + 1 ),
611           countryName);
612       }
613       painter.setPen(m_font.foregroundColor);
614       painter.setFont(foregroundFont);
615       QRect countryNameRect = painter.fontMetrics().boundingRect(countryName);
616 //       qCDebug(KSIRK_LOG) << countryName << "countryNameRect=" << countryNameRect;
617 //       qCDebug(KSIRK_LOG) << "draw at" << int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) ) <<
618 //      int( (country->centralPoint().y()*m_zoom) - (countryNameRect.height()/2) );
619 
620       painter.drawText(
621         int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) ),
622         // HACK HACK why is this 4 necessary below instead of the commented correction ???
623         int( (country->centralPoint().y()*m_zoom) + 4/*- (countryNameRect.height()/2)*/ ),
624         countryName);
625     }
626 
627     QPixmapCache::insert(m_skin+"map"+QString::number(m_width)+QString::number(m_height), m_map);
628   }
629 }
630 
applyZoomFactor(qreal zoomFactor)631 void ONU::applyZoomFactor(qreal zoomFactor)
632 {
633 /** Zoom 1: First method (take a long time to zoom) :
634 */
635 //   qCDebug(KSIRK_LOG) << "zoomFactor=" << zoomFactor << "old zoom=" << m_zoom;
636 //   qCDebug(KSIRK_LOG) << "new zoom=" << m_zoom;
637 
638   m_zoom *= zoomFactor;
639 
640   //m_font.size = (int)(m_font.size*m_zoom);
641   //m_width = (unsigned int)(m_width *m_zoom);
642   //m_height = (unsigned int)(m_height *m_zoom);
643 
644   buildMap();
645 
646   foreach (Country* country, countries)
647   {
648     country->createArmiesSprites();
649   }
650 
651 }
652 
applyZoomFactorFast(qreal zoomFactor)653 void ONU::applyZoomFactorFast(qreal zoomFactor)		//benj
654 {
655 
656 /** Zoom 2 : Second method , Very performent.  Carefull ! Can cause the game to lag.
657  To try this, comment all the first method and uncomment these lines
658 */
659   qCDebug(KSIRK_LOG) << "zoomFactor FASTTTTTTT";
660   int nbLimitZooms = 6;
661 
662   //Application of zoom
663   if (zoomFactor > 1 && m_nbZooms < nbLimitZooms)
664   {
665     m_font.size = (int)(m_font.size*zoomFactor);
666     m_width = (unsigned int)(m_width *zoomFactor);
667     m_height = (unsigned int)(m_height *zoomFactor);
668 
669       m_nbZooms++; // zoom forward
670       m_automaton->game()->frame()->scale(zoomFactor, zoomFactor);
671       m_zoomFactorFinal *= zoomFactor;
672 
673       //starting timer
674       /*if  (m_timerFast->isActive())
675       {
676         m_timerFast->stop();
677       }
678       m_timerFast->start(4000);
679       m_timerFast->setSingleShot(true);*/
680 
681   }
682   else if (zoomFactor < 1 && m_nbZooms > -nbLimitZooms)
683   {
684     m_font.size = (int)(m_font.size*zoomFactor);
685     m_width = (unsigned int)(m_width *zoomFactor);
686     m_height = (unsigned int)(m_height *zoomFactor);
687 
688       m_nbZooms--; // zoom backward
689       m_automaton->game()->frame()->scale(zoomFactor, zoomFactor);
690       m_zoomFactorFinal *= zoomFactor;
691 
692       //starting timer
693       /*if  (m_timerFast->isActive())
694       {
695         m_timerFast->stop();
696       }
697       m_timerFast->start(4000);
698       m_timerFast->setSingleShot(true);*/
699   }
700 }
701 
zoom() const702 double ONU::zoom() const
703 {
704   if (m_automaton->game()->currentWidgetType() == KGameWindow::Map) {
705     return m_zoom;
706   }
707   return m_zoomArena;
708 }
709 
710 
renderer()711 QSvgRenderer* ONU::renderer()
712 {
713   return &m_automaton->rendererFor(m_skin);
714 }
715 
716 
svgDom()717 KGameSvgDocument* ONU::svgDom()
718 {
719   return &m_automaton->svgDomFor(m_skin);
720 }
721 
indexOfCountry(Country * c) const722 unsigned int ONU::indexOfCountry(Country* c) const
723 {
724   return countries.indexOf(c);
725 }
726 
727 
728 /** the SLOTS METHODS FOR THE ONU CLASS*/
changingZoom()729 void ONU::changingZoom()
730 {
731 /*
732   m_automaton->game()->frame()->resetTransform();
733   qreal m_zo=m_zoomFactorFinal;
734   m_zoomFactorFinal=1;
735   applyZoomFactor(m_zo);*/
736 
737  // m_automaton->game()->frame()->scale(1/m_zoomFactorFinal, 1/m_zoomFactorFinal);
738 
739   m_automaton->game()->frame()->resetTransform();
740   applyZoomFactor(m_zoomFactorFinal);
741   m_zoomFactorFinal=1.0;
742 }
743 
744 /**END OF SLOTS METHODS FOR THE ONU*/
745 } // closing namespace GameLogic
746 } // closing namespace Ksirk
747 
748 
749