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