File indexing completed on 2024-04-21 04:04:47

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                : Sat Sep 1 2001  */
0021 
0022 /**
0023  * KGameWindow methods for sprites handling function of the state
0024  */
0025 
0026 // application specific includes
0027 #include "kgamewin.h"
0028 #include "Sprites/backgnd.h"
0029 #include "ksirksettings.h"
0030 #include "Sprites/animspritesgroup.h"
0031 #include "Sprites/cannonsprite.h"
0032 #include "Sprites/cavalrysprite.h"
0033 #include "Sprites/infantrysprite.h"
0034 #include "Sprites/arrowsprite.h"
0035 #include "Sprites/skinSpritesData.h"
0036 #include "GameLogic/KMessageParts.h"
0037 #include "GameLogic/onu.h"
0038 #include "fightArena.h"
0039 
0040 // include files for QT
0041 #include <QMetaObject>
0042 #include <QDir>
0043 #include <QInputDialog>
0044 #include <QMediaPlayer>
0045 
0046 // include files for KDE
0047 #include <KMessageBox>
0048 #include <KLazyLocalizedString>
0049 #include <KLocalizedString>
0050 #include <KConfig>
0051 #include <KStandardAction>
0052 #include "ksirk_debug.h"
0053 #include <KToolBar>
0054 
0055 #include <assert.h>
0056 
0057 namespace Ksirk
0058 {
0059 using namespace GameLogic;
0060 
0061 /**
0062  * Prepares the sprites to be moved : removes the nb necessary sprites from
0063  * source, creates the moving sprites and gives them their destination, etc
0064  */
0065 bool KGameWindow::initArmiesMovement(unsigned int nbABouger, Country *firstCountry, Country *secondCountry)
0066 {
0067   qCDebug(KSIRK_LOG) << "-> " << nbABouger ;
0068   KMessageParts messageParts;
0069 
0070   if (firstCountry-> nbArmies() <= nbABouger)
0071   {
0072     messageParts << kli18n("Cannot move %1 armies from %2 to %3").untranslatedText() << QString::number(nbABouger)
0073       << firstCountry->name() << secondCountry->name();
0074     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
0075     return false;
0076   }
0077   else
0078   {
0079     messageParts << kli18n("Moving %1 armies from %2 to %3").untranslatedText() << QString::number(nbABouger) << firstCountry->name() << secondCountry->name();
0080     broadcastChangeItem(messageParts, ID_STATUS_MSG2);
0081   }
0082 
0083   AnimSpritesGroup* newGroup = new AnimSpritesGroup(this,SLOT(slotMovingArmiesArrived(AnimSpritesGroup*)));
0084   m_animSpritesGroups.push_back(newGroup);
0085   AnimSprite* sprite;
0086   if ((firstCountry-> nbArmies() > 10) && (nbABouger == 10)
0087           && (nbABouger < firstCountry-> nbArmies()))
0088   {
0089     sprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
0090     firstCountry-> decrNbArmies(10);
0091   }
0092   else if ((firstCountry-> nbArmies() > 5) && (nbABouger == 5)
0093           && (nbABouger < firstCountry-> nbArmies()))
0094   {
0095     sprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
0096     firstCountry-> decrNbArmies(5);
0097   }
0098   else if ((firstCountry-> nbArmies() > 1) && (nbABouger == 1)
0099           && (nbABouger < firstCountry-> nbArmies()))
0100   {
0101     sprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
0102     firstCountry->  decrNbArmies();
0103   }
0104   else 
0105   {
0106     messageParts << kli18n("Cannot move %1 armies from %2 to %3") .untranslatedText()
0107       << QString::number(nbABouger) 
0108       << firstCountry->name() 
0109       << secondCountry->name();
0110     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
0111     return false;
0112   }
0113   connect(sprite,&AnimSprite::atDestination,this,&KGameWindow::slotMovingArmyArrived);
0114   sprite->setupTravel(firstCountry, secondCountry);
0115   newGroup->addSprite(sprite);
0116   firstCountry-> createArmiesSprites();
0117   sprite->setAnimated();
0118 //   qCDebug(KSIRK_LOG) << "initArmiesMovement returns true";
0119   return true;
0120 }
0121 
0122 
0123 AnimSprite* KGameWindow::initArmiesMultipleCombat(unsigned int nbA,
0124     Country *firstCountry,
0125     Country *secondCountry, QPointF dest)
0126 {
0127   qCDebug(KSIRK_LOG) << "-> " << nbA ;
0128   KMessageParts messageParts;
0129 
0130   //AnimSpritesGroup* newGroup = new AnimSpritesGroup(this,SLOT(slotMovingArmiesArrived(AnimSpritesGroup*)));
0131   //m_animSpritesGroups.push_back(newGroup);
0132   AnimSprite* sprite = nullptr;
0133   if ((!firstCountry->spritesCannons().isEmpty()) && (nbA == 10))
0134   {
0135       qCDebug(KSIRK_LOG) << "cannon";
0136       sprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
0137 
0138     firstCountry->spritesCannons().hideAndRemoveFirst();
0139   }
0140   else if ((!firstCountry->spritesCavalry().isEmpty()) && (nbA == 5))
0141   {
0142       qCDebug(KSIRK_LOG) << "cavalry";
0143       sprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
0144 
0145       firstCountry->spritesCavalry().hideAndRemoveFirst();
0146   }
0147   else if ((!firstCountry->spritesInfantry().isEmpty()) && (nbA == 1))
0148   {
0149     qCDebug(KSIRK_LOG) << "infantry";
0150     sprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
0151 
0152     firstCountry->spritesInfantry().hideAndRemoveFirst();
0153   }
0154   // cannot comment out this comment below otherwise will use sprite uninitialized
0155   else
0156   {
0157     messageParts << kli18n("Cannot move %1 armies from %2 to %3") .untranslatedText()
0158       << QString::number(nbA) 
0159       << firstCountry->name() 
0160       << secondCountry->name();
0161     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
0162     return nullptr;
0163   }
0164   //connect(sprite,SIGNAL(atDestination(AnimSprite*)),this,SLOT(slotMovingArmyArrived(AnimSprite*)));
0165   
0166   if (backGnd()->bgIsArena())
0167   {
0168     int relativePosInArena=0;
0169 
0170     if (firstCountry->name() == secondCountry->name())
0171     {
0172       sprite->setDefendant();
0173       relativePosInArena = relativePosInArenaDefense;
0174       //relativePosInArenaDefense++;
0175     }
0176     else
0177     {
0178       sprite->setAttacker();
0179       relativePosInArena = relativePosInArenaAttack;
0180       //relativePosInArenaAttack++;
0181     }
0182 
0183     qCDebug(KSIRK_LOG) << "****Test relativePos**** " << relativePosInArena;
0184     QPointF dep = determinePointDepartArena(firstCountry,relativePosInArena);
0185 
0186     sprite-> setPos(dep);
0187 
0188     qCDebug(KSIRK_LOG) << "****dep  point**** " << dep;
0189     qCDebug(KSIRK_LOG) << "****dest point**** " << dest;
0190     sprite->setupTravel(firstCountry, secondCountry,dep,dest);
0191   }
0192   else
0193   {
0194     qCDebug(KSIRK_LOG) << "***************Setup travel normal ************** ";
0195     sprite->setupTravel(firstCountry, secondCountry,&dest);
0196   }
0197 
0198   qCDebug(KSIRK_LOG) << "-> "<< firstCountry->name() << secondCountry->name();
0199   //sprite->setupTravel(firstCountry, secondCountry,&dest);
0200   //newGroup->addSprite(sprite);
0201 //   qCDebug(KSIRK_LOG) << "add a sprite 1";
0202 //   m_animFighters->addSprite(sprite);
0203   //firstCountry-> createArmiesSprites();
0204   //sprite->setAnimated();
0205 //   qCDebug(KSIRK_LOG) << "initArmiesMovement returns true";
0206   return sprite;
0207 }
0208 
0209 
0210 QPointF KGameWindow::determinePointDepartArena(Country *pays, int relativePos)
0211 {
0212   return( QPointF(pays-> pointInfantry().x()*m_theWorld->zoom(),(pays-> pointInfantry().y()+(1-2*(relativePos%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((relativePos+1)/2))*m_theWorld->zoom()));
0213 }
0214 
0215 
0216 void KGameWindow::determinePointArrivee(
0217         QPointF& pointArriveeAttaquant,
0218         QPointF& pointArriveeDefenseur)
0219 {
0220   Country *attackingCountry = firstCountry();
0221   Country *defendingCountry = secondCountry();
0222   if (attackingCountry == nullptr || m_secondCountry == nullptr)
0223   {
0224     qCCritical(KSIRK_LOG) << "attackingCountry=" << (void*)attackingCountry << "defendingCountry=" << (void*)defendingCountry;
0225     return;
0226   }
0227   
0228   //  - attacker's flag point
0229   qreal pointFlagAttaquantX = attackingCountry-> pointFlag().x()*m_theWorld->zoom();
0230 
0231   //  - defender's flag point
0232   qreal pointFlagDefenseurX;
0233   pointFlagDefenseurX = defendingCountry-> pointFlag().x()*m_theWorld->zoom();
0234   
0235   //  - attacker's arrival point (resp. defender's) (left or right of the
0236   //    defender's flag point depending on the attacker's flag point position)
0237   qreal pointArriveeAttaquantX;
0238   qreal pointArriveeY;
0239   qreal pointArriveeDefenseurX;
0240   qreal leftRelativePos;
0241 
0242   // vertical meet point
0243   int diff = Sprites::SkinSpritesData::single().intData("flag-height") - Sprites::SkinSpritesData::single().intData("cannon-height");
0244   pointArriveeY = (((defendingCountry-> pointFlag().y() + diff))* m_theWorld->zoom()) ;
0245   
0246   qCDebug(KSIRK_LOG) << "2 " << defendingCountry-> pointFlag().y() << pointArriveeY;
0247   if (!attackingCountry->communicateWith(defendingCountry))
0248   {
0249     qCCritical(KSIRK_LOG) << "Error in KGameWindow::determinePointDepartArena: " << attackingCountry-> name() << "  and "
0250             << defendingCountry-> name() << " do not communicate!";
0251     exit(2);
0252   }
0253   
0254   // If the flag of the attacker is to the left of the flag of the defender,
0255   // then the arriving point of the attacker is to the left, else it is to
0256   // the right
0257   // The situation is reversed if the one of the attacker will need to go
0258   // through the world limit
0259   if (!attackingCountry->spritesInfantry().isEmpty())
0260   {
0261     leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("infantry-width"))*m_theWorld->zoom();
0262   }
0263   else
0264   {
0265     if (!attackingCountry->spritesCavalry().isEmpty())
0266     {
0267       leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cavalry-width"))*m_theWorld->zoom();
0268     }
0269     else
0270     {
0271       leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cannon-width"))*m_theWorld->zoom();
0272     }
0273   }
0274   
0275   qreal rightRelativePos = (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("flag-width"))*m_theWorld->zoom();
0276 
0277   if (!(qAbs(pointFlagAttaquantX-pointFlagDefenseurX) > (backGnd()-> boundingRect().width() / 2)))
0278   {
0279     if ( pointFlagAttaquantX <= pointFlagDefenseurX )
0280     {
0281         pointArriveeAttaquantX = pointFlagDefenseurX + leftRelativePos;
0282         pointArriveeDefenseurX = pointFlagDefenseurX + rightRelativePos;
0283     }
0284     else
0285     {
0286         pointArriveeAttaquantX = pointFlagDefenseurX + rightRelativePos;
0287         pointArriveeDefenseurX = pointFlagDefenseurX + leftRelativePos;
0288     }
0289   }
0290   else
0291   {
0292     if ( pointFlagAttaquantX <= pointFlagDefenseurX )
0293     {
0294         pointArriveeAttaquantX = pointFlagDefenseurX + rightRelativePos;
0295         pointArriveeDefenseurX = pointFlagDefenseurX + leftRelativePos;
0296     }
0297     else
0298     {
0299         pointArriveeAttaquantX = pointFlagDefenseurX +leftRelativePos;
0300         pointArriveeDefenseurX = pointFlagDefenseurX + rightRelativePos;
0301     }
0302   }
0303 
0304   pointArriveeAttaquant.setX(pointArriveeAttaquantX);
0305   pointArriveeAttaquant.setY(pointArriveeY);
0306   pointArriveeDefenseur.setX(pointArriveeDefenseurX);
0307   pointArriveeDefenseur.setY(pointArriveeY);
0308   qCDebug(KSIRK_LOG) << "3: " << pointArriveeAttaquant << " ; " << pointArriveeDefenseur;
0309 }
0310 
0311 
0312 // point arriveedefenseur inutile
0313 void KGameWindow::determinePointArriveeForArena(
0314     int relative,
0315     QPointF& pointArriveeAttaquant,
0316     QPointF& pointArriveeDefenseur)
0317 {
0318   Country *attackingCountry = firstCountry();
0319   Country *defendingCountry = secondCountry();
0320   
0321   qCDebug(KSIRK_LOG) << m_firstCountry->name() << "("<<(void*)m_firstCountry<<")"
0322       << m_secondCountry->name() << "("<<(void*)m_secondCountry<<")";
0323   qCDebug(KSIRK_LOG) << attackingCountry->name() << "("<<(void*)attackingCountry<<")"
0324       << defendingCountry->name() << "("<<(void*)defendingCountry<<")"
0325       << relative << pointArriveeAttaquant << pointArriveeDefenseur;
0326   //  - attacker's flag point
0327   qreal pointFlagAttaquantX = attackingCountry-> pointFlag().x()*m_theWorld->zoom();
0328 
0329   // in case of arena, the meet will be between the two countries
0330   qreal pointFlagDefenseurX = backGnd()-> boundingRect().width() / 2;
0331   
0332   //  - attacker's arrival point (resp. defender's) (left or right of the
0333   //    defender's flag point depending on the attacker's flag point position)
0334   qreal pointArriveeAttaquantX;
0335   qreal pointArriveeY;
0336   qreal pointArriveeDefenseurX;
0337   qreal pointDepartAttaquantY;
0338   qreal pointDepartDefenseurY;
0339   qreal leftRelativePos;
0340 
0341   qCDebug(KSIRK_LOG) << "1" << attackingCountry->spritesInfantry().isEmpty()
0342   << attackingCountry->name()
0343   << attackingCountry->nbArmies()
0344   << attackingCountry->owner()->name()
0345   << ((attackingCountry->name()==m_firstCountry->name())?attackingCountry->owner()->getNbAttack():attackingCountry->owner()->getNbDefense());
0346   
0347   if ( attackingCountry->nbArmies()%5 != 0
0348     && ((attackingCountry->nbArmies() % 5) >= ((attackingCountry->name()==m_firstCountry->name())?attackingCountry->owner()->getNbAttack():attackingCountry->owner()->getNbDefense())))
0349 //   if (!attackingCountry->spritesInfantry().isEmpty()
0350 //       && ((attackingCountry->nbArmies() % 5) >= ((attackingCountry==m_firstCountry)?attackingCountry->owner()->getNbAttack():attackingCountry->owner()->getNbDefense())))
0351       {
0352     qCDebug(KSIRK_LOG) << "infantry" << attackingCountry->name() << relative;
0353     // We must know
0354     //  - attacker's departure point (pointInfantry)
0355     QPointF dep = determinePointDepartArena(attackingCountry, relative);
0356     qCDebug(KSIRK_LOG) << "dep=" << dep;
0357     pointDepartAttaquantY = dep.y();
0358   }
0359   else if (!attackingCountry->spritesCavalry().isEmpty())
0360   {
0361     qCDebug(KSIRK_LOG) << "cavalry" << attackingCountry->pointCavalry();
0362     // We must know
0363     //  - attacker's departure point (pointCavalry)
0364     pointDepartAttaquantY = attackingCountry-> pointCavalry().y()*m_theWorld->zoom();
0365   }
0366   else
0367   {
0368     qCDebug(KSIRK_LOG) << "cannon" << attackingCountry->pointCannon();
0369     // We must know
0370     //  - attacker's departure point (pointCannon)
0371       pointDepartAttaquantY = attackingCountry-> pointCannon().y()*m_theWorld->zoom();
0372   }
0373 
0374   // problem here: when handling defender, attacker sprites are already moving so
0375   // if it has no more infantry sprites, it will not be able to enter this loop
0376   // solution: use the number of armies (equivalent to the number of stationary
0377   // sprites) and not the number of infantry sprites
0378   // defendingCountry->spritesInfantry().isEmpty() === (defendingCountry->nbArmies()%5==0)
0379   unsigned int num = 0;
0380   if (defendingCountry->name()==m_firstCountry->name())
0381   {
0382     num = defendingCountry->owner()->getNbAttack();
0383   }
0384   else
0385   {
0386     num = defendingCountry->owner()->getNbDefense();
0387   }
0388   qCDebug(KSIRK_LOG) << "2"
0389     << defendingCountry->spritesInfantry().isEmpty()
0390     << defendingCountry->name()
0391     << defendingCountry->nbArmies()
0392     << defendingCountry->owner()->name()
0393     << num;
0394   if ( defendingCountry->nbArmies()%5 != 0
0395       && ((defendingCountry->nbArmies() % 5) >= num)
0396       )
0397 //   if (!defendingCountry->spritesInfantry().isEmpty()
0398 //       && ((defendingCountry->nbArmies() % 5) >= defendingCountry->owner()->getNbDefense()))
0399   {
0400     qCDebug(KSIRK_LOG) << "infantry" << defendingCountry->name() << relative;
0401     //  - defender's departure point (pointInfantry)
0402     QPointF dep = determinePointDepartArena(defendingCountry, relative);
0403     pointDepartDefenseurY = dep.y();
0404     qCDebug(KSIRK_LOG) << "dep=" << dep;
0405   }
0406   else if (!defendingCountry->spritesCavalry().isEmpty())
0407   {
0408     qCDebug(KSIRK_LOG) << "cavalry" << defendingCountry->pointCavalry();
0409     //  - defender's departure point (pointCavalry)
0410     pointDepartDefenseurY = defendingCountry-> pointCavalry().y()*m_theWorld->zoom();
0411   }
0412   else
0413   {
0414     qCDebug(KSIRK_LOG) << "cannon" << defendingCountry->pointCannon();
0415     //  - defender's departure point (pointCannon)
0416     pointDepartDefenseurY = defendingCountry-> pointCannon().y()*m_theWorld->zoom();
0417   }
0418 
0419 
0420   // vertical meet point
0421   // in case of arena, the vertical meet will be as soon as it's possible
0422   qCDebug(KSIRK_LOG) << "Argh " << pointDepartAttaquantY << pointDepartDefenseurY;
0423   pointArriveeY = (pointDepartAttaquantY+pointDepartDefenseurY)/2;
0424   
0425   if (!attackingCountry->communicateWith(defendingCountry))
0426   {
0427     qCCritical(KSIRK_LOG) << "Error in KGameWindow::determinePointArriveeForArena: " << attackingCountry-> name() << "  and "
0428             << defendingCountry-> name() << " do not communicate!";
0429     exit(2);
0430   }
0431   // If the flag of the attacker is to the left of the flag of the defender,
0432   // then the arriving point of the attacker is to the left, else it is to
0433   // the right
0434   // The situation is reversed if the one of the attacker will need to go
0435   // through the world limit
0436 
0437   qreal factor = 0;
0438   if (!attackingCountry->spritesInfantry().isEmpty()
0439     && ((attackingCountry->nbArmies() % 5) >= attackingCountry->owner()->getNbAttack()))
0440   {
0441     factor = Sprites::SkinSpritesData::single().intData("infantry-width");
0442   }
0443   else if (!attackingCountry->spritesCavalry().isEmpty())
0444   {
0445     factor = Sprites::SkinSpritesData::single().intData("cavalry-width");
0446   }
0447   else
0448   {
0449     factor = Sprites::SkinSpritesData::single().intData("cannon-width");
0450   }
0451   leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + factor)*m_theWorld->zoom();
0452 
0453   
0454   qreal rightRelativePos = (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("flag-width"))*m_theWorld->zoom();
0455 
0456   //if (!(qAbs(pointFlagAttaquantX-pointFlagDefenseurX) > (backGnd()-> boundingRect().width() / 2)) || backGnd()->bgIsArena())
0457   //{
0458   if ( pointFlagAttaquantX <= pointFlagDefenseurX )
0459   {
0460       pointArriveeAttaquantX = pointFlagDefenseurX + leftRelativePos;
0461       pointArriveeDefenseurX = pointFlagDefenseurX + rightRelativePos;
0462   }
0463   else
0464   {
0465       pointArriveeAttaquantX = pointFlagDefenseurX + rightRelativePos;
0466       pointArriveeDefenseurX = pointFlagDefenseurX + leftRelativePos;
0467   }
0468 
0469   pointArriveeAttaquant.setX(pointArriveeAttaquantX);
0470   pointArriveeAttaquant.setY(pointArriveeY);
0471   pointArriveeDefenseur.setX(pointArriveeDefenseurX);
0472   pointArriveeDefenseur.setY(pointArriveeY);
0473   qCDebug(KSIRK_LOG) << "Done: " << pointArriveeAttaquant << " ; " << pointArriveeDefenseur;
0474 }
0475 
0476 
0477 void KGameWindow::initCombatMovement()
0478 {
0479   qCDebug(KSIRK_LOG) << "1";
0480 
0481   Country *attackingCountry = firstCountry();
0482   Country *defendingCountry = secondCountry();
0483   if (attackingCountry == nullptr || defendingCountry == nullptr)
0484   {
0485     qCCritical(KSIRK_LOG) << "attackingCountry=" << (void*)attackingCountry << "defendingCountry=" << (void*)defendingCountry;
0486     return;
0487   }
0488   
0489   getRightDialog()->close();
0490   if (firstCountry() != nullptr && firstCountry()->owner() != nullptr 
0491     && secondCountry() != nullptr && secondCountry()->owner() != nullptr)
0492   {
0493     getRightDialog()->displayFightDetails(firstCountry(), secondCountry(),
0494         firstCountry()->owner()->getNbAttack(), secondCountry()->owner()->getNbDefense());
0495   }
0496   centerOnFight();  //center the game on the fight
0497   if  (isArena()
0498       && ! m_automaton->currentPlayer()->isAI()
0499       && !m_automaton->currentPlayer()->isVirtual())
0500   {
0501     qCDebug(KSIRK_LOG) << "Attack with arena";
0502     // init and display the arena view
0503     showArena();
0504   }
0505 
0506   m_animFighters->clear();
0507   m_animFighters->changeTarget(this,SLOT(slotMovingFightersArrived(AnimSpritesGroup*)));
0508 
0509   QString sndRoulePath;
0510   AnimSprite* defenderSprite = nullptr;
0511   AnimSprite* attackingSprite = nullptr;
0512 
0513   QPointF pointArriveeAttaquant(0,0);
0514   QPointF pointArriveeDefenseur(0,0);
0515  
0516   if (backGnd()->bgIsArena())
0517   {
0518     determinePointArriveeForArena(0,
0519         pointArriveeAttaquant, pointArriveeDefenseur);
0520   }
0521   else
0522   {
0523     determinePointArrivee(pointArriveeAttaquant, pointArriveeDefenseur);
0524   }
0525 
0526   if (!attackingCountry->spritesInfantry().isEmpty()
0527       && ((attackingCountry->nbArmies() % 5) >= attackingCountry->owner()->getNbAttack())
0528       && backGnd()->bgIsArena())
0529   {
0530     qCDebug(KSIRK_LOG) << "**NB-ATTACK**" << attackingCountry->owner()->getNbAttack();
0531 
0532     for (unsigned int i=0; i < attackingCountry->owner()->getNbAttack() ; i++)
0533     {
0534       attackingSprite = simultaneousAttack(1,KGameWindow::Attack);
0535       if (attackingSprite != nullptr)
0536       {
0537         qCDebug(KSIRK_LOG) << "add a sprite";
0538         m_animFighters->addSprite(attackingSprite);
0539       }
0540     }
0541     nbSpriteAttacking=attackingCountry->owner()->getNbAttack();
0542   }
0543   else
0544   {
0545     qCDebug(KSIRK_LOG) << "creating attackingSprite"
0546               << attackingCountry->name()
0547               << attackingCountry->nbArmies()
0548               << attackingCountry->spritesInfantry().size()
0549               << attackingCountry->spritesCavalry().size()
0550               << attackingCountry->spritesCannons().size();
0551     nbSpriteAttacking=1;
0552     if ( (attackingCountry->nbArmies() != 0)
0553       && attackingCountry->spritesInfantry().isEmpty()
0554       && attackingCountry->spritesCavalry().isEmpty()
0555       && attackingCountry->spritesCannons().isEmpty())
0556     {
0557       attackingCountry->createArmiesSprites();
0558     }
0559     if (!attackingCountry->spritesCavalry().isEmpty())
0560     {
0561       qCDebug(KSIRK_LOG) << "cavalry" << backGnd()->bgIsArena();
0562       if (backGnd()->bgIsArena())
0563       {
0564         attackingSprite = simultaneousAttack(5,KGameWindow::Attack);
0565       }
0566       else
0567       {
0568         attackingSprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
0569 
0570         attackingCountry->spritesCavalry().hideAndRemoveFirst();
0571       }
0572     }
0573     else if (!attackingCountry->spritesCannons().isEmpty())
0574     {
0575       qCDebug(KSIRK_LOG) << "cannon" << backGnd()->bgIsArena();
0576       if (backGnd()->bgIsArena())
0577       {
0578         attackingSprite = simultaneousAttack(10,KGameWindow::Attack);
0579       }
0580       else
0581       {
0582         attackingSprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
0583 
0584         attackingCountry->spritesCannons().hideAndRemoveFirst();
0585       }
0586     }
0587     else if (!attackingCountry->spritesInfantry().isEmpty())
0588     {
0589       qCDebug(KSIRK_LOG) << "infantry" << backGnd()->bgIsArena();
0590       if (backGnd()->bgIsArena())
0591       {
0592         attackingSprite = simultaneousAttack(1,KGameWindow::Attack);
0593       }
0594       else
0595       {
0596         attackingSprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
0597 
0598         attackingCountry->spritesInfantry().hideAndRemoveFirst();
0599       }
0600     }
0601     else 
0602     {
0603       qCDebug(KSIRK_LOG) << "No sprite on attacking country!";
0604       assert(false);
0605     }
0606 
0607     if (attackingSprite == nullptr)
0608     {
0609       qCCritical(KSIRK_LOG) << "ERROR: null attackingSprite at " << __FILE__ << ", line " << __LINE__;
0610 //       return;
0611     }
0612     else
0613     {
0614       qCDebug(KSIRK_LOG) << "attackingSprite created";
0615 
0616       // Adding the number of attackers decoration
0617       if (attackingCountry->owner()->getNbAttack() == 1)
0618       {
0619         attackingSprite->addDecoration("mark1", QRect(0,0,10,10));
0620       }
0621       else if (attackingCountry->owner()->getNbAttack() == 2)
0622       {
0623         attackingSprite->addDecoration("mark2", QRect(0,0,10,10));
0624       }
0625       else
0626       {
0627         attackingSprite->addDecoration("mark3", QRect(0,0,10,10));
0628       }
0629 
0630       attackingSprite-> setAttacker();
0631       attackingSprite->setupTravel(attackingCountry, defendingCountry, &pointArriveeAttaquant);
0632       qCDebug(KSIRK_LOG) << "add a sprite 2";
0633       m_animFighters->addSprite(attackingSprite);
0634       //(pointDepartAttaquantX <= pointArriveeAttaquantX) ? attackingSprite-> setLookRight() : attackingSprite-> setLookLeft();
0635       sndRoulePath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/roll.wav");
0636       if (sndRoulePath.isNull())
0637       {
0638         KMessageBox::error(nullptr, i18n("Sound roule not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
0639         exit(2);
0640       }
0641       if (KsirkSettings::soundEnabled())
0642       {
0643         m_audioPlayer->setSource(QUrl::fromLocalFile(sndRoulePath));
0644         m_audioPlayer->play();
0645       }
0646     }
0647   }
0648 
0649   if (!defendingCountry->spritesInfantry().isEmpty()
0650     && ((defendingCountry->nbArmies() % 5) >= defendingCountry->owner()->getNbDefense())
0651     && backGnd()->bgIsArena())
0652   {
0653     qCDebug(KSIRK_LOG) << "**NB-DEFENSE**" << defendingCountry->owner()->getNbDefense();
0654 
0655     for (unsigned int i=0;i< defendingCountry->owner()->getNbDefense();i++)
0656     {
0657       defenderSprite = simultaneousAttack(1,KGameWindow::Defense);
0658       if (defenderSprite != nullptr)
0659       {
0660         qCDebug(KSIRK_LOG) << "add a sprite";
0661         m_animFighters->addSprite(defenderSprite);
0662       }
0663     }
0664     nbSpriteDefending=defendingCountry->owner()->getNbDefense();
0665   }
0666   else
0667   {
0668     qCDebug(KSIRK_LOG) << "creating defenderSprite" << defendingCountry->name()
0669               << defendingCountry->nbArmies()
0670               << defendingCountry->spritesInfantry().size()
0671               << defendingCountry->spritesCavalry().size()
0672               << defendingCountry->spritesCannons().size();
0673     nbSpriteDefending=1;
0674     if ( (defendingCountry->nbArmies() != 0) 
0675       && defendingCountry->spritesInfantry().isEmpty()
0676       && defendingCountry->spritesCavalry().isEmpty()
0677       && defendingCountry->spritesCannons().isEmpty())
0678     {
0679       defendingCountry->createArmiesSprites();
0680     }
0681     if (!defendingCountry->spritesCavalry().isEmpty())
0682     {
0683       qCDebug(KSIRK_LOG) << "cavalry" << backGnd()->bgIsArena();
0684       if (backGnd()->bgIsArena())
0685       {
0686         defenderSprite = simultaneousAttack(5,KGameWindow::Defense);
0687       }
0688       else
0689       {
0690         defenderSprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
0691 
0692         defendingCountry->spritesCavalry().hideAndRemoveFirst();
0693       }
0694     }
0695     else if (!defendingCountry->spritesCannons().isEmpty())
0696     {
0697       qCDebug(KSIRK_LOG) << "cannon" << backGnd()->bgIsArena();
0698       if (backGnd()->bgIsArena())
0699       {
0700         defenderSprite = simultaneousAttack(10,KGameWindow::Defense);
0701       }
0702       else
0703       {
0704         defenderSprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
0705 
0706         defendingCountry->spritesCannons().hideAndRemoveFirst();
0707       }
0708     }
0709     else if (!defendingCountry->spritesInfantry().isEmpty())
0710     {
0711       qCDebug(KSIRK_LOG) << "infantry" << backGnd()->bgIsArena();
0712       if (backGnd()->bgIsArena())
0713       {
0714         defenderSprite = simultaneousAttack(1,KGameWindow::Defense);
0715       }
0716       else
0717       {
0718         defenderSprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
0719 
0720         defendingCountry->spritesInfantry().hideAndRemoveFirst();
0721       }
0722     }
0723     else
0724     {
0725       qCCritical(KSIRK_LOG) << "No sprite on defending country" << defendingCountry->name();
0726       return;
0727     }
0728 
0729     if (defenderSprite==nullptr)
0730     {
0731       qCCritical(KSIRK_LOG) << "ERROR: null defenderSprite at " << __FILE__ << ", line " << __LINE__;
0732       return;
0733     }
0734     else
0735     {
0736       if (defendingCountry->owner()->getNbDefense() == 1)
0737       {
0738         defenderSprite->addDecoration("mark1", QRect(0,0,10,10));
0739       }
0740       else if (defendingCountry->owner()->getNbDefense() == 2)
0741       {
0742         defenderSprite->addDecoration("mark2", QRect(0,0,10,10));
0743       }
0744 
0745       defenderSprite-> setDefendant();
0746       defenderSprite-> setupTravel(defendingCountry, defendingCountry, &pointArriveeDefenseur);
0747       //(pointDepartDefenseurX <= pointArriveeDefenseurX) ? defenderSprite-> setLookRight() : defenderSprite-> setLookLeft();
0748       qCDebug(KSIRK_LOG) << "add a sprite 3";
0749       m_animFighters->addSprite(defenderSprite);
0750       sndRoulePath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/roll.wav");
0751       if (sndRoulePath.isNull())
0752       {
0753         KMessageBox::error(nullptr, i18n("Sound roule not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
0754         exit(2);
0755       }
0756       if (KsirkSettings::soundEnabled())
0757       {
0758         m_audioPlayer->setSource(QUrl::fromLocalFile(sndRoulePath));
0759         m_audioPlayer->play();
0760       }
0761     }
0762   }
0763   qCDebug(KSIRK_LOG) << "Done";
0764 }
0765 
0766 void KGameWindow::animCombat()
0767 {
0768   qCDebug(KSIRK_LOG);
0769   m_animFighters->changeTarget(this, SLOT(slotFiringFinished(AnimSpritesGroup*)));
0770 
0771   AnimSpritesGroup::iterator it, it_end;
0772   it = m_animFighters->begin(); it_end = m_animFighters->end();
0773   for (; it != it_end; it++)
0774   {
0775     qCDebug(KSIRK_LOG) << "a sprite position: " << (*it)->pos();
0776     AnimSprite* sprite = (*it);
0777     sprite-> changeSequence("firing");
0778 
0779     qreal firingRelativePos = (Sprites::SkinSpritesData::single().intData("cannon-width") - Sprites::SkinSpritesData::single().intData("firing-width"))*m_theWorld->zoom();
0780     if (sprite-> looksToLeft()) 
0781     {
0782       sprite-> setPos(
0783         sprite-> x() + firingRelativePos,
0784         sprite-> y() );
0785     }
0786     else
0787     {
0788       sprite-> setPos(
0789       sprite-> x() + firingRelativePos,
0790                       sprite-> y() );
0791     }
0792     sprite->setAnimated(1);
0793 
0794     QString sndCanonPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/cannon.wav");
0795     if (sndCanonPath.isNull())
0796     {
0797       KMessageBox::error(nullptr,
0798           i18n("Sound cannon not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
0799       exit(2);
0800     }
0801     if (KsirkSettings::soundEnabled())
0802     {
0803       m_audioPlayer->setSource(QUrl::fromLocalFile(sndCanonPath));
0804       m_audioPlayer->play();
0805     }
0806   }
0807 }
0808 
0809 // not currently in use
0810 void KGameWindow::stopCombat()
0811 {
0812 /*
0813 //   qCDebug(KSIRK_LOG);
0814   AnimSpritesGroup::iterator it = m_animFighters->begin();
0815   while (it != m_animFighters->end())
0816   {
0817     CannonSprite* sprite = (CannonSprite*)(*it);
0818 //     it = m_animFighters.remove(it);
0819     sprite-> changeSequence("cannon");
0820 
0821     if (sprite-> looksToLeft()) 
0822     {
0823       sprite-> setPos(
0824         sprite->x() + (Sprites::SkinSpritesData::single().intData("cannon-width"))*m_theWorld->zoom(),
0825         sprite-> y() );
0826     }
0827     else 
0828     {
0829 //       sprite-> setX(sprite-> x());
0830     }
0831   }*/
0832 }
0833 
0834 
0835 void KGameWindow::animExplosion(int who)
0836 {
0837   qCDebug(KSIRK_LOG) << who;
0838   Country *attackingCountry = firstCountry();
0839   
0840   m_animFighters->changeTarget(this, SLOT(slotExplosionFinished(AnimSpritesGroup*)));
0841 
0842   qCDebug(KSIRK_LOG) << m_animFighters->size() << " fighters";
0843   unsigned int toArrive = 0;
0844   AnimSpritesGroup::iterator it = m_animFighters->begin();
0845   for (;it != m_animFighters->end();it++)
0846   {
0847     AnimSprite* sprite = (AnimSprite*)(*it);
0848     if ( (who == 2) // both are killed
0849         || ((who == 0) && (sprite-> isAttacker()))  // Attacker is killed
0850         || ((who == 1) && (sprite-> isDefendant())) ) // Defender is killed
0851     {
0852       sprite-> changeSequence("exploding");
0853 
0854       qreal firingRelativePos = (Sprites::SkinSpritesData::single().intData("firing-width") - Sprites::SkinSpritesData::single().intData("exploding-width"))*m_theWorld->zoom();
0855       if (sprite-> looksToLeft())
0856       {
0857         sprite-> setPos(
0858           sprite-> x() + firingRelativePos,
0859           sprite-> y() );
0860       }
0861 
0862       if (sprite->isAttacker())
0863       {
0864         qCDebug(KSIRK_LOG) << "  removing a sprite";
0865         //qCDebug(KSIRK_LOG) << "i attack" << i;
0866         qCDebug(KSIRK_LOG) << "NKA" << NKA;
0867 
0868         sprite->setAnimated(NKA);
0869 
0870         QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
0871         if (sndCrashPath.isNull())
0872         {
0873           KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
0874           exit(2);
0875         }
0876         if (KsirkSettings::soundEnabled())
0877         {
0878           m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
0879           m_audioPlayer->play();
0880         }
0881       }
0882 
0883       if (sprite->isDefendant())
0884       {
0885         qCDebug(KSIRK_LOG) << "  removing a sprite";
0886         qCDebug(KSIRK_LOG) << "NKD" << NKD;
0887 
0888         sprite->setAnimated(NKD);
0889 
0890         QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
0891         if (sndCrashPath.isNull())
0892         {
0893           KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
0894           exit(2);
0895         }
0896         if (KsirkSettings::soundEnabled())
0897         {
0898           m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
0899           m_audioPlayer->play();
0900         }
0901       }
0902     }
0903     else  // the sprite is not the one (or one the several) killed
0904     {
0905       qCDebug(KSIRK_LOG) << "  keeping a sprite";
0906       
0907       if ((attackingCountry->nbArmies() % 10) == 0)
0908       {
0909         sprite-> changeSequence("cannon");
0910       }
0911       else if ((attackingCountry->nbArmies() % 5) == 0)
0912       {
0913         sprite-> changeSequence("cavalry");
0914       }
0915       else
0916       {
0917         sprite-> changeSequence("infantry");
0918       }
0919 
0920       sprite->setStatic();
0921       toArrive++;
0922     }
0923   }
0924   for (unsigned int i=0; i < toArrive; i++)
0925   {
0926     m_animFighters->oneArrived(nullptr);
0927   }
0928   qCDebug(KSIRK_LOG) << "loop done";
0929 
0930   /*QString sndCrashPath = m_dirs-> findResource("appdata", m_automaton->skin() + "/Sounds/crash.wav");
0931   if (sndCrashPath.isNull())
0932   {
0933     KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
0934     exit(2);
0935   }
0936   if (KsirkSettings::soundEnabled())
0937   {
0938     m_audioPlayer->setSource(sndCrashPath);
0939     m_audioPlayer->play();
0940   }*/
0941   qCDebug(KSIRK_LOG) << "finished";
0942 //   m_frame-> initTimer();
0943 //    qCDebug(KSIRK_LOG)<<"OUT";
0944 }
0945 
0946 
0947 void KGameWindow::animExplosionForArena()
0948 {
0949   qCDebug(KSIRK_LOG);
0950 
0951   Country *attackingCountry = firstCountry();
0952   Country *defendingCountry = secondCountry();
0953 
0954   m_animFighters->changeTarget(this, SLOT(slotExplosionFinished(AnimSpritesGroup*)));
0955 
0956   qCDebug(KSIRK_LOG) << "hidden; " << m_animFighters->size() << " fighters";
0957   AnimSpritesGroup::iterator it = m_animFighters->begin();
0958   
0959   int nbAttackerSurvivor=attackingCountry->owner()->getNbAttack()-NKA;
0960   int nbDefenderSurvivor=defendingCountry->owner()->getNbDefense()-NKD;
0961 
0962   qCDebug(KSIRK_LOG) << "nbAttackerSurvivor" << nbAttackerSurvivor;
0963   qCDebug(KSIRK_LOG) << "nbDefenderSurvivor" << nbDefenderSurvivor;
0964   qCDebug(KSIRK_LOG) << "nbSpriteAttacking" << nbSpriteAttacking;
0965   qCDebug(KSIRK_LOG) << "nbSpriteDefending" << nbSpriteDefending;
0966 
0967   for (int nbSpriteTreated=0;
0968       (nbSpriteTreated < nbSpriteAttacking)&&(it!=m_animFighters->end());
0969       it++,nbSpriteTreated++)
0970   {
0971     AnimSprite* sprite = (AnimSprite*)(*it);
0972 
0973     qCDebug(KSIRK_LOG) << "nbSpriteTreated" << nbSpriteTreated;
0974 
0975     if(dynamic_cast<CannonSprite*>(sprite) != nullptr)
0976     {
0977       qCDebug(KSIRK_LOG) << "*******CANNON*******";
0978 
0979       if (NKA>0)
0980       {
0981         sprite-> changeSequence("exploding");
0982 
0983         if (sprite->isAttacker())
0984         {
0985           qCDebug(KSIRK_LOG) << "  removing a sprite";
0986           //qCDebug(KSIRK_LOG) << "i attack" << i;
0987           qCDebug(KSIRK_LOG) << "NKA" << NKA;
0988 
0989           sprite->setAnimated(NKA);
0990 
0991           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
0992           if (sndCrashPath.isNull())
0993           {
0994             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
0995             exit(2);
0996           }
0997           if (KsirkSettings::soundEnabled())
0998           {
0999             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1000             m_audioPlayer->play();
1001           }
1002         }
1003       }
1004       else
1005       {
1006         sprite-> changeSequence("cannon");
1007 
1008         sprite->setStatic();
1009         m_animFighters->oneArrived(nullptr);
1010       }
1011     }
1012     else if(dynamic_cast<CavalrySprite*>(sprite) != nullptr)
1013     {
1014       qCDebug(KSIRK_LOG) << "*******CAVALIER*******";
1015 
1016       if (NKA>0)
1017       {
1018         sprite-> changeSequence("exploding");
1019 
1020         if (sprite->isAttacker())
1021         {
1022           qCDebug(KSIRK_LOG) << "  removing a sprite";
1023           //qCDebug(KSIRK_LOG) << "i attack" << i;
1024           qCDebug(KSIRK_LOG) << "NKA" << NKA;
1025 
1026           sprite->setAnimated(NKA);
1027 
1028           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
1029           if (sndCrashPath.isNull())
1030           {
1031             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
1032             exit(2);
1033           }
1034           if (KsirkSettings::soundEnabled())
1035           {
1036             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1037             m_audioPlayer->play();
1038           }
1039         }
1040       }
1041       else
1042       {
1043         sprite-> changeSequence("cavalry");
1044 
1045         sprite->setStatic();
1046         m_animFighters->oneArrived(nullptr);
1047       }
1048     }
1049     else
1050     {
1051       if (nbAttackerSurvivor<=0)
1052       {
1053         sprite-> changeSequence("exploding");
1054 
1055         if (sprite->isAttacker())
1056         {
1057           qCDebug(KSIRK_LOG) << "  removing a sprite";
1058           //qCDebug(KSIRK_LOG) << "i attack" << i;
1059           qCDebug(KSIRK_LOG) << "NKA" << NKA;
1060 
1061           sprite->setAnimated(1);
1062 
1063           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
1064           if (sndCrashPath.isNull())
1065           {
1066             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
1067             exit(2);
1068           }
1069           if (KsirkSettings::soundEnabled())
1070           {
1071             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1072             m_audioPlayer->play();
1073           }
1074         }
1075       }
1076       else
1077       {
1078         qCDebug(KSIRK_LOG) << "  keeping a sprite";
1079         if (sprite->isAttacker())
1080         {
1081           sprite-> changeSequence("infantry");
1082 
1083           nbAttackerSurvivor--;
1084         }
1085         sprite->setStatic();
1086         m_animFighters->oneArrived(nullptr);
1087       }
1088     }
1089   }
1090 
1091   qCDebug(KSIRK_LOG) << "  loop done attack";
1092 
1093   for (int nbSpriteTreated=0;
1094       (nbSpriteTreated < nbSpriteDefending)&&(it!=m_animFighters->end());
1095       it++,nbSpriteTreated++)
1096   {
1097     qCDebug(KSIRK_LOG) << "nbSpriteTreated" << nbSpriteTreated;
1098 
1099     AnimSprite* sprite = (AnimSprite*)(*it);
1100 
1101     if(dynamic_cast<CannonSprite*>(sprite) != nullptr)
1102     {
1103       qCDebug(KSIRK_LOG) << "*******CANNON*******";
1104 
1105       if (NKD>0)
1106       {
1107         sprite-> changeSequence("exploding");
1108 
1109         if (sprite->isDefendant())
1110         {
1111           qCDebug(KSIRK_LOG) << "  removing a sprite";
1112           //qCDebug(KSIRK_LOG) << "i attack" << i;
1113           qCDebug(KSIRK_LOG) << "NKD" << NKD;
1114 
1115           sprite->setAnimated(NKD);
1116 
1117           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
1118           if (sndCrashPath.isNull())
1119           {
1120             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
1121             exit(2);
1122           }
1123           if (KsirkSettings::soundEnabled())
1124           {
1125             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1126             m_audioPlayer->play();
1127           }
1128         }
1129       }
1130       else
1131       {
1132         sprite-> changeSequence("cannon");
1133 
1134         sprite->setStatic();
1135         m_animFighters->oneArrived(nullptr);
1136       }
1137     }
1138     else if(dynamic_cast<CavalrySprite*>(sprite) != nullptr)
1139     {
1140       qCDebug(KSIRK_LOG) << "*******CAVALIER*******";
1141 
1142       if (NKD>0)
1143       {
1144         sprite-> changeSequence("exploding");
1145 
1146         if (sprite->isDefendant())
1147         {
1148           qCDebug(KSIRK_LOG) << "  removing a sprite";
1149           //qCDebug(KSIRK_LOG) << "i attack" << i;
1150           qCDebug(KSIRK_LOG) << "NKD" << NKD;
1151 
1152           sprite->setAnimated(NKD);
1153 
1154           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
1155           if (sndCrashPath.isNull())
1156           {
1157             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
1158             exit(2);
1159           }
1160           if (KsirkSettings::soundEnabled())
1161           {
1162             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1163             m_audioPlayer->play();
1164           }
1165         }
1166       }
1167       else
1168       {
1169         sprite-> changeSequence("cavalry");
1170 
1171         sprite->setStatic();
1172         m_animFighters->oneArrived(nullptr);
1173       }
1174     }
1175     else
1176     {
1177       if (nbDefenderSurvivor<=0)
1178       {
1179         sprite-> changeSequence("exploding");
1180 
1181         if (sprite->isDefendant())
1182         {
1183           qCDebug(KSIRK_LOG) << "  removing a sprite";
1184           qCDebug(KSIRK_LOG) << "NKD" << NKD;
1185 
1186           sprite->setAnimated(1);
1187 
1188           QString sndCrashPath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/crash.wav");
1189           if (sndCrashPath.isNull())
1190           {
1191             KMessageBox::information(this, i18n("Sound crash not found - Verify your installation\nProgram cannot continue"), i18n("KsirK - Error!"));
1192             exit(2);
1193           }
1194           if (KsirkSettings::soundEnabled())
1195           {
1196             m_audioPlayer->setSource(QUrl::fromLocalFile(sndCrashPath));
1197             m_audioPlayer->play();
1198           }
1199         }
1200       }
1201       else  // the sprite is not the one (or one the several) killed
1202       {
1203         qCDebug(KSIRK_LOG) << "  keeping a sprite";
1204 
1205         if (sprite->isDefendant())
1206         {
1207           sprite-> changeSequence("infantry");
1208 
1209           nbDefenderSurvivor--;
1210         }
1211         sprite->setStatic();
1212         m_animFighters->oneArrived(nullptr);
1213       }
1214     }
1215   }
1216 
1217   qCDebug(KSIRK_LOG) << "  loop done defense";
1218 
1219   qCDebug(KSIRK_LOG) << "finished";
1220 }
1221 
1222 void KGameWindow::stopExplosion()
1223 {
1224     qCDebug(KSIRK_LOG);
1225     m_animFighters->hideAndRemoveAll();
1226 }
1227 
1228 void KGameWindow::initCombatBringBackForArena(Country *attackingCountry, Country *defendingCountry)
1229 {
1230   qCDebug(KSIRK_LOG);
1231   int who = 0;
1232   if ((NKD != 0)&&(NKA != 0)) who = 2;
1233   else if (NKA != 0) who = 0;
1234   else if (NKD != 0) who = 1;
1235   else KMessageBox::information(nullptr, i18n("Problem: no one destroyed"));
1236 
1237   //CannonSprite *newSprite;
1238   AnimSprite* newSprite;
1239 
1240   qreal leftRelativePos;
1241   qreal pointDepartAttaquantY;
1242   qreal pointDepartDefenseurY;
1243 
1244   qreal flagYDiff = (Sprites::SkinSpritesData::single().intData("flag-height") - Sprites::SkinSpritesData::single().intData("cannon-height"))*m_theWorld->zoom();
1245   qreal pointFlagX = backGnd()->boundingRect().width()/2;
1246 
1247   if ((attackingCountry->nbArmies() % 10) == 0)
1248   {
1249       pointDepartAttaquantY = attackingCountry-> pointCannon().y()*      m_theWorld->zoom();
1250   }
1251   else
1252   {
1253     if ((attackingCountry->nbArmies() % 5) == 0)
1254     {
1255         pointDepartAttaquantY = attackingCountry-> pointCavalry().y()*      m_theWorld->zoom();
1256     }
1257     else
1258     {
1259         pointDepartAttaquantY = attackingCountry-> pointInfantry().y()*      m_theWorld->zoom();
1260     }
1261   }
1262 
1263   if ((defendingCountry->nbArmies() % 10) == 0)
1264   {
1265       pointDepartDefenseurY = defendingCountry-> pointCannon().y()*      m_theWorld->zoom();
1266   }
1267   else
1268   {
1269     if ((defendingCountry->nbArmies() % 5) == 0)
1270     {
1271         pointDepartDefenseurY = defendingCountry-> pointCavalry().y()*      m_theWorld->zoom();
1272     }
1273     else
1274     {
1275         pointDepartDefenseurY = defendingCountry-> pointInfantry().y()*      m_theWorld->zoom();
1276     }
1277   }
1278 
1279   qreal pointArriveeY = (pointDepartAttaquantY+pointDepartDefenseurY)/2;
1280 
1281   QPointF start(pointFlagX,pointArriveeY);
1282 
1283   qreal rightRelativePos = (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("flag-width"))*m_theWorld->zoom();
1284 
1285   if (who == 0) //Attaquant detruit, ramene defenseur
1286   {
1287     if ((defendingCountry->nbArmies() % 10) == 0)
1288     {
1289       newSprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
1290 
1291       leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cannon-width"))*m_theWorld->zoom();
1292     }
1293     else
1294     {
1295       if ((defendingCountry->nbArmies() % 5) == 0)
1296       {
1297         newSprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
1298 
1299         leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cavalry-width"))*m_theWorld->zoom();
1300       }
1301       else
1302       {
1303         newSprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
1304 
1305         leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("infantry-width"))*m_theWorld->zoom();
1306       }
1307     }
1308 
1309     if (backGnd()->bgIsArena() || ((attackingCountry-> pointFlag().x() <= defendingCountry-> pointFlag().x()) && !((qAbs(attackingCountry-> pointFlag().x()-defendingCountry-> pointFlag().x()) > (backGnd()-> boundingRect().width() / 2)) && (attackingCountry->communicateWith(defendingCountry)))))
1310     {
1311         newSprite-> setPos((start)+QPointF(rightRelativePos, flagYDiff));
1312     }
1313     else
1314     {
1315         newSprite-> setPos((start)+QPointF(leftRelativePos, flagYDiff));
1316     }
1317 
1318     connect(newSprite,&AnimSprite::atDestination,this,&KGameWindow::slotBring);
1319 
1320     QPointF dest;
1321     //int nbPos;
1322     if ((defendingCountry->nbArmies() % 10) == 0)
1323     {
1324       //nbPos = (defendingCountry->nbArmies() / 10);
1325       //dest = QPointF(defendingCountry-> pointCannon().x()*m_theWorld->zoom(),(defendingCountry-> pointCannon().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("cannon-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1326       dest = QPointF(defendingCountry-> pointCannon().x()*m_theWorld->zoom(),(defendingCountry-> pointCannon().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("cannon-height")+8)*((0+1)/2))*m_theWorld->zoom());
1327     }
1328     else
1329     {
1330       if ((defendingCountry->nbArmies() % 5) == 0)
1331       {
1332         //nbPos = (defendingCountry->nbArmies() / 5);
1333         //dest = QPointF(defendingCountry-> pointCavalry().x()*m_theWorld->zoom(),(defendingCountry-> pointCavalry().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("cavalry-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1334         dest = QPointF(defendingCountry-> pointCavalry().x()*m_theWorld->zoom(),(defendingCountry-> pointCavalry().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("cavalry-height")+8)*((0+1)/2))*m_theWorld->zoom());
1335       }
1336       else
1337       {
1338         //nbPos = (defendingCountry->nbArmies()) % 5;
1339 
1340         //dest = QPointF(defendingCountry-> pointInfantry().x()*m_theWorld->zoom(),(defendingCountry-> pointInfantry().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1341         dest = QPointF(defendingCountry-> pointInfantry().x()*m_theWorld->zoom(),(defendingCountry-> pointInfantry().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((0+1)/2))*m_theWorld->zoom());
1342       }
1343     }
1344 
1345     ((AnimSprite*)newSprite)-> setupTravel(attackingCountry, defendingCountry, newSprite-> pos(), dest);
1346 
1347     newSprite-> turnTowardDestination();
1348     qCDebug(KSIRK_LOG) << "add a sprite 4";
1349     m_animFighters->addSprite(newSprite);
1350 
1351     QString sndRoulePath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/roll.wav");
1352     if (sndRoulePath.isNull())
1353     {
1354         KMessageBox::error(nullptr, i18n("Sound roule not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
1355         exit(2);
1356     }
1357     if (KsirkSettings::soundEnabled())
1358     {
1359             m_audioPlayer->setSource(QUrl::fromLocalFile(sndRoulePath));
1360             m_audioPlayer->play();
1361     }
1362   }
1363   else if (who == 1) //Defenseur detruit, ramene Attaquant
1364   {
1365     if ((attackingCountry->nbArmies() % 10) == 0)
1366     {
1367       newSprite = new CannonSprite(m_theWorld->zoom(), backGnd(), 200);
1368 
1369       leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cannon-width"))*m_theWorld->zoom();
1370     }
1371     else
1372     {
1373       if ((attackingCountry->nbArmies() % 5) == 0)
1374       {
1375         newSprite = new CavalrySprite(m_theWorld->zoom(), backGnd(), 200);
1376 
1377         leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("cavalry-width"))*m_theWorld->zoom();
1378       }
1379       else
1380       {
1381         newSprite = new InfantrySprite(m_theWorld->zoom(), backGnd(), 200);
1382 
1383         leftRelativePos = - (Sprites::SkinSpritesData::single().intData("width-between-flag-and-fighter") + Sprites::SkinSpritesData::single().intData("infantry-width"))*m_theWorld->zoom();
1384       }
1385     }
1386 
1387       if (backGnd()->bgIsArena() || ((attackingCountry-> pointFlag().x() <= defendingCountry-> pointFlag().x()) && !((qAbs(attackingCountry-> pointFlag().x()-defendingCountry-> pointFlag().x()) > (backGnd()-> boundingRect().width() / 2)) && (attackingCountry->communicateWith(defendingCountry)))))
1388       {
1389           newSprite-> setPos((start)+QPointF(leftRelativePos,flagYDiff));
1390       }
1391       else
1392       {
1393           newSprite-> setPos((start)+QPointF(rightRelativePos,flagYDiff));
1394       }
1395 
1396       connect(newSprite,&AnimSprite::atDestination,this,&KGameWindow::slotBring);
1397 
1398     QPointF dest;
1399     //int nbPos;
1400     if ((attackingCountry->nbArmies() % 10) == 0)
1401     {
1402       //nbPos = (attackingCountry->nbArmies() / 10);
1403       //dest = QPointF(attackingCountry-> pointCannon().x()*m_theWorld->zoom(),(attackingCountry-> pointCannon().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("cannon-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1404       dest = QPointF(attackingCountry-> pointCannon().x()*m_theWorld->zoom(),(attackingCountry-> pointCannon().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("cannon-height")+8)*((0+1)/2))*m_theWorld->zoom());
1405     }
1406     else
1407     {
1408       if ((attackingCountry->nbArmies() % 5) == 0)
1409       {
1410         //nbPos = (attackingCountry->nbArmies() / 5);
1411         //dest = QPointF(attackingCountry-> pointCavalry().x()*m_theWorld->zoom(),(attackingCountry-> pointCavalry().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("cavalry-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1412         dest = QPointF(attackingCountry-> pointCavalry().x()*m_theWorld->zoom(),(attackingCountry-> pointCavalry().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("cavalry-height")+8)*((0+1)/2))*m_theWorld->zoom());
1413       }
1414       else
1415       {
1416         //nbPos = attackingCountry->nbArmies() % 5;
1417         //dest = QPointF(attackingCountry-> pointInfantry().x()*m_theWorld->zoom(),(attackingCountry-> pointInfantry().y()+(1-2*(nbPos%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((nbPos+1)/2))*m_theWorld->zoom());
1418         dest = QPointF(attackingCountry-> pointInfantry().x()*m_theWorld->zoom(),(attackingCountry-> pointInfantry().y()+(1-2*(0%2))*(Sprites::SkinSpritesData::single().intData("infantry-height")+8)*((0+1)/2))*m_theWorld->zoom());
1419       }
1420     }
1421 
1422       ((AnimSprite*)newSprite)-> setupTravel(defendingCountry, attackingCountry, newSprite-> pos(), dest);
1423 
1424       newSprite-> turnTowardDestination();
1425       qCDebug(KSIRK_LOG) << "add a sprite 5";
1426       m_animFighters->addSprite(newSprite);
1427 
1428       QString sndRoulePath = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Sounds/roll.wav");
1429       if (sndRoulePath.isNull())
1430       {
1431           KMessageBox::error(nullptr, i18n("Sound roule not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
1432           exit(2);
1433       }
1434       if (KsirkSettings::soundEnabled())
1435       {
1436               m_audioPlayer->setSource(QUrl::fromLocalFile(sndRoulePath));
1437               m_audioPlayer->play();
1438       }
1439   }
1440   else if (who == 2)
1441   {
1442   } //Attaquant ET Defenseur detruits
1443   else  // error
1444   {
1445     qCCritical(KSIRK_LOG) << Q_FUNC_INFO << __FILE__ << __LINE__ << i18n("Bug: who should be 0, 1 or 2.");
1446     exit(1);
1447   }
1448 
1449   relativePosInArenaDefense=0;
1450   relativePosInArenaAttack=0;
1451 }
1452 
1453 /**
1454   * Disconnects the mouse events signals from their slots to avoid human
1455   * player actions when it is the turn of the AI
1456   */
1457 void KGameWindow::disconnectMouse()
1458 {
1459 /*  if ( ! disconnect(m_frame, SIGNAL(signalLeftButtonDown(QPoint)),
1460                     this, SLOT(slotLeftButtonDown(QPoint))))
1461     qCCritical(KSIRK_LOG) << "cannot connect slotLeftButtonDown !";
1462   if ( ! disconnect(m_frame, SIGNAL(signalLeftButtonUp(QPoint)),
1463                     this, SLOT(slotLeftButtonUp(QPoint))))
1464     qCCritical(KSIRK_LOG) << "cannot connect slotLeftButtonUp !";
1465   if ( ! disconnect(m_frame, SIGNAL(signalRightButtonDown(QPoint)),
1466                     this, SLOT(slotRightButtonDown(QPoint))))
1467     qCCritical(KSIRK_LOG) << "cannot connect slotRightButtonDown !";*/
1468 }
1469 
1470 /**
1471   * Reconnect the mouse events signals to their slots to allow human players to
1472   * play
1473   */
1474 void KGameWindow::reconnectMouse()
1475 {
1476 /*  if ( ! connect(m_frame, SIGNAL(signalLeftButtonDown(QPoint)),
1477                     this, SLOT(slotLeftButtonDown(QPoint))))
1478   qCCritical(KSIRK_LOG) << "cannot connect slotLeftButtonDown !";
1479   if ( ! connect(m_frame, SIGNAL(signalLeftButtonUp(QPoint)),
1480                     this, SLOT(slotLeftButtonUp(QPoint))))
1481   qCCritical(KSIRK_LOG) << "cannot connect slotLeftButtonUp !";
1482   if ( ! connect(m_frame, SIGNAL(signalRightButtonDown(QPoint)),
1483                     this, SLOT(slotRightButtonDown(QPoint))))
1484   qCCritical(KSIRK_LOG) << "cannot connect slotRightButtonDown !";*/
1485 }
1486 
1487 bool KGameWindow::haveAnimFighters() const
1488 {
1489     return !m_animFighters->empty();
1490 }
1491 
1492 void KGameWindow::updateScrollArrows()
1493 {
1494   qCDebug(KSIRK_LOG);
1495   if (m_uparrow != nullptr)
1496   {
1497     QPointF pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,0));
1498     pos = pos + QPointF(-(m_uparrow->boundingRect().width()/2),m_uparrow->boundingRect().height());
1499     m_uparrow->setPos(pos);
1500     m_uparrow->setActive(false);
1501   }
1502   if (m_downarrow != nullptr)
1503   {
1504     QPointF pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,m_frame->viewport()->height()));
1505     pos = pos - QPointF(m_downarrow->boundingRect().width()/2,m_downarrow->boundingRect().height());
1506     m_downarrow->setPos(pos);
1507     m_downarrow->setActive(false);
1508   }
1509   if (m_leftarrow != nullptr)
1510   {
1511     QPointF pos = m_frame->mapToScene(QPoint(0,m_frame->viewport()->height()/2));
1512     pos = pos - QPointF(m_downarrow->boundingRect().width()/2,m_downarrow->boundingRect().height());
1513     pos = pos + QPointF(m_leftarrow->boundingRect().width(),-(m_leftarrow->boundingRect().height()/2));
1514     m_leftarrow->setPos(pos);
1515     m_leftarrow->setActive(false);
1516   }
1517   if (m_rightarrow != nullptr)
1518   {
1519     QPointF pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width(),m_frame->viewport()->height()/2));
1520     pos = pos - QPointF(m_rightarrow->boundingRect().width(),m_rightarrow->boundingRect().height()/2);
1521     m_rightarrow->hide();
1522     m_rightarrow->setPos(pos);
1523     m_rightarrow->show();
1524     m_rightarrow->setActive(false);
1525   }
1526 }
1527 
1528 } // closing namespace KsirK