File indexing completed on 2024-10-06 06:48:46
0001 /* This file is part of KsirK. 0002 Copyright (C) 2001-2007 Gael de Chalendar <kleag@free.fr> 0003 0004 KsirK is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public 0006 License as published by the Free Software Foundation, either version 2 0007 of the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0012 General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program; if not, write to the Free Software 0016 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 0017 02110-1301, USA 0018 */ 0019 0020 /* begin : Wed Jul 18 2001 */ 0021 0022 #include "country.h" 0023 #include "player.h" 0024 #include "Sprites/backgnd.h" 0025 #include "kgamewin.h" 0026 #include "ksirksettings.h" 0027 #include "Sprites/flagsprite.h" 0028 #include "Sprites/skinSpritesData.h" 0029 #include "GameLogic/onu.h" 0030 0031 #include <KLocalizedString> 0032 #include "ksirk_debug.h" 0033 #include <QSvgRenderer> 0034 #include <QApplication> 0035 #include <QDataStream> 0036 #include <QBitmap> 0037 #include <QGraphicsSvgItem> 0038 #include <QTextStream> 0039 0040 namespace Ksirk 0041 { 0042 0043 namespace GameLogic 0044 { 0045 0046 Country::Country(GameAutomaton* game, 0047 const QString& theName, 0048 const QPointF& anchorPoint, 0049 const QPointF& centralPoint, 0050 const QPointF& flagPoint, 0051 const QPointF& cannonPoint, 0052 const QPointF& cavalryPoint, 0053 const QPointF& infantryPoint) : 0054 m_automaton(game), 0055 m_belongsTo(nullptr), 0056 m_flag(nullptr), 0057 m_nbArmies(0), 0058 m_name(theName), 0059 m_anchorPoint(anchorPoint), 0060 m_centralPoint(centralPoint), 0061 m_pointFlag(flagPoint), 0062 m_pointCannon(cannonPoint), 0063 m_pointCavalry(cavalryPoint), 0064 m_pointInfantry(infantryPoint), 0065 m_highlighting(nullptr), 0066 m_renderer(new QSvgRenderer()), 0067 m_highlighting_locked(false), 0068 m_nbArmiesItem(nullptr) 0069 { 0070 // qCDebug(KSIRK_LOG) << m_name << ", " << this ; 0071 } 0072 0073 Country::~Country() 0074 { 0075 // qCDebug(KSIRK_LOG) << "Deleting country " << m_name << ", " << this ; 0076 if (m_flag) 0077 { 0078 m_flag->hide(); 0079 delete m_flag; 0080 m_flag = nullptr; 0081 } 0082 delete m_renderer; 0083 } 0084 0085 void Country::reset() 0086 { 0087 // qCDebug(KSIRK_LOG) << "Country::reset " << m_name ; 0088 clearAllSprites(); 0089 m_belongsTo = nullptr; 0090 nbArmies(1); 0091 createArmiesSprites(); 0092 0093 if (m_flag) 0094 { 0095 m_flag->hide(); 0096 delete m_flag; 0097 m_flag = nullptr; 0098 } 0099 } 0100 0101 void Country::createArmiesSprites() 0102 { 0103 // qCDebug(KSIRK_LOG) << name() << nbArmies(); 0104 BackGnd* bg = m_automaton->game()->backGnd(); 0105 0106 unsigned int armies = nbArmies(); 0107 clearAllSprites(); 0108 int i = 0; 0109 while (armies >= 10) // Ajout des sprites de canon 0110 { 0111 // qCDebug(KSIRK_LOG) << " cannon" << i << armies; 0112 CannonSprite *sprite = new CannonSprite(bg->onu()->zoom(), bg); 0113 sprite-> setDestination(nullptr); // Sprite immobile 0114 if (m_automaton->game()->currentWidgetType() == Ksirk::KGameWindow::Arena) 0115 { 0116 sprite-> setPos( 0117 m_pointCannon.x()*bg->onu()->zoom(), 0118 (m_pointCannon.y()+(1-2*(i%2))*(Sprites::SkinSpritesData::single().intData("cannon-height")+8)*((i+1)/2))*bg->onu()->zoom()); 0119 if (this->name() == m_automaton->game()->secondCountry()->name()) 0120 { 0121 sprite->setLookLeft(); 0122 } 0123 } 0124 else 0125 { 0126 sprite-> setPos((m_pointCannon.x()+5*i)*bg->onu()->zoom(),(m_pointCannon.y()+5*i)*bg->onu()->zoom()); 0127 } 0128 m_spritesCannons.append(sprite); 0129 i++; 0130 armies -= 10; 0131 } 0132 i = 0; 0133 while (armies >= 5) // Adding the cavalryman sprites 0134 { 0135 // qCDebug(KSIRK_LOG) << " cavalry" << i << armies; 0136 CavalrySprite *sprite = new CavalrySprite(bg->onu()->zoom(), bg); 0137 sprite-> setDestination(nullptr); // Sprite immobile 0138 if (m_automaton->game()->currentWidgetType() == Ksirk::KGameWindow::Arena) 0139 { 0140 // qCDebug(KSIRK_LOG) << "arena"; 0141 sprite-> setPos( 0142 m_pointCavalry.x()*bg->onu()->zoom(), 0143 (m_pointCavalry.y()+(1-2*(i%2))*(Sprites::SkinSpritesData::single().intData("cavalry-height")+8)*((i+1)/2))*bg->onu()->zoom()); 0144 // qCDebug(KSIRK_LOG) << "setPos done"; 0145 if (this->name() == m_automaton->game()->secondCountry()->name()) 0146 { 0147 sprite->setLookLeft(); 0148 } 0149 } 0150 else 0151 { 0152 sprite-> setPos((m_pointCavalry.x()+5*i)*bg->onu()->zoom(),(m_pointCavalry.y()+5*i)*bg->onu()->zoom()); 0153 } 0154 // qCDebug(KSIRK_LOG) << "appending"; 0155 m_spritesCavalry.append(sprite); 0156 i++; 0157 armies -= 5; 0158 } 0159 i = 0; 0160 while (armies > 0) // Ajout des sprites de fantassin 0161 { 0162 // qCDebug(KSIRK_LOG) << " infantry" << i << armies; 0163 InfantrySprite *sprite = new InfantrySprite(bg->onu()->zoom(), bg); 0164 sprite-> setDestination(nullptr); // Sprite immobile 0165 if (m_automaton->game()->currentWidgetType() == Ksirk::KGameWindow::Arena) 0166 { 0167 sprite-> setPos( 0168 m_pointInfantry.x()*bg->onu()->zoom(), 0169 (m_pointInfantry.y()+(1-2*(i%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((i+1)/2))*bg->onu()->zoom()); 0170 if (this->name() == m_automaton->game()->secondCountry()->name()) 0171 { 0172 sprite->setLookLeft(); 0173 } 0174 } 0175 else 0176 { 0177 sprite-> setPos((m_pointInfantry.x()+5*i)*bg->onu()->zoom(),(m_pointInfantry.y()+5*i)*bg->onu()->zoom()); 0178 } 0179 m_spritesInfantry.append(sprite); 0180 i++; 0181 armies--; 0182 } 0183 0184 // qCDebug(KSIRK_LOG) << "adding flag" << m_belongsTo ; 0185 if (m_belongsTo) 0186 { 0187 // qCDebug(KSIRK_LOG) << m_belongsTo->flagFileName(); 0188 flag(m_belongsTo->flagFileName(), bg); 0189 } 0190 0191 // qCDebug(KSIRK_LOG) << "adding nb armies text"; 0192 if (m_nbArmiesItem == nullptr) 0193 { 0194 m_nbArmiesItem = new QGraphicsSimpleTextItem(QString::number(m_nbArmies),bg); 0195 m_nbArmiesItem->setPos((m_pointFlag.x()+5),(m_pointFlag.y()+7)); 0196 m_nbArmiesItem->setZValue(20); 0197 m_nbArmiesItem->setBrush(Qt::white); 0198 m_nbArmiesItem->setPen(QPen(Qt::yellow)); 0199 } 0200 if (!KsirkSettings::showArmiesNumbers()) 0201 { 0202 m_nbArmiesItem->hide(); 0203 } 0204 else 0205 { 0206 m_nbArmiesItem->show(); 0207 } 0208 // qCDebug(KSIRK_LOG) << "Done"; 0209 } 0210 0211 void Country::flag(const QString& theFlagFileName, BackGnd *backGnd) 0212 { 0213 // qCDebug(KSIRK_LOG) << "Country("<<m_name<<", "<<this<<")::flag flagFileName " << theFlagFileName ; 0214 0215 if (m_flag) 0216 { 0217 m_flag->hide(); 0218 delete m_flag; 0219 m_flag = nullptr; 0220 } 0221 0222 m_flag = new FlagSprite(theFlagFileName, backGnd->onu()->zoom(), backGnd); 0223 m_flag-> setDestination(nullptr); 0224 m_flag-> setPos(m_pointFlag.x()*backGnd->onu()->zoom(),m_pointFlag.y()*backGnd->onu()->zoom()); 0225 m_flag-> setZValue(10); 0226 0227 // qDebug("OUT Country::flag"); 0228 } 0229 0230 bool Country::communicateWith(const Country* otherCountry) const 0231 { 0232 if (!otherCountry) 0233 { 0234 qCDebug(KSIRK_LOG) << "OUT otherCountry null Country::communicateWith"; 0235 return false; 0236 } 0237 0238 // a country is considered to communicate with itself 0239 if (otherCountry == this) {return true;} 0240 0241 // qCDebug(KSIRK_LOG) << "Country::communicateWith (" << name() << ", " << otherCountry-> name() << ")" << endl << flush; 0242 // unsigned int nbNeighbours = neighbours().size(); 0243 foreach (Country* neighbour, neighbours()) 0244 { 0245 if (neighbour == otherCountry) 0246 { 0247 // qCDebug(KSIRK_LOG) << "OUT true Country::communicateWith" << endl << flush; 0248 return true; 0249 } 0250 } 0251 // qCDebug(KSIRK_LOG) << "OUT false Country::communicateWith" << endl << flush; 0252 return false; 0253 } 0254 0255 /** @returns a pointer on the Player that holds this Country */ 0256 const Player * Country::owner() const 0257 { 0258 return m_belongsTo; 0259 } 0260 0261 Player * Country::owner() 0262 { 0263 return m_belongsTo; 0264 } 0265 0266 /** At the end of this method, the Country belogns to the argument player */ 0267 void Country::owner(Player *player) 0268 { 0269 m_belongsTo = player; 0270 if (player != nullptr) 0271 { 0272 createArmiesSprites(); 0273 flag(m_belongsTo->flagFileName(), m_automaton->game()-> backGnd()); 0274 } 0275 } 0276 0277 unsigned int Country::nbArmies() const 0278 { 0279 return m_nbArmies; 0280 } 0281 0282 void Country::nbArmies(unsigned int nb) 0283 { 0284 m_nbArmies = nb; 0285 if (m_nbArmiesItem!=nullptr) 0286 { 0287 m_nbArmiesItem->setText(QString::number(m_nbArmies)); 0288 } 0289 } 0290 0291 void Country::incrNbArmies(unsigned int nb) 0292 { 0293 nbArmies(nbArmies() + nb); 0294 } 0295 0296 void Country::decrNbArmies(unsigned int nb) 0297 { 0298 nbArmies(nbArmies() - nb); 0299 } 0300 0301 const QString Country::name() const 0302 { 0303 return (m_name); 0304 } 0305 0306 const QString Country::i18name() const 0307 { 0308 return (i18n(m_name.toUtf8().data())); 0309 } 0310 0311 const QPointF& Country::anchorPoint() const 0312 { 0313 return (m_anchorPoint); 0314 } 0315 0316 const QPointF& Country::centralPoint() const 0317 { 0318 return (m_centralPoint); 0319 } 0320 0321 const QPointF& Country::pointFlag() const 0322 { 0323 return (m_pointFlag); 0324 } 0325 0326 const QPointF& Country::pointCannon() const 0327 { 0328 return (m_pointCannon); 0329 } 0330 0331 const QPointF& Country::pointCavalry() const 0332 { 0333 return (m_pointCavalry); 0334 } 0335 0336 const QPointF& Country::pointInfantry() const 0337 { 0338 return (m_pointInfantry); 0339 } 0340 0341 void Country::anchorPoint(const QPointF pt) 0342 { 0343 m_anchorPoint = pt; 0344 } 0345 0346 void Country::centralPoint(const QPointF pt) 0347 { 0348 m_centralPoint = pt; 0349 } 0350 0351 void Country::pointFlag(const QPointF pt) 0352 { 0353 m_pointFlag = pt; 0354 } 0355 0356 void Country::pointCannon(const QPointF pt) 0357 { 0358 m_pointCannon = pt; 0359 } 0360 0361 void Country::pointCavalry(const QPointF pt) 0362 { 0363 m_pointCavalry = pt; 0364 } 0365 0366 void Country::pointInfantry(const QPointF pt) 0367 { 0368 m_pointInfantry = pt; 0369 } 0370 0371 AnimSpritesList< CannonSprite >& Country::spritesCannons() 0372 { 0373 return (m_spritesCannons); 0374 } 0375 0376 AnimSpritesList< CavalrySprite >& Country::spritesCavalry() 0377 { 0378 return (m_spritesCavalry); 0379 } 0380 0381 AnimSpritesList< InfantrySprite >& Country::spritesInfantry() 0382 { 0383 return (m_spritesInfantry); 0384 } 0385 0386 /** No descriptions */ 0387 void Country::neighbours(const QList<Country*>& neighboursVect) 0388 { 0389 m_neighbours = neighboursVect; 0390 } 0391 0392 /** No descriptions */ 0393 QList< Country* >& Country::neighbours() 0394 { 0395 // qCDebug(KSIRK_LOG) << "Country::neighbours" << endl << flush; 0396 return m_neighbours; 0397 } 0398 0399 /** No descriptions */ 0400 const QList< Country* >& Country::neighbours() const 0401 { 0402 // qCDebug(KSIRK_LOG) << "Country::neighbours const" << endl << flush; 0403 return m_neighbours; 0404 } 0405 0406 /*! 0407 \fn Ksirk::Country::clearAllSprites() 0408 */ 0409 void Country::clearAllSprites() 0410 { 0411 // qCDebug(KSIRK_LOG); 0412 m_spritesCannons.hideAndRemoveAll(); 0413 m_spritesCavalry.hideAndRemoveAll(); 0414 m_spritesInfantry.hideAndRemoveAll(); 0415 } 0416 0417 const QPointF& Country::pointFor(const AnimSprite* sprite) 0418 { 0419 if (dynamic_cast<const InfantrySprite*>(sprite)) 0420 { 0421 return pointInfantry(); 0422 } 0423 else if (dynamic_cast<const CavalrySprite*>(sprite)) 0424 { 0425 return pointCavalry(); 0426 } 0427 else if (dynamic_cast<const CannonSprite*>(sprite)) 0428 { 0429 return pointCannon(); 0430 } 0431 else if (dynamic_cast<const FlagSprite*>(sprite)) 0432 { 0433 return pointFlag(); 0434 } 0435 else 0436 { 0437 qCCritical(KSIRK_LOG) << "Unknown sprite type"; 0438 exit(1); 0439 } 0440 } 0441 0442 void Country::saveXml(QTextStream& xmlStream) 0443 { 0444 QString name = m_name; 0445 name = name.replace("&","&"); 0446 name = name.replace("<","<"); 0447 name = name.replace(">",">"); 0448 xmlStream << "<country name=\""<<name<<"\" owner=\""; 0449 if (m_belongsTo == nullptr) 0450 xmlStream << "none"; 0451 else 0452 { 0453 QString pname = m_belongsTo->name(); 0454 pname = pname.replace("&","&"); 0455 pname = pname.replace("<","<"); 0456 pname = pname.replace(">",">"); 0457 xmlStream << pname; 0458 } 0459 xmlStream << "\" "; 0460 0461 xmlStream << "nbArmies=\""<<nbArmies() << "\" "; 0462 0463 xmlStream << " />"; 0464 0465 } 0466 0467 void Country::send(QDataStream& stream) 0468 { 0469 // qCDebug(KSIRK_LOG) << (m_belongsTo?m_belongsTo->name():"") << quint32(m_nbArmies); 0470 stream << m_name << (m_belongsTo?m_belongsTo->name():"") << quint32(m_nbArmies); 0471 } 0472 0473 bool Country::hasAdjacentEnemy() 0474 { 0475 for (int j = 0; j < m_neighbours.size(); j++) 0476 { 0477 if ( m_neighbours[j]->owner() != m_belongsTo ) 0478 { 0479 return true; 0480 } 0481 } 0482 return false; 0483 } 0484 0485 void Country::highlight(const QColor& color, qreal opacity) 0486 { 0487 // qCDebug(KSIRK_LOG) << color; 0488 if (m_highlighting_locked) 0489 { 0490 return; 0491 } 0492 clearHighlighting(); 0493 0494 ONU* onu = m_automaton->game()->theWorld(); 0495 if (onu == nullptr) 0496 { 0497 qCWarning(KSIRK_LOG) << "onu is null"; 0498 return; 0499 } 0500 QDomNode countryElement = onu->svgDom()->elementById(m_name); 0501 if (countryElement.isNull()) 0502 { 0503 qCWarning(KSIRK_LOG) << "Got a null element"; 0504 return; 0505 } 0506 // qCDebug(KSIRK_LOG) <<"got country"; 0507 0508 onu->svgDom()->setCurrentNode(countryElement); 0509 onu->svgDom()->setStyleProperty("fill", color.name()); 0510 onu->svgDom()->setStyleProperty("fill-opacity", QString::number(opacity)); 0511 0512 // qCDebug(KSIRK_LOG) <<"loading"; 0513 QByteArray svg = onu->svgDom()->nodeToByteArray(); 0514 m_renderer->load(svg); 0515 0516 // qCDebug(KSIRK_LOG) <<"loaded"; 0517 m_highlighting = new QGraphicsSvgItem(m_automaton->game()->backGndWorld()); 0518 m_highlighting->setSharedRenderer(m_renderer); 0519 m_highlighting->setElementId(m_name); 0520 m_highlighting->setPos( 0521 (m_anchorPoint.x()-m_highlighting->boundingRect().width()/2)*onu->zoom(), 0522 (m_anchorPoint.y()-m_highlighting->boundingRect().height()/2)*onu->zoom()); 0523 0524 m_highlighting->setScale(onu->zoom()); 0525 // qCDebug(KSIRK_LOG) << "done"; 0526 } 0527 0528 void Country::highlightAsAttacker() 0529 { 0530 // qCDebug(KSIRK_LOG); 0531 highlight(Qt::red, 0.6); 0532 m_highlighting_locked = true; 0533 } 0534 0535 void Country::highlightAsDefender() 0536 { 0537 // qCDebug(KSIRK_LOG); 0538 highlight(Qt::yellow,0.6); 0539 m_highlighting_locked = true; 0540 } 0541 0542 void Country::clearHighlighting() 0543 { 0544 // qCDebug(KSIRK_LOG) << m_highlighting_locked << (void*)m_highlighting; 0545 if (!m_highlighting_locked && m_highlighting!=nullptr) 0546 { 0547 m_highlighting->hide(); 0548 delete m_highlighting; 0549 m_highlighting = nullptr; 0550 } 0551 // qCDebug(KSIRK_LOG) << "done"; 0552 } 0553 0554 bool Country::isHighlightingLocked() 0555 { 0556 // qCDebug(KSIRK_LOG); 0557 return m_highlighting_locked; 0558 } 0559 0560 void Country::releaseHighlightingLock() 0561 { 0562 // qCDebug(KSIRK_LOG); 0563 m_highlighting_locked=false; 0564 } 0565 0566 0567 QDataStream& operator>>(QDataStream& stream, Country* country) 0568 { 0569 country->reset(); 0570 quint32 nbArmies/*, nbAddedArmies*/; 0571 QString ownerName; 0572 stream >> ownerName >> nbArmies/* >> nbAddedArmies*/; 0573 // qCDebug(KSIRK_LOG) << ownerName << nbArmies/* << nbAddedArmies*/; 0574 country->owner(country->automaton()->playerNamed(ownerName)); 0575 country->nbArmies(nbArmies); 0576 // country->nbAddedArmies(nbAddedArmies); 0577 country->createArmiesSprites(); 0578 return stream; 0579 } 0580 0581 0582 void Country::copyForArena(Country* trueCountry) 0583 { 0584 // qCDebug(KSIRK_LOG) << trueCountry->name(); 0585 // remove existing elements 0586 clearAllSprites(); 0587 if (m_flag) 0588 { 0589 m_flag->hide(); 0590 delete m_flag; 0591 m_flag = nullptr; 0592 } 0593 0594 // change parameters 0595 m_name = trueCountry->m_name; 0596 m_continent = trueCountry->m_continent; 0597 m_belongsTo = trueCountry->m_belongsTo; 0598 m_nbArmies = trueCountry->m_nbArmies; 0599 // m_id = trueCountry->m_id; 0600 0601 // make again the display 0602 createArmiesSprites(); 0603 } 0604 0605 } // closing namespace GameLogic 0606 0607 } // closing namespace Ksirk