File indexing completed on 2024-10-06 06:48:48
0001 /*************************************************************************** 0002 onu.cpp - description 0003 ------------------- 0004 begin : Wed Jul 18 2001 0005 copyright : (C) 2001-2006 by Gael de Chalendar (aka Kleag) 0006 email : kleag@free.fr 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either either version 2 0014 of the License, or (at your option) any later version.of the License, or * 0015 * (at your option) any later version. * 0016 * * 0017 * You should have received a copy of the GNU General Public License 0018 * along with this program; if not, write to the Free Software 0019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0020 * 02110-1301, USA 0021 ***************************************************************************/ 0022 #include "onu.h" 0023 #include "Sprites/skinSpritesData.h" 0024 #include "goal.h" 0025 0026 #include <QApplication> 0027 #include <QFile> 0028 #include <qdom.h> 0029 #include <QPainter> 0030 #include <QPixmapCache> 0031 #include <QMenuBar> 0032 #include <KLocalizedString> 0033 #include "ksirk_debug.h" 0034 #include <KMessageBox> 0035 #include <KConfig> 0036 #include <KConfigGroup> 0037 0038 namespace Ksirk 0039 { 0040 0041 namespace GameLogic 0042 { 0043 0044 ONU::ONU(GameAutomaton* automaton, 0045 const QString& configFileName): 0046 QObject(automaton), 0047 m_automaton(automaton), 0048 m_configFileName(configFileName), 0049 countries(), 0050 nationalities(), 0051 m_continents(), 0052 m_skin(), 0053 m_zoom(1.0), 0054 m_zoomArena(1.0), 0055 m_nbZooms(0), 0056 m_zoomFactorFinal(1) 0057 { 0058 qCDebug(KSIRK_LOG) << "ONU constructor: " << m_configFileName; 0059 m_font.family = "URW Chancery L"; 0060 m_font.size = (int)(13*m_zoom); 0061 m_font.weight = QFont::Bold; 0062 m_font.italic = true; 0063 m_font.foregroundColor = "black"; 0064 m_font.backgroundColor = "white"; 0065 0066 m_timerFast=new QTimer(this); //instanciation of the timer 0067 QObject::connect(m_timerFast,&QTimer::timeout, this, &ONU::changingZoom); //connect the timer to the good slot 0068 0069 Sprites::SkinSpritesData::changeable().init(); 0070 // unsigned int nationalityId = 0; 0071 // unsigned int continentId = 0; 0072 KConfig config(configFileName); 0073 0074 KConfigGroup onugroup = config.group(QStringLiteral("onu")); 0075 0076 qCDebug(KSIRK_LOG) << "ONU XML format version: " << onugroup.readEntry("format-version"); 0077 QString formatVersion = onugroup.readEntry("format-version"); 0078 0079 if (formatVersion != ONU_FILE_FORMAT_VERSION) 0080 { 0081 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"; 0082 // KMessageBox::error(0, 0083 // i18n("Error - Invalid skin definition file format. Expected %1 and got %2",QString(ONU_FILE_FORMAT_VERSION),formatVersion) + "<br>" + m_configFileName, 0084 // i18n("Fatal Error")); 0085 return; 0086 } 0087 0088 m_name = onugroup.readEntry("name"); 0089 m_skin = onugroup.readEntry("skinpath"); 0090 0091 qCDebug(KSIRK_LOG) << "skin snapshot file: " << QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg"); 0092 const QString snapshotCacheId = m_skin + QLatin1String("snapshot"); 0093 if (!QPixmapCache::find(snapshotCacheId, &m_snapshot)) 0094 { 0095 // Pixmap isn't in the cache, create it and insert to cache 0096 m_snapshot = QPixmap(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg")); 0097 if (m_snapshot.isNull()) 0098 { 0099 qCCritical(KSIRK_LOG) << "Was not able to load the snapshot image: " << QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + "/Images/snapshot.jpg"); 0100 } 0101 QPixmapCache::insert(snapshotCacheId, m_snapshot); 0102 } 0103 m_width = onugroup.readEntry("width",0); 0104 m_height = onugroup.readEntry("height",0); 0105 m_description = onugroup.readEntry("desc"); 0106 // countries.resize(onugroup.readEntry("nb-countries",0)); 0107 // nationalities.resize(onugroup.readEntry("nb-nationalities",0)); 0108 // m_continents.resize(onugroup.readEntry("nb-continents",0)); 0109 // root.attribute("map"); 0110 QString poolString = onugroup.readEntry("pool"); 0111 qCDebug(KSIRK_LOG) << "Pool path: " << poolString; 0112 qCDebug(KSIRK_LOG) << "Searching resource: " << (m_skin + '/' + poolString); 0113 0114 QString poolFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + '/' + poolString); 0115 qCDebug(KSIRK_LOG) << "Pool file name: " << poolFileName; 0116 if (poolFileName.isEmpty()) 0117 { 0118 KMessageBox::error(nullptr, 0119 i18n("Pool filename not found\nProgram cannot continue"), 0120 i18n("Error!")); 0121 exit(2); 0122 } 0123 m_map = QPixmap(); 0124 qCDebug(KSIRK_LOG) << m_skin << "before pool loading"; 0125 if (!m_automaton->rendererFor(m_skin).isValid()) 0126 m_automaton->rendererFor(m_skin).load(poolFileName); 0127 if (m_automaton->svgDomFor(m_skin).svgFilename().isNull()) 0128 m_automaton->svgDomFor(m_skin).load(poolFileName); 0129 qCDebug(KSIRK_LOG) << m_skin << "after pool loading"; 0130 0131 QString mapMaskFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_skin + '/' + onugroup.readEntry("map-mask")); 0132 qCDebug(KSIRK_LOG) << "Map mask file name: " << mapMaskFileName; 0133 if (mapMaskFileName.isNull()) 0134 { 0135 KMessageBox::error(nullptr, 0136 i18n("Map mask image not found\nProgram cannot continue"), 0137 i18n("Error!")); 0138 exit(2); 0139 } 0140 qCDebug(KSIRK_LOG) << "Loading map mask file: " << mapMaskFileName; 0141 QPixmap countriesMaskPix; 0142 const QString mapMaskCacheId = m_skin + QLatin1String("mapmask"); 0143 if (!QPixmapCache::find(mapMaskCacheId, &countriesMaskPix)) 0144 { 0145 // Pixmap isn't in the cache, create it and insert to cache 0146 countriesMaskPix = QPixmap(mapMaskFileName); 0147 if (countriesMaskPix.isNull()) 0148 { 0149 qCCritical(KSIRK_LOG) << "Was not able to load the map mask image: " << mapMaskFileName ; 0150 } 0151 QPixmapCache::insert(mapMaskCacheId, countriesMaskPix); 0152 } 0153 // countriesMask = QImage(mapMaskFileName); 0154 countriesMask = countriesMaskPix.toImage(); 0155 0156 Sprites::SkinSpritesData::changeable().intData("width-between-flag-and-fighter", onugroup.readEntry("width-between-flag-and-fighter",0)); 0157 0158 Sprites::SkinSpritesData::changeable().intData("flag-width", config.group(QStringLiteral("flag")).readEntry("width",0)); 0159 Sprites::SkinSpritesData::changeable().intData("flag-height", config.group(QStringLiteral("flag")).readEntry("height",0)); 0160 Sprites::SkinSpritesData::changeable().intData("flag-frames", config.group(QStringLiteral("flag")).readEntry("frames",0)); 0161 Sprites::SkinSpritesData::changeable().intData("flag-versions", config.group(QStringLiteral("flag")).readEntry("versions",0)); 0162 0163 // Sprites::SkinSpritesData::changeable().strData("infantry-id", config.group(QStringLiteral("infantry")).readEntry("id")); 0164 Sprites::SkinSpritesData::changeable().intData("infantry-width", config.group(QStringLiteral("infantry")).readEntry("width",0)); 0165 Sprites::SkinSpritesData::changeable().intData("infantry-height", config.group(QStringLiteral("infantry")).readEntry("height",0)); 0166 Sprites::SkinSpritesData::changeable().intData("infantry-frames", config.group(QStringLiteral("infantry")).readEntry("frames",0)); 0167 Sprites::SkinSpritesData::changeable().intData("infantry-versions", config.group(QStringLiteral("infantry")).readEntry("versions",0)); 0168 0169 // Sprites::SkinSpritesData::changeable().strData("infantry1-id", config.group(QStringLiteral("infantry1")).readEntry("id")); 0170 Sprites::SkinSpritesData::changeable().intData("infantry1-width", config.group(QStringLiteral("infantry1")).readEntry("width",0)); 0171 Sprites::SkinSpritesData::changeable().intData("infantry1-height", config.group(QStringLiteral("infantry1")).readEntry("height",0)); 0172 Sprites::SkinSpritesData::changeable().intData("infantry1-frames", config.group(QStringLiteral("infantry1")).readEntry("frames",0)); 0173 Sprites::SkinSpritesData::changeable().intData("infantry1-versions", config.group(QStringLiteral("infantry1")).readEntry("versions",0)); 0174 0175 // Sprites::SkinSpritesData::changeable().strData("infantry2-id", config.group(QStringLiteral("infantry2")).readEntry("id")); 0176 Sprites::SkinSpritesData::changeable().intData("infantry2-width", config.group(QStringLiteral("infantry2")).readEntry("width",0)); 0177 Sprites::SkinSpritesData::changeable().intData("infantry2-height", config.group(QStringLiteral("infantry2")).readEntry("height",0)); 0178 Sprites::SkinSpritesData::changeable().intData("infantry2-frames", config.group(QStringLiteral("infantry2")).readEntry("frames",0)); 0179 Sprites::SkinSpritesData::changeable().intData("infantry2-versions", config.group(QStringLiteral("infantry2")).readEntry("versions",0)); 0180 0181 // Sprites::SkinSpritesData::changeable().strData("infantry3-id", config.group(QStringLiteral("infantry3")).readEntry("id")); 0182 Sprites::SkinSpritesData::changeable().intData("infantry3-width", config.group(QStringLiteral("infantry3")).readEntry("width",0)); 0183 Sprites::SkinSpritesData::changeable().intData("infantry3-height", config.group(QStringLiteral("infantry3")).readEntry("height",0)); 0184 Sprites::SkinSpritesData::changeable().intData("infantry3-frames", config.group(QStringLiteral("infantry3")).readEntry("frames",0)); 0185 Sprites::SkinSpritesData::changeable().intData("infantry3-versions", config.group(QStringLiteral("infantry3")).readEntry("versions",0)); 0186 0187 // Sprites::SkinSpritesData::changeable().strData("cavalry-id", config.group(QStringLiteral("cavalry")).readEntry("id")); 0188 Sprites::SkinSpritesData::changeable().intData("cavalry-width", config.group(QStringLiteral("cavalry")).readEntry("width",0)); 0189 Sprites::SkinSpritesData::changeable().intData("cavalry-height", config.group(QStringLiteral("cavalry")).readEntry("height",0)); 0190 Sprites::SkinSpritesData::changeable().intData("cavalry-frames", config.group(QStringLiteral("cavalry")).readEntry("frames",0)); 0191 Sprites::SkinSpritesData::changeable().intData("cavalry-versions", config.group(QStringLiteral("cavalry")).readEntry("versions",0)); 0192 0193 // Sprites::SkinSpritesData::changeable().strData("cannon-id", config.group(QStringLiteral("cannon")).readEntry("id")); 0194 Sprites::SkinSpritesData::changeable().intData("cannon-width", config.group(QStringLiteral("cannon")).readEntry("width",0)); 0195 Sprites::SkinSpritesData::changeable().intData("cannon-height", config.group(QStringLiteral("cannon")).readEntry("height",0)); 0196 Sprites::SkinSpritesData::changeable().intData("cannon-frames", config.group(QStringLiteral("cannon")).readEntry("frames",0)); 0197 Sprites::SkinSpritesData::changeable().intData("cannon-versions", config.group(QStringLiteral("cannon")).readEntry("versions",0)); 0198 0199 // Sprites::SkinSpritesData::changeable().strData("firing-id", config.group(QStringLiteral("firing")).readEntry("id")); 0200 Sprites::SkinSpritesData::changeable().intData("firing-width", config.group(QStringLiteral("firing")).readEntry("width",0)); 0201 Sprites::SkinSpritesData::changeable().intData("firing-height", config.group(QStringLiteral("firing")).readEntry("height",0)); 0202 Sprites::SkinSpritesData::changeable().intData("firing-frames", config.group(QStringLiteral("firing")).readEntry("frames",0)); 0203 Sprites::SkinSpritesData::changeable().intData("firing-versions", config.group(QStringLiteral("firing")).readEntry("versions",0)); 0204 0205 // Sprites::SkinSpritesData::changeable().strData("exploding-id", config.group(QStringLiteral("exploding")).readEntry("id")); 0206 Sprites::SkinSpritesData::changeable().intData("exploding-width", config.group(QStringLiteral("exploding")).readEntry("width",0)); 0207 Sprites::SkinSpritesData::changeable().intData("exploding-height", config.group(QStringLiteral("exploding")).readEntry("height",0)); 0208 Sprites::SkinSpritesData::changeable().intData("exploding-frames", config.group(QStringLiteral("exploding")).readEntry("frames",0)); 0209 Sprites::SkinSpritesData::changeable().intData("exploding-versions", config.group(QStringLiteral("exploding")).readEntry("versions",0)); 0210 0211 KConfigGroup fontgroup = config.group(QStringLiteral("font")); 0212 m_font.family = fontgroup.readEntry("family","URW Chancery L"); 0213 m_font.size = fontgroup.readEntry("size",(int)(13*m_zoom)); 0214 QString w = fontgroup.readEntry("weight", "bold");; 0215 if (w == "normal") 0216 { 0217 m_font.weight = QFont::Normal; 0218 } 0219 else if (w == "light") 0220 { 0221 m_font.weight = QFont::Light; 0222 } 0223 else if (w == "demibold") 0224 { 0225 m_font.weight = QFont::DemiBold; 0226 } 0227 else if (w == "bold") 0228 { 0229 m_font.weight = QFont::Bold; 0230 } 0231 else if (w == "black") 0232 { 0233 m_font.weight = QFont::Black; 0234 } 0235 m_font.italic = fontgroup.readEntry("italic", true); 0236 m_font.foregroundColor = fontgroup.readEntry("foreground-color", "black"); 0237 m_font.backgroundColor = fontgroup.readEntry("background-color", "white"); 0238 0239 QStringList countriesList = onugroup.readEntry("countries", QStringList()); 0240 foreach (const QString &country, countriesList) 0241 { 0242 KConfigGroup countryGroup = config.group(country); 0243 // unsigned int id = countryGroup.readEntry("id",0); 0244 QString name = country; 0245 QPointF anchorPoint = countryGroup.readEntry("anchor-point",QPointF())*m_zoom; 0246 QPointF centralPoint = countryGroup.readEntry("central-point",QPointF())*m_zoom; 0247 QPointF flagPoint = countryGroup.readEntry("flag-point",QPointF())*m_zoom; 0248 QPointF cannonPoint = countryGroup.readEntry("cannon-point",QPointF())*m_zoom; 0249 QPointF cavalryPoint = countryGroup.readEntry("cavalry-point",QPointF())*m_zoom; 0250 QPointF infantryPoint = countryGroup.readEntry("infantry-point",QPointF())*m_zoom; 0251 0252 // qCDebug(KSIRK_LOG) << "Creating country " << name; 0253 // qCDebug(KSIRK_LOG) << "\tflag point: " << flagPoint; 0254 // qCDebug(KSIRK_LOG) << "\tcentral point: " << centralPoint; 0255 // qCDebug(KSIRK_LOG) << "\tcannon point: " << cannonPoint; 0256 // qCDebug(KSIRK_LOG) << "\tcavalry point: " << cavalryPoint; 0257 // qCDebug(KSIRK_LOG) << "\tinfantry point: " << infantryPoint; 0258 countries.push_back(new Country(automaton, name, anchorPoint, centralPoint, 0259 flagPoint, cannonPoint, cavalryPoint, infantryPoint)); 0260 } 0261 QStringList nationalitiesList = onugroup.readEntry("nationalities", QStringList()); 0262 foreach (const QString &nationality, nationalitiesList) 0263 { 0264 // qCDebug(KSIRK_LOG) << "Creating nationality " << nationality; 0265 KConfigGroup nationalityGroup = config.group(nationality); 0266 QString leader = nationalityGroup.readEntry("leader",""); 0267 QString flag = nationalityGroup.readEntry("flag",""); 0268 // qCDebug(KSIRK_LOG) << "Creating nationality " << name << " ; flag: " << flag; 0269 nationalities.push_back(new Nationality(nationality, flag, leader)); 0270 // nationalityId++; 0271 } 0272 0273 0274 QStringList continentsList = onugroup.readEntry("continents", QStringList()); 0275 foreach (const QString &continent, continentsList) 0276 { 0277 KConfigGroup continentGroup = config.group(continent); 0278 0279 // unsigned int id = continentGroup.readEntry("id",0); 0280 unsigned int bonus = continentGroup.readEntry("bonus",0); 0281 QList<QString> countryIdList = continentGroup.readEntry("continent-countries",QList<QString>()); 0282 // int countryId; 0283 QList<Country*> continentList; 0284 foreach(const QString& countryId, countryIdList) 0285 { 0286 // qCDebug(KSIRK_LOG) << "Adding" << countryId << "to" << continent << "list"; 0287 Country *c = countryNamed(countryId); 0288 if (c) 0289 { 0290 continentList.push_back(c); 0291 } 0292 } 0293 // qCDebug(KSIRK_LOG) << "Creating continent " << name; 0294 m_continents.push_back(new Continent(continent, continentList, bonus)); 0295 } 0296 0297 QStringList goalsList = onugroup.readEntry("goals", QStringList()); 0298 foreach (const QString &_goal, goalsList) 0299 { 0300 // qCDebug(KSIRK_LOG) << "init goal " << _goal; 0301 KConfigGroup goalGroup = config.group(_goal); 0302 0303 Goal* goal = new Goal(automaton); 0304 goal->description(goalGroup.readEntry("desc","")); 0305 QString goalType = goalGroup.readEntry("type",""); 0306 if (goalType == "countries") 0307 { 0308 goal->type(Goal::Countries); 0309 goal->nbCountries(goalGroup.readEntry("nbCountries",0)); 0310 goal->nbArmiesByCountry(goalGroup.readEntry("nbArmiesByCountry",0)); 0311 // qCDebug(KSIRK_LOG) << " nb countries: **********************************" << goal->nbCountries(); 0312 // qCDebug(KSIRK_LOG) << " nbarmies countries: **********************************" << goal->nbArmiesByCountry(); 0313 } 0314 else if (goalType == "continents" ) 0315 { 0316 goal->type(Goal::Continents); 0317 QList<QString> contList = goalGroup.readEntry("continents",QList<QString>()); 0318 foreach(const QString& continentId, contList) 0319 { 0320 // Bug 308527. Use only known continents. 0321 if (continentsList.contains(continentId)) 0322 goal->continents().push_back(continentId); 0323 else 0324 { 0325 qCDebug(KSIRK_LOG) << "Unknown continent " << continentId << " in skin " << m_skin ; 0326 } 0327 } 0328 } 0329 else if (goalType == "player" ) 0330 { 0331 goal->type(Goal::GoalPlayer); 0332 unsigned int nb = goalGroup.readEntry("nbCountriesFallback",0); 0333 goal->nbCountries(nb); 0334 } 0335 automaton->goals().push_back(goal); 0336 } 0337 0338 foreach (const QString &countryName, countriesList) 0339 { 0340 Country *country = countryNamed(countryName); 0341 0342 if (!country) 0343 { 0344 continue; 0345 } 0346 0347 // qCDebug(KSIRK_LOG) << "building neighbours list of " << countryName; 0348 QList< Country* > theNeighbours; 0349 KConfigGroup countryGroup = config.group(countryName); 0350 QList<QString> theNeighboursIds = countryGroup.readEntry("neighbours",QList<QString>()); 0351 // int neighbourId; 0352 foreach(const QString& neighbourId, theNeighboursIds) 0353 { 0354 Country *c = countryNamed(neighbourId); 0355 if (c) 0356 { 0357 theNeighbours.push_back(c); 0358 } 0359 } 0360 0361 country-> neighbours(theNeighbours); 0362 } 0363 buildMap(); 0364 0365 qCDebug(KSIRK_LOG) << "OUT"; 0366 } 0367 0368 ONU::~ONU() 0369 { 0370 delete m_timerFast; 0371 0372 QList<Country*>::iterator countriesIt, countriesIt_end; 0373 countriesIt = countries.begin(); countriesIt_end = countries.end(); 0374 for (; countriesIt != countriesIt_end; countriesIt++) 0375 { 0376 delete *countriesIt; 0377 } 0378 0379 QList<Nationality*>::iterator nationalitiesIt, nationalitiesIt_end; 0380 nationalitiesIt = nationalities.begin(); nationalitiesIt_end = nationalities.end(); 0381 for (; nationalitiesIt != nationalitiesIt_end; nationalitiesIt++) 0382 { 0383 delete *nationalitiesIt; 0384 } 0385 0386 QList<Continent*>::iterator continentsIt, continentsIt_end; 0387 continentsIt = m_continents.begin(); continentsIt_end = m_continents.end(); 0388 for (; continentsIt != continentsIt_end; continentsIt++) 0389 { 0390 delete *continentsIt; 0391 } 0392 0393 } 0394 0395 0396 /** This method returns a pointer to the country that contains the point (x,y). 0397 If there is no country at (x,y), the functions returns 0. */ 0398 Country* ONU::countryAt(const QPointF& point) 0399 { 0400 // qCDebug(KSIRK_LOG) << "ONU::countryAt x y " << x << " " << y; 0401 QPointF norm = point; 0402 norm /= m_zoom; 0403 if ( norm.x() < 0 || norm.x() >= countriesMask.width() 0404 || norm.y() < 0 || norm.y() >= countriesMask.height() ) 0405 return nullptr; 0406 0407 int index = qBlue(countriesMask.pixel(norm.toPoint())); 0408 // qCDebug(KSIRK_LOG) << "OUT ONU::countryAt: " << index; 0409 if (index >= countries.size()) return nullptr; 0410 return countries.at(index); 0411 } 0412 0413 void ONU::reset() 0414 { 0415 qCDebug(KSIRK_LOG); 0416 foreach (Country* country, countries) 0417 { 0418 country-> reset(); 0419 } 0420 } 0421 0422 0423 QList<Country*>& ONU::getCountries() 0424 { 0425 return countries; 0426 } 0427 0428 QList<Nationality*>& ONU::getNationalities() 0429 { 0430 return nationalities; 0431 } 0432 0433 /** Read property of QList<Continent*> continents. */ 0434 const QList<Continent*>& ONU::getContinents() const 0435 { 0436 return m_continents; 0437 } 0438 0439 QList<Continent*>& ONU::getContinents() 0440 { 0441 return m_continents; 0442 } 0443 0444 /** 0445 * Returns the list of countries neighbours of this country that does not 0446 * belongs to the argument player. 0447 */ 0448 QList<Country*> ONU::neighboursBelongingTo(const Country& country, const Player* player) 0449 { 0450 QList<Country*> list; 0451 foreach (Country *c, country.neighbours()) 0452 { 0453 if ((country.communicateWith(c)) && (c-> owner() == player)) 0454 {list.push_back(c);} 0455 } 0456 return list; 0457 } 0458 0459 /** 0460 * Returns the list of countries neighbours of this country that does not 0461 * belongs to the argument player. 0462 */ 0463 QList<Country*> ONU::neighboursNotBelongingTo(const Country& country, const Player* player) 0464 { 0465 QList<Country*> list; 0466 foreach (Country *c, country.neighbours()) 0467 { 0468 if ((country.communicateWith(c)) && (c-> owner() != player)) 0469 {list.push_back(c);} 0470 } 0471 return list; 0472 } 0473 0474 /** 0475 * Returns the country named "name" ; 0 in case there is no such country 0476 */ 0477 Country* ONU::countryNamed(const QString& name) 0478 { 0479 if (name.isEmpty()) 0480 { 0481 // qCDebug(KSIRK_LOG) << "request for country with empty name"; 0482 return nullptr; 0483 } 0484 0485 foreach (Country *c, countries) 0486 { 0487 if (c-> name() == name) 0488 return c; 0489 } 0490 0491 // qCDebug(KSIRK_LOG) << "request for country" << name << "which doesn't seem to exist."; 0492 return nullptr; 0493 } 0494 0495 /** @return the number of countries in the world */ 0496 unsigned int ONU::getNbCountries() const 0497 { 0498 return(countries.size()); 0499 } 0500 0501 void ONU::saveXml(QTextStream& xmlStream) 0502 { 0503 xmlStream << "<ONU file=\"" << m_configFileName << "\" >"; 0504 0505 xmlStream << "<countries>"; 0506 foreach (Country *c, countries) 0507 { 0508 c->saveXml(xmlStream); 0509 } 0510 xmlStream << "</countries>"; 0511 xmlStream << "</ONU>"; 0512 } 0513 0514 unsigned int ONU::width() const 0515 { 0516 return m_width; 0517 } 0518 0519 unsigned int ONU::height() const 0520 { 0521 return m_height; 0522 } 0523 0524 /** Returns the nation named "name" ; 0 in case there is no such nation */ 0525 Nationality* ONU::nationNamed(const QString& name) 0526 { 0527 foreach (Nationality *n, nationalities) 0528 { 0529 if (n->name() == name) 0530 { 0531 return n; 0532 } 0533 } 0534 return nullptr; 0535 } 0536 0537 void ONU::sendCountries(QDataStream& stream) 0538 { 0539 stream << quint32(countries.size()); 0540 foreach (Country* country, countries) 0541 { 0542 // qCDebug(KSIRK_LOG) << "Sending country " << country->name(); 0543 country->send(stream); 0544 } 0545 } 0546 0547 /*const Continent* ONU::continentWithId(const unsigned int id) const 0548 { 0549 for (unsigned int i = 0; i < m_continents.size(); i++) 0550 { 0551 if ( m_continents.at(i)->id() == id) 0552 { 0553 return m_continents.at(i); 0554 } 0555 } 0556 return 0; 0557 } 0558 */ 0559 Continent* ONU::continentNamed(const QString& name) 0560 { 0561 foreach (Continent *c, m_continents) 0562 { 0563 if (c-> name() == name) 0564 return c; 0565 } 0566 return nullptr; 0567 } 0568 0569 void ONU::buildMap() 0570 { 0571 qCDebug(KSIRK_LOG) << "with zoom="<< m_zoom; 0572 //QSize size((int)(m_automaton->rendererFor(m_skin).defaultSize().width()*m_zoom),(int)(m_automaton->rendererFor(m_skin).defaultSize().height()*m_zoom)); 0573 const qreal dpr = qApp->devicePixelRatio(); 0574 const int mapDeviceWidth = m_width * dpr; 0575 const int mapDeviceHeight = m_height * dpr; 0576 const QString mapCacheId = m_skin + QLatin1String("map") + QString::number(mapDeviceWidth) + QLatin1Char('x') + QString::number(mapDeviceHeight); 0577 if (!QPixmapCache::find(mapCacheId, &m_map)) 0578 { 0579 // Pixmap isn't in the cache, create it and insert to cache 0580 m_map = QPixmap(mapDeviceWidth, mapDeviceHeight); 0581 m_map.fill(Qt::transparent); 0582 QPainter painter(&m_map); 0583 m_automaton->rendererFor(m_skin).render(&painter, "map"); 0584 0585 QFont foregroundFont(m_font.family, m_font.size, m_font.weight, m_font.italic); 0586 QFont backgroundFont(m_font.family, m_font.size, QFont::Normal, m_font.italic); 0587 0588 painter.scale(dpr, dpr); 0589 foreach (Country* country, countries) 0590 { 0591 const QString& countryName = i18n(country->name().toUtf8().data()); 0592 if (m_font.backgroundColor != "none") 0593 { 0594 painter.setPen(m_font.backgroundColor); 0595 painter.setFont(backgroundFont); 0596 QRect countryNameRect = painter.fontMetrics().boundingRect(countryName); 0597 painter.drawText( 0598 int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) + 1 ), 0599 // HACK HACK see the same below 0600 int( (country->centralPoint().y()*m_zoom) + 4/*(countryNameRect.height()/2)*/ + 1 ), 0601 countryName); 0602 } 0603 painter.setPen(m_font.foregroundColor); 0604 painter.setFont(foregroundFont); 0605 QRect countryNameRect = painter.fontMetrics().boundingRect(countryName); 0606 // qCDebug(KSIRK_LOG) << countryName << "countryNameRect=" << countryNameRect; 0607 // qCDebug(KSIRK_LOG) << "draw at" << int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) ) << 0608 // int( (country->centralPoint().y()*m_zoom) - (countryNameRect.height()/2) ); 0609 0610 painter.drawText( 0611 int( (country->centralPoint().x()*m_zoom) - (countryNameRect.width()/2) ), 0612 // HACK HACK why is this 4 necessary below instead of the commented correction ??? 0613 int( (country->centralPoint().y()*m_zoom) + 4/*- (countryNameRect.height()/2)*/ ), 0614 countryName); 0615 } 0616 m_map.setDevicePixelRatio(dpr); 0617 0618 QPixmapCache::insert(mapCacheId, m_map); 0619 } 0620 } 0621 0622 void ONU::applyZoomFactor(qreal zoomFactor) 0623 { 0624 /** Zoom 1: First method (take a long time to zoom) : 0625 */ 0626 // qCDebug(KSIRK_LOG) << "zoomFactor=" << zoomFactor << "old zoom=" << m_zoom; 0627 // qCDebug(KSIRK_LOG) << "new zoom=" << m_zoom; 0628 0629 m_zoom *= zoomFactor; 0630 0631 //m_font.size = (int)(m_font.size*m_zoom); 0632 //m_width = (unsigned int)(m_width *m_zoom); 0633 //m_height = (unsigned int)(m_height *m_zoom); 0634 0635 buildMap(); 0636 0637 foreach (Country* country, countries) 0638 { 0639 country->createArmiesSprites(); 0640 } 0641 0642 } 0643 0644 void ONU::applyZoomFactorFast(qreal zoomFactor) //benj 0645 { 0646 0647 /** Zoom 2 : Second method , Very performent. Carefull ! Can cause the game to lag. 0648 To try this, comment all the first method and uncomment these lines 0649 */ 0650 qCDebug(KSIRK_LOG) << "zoomFactor FASTTTTTTT"; 0651 int nbLimitZooms = 6; 0652 0653 //Application of zoom 0654 if (zoomFactor > 1 && m_nbZooms < nbLimitZooms) 0655 { 0656 m_font.size = (int)(m_font.size*zoomFactor); 0657 m_width = (unsigned int)(m_width *zoomFactor); 0658 m_height = (unsigned int)(m_height *zoomFactor); 0659 0660 m_nbZooms++; // zoom forward 0661 m_automaton->game()->frame()->scale(zoomFactor, zoomFactor); 0662 m_zoomFactorFinal *= zoomFactor; 0663 0664 //starting timer 0665 /*if (m_timerFast->isActive()) 0666 { 0667 m_timerFast->stop(); 0668 } 0669 m_timerFast->start(4000); 0670 m_timerFast->setSingleShot(true);*/ 0671 0672 } 0673 else if (zoomFactor < 1 && m_nbZooms > -nbLimitZooms) 0674 { 0675 m_font.size = (int)(m_font.size*zoomFactor); 0676 m_width = (unsigned int)(m_width *zoomFactor); 0677 m_height = (unsigned int)(m_height *zoomFactor); 0678 0679 m_nbZooms--; // zoom backward 0680 m_automaton->game()->frame()->scale(zoomFactor, zoomFactor); 0681 m_zoomFactorFinal *= zoomFactor; 0682 0683 //starting timer 0684 /*if (m_timerFast->isActive()) 0685 { 0686 m_timerFast->stop(); 0687 } 0688 m_timerFast->start(4000); 0689 m_timerFast->setSingleShot(true);*/ 0690 } 0691 } 0692 0693 double ONU::zoom() const 0694 { 0695 if (m_automaton->game()->currentWidgetType() == KGameWindow::Map) { 0696 return m_zoom; 0697 } 0698 return m_zoomArena; 0699 } 0700 0701 0702 QSvgRenderer* ONU::renderer() 0703 { 0704 return &m_automaton->rendererFor(m_skin); 0705 } 0706 0707 0708 KGameSvgDocument* ONU::svgDom() 0709 { 0710 return &m_automaton->svgDomFor(m_skin); 0711 } 0712 0713 unsigned int ONU::indexOfCountry(Country* c) const 0714 { 0715 return countries.indexOf(c); 0716 } 0717 0718 0719 /** the SLOTS METHODS FOR THE ONU CLASS*/ 0720 void ONU::changingZoom() 0721 { 0722 /* 0723 m_automaton->game()->frame()->resetTransform(); 0724 qreal m_zo=m_zoomFactorFinal; 0725 m_zoomFactorFinal=1; 0726 applyZoomFactor(m_zo);*/ 0727 0728 // m_automaton->game()->frame()->scale(1/m_zoomFactorFinal, 1/m_zoomFactorFinal); 0729 0730 m_automaton->game()->frame()->resetTransform(); 0731 applyZoomFactor(m_zoomFactorFinal); 0732 m_zoomFactorFinal=1.0; 0733 } 0734 0735 /**END OF SLOTS METHODS FOR THE ONU*/ 0736 } // closing namespace GameLogic 0737 } // closing namespace Ksirk 0738 0739 #include "moc_onu.cpp"