Warning, file /games/ksirk/ksirk/kgamewin.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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                : mer jui 11 22:27:28 EDT 2001   */
0021 
0022 // application specific includes
0023 #include "kgamewin.h"
0024 #include "ksirkConfigDialog.h"
0025 #include "ksirksettings.h"
0026 #include "Sprites/animspritesgroup.h"
0027 #include "Sprites/arrowsprite.h"
0028 #include "GameLogic/aiplayer.h"
0029 #include "GameLogic/aiColsonPlayer.h"
0030 #include "GameLogic/aiplayerio.h"
0031 #include "GameLogic/dice.h"
0032 #include "GameLogic/KMessageParts.h"
0033 #include "GameLogic/goal.h"
0034 #include "GameLogic/KsirkChatItem.h"
0035 #include "GameLogic/KsirkChatModel.h"
0036 #include "GameLogic/KsirkChatDelegate.h"
0037 #include "SaveLoad/ksirkgamexmlloader.h"
0038 #include "Sprites/backgnd.h"
0039 #include "Dialogs/kplayersetupwidget.h"
0040 #include "Dialogs/kwaitedplayersetupdialog.h"
0041 #include "Dialogs/restartOrExitDialogImpl.h"
0042 #include "Dialogs/newGameDialogImpl.h"
0043 #include "Dialogs/newGameSummaryWidget.h"
0044 #include "Dialogs/jabbergameui.h"
0045 #include "Dialogs/tcpconnectwidget.h"
0046 #include "im.h"
0047 #include "xmpp_tasks.h"
0048 
0049 
0050 //include files for QT
0051 #include <QAction>
0052 #include <QDialog>
0053 #include <QDockWidget>
0054 #include <QFileDialog>
0055 #include <QGridLayout>
0056 #include <QHostInfo>
0057 #include <QIcon>
0058 #include <QMenuBar>
0059 #include <QMovie>
0060 #include <QStatusBar>
0061 #include <QString>
0062 #include <QSvgRenderer>
0063 #include <QTreeView>
0064 #include <QUuid>
0065 
0066 // include files for KDE
0067 #include <kwidgetsaddons_version.h>
0068 #include <KMessageBox>
0069 #include <KLocalizedString>
0070 #include <KConfig>
0071 #include <KStandardGameAction>
0072 #include <KStandardAction>
0073 #include <KActionCollection>
0074 #include "ksirk_debug.h"
0075 #include <phonon/mediaobject.h>
0076 #include <KGamePopupItem>
0077 #include <KToolBar>
0078 #include <KAboutData>
0079 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
0080 #include <libkdegamesprivate/kgame/kgamechat.h>
0081 #include <sys/utsname.h>
0082 
0083 namespace Ksirk
0084 {
0085 using namespace GameLogic;
0086 
0087 // port all occurrences of m_accels
0088 // port all occurrences of setBarPos
0089 
0090 KGameWindow::KGameWindow(QWidget* parent) :
0091   KXmlGuiWindow(parent),
0092   m_rightDock(nullptr),
0093   m_rightDialog(nullptr),
0094   m_automaton(new GameAutomaton()),
0095   m_wSlide(nullptr),
0096   m_currentDisplayedWidget(MainMenu),
0097   NKD(0), NKA(0),
0098   m_useArena(false),
0099   nbSpriteAttacking(0),
0100   nbSpriteDefending(0),
0101   relativePosInArenaAttack(0),
0102   relativePosInArenaDefense(0),
0103   m_theWorld(nullptr),
0104   m_scene_world(nullptr), m_scene_arena(nullptr),
0105   m_backGnd_world(nullptr), m_backGnd_arena(nullptr),
0106   m_animFighters(new AnimSpritesGroup(this,SLOT(slotMovingFightersArrived(AnimSpritesGroup*)))),
0107   m_nbMovedArmies(0),
0108   m_firstCountry(nullptr), m_secondCountry(nullptr),
0109   m_frame(nullptr),
0110   m_arena(nullptr),
0111   m_mainMenu(nullptr),
0112   m_goalAction(nullptr),
0113   m_barFlag(new QLabel(this)),
0114   m_chatDlg(nullptr),
0115   m_audioPlayer(Phonon::createPlayer( Phonon::NotificationCategory )),
0116   m_timer(this),
0117   m_message(nullptr),
0118   m_mouseLocalisation(nullptr),
0119   m_defenseDialog(nullptr),
0120   m_fileName(),
0121   m_uparrow(nullptr),
0122   m_downarrow(nullptr),
0123   m_leftarrow(nullptr),
0124   m_rightarrow(nullptr),
0125   m_reinitializingGame(false),
0126   m_newGameDialog(nullptr),
0127   m_newPlayerWidget(nullptr),
0128   m_stateBeforeNewGame(GameAutomaton::INVALID),
0129   m_stackWidgetBeforeNewGame(-1),
0130   m_jabberClient(new JabberClient()),
0131   m_advertizedHostName(QHostInfo::localHostName()),
0132   m_jabberGameWidget(nullptr),
0133   m_presents(),
0134   m_newGameSetup(new NewGameSetup(m_automaton))
0135   {
0136   qCDebug(KSIRK_LOG) << "KGameWindow constructor begin";
0137 
0138   statusBar()->addWidget(m_barFlag);
0139 
0140 //   m_accels.setEnabled(true);
0141   
0142   QString iconFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/soldierKneeling.png");
0143   if (iconFileName.isNull())
0144   {
0145       KMessageBox::error(nullptr, i18n("Cannot load icon<br>Program cannot continue"), i18n("Error!"));
0146       exit(2);
0147   }
0148   QPixmap icon(iconFileName);
0149 
0150   m_bottomDock = new QDockWidget(this);
0151   m_bottomDock->setObjectName("bottom-dock");
0152   m_bottomDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
0153   m_bottomDock->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::TopDockWidgetArea);
0154 
0155   QWidget* titleChatWidget = new QWidget(m_bottomDock);
0156   QHBoxLayout* titleChatLayout = new QHBoxLayout(titleChatWidget);
0157   titleChatWidget->setLayout(titleChatLayout);
0158   titleChatWidget->setFixedHeight(35);
0159 
0160   QWidget* newMessageChat = new QWidget(titleChatWidget);
0161   QHBoxLayout* newMessageChatLayout = new QHBoxLayout(newMessageChat);
0162   newMessageChat->setLayout(newMessageChatLayout);
0163 
0164   KsirkChatModel* chatModel = new KsirkChatModel(m_bottomDock,this);
0165   KsirkChatDelegate* chatDelegate = new KsirkChatDelegate(m_bottomDock);
0166   // m_bottomDock is the KGameChat parent widget
0167   m_chatDlg = new KGameChat(m_automaton, 10000, m_bottomDock,chatModel,chatDelegate);
0168   connect(m_chatDlg,
0169           SIGNAL(signalReturnPressed(QString)),
0170           this,
0171           SLOT(slotChatMessage()));
0172 
0173 
0174   m_upChatFloatPix.load(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/2UpArrow.png"));
0175   m_downChatFloatPix.load(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/2DownArrow.png"));
0176   m_chatIsReduced = false;
0177 
0178   m_titleChatMsg = new QLabel(i18n("No message..."));
0179   QPixmap downChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/downArrow.png"));
0180   m_reduceChatButton = new QPushButton(downChatReducePix,"");
0181   m_floatChatButton = new QPushButton(m_upChatFloatPix,"");
0182   m_reduceChatButton->setFixedSize(30,30);
0183   m_floatChatButton->setFixedSize(30,30);
0184   connect(m_floatChatButton,
0185           SIGNAL(clicked()),
0186           this,
0187           SLOT(slotChatFloatButtonPressed()));
0188   connect(m_bottomDock,
0189           SIGNAL(topLevelChanged(bool)),
0190           this,
0191           SLOT(slotChatFloatChanged(bool)));
0192   connect(m_reduceChatButton,
0193           SIGNAL(clicked()),
0194           this,
0195           SLOT(slotChatReduceButton()));
0196 
0197   newMessageChatLayout->addWidget(m_titleChatMsg);
0198   m_titleChatMsg->hide();
0199 
0200   titleChatLayout->addWidget(newMessageChat);
0201   titleChatLayout->addWidget(m_reduceChatButton);
0202   titleChatLayout->addWidget(m_floatChatButton);
0203 
0204   m_bottomDock->setWidget(m_chatDlg);
0205   m_bottomDock->setTitleBarWidget(titleChatWidget);
0206   addDockWidget(Qt::BottomDockWidgetArea, m_bottomDock); // master dockwidget
0207 
0208 //    qCDebug(KSIRK_LOG) << "Before initActions";
0209   initActions();
0210 
0211   qCDebug(KSIRK_LOG) << "Setting up GUI";
0212   setupGUI();
0213 
0214   qCDebug(KSIRK_LOG) << "Creating automaton";
0215   m_automaton->init(this);
0216 
0217   // create a central widget if it doesent' exists
0218   m_centralWidget = new QStackedWidget(this);
0219   setCentralWidget(m_centralWidget);
0220   m_mainMenu = new mainMenu(this, m_centralWidget);
0221   m_mainMenu->init(m_theWorld);
0222   
0223   /// @FIXME Hides the "Play KsirK over Jabber Network" button while Jabber
0224   /// connection does not work
0225   m_mainMenu->pbJabberGame->hide();
0226   
0227   m_newGameDialog = new NewGameWidget(m_newGameSetup, m_centralWidget);
0228   connect(m_newGameDialog,SIGNAL(newGameOK()), this, SLOT(slotNewGameNext()));
0229   connect(m_newGameDialog,SIGNAL(newGameKO()), this, SLOT(slotNewGameKO()));
0230   m_newPlayerWidget = new KPlayerSetupWidget(m_centralWidget);
0231   connect(m_newPlayerWidget,SIGNAL(next()),this,SLOT(slotNewPlayerNext()));
0232   connect(m_newPlayerWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
0233   connect(m_newPlayerWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
0234   connect(m_newPlayerWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
0235   connect(m_newPlayerWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
0236   qCDebug(KSIRK_LOG) << "create the Jabber widget if it doesn't exist";
0237   m_jabberGameWidget = new KsirkJabberGameWidget(m_centralWidget);
0238   m_centralWidget->addWidget(m_mainMenu); // MAINMENU_INDEX 0
0239   m_centralWidget->addWidget(m_newGameDialog); // NEWGAME_INDEX 1
0240   m_centralWidget->addWidget(m_jabberGameWidget); // JABBERGAME_INDEX 2
0241   m_centralWidget->addWidget(m_newPlayerWidget);  // NEWPLAYER_INDEX 3
0242   m_newGameSummaryWidget = new NewGameSummaryWidget(m_centralWidget);
0243   connect(m_newGameSummaryWidget->finishButton,SIGNAL(clicked(bool)),this,SLOT(slotStartNewGame()));
0244   connect(m_newGameSummaryWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
0245   connect(m_newGameSummaryWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
0246   m_centralWidget->addWidget(m_newGameSummaryWidget);  // NEWGAMESUMMARY_INDEX 4
0247   m_tcpConnectWidget = new TcpConnectWidget(this);
0248   m_centralWidget->addWidget(m_tcpConnectWidget);  // TCPCONNECT_INDEX 5
0249   connect(m_tcpConnectWidget,SIGNAL(next()),this,SLOT(slotConnectToServer()));
0250   connect(m_tcpConnectWidget,SIGNAL(previous()),this,SLOT(slotTcpConnectPrevious()));
0251   connect(m_tcpConnectWidget,SIGNAL(cancel()),this,SLOT(slotTcpConnectCancel()));
0252   m_centralWidget->setCurrentIndex(MAINMENU_INDEX);
0253   m_currentDisplayedWidget = MainMenu;
0254   m_bottomDock->hide();
0255   
0256   
0257 //    qCDebug(KSIRK_LOG) << "Before initStatusBar";
0258   initStatusBar();
0259   
0260   menuBar()-> show();
0261   
0262   explain();
0263   m_automaton->run();
0264   setMouseTracking(true);
0265 
0266   m_timer.setSingleShot(true);
0267   connect(&m_timer,SIGNAL(timeout()),this,SLOT(evenementTimer()));
0268 
0269   m_initialPresence = XMPP::Status ( "", "", 5, true );
0270 
0271   qCDebug(KSIRK_LOG) << "Connecting Jabber signals";
0272   QObject::connect ( m_jabberClient, SIGNAL (csDisconnected()), this, SLOT (slotCSDisconnected()) );
0273   QObject::connect ( m_jabberClient, SIGNAL (csError(int)), this, SLOT (slotCSError(int)) );
0274   QObject::connect ( m_jabberClient, SIGNAL (tlsWarning(QCA::TLS::IdentityResult,QCA::Validity)), this, SLOT (slotHandleTLSWarning(QCA::TLS::IdentityResult,QCA::Validity)) );
0275   QObject::connect ( m_jabberClient, SIGNAL (connected()), this, SLOT (slotConnected()) );
0276   QObject::connect ( m_jabberClient, SIGNAL (error(JabberClient::ErrorCode)), this, SLOT (slotClientError(JabberClient::ErrorCode)) );
0277   
0278 //   QObject::connect ( m_jabberClient, SIGNAL (subscription(XMPP::Jid,QString)), this, SLOT (slotSubscription(XMPP::Jid,QString)) );
0279   QObject::connect ( m_jabberClient, SIGNAL (rosterRequestFinished(bool)), this, SLOT (slotRosterRequestFinished(bool)) );
0280 //   QObject::connect ( m_jabberClient, SIGNAL (newContact(XMPP::RosterItem)), this, SLOT (slotContactUpdated(XMPP::RosterItem)) );
0281 //   QObject::connect ( m_jabberClient, SIGNAL (contactUpdated(XMPP::RosterItem)), this, SLOT (slotContactUpdated(XMPP::RosterItem)) );
0282 //   QObject::connect ( m_jabberClient, SIGNAL (contactDeleted(XMPP::RosterItem)), this, SLOT (slotContactDeleted(XMPP::RosterItem)) );
0283 //   QObject::connect ( m_jabberClient, SIGNAL (resourceAvailable(XMPP::Jid,XMPP::Resource)), this, SLOT (slotResourceAvailable(XMPP::Jid,XMPP::Resource)) );
0284 //   QObject::connect ( m_jabberClient, SIGNAL (resourceUnavailable(XMPP::Jid,XMPP::Resource)), this, SLOT (slotResourceUnavailable(XMPP::Jid,XMPP::Resource)) );
0285   QObject::connect ( m_jabberClient, SIGNAL (messageReceived(XMPP::Message)), this, SLOT (slotReceivedMessage(XMPP::Message)) );
0286 //   QObject::connect ( m_jabberClient, SIGNAL (incomingFileTransfer()), this, SLOT (slotIncomingFileTransfer()) );
0287   QObject::connect ( m_jabberClient, SIGNAL (groupChatJoined(XMPP::Jid)), this, SLOT (slotGroupChatJoined(XMPP::Jid)) );
0288   QObject::connect ( m_jabberClient, SIGNAL (groupChatLeft(XMPP::Jid)), this, SLOT (slotGroupChatLeft(XMPP::Jid)) );
0289   QObject::connect ( m_jabberClient, SIGNAL (groupChatPresence(XMPP::Jid,XMPP::Status)), this, SLOT (slotGroupChatPresence(XMPP::Jid,XMPP::Status)) );
0290   
0291   QObject::connect ( m_jabberClient, SIGNAL (groupChatError(XMPP::Jid,int,QString)), this, SLOT (slotGroupChatError(XMPP::Jid,int,QString)) );
0292   QObject::connect ( m_jabberClient, SIGNAL (debugMessage(QString)), this, SLOT (slotClientDebugMessage(QString)) );
0293   
0294   m_jabberClient->setUseXMPP09 ( true );
0295 //     m_jabberClient->setUseSSL ( true );
0296   m_jabberClient->setAllowPlainTextPassword ( true );
0297 
0298   struct utsname utsBuf;
0299   uname (&utsBuf);
0300   m_jabberClient->setClientName ("KsirK");
0301   m_jabberClient->setClientVersion (KAboutData::applicationData().version());
0302   m_jabberClient->setOSName (QString ("%1 %2").arg (utsBuf.sysname, 1).arg (utsBuf.release, 2));
0303   
0304   // Set caps node information
0305   m_jabberClient->setCapsNode("http://ksirk.kde.org/jabber/caps");
0306   m_jabberClient->setCapsVersion(KAboutData::applicationData().version());
0307   
0308   // Set Disco Identity information
0309   DiscoItem::Identity identity;
0310   identity.category = "client";
0311   identity.type = "pc";
0312   identity.name = "KsirK";
0313   m_jabberClient->setDiscoIdentity(identity);
0314 
0315   connect (this, SIGNAL(newJabberGame(QString,int,QString)), m_automaton, SIGNAL(newJabberGame(QString,int,QString)));
0316 
0317   m_automaton->skin("skins/default");
0318 }
0319 
0320 KGameWindow::~KGameWindow()
0321 {
0322   qCDebug(KSIRK_LOG);
0323 
0324   if (m_jabberClient != nullptr)
0325   {
0326     delete m_jabberClient;
0327     m_jabberClient = nullptr;
0328   }
0329   if (m_automaton != nullptr)
0330   {
0331     m_automaton->setGameStatus( KGame::End );
0332     delete m_automaton; m_automaton = nullptr;
0333   }
0334   delete m_backGnd_world; m_backGnd_world = nullptr;
0335   delete m_scene_world; m_scene_world = nullptr;
0336 //   if (m_barFlagButton) {delete m_barFlagButton; m_barFlagButton = 0;}
0337   delete m_frame; m_frame = nullptr;
0338   delete m_backGnd_arena; m_backGnd_arena = nullptr;
0339   delete m_arena; m_arena = nullptr;
0340   delete m_scene_arena; m_scene_arena = nullptr;
0341   delete m_mainMenu; m_mainMenu = nullptr;
0342   delete m_audioPlayer;
0343   delete m_rightDialog;
0344   delete m_defenseDialog;
0345   delete m_newGameSetup;
0346 }
0347 
0348 void KGameWindow::initActions()
0349 {
0350   QAction *action;
0351 
0352   // standard game actions
0353   action = KStandardGameAction::gameNew(this, SLOT(slotNewGame()), this);
0354   actionCollection()->addAction(action->objectName(), action);
0355   action = KStandardGameAction::load(this, SLOT(slotOpenGame()), this);
0356   actionCollection()->addAction(action->objectName(), action);
0357   m_saveGameAction = KStandardGameAction::save(this, SLOT(slotSaveGame()), this);
0358   m_saveGameAction->setEnabled(false);
0359   actionCollection()->addAction(m_saveGameAction->objectName(), m_saveGameAction);
0360   action = KStandardGameAction::quit(this, SLOT(close()), this);
0361   actionCollection()->addAction(action->objectName(), action);
0362 
0363   m_zoomInAction = KStandardAction::zoomIn(this, SLOT(slotZoomIn()), this);
0364   m_zoomInAction->setEnabled(false);
0365   actionCollection()->addAction(m_zoomInAction->objectName(), m_zoomInAction);
0366 
0367   m_zoomOutAction = KStandardAction::zoomOut(this, SLOT(slotZoomOut()), this);
0368   m_zoomOutAction->setEnabled(false);
0369   actionCollection()->addAction(m_zoomOutAction->objectName(), m_zoomOutAction);
0370 
0371   KStandardAction::preferences( this, SLOT(optionsConfigure()), actionCollection() );
0372 
0373   // specific ksirk action
0374   QString imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, "jabber.png");
0375   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
0376   if (imageFileName.isNull())
0377   {
0378     KMessageBox::error(nullptr, i18n("Cannot load button image %1<br>Program cannot continue",QString("jabber.png")), i18n("Error!"));
0379     exit(2);
0380   }
0381   m_jabberAction = new QAction(QIcon(QPixmap(imageFileName)), i18n("Play over Jabber"), this);
0382   m_jabberAction-> setText(i18n("Play KsirK over the Jabber Network"));
0383   m_jabberAction-> setIconText(i18n("Jabber"));
0384   actionCollection()->setDefaultShortcut(m_jabberAction, Qt::CTRL+Qt::Key_J);
0385   m_jabberAction->setStatusTip(i18n("Allow to connect to a KsirK Jabber Multi User Gaming Room to create new games or to join present games"));
0386   connect(m_jabberAction,SIGNAL(triggered(bool)),this,SLOT(slotJabberGame()));
0387   qCDebug(KSIRK_LOG) << "Adding action game_jabber";
0388   actionCollection()->addAction("game_jabber", m_jabberAction);
0389 
0390   // specific ksirk action
0391   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEWNETGAME);
0392   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
0393   if (imageFileName.isNull())
0394   {
0395     KMessageBox::error(nullptr, i18n("Cannot load button image %1<br>Program cannot continue",QString(CM_NEWNETGAME)), i18n("Error!"));
0396     exit(2);
0397   }
0398   QAction * newSocketAction = new QAction(QIcon(QPixmap(imageFileName)), i18n("New Standard TCP/IP Network Game"), this);
0399   newSocketAction->setIconText(i18n("New TCP/IP"));
0400   actionCollection()->setDefaultShortcut(newSocketAction, Qt::CTRL+Qt::Key_T);
0401   newSocketAction->setStatusTip(i18n("Create a new standard TCP/IP network game"));
0402   connect(newSocketAction,SIGNAL(triggered(bool)),this,SLOT(slotNewSocketGame()));
0403   qCDebug(KSIRK_LOG) << "Adding action game_new_socket";
0404   actionCollection()->addAction("game_new_socket", newSocketAction);
0405   
0406                                      
0407   // specific ksirk action
0408   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEWNETGAME);
0409   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
0410   if (imageFileName.isNull())
0411   {
0412     KMessageBox::error(nullptr, i18n("Cannot load button image %1<br>Program cannot continue",QString(CM_NEWNETGAME)), i18n("Error!"));
0413     exit(2);
0414   }
0415   QAction * joinAction = new QAction(QIcon(QPixmap(imageFileName)),
0416         i18n("Join a Standard TCP/IP Network Game"), this);
0417   joinAction->setIconText(i18n("Join TCP/IP"));
0418   actionCollection()->setDefaultShortcut(joinAction, Qt::CTRL+Qt::SHIFT+Qt::Key_J);
0419   joinAction->setStatusTip(i18n("Join a standard TCP/IP network game"));
0420   connect(joinAction,SIGNAL(triggered(bool)),this,SLOT(slotJoinNetworkGame()));
0421    qCDebug(KSIRK_LOG) << "Adding action game_join_socket";
0422   actionCollection()->addAction("game_join_socket", joinAction);
0423 
0424   m_goalAction = new QAction(i18n("Goal"), this);
0425   m_goalAction-> setText(i18n("Display the Current Player's Goal"));
0426   m_goalAction-> setIconText("  ");
0427   actionCollection()->setDefaultShortcut(m_goalAction, Qt::CTRL+Qt::Key_G);
0428   m_goalAction->setStatusTip(i18n("Display the current player's goal"));
0429   connect(m_goalAction,SIGNAL(triggered(bool)),this,SLOT(slotShowGoal()));
0430   m_goalAction->setVisible(false);
0431   qCDebug(KSIRK_LOG) << "Adding action game_goal";
0432   actionCollection()->addAction("game_goal", m_goalAction);
0433   
0434   m_contextualHelpAction = new QAction(
0435         i18n("Contextual Help"), this);
0436   m_contextualHelpAction->setEnabled(false);
0437   actionCollection()->setDefaultShortcut(m_contextualHelpAction, Qt::CTRL+Qt::Key_F1);
0438   connect(m_contextualHelpAction,SIGNAL(triggered(bool)),this,SLOT(slotContextualHelp()));
0439   actionCollection()->addAction("help_contextual", m_contextualHelpAction);
0440 
0441 
0442   QString nextPlayerActionImageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEXTPLAYER);
0443   m_nextPlayerAction =  new QAction(QIcon(nextPlayerActionImageFileName),
0444         i18n("Next Player"), this);
0445   connect(m_nextPlayerAction, SIGNAL(triggered(bool)), this, SLOT(slotNextPlayer()));
0446   m_contextualHelpAction->setStatusTip(i18n("Lets the next player play"));
0447   m_nextPlayerAction->setEnabled(false);
0448   actionCollection()->addAction("game_nextplayer", m_nextPlayerAction);
0449 
0450   QAction * finishMovesAction = new QAction(
0451         i18n("Finish moves"), this);
0452   actionCollection()->setDefaultShortcut(finishMovesAction, Qt::Key_Space);
0453   finishMovesAction->setStatusTip(i18n("Finish moving the current sprites"));
0454   connect(finishMovesAction,SIGNAL(triggered(bool)),this,SLOT(slotFinishMoves()));
0455   actionCollection()->addAction("game_finish_moves", finishMovesAction);
0456 
0457 
0458 }
0459 
0460 void KGameWindow::initStatusBar()
0461 {
0462   statusBar()-> setSizeGripEnabled(true);
0463   //QT5 statusBar()->insertPermanentItem("", ID_STATUS_MSG, 2);
0464   //QT5 statusBar()-> setItemAlignment(ID_STATUS_MSG, Qt::AlignLeft | Qt::AlignVCenter);
0465 
0466   //QT5 statusBar()->insertPermanentItem("", ID_STATUS_MSG2, 3);
0467   //QT5 statusBar()-> setItemAlignment(ID_STATUS_MSG2, Qt::AlignLeft | Qt::AlignVCenter);
0468   //QT5 statusBar()->addPermanentWidget(m_barFlag);
0469 }
0470 
0471 Country* KGameWindow::clickIn(const QPointF &pointf)
0472 {
0473 //   qCDebug(KSIRK_LOG) << "KGameWindow::clickIn " << pointf;
0474  /* if(isMyState(GameLogic::GameAutomaton::INIT) || m_theWorld-> countryAt( pointf )==0)
0475   {
0476     m_rightDock->hide();
0477   }*/
0478   return m_theWorld-> countryAt( pointf );
0479 }
0480 
0481 Player* KGameWindow::currentPlayer()
0482 {
0483 //   qCDebug(KSIRK_LOG) << "KGameWindow::currentPlayer";
0484   Player* current = m_automaton->currentPlayer();
0485 
0486   return current;
0487 }
0488 
0489 void KGameWindow::loadDices()
0490 {
0491   qCDebug(KSIRK_LOG);
0492   
0493   m_dices[Blue] = QList<QPixmap>();
0494   m_dices[Red] = QList<QPixmap>();
0495   m_dices[Blue].push_back(buildDice("bluedice1"));
0496   m_dices[Blue].push_back(buildDice("bluedice2"));
0497   m_dices[Blue].push_back(buildDice("bluedice3"));
0498   m_dices[Blue].push_back(buildDice("bluedice4"));
0499   m_dices[Blue].push_back(buildDice("bluedice5"));
0500   m_dices[Blue].push_back(buildDice("bluedice6"));
0501   m_dices[Red].push_back(buildDice("reddice1"));
0502   m_dices[Red].push_back(buildDice("reddice2"));
0503   m_dices[Red].push_back(buildDice("reddice3"));
0504   m_dices[Red].push_back(buildDice("reddice4"));
0505   m_dices[Red].push_back(buildDice("reddice5"));
0506   m_dices[Red].push_back(buildDice("reddice6"));
0507 }
0508 
0509 QPixmap KGameWindow::buildDice(const QString& id)
0510 {
0511   qCDebug(KSIRK_LOG);
0512 
0513   QSize size(32,32);
0514   QImage image(size, QImage::Format_ARGB32_Premultiplied);
0515   image.fill(0);
0516   QPainter p(&image);
0517   if (m_theWorld != nullptr)
0518   {
0519     m_theWorld->renderer()->render(&p, id);
0520   }
0521 
0522   return QPixmap::fromImage(image);
0523 }
0524 
0525 QPixmap KGameWindow::getDice(DiceColor color, int num)
0526 {
0527   if(num==0 || num==-1)
0528 {return QPixmap();}
0529   else {return m_dices[color][num-1];}
0530 }
0531 
0532 void KGameWindow::newSkin(const QString& onuFileName)
0533 {
0534   qCDebug(KSIRK_LOG) << onuFileName;
0535   clear();
0536 
0537   m_animFighters->clear();
0538   foreach(AnimSpritesGroup* sprites, m_animSpritesGroups)
0539   {
0540     sprites->clear();
0541     delete sprites;
0542   }
0543   m_animSpritesGroups.clear();
0544 
0545   if (m_centralWidget != nullptr)
0546   {
0547     m_centralWidget->setCurrentIndex(-1);
0548   }
0549 
0550 // NOTE:I wanted to recreate the automaton here. But it isn't possible as this
0551 // method is called from inside a GameAutomaton method. Furthermore, it isn't
0552 // a good solution because the central KGame object should not be recreated
0553 // but reinitialized as needed
0554 //   m_automaton->init(0);
0555 //   delete m_automaton;
0556 //   m_automaton = new GameAutomaton();
0557 //   m_automaton->init(this);
0558 
0559   m_mouseLocalisation = nullptr;
0560   if (m_theWorld != nullptr)
0561   {
0562 //     m_theWorld-> reset();
0563     delete m_theWorld;
0564     m_theWorld = nullptr;
0565   }
0566 
0567   QString onuDefinitionFileName = onuFileName;
0568   if (onuDefinitionFileName.isEmpty())
0569   {
0570     onuDefinitionFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Data/world.desktop");
0571   }
0572   else if (!QFile::exists(onuDefinitionFileName))
0573   {
0574     onuDefinitionFileName.clear();
0575   }
0576   if (onuDefinitionFileName.isEmpty())
0577   {
0578       KMessageBox::error(nullptr,
0579           i18n("World definition file not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
0580       exit(2);
0581   }
0582   // Bug 308527. Need to remove all goals on new game. Only goals for selected skin will be loaded.
0583   m_automaton->removeAllGoals();
0584   qCDebug(KSIRK_LOG) << "Got World definition file name: " <<  onuDefinitionFileName;
0585   m_theWorld = new ONU(m_automaton, onuDefinitionFileName);
0586   if (m_theWorld->skin().isEmpty())
0587   {
0588     delete m_theWorld;
0589     m_theWorld = nullptr;
0590   }
0591   loadDices();
0592 
0593   // put the size to the window size if it's the main menu
0594   int width;
0595   int height;
0596   if (m_scene_arena == nullptr || m_theWorld == nullptr)
0597   {
0598      width = 2000;
0599      height = 2000;
0600   }
0601   else
0602   {
0603      width = m_theWorld->width();
0604      height = m_theWorld->height();
0605   }
0606 
0607   //Creation of the arena background
0608   if (m_backGnd_arena != nullptr)
0609   {
0610     qCDebug(KSIRK_LOG) << "Before m_backGnd_arena delete";
0611     delete m_backGnd_arena;
0612   }
0613   //Creation of the background
0614   if (m_backGnd_world != nullptr)
0615   {
0616     qCDebug(KSIRK_LOG) << "Before m_backGnd_world delete";
0617     delete m_backGnd_world;
0618   }
0619 
0620   // create the arena view
0621   if (m_scene_arena != nullptr)
0622   {
0623     qCDebug(KSIRK_LOG) << "Before m_scene_arena delete";
0624     delete m_scene_arena;
0625   }
0626   m_scene_arena = new QGraphicsScene(0, 0, width, height,this);
0627 
0628   if (m_frame != nullptr)
0629   {
0630     m_frame->setUpdatesEnabled(false);
0631     m_uparrow = nullptr;
0632     m_downarrow = nullptr;
0633     m_leftarrow = nullptr;
0634     m_rightarrow = nullptr;
0635     m_centralWidget->removeWidget(m_frame);
0636     delete m_frame;
0637     m_frame = nullptr;
0638   }
0639   if (m_scene_world != nullptr)
0640   {
0641     qCDebug(KSIRK_LOG) << "Before m_scene_world delete";
0642     delete m_scene_world;
0643   }
0644   m_scene_world = new QGraphicsScene(0, 0, width, height,this);
0645 
0646   qCDebug(KSIRK_LOG) << "create the world map view";
0647   if (m_theWorld != nullptr)
0648   {
0649     m_frame = new DecoratedGameFrame(m_centralWidget, width, height, m_automaton);
0650     m_frame->setMaximumWidth(width);
0651     m_frame->setMaximumHeight(height);
0652     m_frame->setCacheMode( QGraphicsView::CacheBackground );
0653     m_frame->setIcon();
0654   }
0655   
0656   if (m_arena != nullptr)
0657   {
0658     m_centralWidget->removeWidget(m_arena);
0659     delete m_arena;
0660     m_arena = nullptr;
0661   }
0662   if (m_theWorld != nullptr)
0663   {
0664     m_arena = new FightArena(m_centralWidget, width, height, m_scene_arena, m_theWorld, m_automaton);
0665     m_arena->setMaximumWidth(width);
0666     m_arena->setMaximumHeight(height);
0667     m_arena->setCacheMode( QGraphicsView::CacheBackground );
0668   }
0669   
0670   qCDebug(KSIRK_LOG) << "put the menu, map and arena in the central widget";
0671   if (m_frame != nullptr)
0672   {
0673     m_centralWidget->addWidget(m_frame); // MAP_INDEX 6
0674   }
0675   if (m_arena != nullptr)
0676   {
0677     m_centralWidget->addWidget(m_arena); // ARENA_INDEX 7
0678   }
0679   
0680   if (m_theWorld == nullptr)
0681   {
0682     return;
0683   }
0684   m_backGnd_arena = new BackGnd(m_scene_arena, m_theWorld, true);
0685   m_backGnd_world = new BackGnd(m_scene_world, m_theWorld);
0686 
0687 //   m_scene_world->setDoubleBuffering(true);
0688   qCDebug(KSIRK_LOG) << "Before initView";
0689   initView();
0690   qCDebug(KSIRK_LOG) <<"After m_backGnd new="<< m_backGnd_world;
0691   m_frame->setFocus();
0692 
0693   m_uparrow = new Sprites::ArrowSprite(Qt::UpArrow, m_backGnd_world);
0694   m_uparrow->setZValue(1000);
0695   QPointF pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,0));
0696   pos = pos + QPointF(-(m_uparrow->boundingRect().width()/2),m_uparrow->boundingRect().height());
0697   m_uparrow->setPos(pos);
0698   m_uparrow->setActive(false);
0699   
0700   m_downarrow = new Sprites::ArrowSprite(Qt::DownArrow, m_backGnd_world);
0701   m_downarrow->setZValue(1000);
0702   pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,m_frame->viewport()->height()));
0703   pos = pos - QPointF(m_downarrow->boundingRect().width()/2,m_downarrow->boundingRect().height());
0704   m_downarrow->setPos(pos);
0705   m_downarrow->setActive(false);
0706   pos = m_frame->mapToScene(QPoint(0,m_frame->viewport()->height()/2));
0707   
0708   m_leftarrow = new Sprites::ArrowSprite(Qt::LeftArrow, m_backGnd_world);
0709   m_leftarrow->setZValue(1000);
0710   pos = pos + QPointF(m_leftarrow->boundingRect().width(),-(m_leftarrow->boundingRect().height()/2));
0711   m_leftarrow->setPos(pos);
0712   m_leftarrow->setActive(false);
0713   
0714   m_rightarrow = new Sprites::ArrowSprite(Qt::RightArrow, m_backGnd_world);
0715   m_rightarrow->setZValue(1000);
0716   pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width(),m_frame->viewport()->height()/2));
0717   pos = pos - QPointF(m_rightarrow->boundingRect().width(),m_rightarrow->boundingRect().height()/2);
0718   m_rightarrow->setPos(pos);
0719   m_rightarrow->setActive(false);
0720   
0721   qCDebug(KSIRK_LOG) <<"End new skin";
0722 }
0723 
0724 KRightDialog * KGameWindow::getRightDialog()
0725 {
0726   return m_rightDialog;
0727 }
0728 
0729 void KGameWindow::initView()
0730 {
0731   qCDebug(KSIRK_LOG);
0732   QString iconFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/soldierKneeling.png");
0733   if (iconFileName.isNull())
0734   {
0735       KMessageBox::error(nullptr, i18n("Cannot load icon<br>Program cannot continue"), i18n("Error!"));
0736       exit(2);
0737   }
0738 // to port : still necessary ?
0739 //   m_frame->setIcon(QPixmap(iconFileName));
0740 
0741   disconnectMouse();
0742   reconnectMouse();
0743   setCaption("KsirK",false);
0744   m_scene_world-> update();
0745   m_frame->setScene(m_scene_world);
0746   
0747   m_scene_arena-> update();
0748   m_arena->setScene(m_scene_arena);
0749 
0750   //ADD a dock widget on the right
0751 
0752   if (m_rightDialog != nullptr)
0753   {
0754     m_rightDialog->hide();
0755     delete m_rightDialog;
0756   }
0757 
0758   if (m_rightDock != nullptr)
0759   {
0760     m_rightDock->hide();
0761     delete m_rightDock;
0762   }
0763   m_rightDock = new QDockWidget(this);
0764   m_rightDock->setObjectName("right-dock");
0765   m_rightDock->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
0766   m_rightDock->setFeatures(QDockWidget::NoDockWidgetFeatures);
0767 
0768   m_rightDialog = new KRightDialog(m_rightDock,theWorld(),this);
0769   m_rightDock->setWidget(m_rightDialog);
0770   qCDebug(KSIRK_LOG) << "hiding right dock";
0771   m_rightDock->hide();
0772   addDockWidget(Qt::RightDockWidgetArea, m_rightDock);
0773   m_frame->setFocus();
0774 }
0775 
0776 bool KGameWindow::attackEnd()
0777 {
0778   qCDebug(KSIRK_LOG);
0779   if (m_firstCountry==nullptr || m_secondCountry == nullptr)
0780   {
0781     return false;
0782   }
0783 
0784   m_firstCountry->releaseHighlightingLock();
0785   m_firstCountry->clearHighlighting();
0786   m_secondCountry->releaseHighlightingLock();
0787   m_secondCountry->clearHighlighting();
0788 
0789   // Bug 315491.
0790   bool playerDeleted = false;
0791   bool res = false;
0792   QString mes = "";
0793   qCDebug(KSIRK_LOG) << "There is now " << m_secondCountry-> nbArmies() << " armies in " << m_secondCountry->name() << ".";
0794   if (m_secondCountry-> nbArmies() < 1)
0795   {
0796     QPixmap pm = currentPlayer()->getFlag()->image(0);
0797 
0798     KMessageParts messageParts;
0799     messageParts << pm << I18N_NOOP("<font color=\"red\">%1 conquered %2 from %3</font>") << currentPlayer()->name() << m_secondCountry-> name() << m_firstCountry-> name();
0800     broadcastChangeItem(messageParts, ID_NO_STATUS_MSG);
0801     
0802     Player* oldOwner = m_secondCountry-> owner();
0803     unsigned int newOldOwnerNbCountries = oldOwner-> getNbCountries() - 1;
0804     
0805     if (m_automaton->isAdmin())
0806     {
0807       currentPlayer()-> incrNbCountries();
0808       oldOwner-> decrNbCountries();
0809     }
0810 
0811     m_secondCountry-> owner(currentPlayer());
0812     m_secondCountry-> nbArmies(currentPlayer()->getNbAttack());
0813     m_firstCountry-> decrNbArmies(currentPlayer()->getNbAttack());
0814     m_scene_world-> update();
0815     if (m_firstCountry->nbArmies() > 1)
0816     {
0817       res = true;
0818     }
0819     qCDebug(KSIRK_LOG) << oldOwner-> name() << " now owns " << newOldOwnerNbCountries << " countries.";
0820     if (newOldOwnerNbCountries == 0)
0821     {
0822       QString oldOwnerId = oldOwner->name();
0823       showMessage(i18n("%1, you are defeated! Bye, bye...",oldOwner->name()), 10, ForceShowing);
0824 /*      KMessageBox::information(this,
0825                                i18n("%1, you are defeated! Bye, bye...",oldOwner->name()),
0826                                i18n("KsirK - Game Over!"));*/
0827       if (m_automaton->isAdmin())
0828       {
0829         // Bug 315491.
0830         playerDeleted = true;
0831         qCDebug(KSIRK_LOG) << "Removing player " << oldOwner-> name();
0832         int i = m_automaton->playerList()->indexOf(oldOwner);
0833         if (i != -1)
0834           delete m_automaton->playerList()->takeAt(i);
0835         qCDebug(KSIRK_LOG) << "There is now " << m_automaton->playerList()->count() << " players";
0836         m_automaton->setMinPlayers(m_automaton->playerList()->count());
0837         m_automaton->setGameStatus(KGame::Run);
0838       }
0839       if ( m_automaton->isAdmin()
0840         && ( ( m_automaton->useGoals()
0841              && ( currentPlayer()->goal().type() == GameLogic::Goal::GoalPlayer)
0842              && ( *currentPlayer()->goal().players().begin() == oldOwnerId ) )
0843            || (m_automaton->playerList()->count() == 1) ) )
0844       {
0845         m_automaton->state(GameLogic::GameAutomaton::GAME_OVER);
0846         QByteArray buffer;
0847         QDataStream stream(&buffer, QIODevice::WriteOnly);
0848         stream << currentPlayer()->id();
0849         m_automaton->sendMessage(buffer,Winner);
0850         res = false;
0851       }
0852       else if (m_automaton->isAdmin())
0853       {
0854         foreach (KPlayer* player, *m_automaton->playerList())
0855         {
0856           m_automaton->checkGoal((Player*)player);
0857         }
0858       }
0859     }
0860     else if (m_automaton->isAdmin())
0861     {
0862       m_automaton->checkGoal();
0863     }
0864   }
0865   // Bug 315491.
0866   if (!playerDeleted)
0867   {
0868     if (backGnd()->bgIsArena())
0869     {
0870       m_arena->countryAttack()->createArmiesSprites();
0871       m_arena->countryDefense()->createArmiesSprites();
0872     }
0873     else
0874     {
0875       m_firstCountry->createArmiesSprites();
0876       m_secondCountry->createArmiesSprites();
0877     }
0878   }
0879   if (m_automaton->isAdmin())
0880   {
0881     if (res)
0882     {
0883       QByteArray buffer;
0884       QDataStream stream(&buffer, QIODevice::WriteOnly);
0885       m_automaton->sendMessage(buffer,StartLocalCurrentAI);
0886     }
0887     else
0888     {
0889       if (m_firstCountry->nbArmies() < 2 || !m_automaton->isAttackAuto())
0890       {
0891         QByteArray buffer;
0892         QDataStream stream(&buffer, QIODevice::WriteOnly);
0893         m_automaton->sendMessage(buffer,ClearHighlighting);
0894         KMessageParts messageParts;
0895         messageParts << I18N_NOOP("%1: it is up to you again") << currentPlayer()-> name();
0896         broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
0897       }
0898     }
0899   }
0900   m_automaton->setGameStatus(KGame::Run);
0901   return res;
0902 }
0903 
0904 void KGameWindow::winner(const Player* player)
0905 {
0906   qCDebug(KSIRK_LOG) << player->name();
0907   QString msg = i18n("%1 won!");
0908   if (!player->isVirtual())
0909   {
0910     msg = i18n("<big><b>%1</b>, you won!</big>");
0911   }
0912   if (m_automaton->useGoals())
0913   {
0914     msg += i18n("<br>Winner's goal was stated like this:<br><i>%1</i><br><br>Do you want to play again?", player->goal().message());
0915   }
0916   else
0917   {
0918     if (!player->isVirtual())
0919     {
0920       msg += i18n("<br>You conquered all the world!");
0921     }
0922     else
0923     {
0924       msg += i18n("<br>He conquered all the world!");
0925     }
0926   }
0927   RestartOrExitDialogImpl* restartDia = new RestartOrExitDialogImpl(i18n(msg.toUtf8().data(),player->name()));
0928               
0929   connect((QObject*)restartDia->newGameButton,
0930               SIGNAL(clicked()),
0931               this,
0932               SLOT(slotNewGame()));
0933 
0934   connect((QObject*)restartDia->exitButton,
0935               SIGNAL(clicked()),
0936               this,
0937               SLOT(slotExit()));
0938 
0939   restartDia->show();
0940 }
0941 
0942 void KGameWindow::resolveAttack()
0943 {
0944 
0945 //    qCDebug(KSIRK_LOG) << "KGameWindow::resolveAttack";
0946 
0947   int A1 = -1; int A2 = -1; int A3 = -1; int AE = -1;
0948   int D1 = -1; int D2 = -1; int DE = -1;
0949 
0950   NKD = NKA = 0;
0951   if (currentPlayer() == nullptr || m_secondCountry == nullptr || m_secondCountry->owner() == nullptr || m_firstCountry == nullptr)
0952     return;
0953 
0954   int secondOldNbArmies = m_secondCountry->nbArmies();
0955 
0956   A1 = Dice::roll();
0957   if (currentPlayer()-> getNbAttack() > 1) A2 = Dice::roll();
0958   if (currentPlayer()-> getNbAttack() > 2) A3 = Dice::roll();
0959   if ((A1>=A2)&&(A1>=A3))  // A1 is the greater ; don't move it; look at the two others
0960     if (A2>=A3) {} // A2 greater than A3 ; don't move
0961     else {AE = A2;A2 = A3;A3 = AE;} // A2 lesser than A3 ; swap them
0962   else
0963   { // A1 is not the greater
0964     if (A2>=A3) {AE=A1;A1=A2;A2=AE;}  // A2 is greater than A3, so it is the greater; swap it with A1
0965     else {AE=A1;A1=A3;A3=AE;} // A3 is greater than A2, so it is the greater; swap it with A1
0966                                             // now the new A1 is the greater, look at the 2 others
0967     if (A2>=A3) {} // A2 greater than A3, nothing to do
0968     else {AE=A2;A2=A3;A3=AE;} // A2 lesser than A3; swap them
0969   }
0970   D1 = Dice::roll();
0971   if (m_secondCountry-> owner()-> getNbDefense() > 1)
0972     D2 = Dice::roll();
0973   if (D2>D1) {DE=D1;D1=D2;D2=DE;}
0974   if (A1>D1)
0975   {
0976     QByteArray buffer;
0977     QDataStream stream(&buffer, QIODevice::WriteOnly);
0978     stream << m_secondCountry->name() << quint32(1);
0979     m_automaton->sendMessage(buffer,DecrNbArmies);
0980     NKD++;
0981   }
0982   else
0983   {
0984     QByteArray buffer;
0985     QDataStream stream(&buffer, QIODevice::WriteOnly);
0986     stream << m_firstCountry->name() << quint32(1);
0987     m_automaton->sendMessage(buffer,DecrNbArmies);
0988     NKA++;
0989   }
0990   if ((A2>0)&&(D2>0))
0991   {
0992     if (A2>D2)
0993     {
0994       QByteArray buffer;
0995       QDataStream stream(&buffer, QIODevice::WriteOnly);
0996       stream << m_secondCountry->name() << quint32(1);
0997       m_automaton->sendMessage(buffer,DecrNbArmies);
0998       NKD++;
0999     }
1000     else
1001     {
1002       QByteArray buffer;
1003       QDataStream stream(&buffer, QIODevice::WriteOnly);
1004       stream << m_firstCountry->name() << quint32(1);
1005       m_automaton->sendMessage(buffer,DecrNbArmies);
1006       NKA++;
1007     }
1008   }
1009 //   qCDebug(KSIRK_LOG) << "(" << A1<<", "<<A2<<", "<<A3<<") <-> ("<<D1<<", "<<D2<<")" ;
1010 //   qCDebug(KSIRK_LOG) << "Attacker loses " << NKA<<" armies; Defender loses "<<NKD<<" armies." ;
1011   
1012   QByteArray buffer3;
1013   QDataStream stream3(&buffer3, QIODevice::WriteOnly);
1014   stream3 << (quint32)A1 << (quint32)A2 << (quint32)A3 << (quint32)D1 << (quint32)D2 << (quint32)NKA << (quint32)NKD << (quint32)(secondOldNbArmies-NKD < 1);
1015   qCDebug(KSIRK_LOG) << "sending DisplayFightResult";
1016   m_automaton->sendMessage(buffer3,DisplayFightResult);
1017 
1018   QByteArray buffer2;
1019   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1020   
1021   if ((NKD != 0)&&(NKA != 0)) stream2 << quint32(2);
1022   else if (NKA != 0) stream2 << quint32(0);
1023   else if (NKD != 0) stream2 << quint32(1);
1024   m_automaton->sendMessage(buffer2,AnimExplosion);
1025 
1026   //qCDebug(KSIRK_LOG)<< "A1:"<< A1<<", A2: " <<A2 <<"A3:" << A3;
1027   //qCDebug(KSIRK_LOG)<< "D1:"<< D1<<", D2: " <<D2;
1028   // if arena is displayed, update the arena countries too
1029   if (currentWidgetType() == Arena) {
1030     arena()->countryAttack()->decrNbArmies(NKA);
1031     arena()->countryDefense()->decrNbArmies(NKD);
1032   }
1033   m_secondCountry-> owner()-> setNbDefense(0);
1034 }
1035 
1036 
1037 
1038 /**
1039   * Reimplementation of the inherited function called when a window close event arise
1040   */
1041 bool KGameWindow::queryClose()
1042 {
1043   qCDebug(KSIRK_LOG);
1044 
1045   if ((m_automaton->state() == GameAutomaton::INIT) || (m_automaton->state() ==  GameAutomaton::INTERLUDE))
1046   {
1047 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
1048     switch ( KMessageBox::warningTwoActions( this,
1049 #else
1050     switch ( KMessageBox::warningYesNo( this,
1051 #endif
1052                                         i18n("Do you want to quit the game?"),
1053                                         QString(),
1054                                         KGuiItem(i18nc("@action:button", "Quit Game")),
1055                                         KStandardGuiItem::cancel()) )
1056     {
1057 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
1058     case KMessageBox::PrimaryAction :
1059 #else
1060     case KMessageBox::Yes :
1061 #endif
1062         break;
1063     default:
1064         return false;
1065     }
1066   }
1067   else
1068   {
1069 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
1070     switch ( KMessageBox::warningTwoActionsCancel( this,
1071 #else
1072     switch ( KMessageBox::warningYesNoCancel( this,
1073 #endif
1074                                               i18n("Before you quit, do you want to save your game?"),
1075                                               QString(),
1076                                               KStandardGuiItem::save(),
1077                                               KStandardGuiItem::discard()) )
1078     {
1079 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
1080     case KMessageBox::PrimaryAction :
1081 #else
1082     case KMessageBox::Yes :
1083 #endif
1084         slotSaveGame();
1085         break;
1086 #if KWIDGETSADDONS_VERSION >= QT_VERSION_CHECK(5, 100, 0)
1087     case KMessageBox::SecondaryAction :
1088 #else
1089     case KMessageBox::No :
1090 #endif
1091         break;
1092     default: // cancel
1093         return false;
1094     }
1095   }
1096 //   hide();
1097   disconnect(&m_timer,SIGNAL(timeout()),this,SLOT(evenementTimer()));
1098   disconnectMouse();
1099   m_mouseLocalisation = nullptr;
1100   m_automaton->setGameStatus(KGame::End);
1101   
1102 /*  if (m_theWorld != 0)
1103   {
1104     delete m_theWorld;
1105     m_theWorld = 0;
1106   }
1107   while (!m_automaton->playerList()->isEmpty())
1108   {
1109     delete m_automaton->playerList()->takeFirst();
1110   }
1111   delete m_automaton; m_automaton = 0;*/
1112   KSharedConfig::openConfig()->sync();
1113   return true;
1114 }
1115 
1116 bool KGameWindow::actionOpenGame()
1117 {
1118   qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame";
1119 
1120   QString fileName = QFileDialog::getOpenFileName(this, i18nc("@title:window", "KsirK - Load Game"), QString(), "*.xml");
1121   if (!fileName.isEmpty())
1122   {
1123     m_fileName = fileName;
1124     m_automaton->setGameStatus(KGame::End);
1125     m_waitedPlayers.clear();
1126     qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame loader";
1127     Ksirk::SaveLoad::GameXmlLoader loader(fileName, *this, m_waitedPlayers);
1128     qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame loading done";
1129     for (unsigned int i = 0; i < m_theWorld->getNbCountries(); i++)
1130     {
1131       Country* country = m_theWorld-> getCountries().at(i);
1132       qCDebug(KSIRK_LOG) << "Adding sprites to " << country->name();
1133       country-> createArmiesSprites();
1134       Player *player = country-> owner();
1135       if (player)
1136       {
1137         country-> flag(player->flagFileName(), m_backGnd_world);
1138       }
1139     }
1140     m_backGnd_world->hide();
1141     m_backGnd_world->show();
1142     if (m_waitedPlayers.empty())
1143     {
1144       QByteArray buffer;
1145       QDataStream stream(&buffer, QIODevice::WriteOnly);
1146       m_automaton->sendMessage(buffer,StartGame);
1147       m_automaton->sendMessage(buffer,ClearHighlighting);
1148       m_frame->setFocus();
1149       qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame false1";
1150       m_frame->setArenaOptionEnabled(true);
1151       reduceChat();
1152 
1153       return false;
1154     }
1155     else
1156     {
1157       KMessageParts messageParts;
1158       messageParts << I18N_NOOP("Waiting for the connection of %1 network players.") << QString::number(m_waitedPlayers.size());
1159       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1160       qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame true";
1161       unreduceChat();
1162       m_frame->setArenaOptionEnabled(false);
1163       return true;
1164     }
1165   }
1166   qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame false2";
1167   return false;
1168 }
1169 
1170 void KGameWindow::displayRecyclingButtons()
1171 {
1172   qCDebug(KSIRK_LOG);
1173   if (m_automaton->allLocalPlayersComputer())
1174   {
1175 //     qCDebug(KSIRK_LOG) << "There is only computer local players";
1176     PlayersArray::iterator it = m_automaton->playerList()->begin();
1177     PlayersArray::iterator it_end = m_automaton->playerList()->end();
1178     for (; it != it_end; it++)
1179     {
1180 //       qCDebug(KSIRK_LOG) << "Looking at player " << (*it)->name() 
1181 //               << ". is AI  : " << ((Player*)(*it))->isAI() 
1182 //               << ". isRunning: " << ((static_cast<AIPlayer *>(*it))-> isRunning())
1183 //               << ". virtual: " << (*it)->isVirtual() 
1184 //                      ;
1185       if ( ((Player*)(*it))->isAI() 
1186            && (!(static_cast<AIPlayer *>(*it))-> isRunning())
1187         && (!(*it)->isVirtual()) ) 
1188       {
1189 //         qCDebug(KSIRK_LOG) << "Starting computer player " << (*it)->name();
1190         (static_cast<AIPlayer *>(*it))-> start();
1191         break;
1192       }
1193     }
1194   }
1195   else
1196   {
1197     m_rightDock->show();
1198   }
1199   m_nextPlayerAction->setEnabled(false);
1200 }
1201 
1202 void KGameWindow::clearHighlighting()
1203 {
1204   qCDebug(KSIRK_LOG);
1205   if (m_firstCountry != nullptr)
1206   {
1207     m_firstCountry->releaseHighlightingLock();
1208     m_firstCountry->clearHighlighting();
1209     m_firstCountry = nullptr;
1210   }
1211   if (m_secondCountry != nullptr)
1212   {
1213     m_secondCountry->releaseHighlightingLock();
1214     m_secondCountry->clearHighlighting();
1215     m_secondCountry = nullptr;
1216   }
1217 
1218   if (currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()))
1219   {
1220     if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning()) (static_cast<AIPlayer *>(currentPlayer()))-> start();
1221     m_nextPlayerAction->setEnabled(false);
1222   }
1223   else if (currentPlayer() && !currentPlayer()->isVirtual())
1224   {
1225     slotContextualHelp();
1226     m_nextPlayerAction->setEnabled(true);
1227   }
1228   else
1229   {
1230     m_nextPlayerAction->setEnabled(false);
1231   }
1232 }
1233 
1234 QString KGameWindow::defenseLabel()
1235 {
1236   if (firstCountry() && firstCountry()->owner() && secondCountry())
1237     return i18np("<font color=\"red\">%2</font> attacks you from <font color=\"red\">%3</font> with 1 army!<br> How do you want to defend <font color=\"blue\">%4</font>?",
1238                         "<font color=\"red\">%2</font> attacks you from <font color=\"red\">%3</font> with %1 armies!<br> How do you want to defend <font color=\"blue\">%4</font>?",
1239                         QString::number(this->firstCountry()->owner()->getNbAttack()),
1240                         this->firstCountry()->owner()->name(),
1241                         this->firstCountry()->name(),
1242                         this->secondCountry()->name());
1243   else
1244     return "";
1245 }
1246 
1247 void KGameWindow::createDefenseDialog()
1248 {
1249   qCDebug(KSIRK_LOG);
1250   // Create Window Dialog
1251   m_defenseDialog = new QDialog ();
1252 
1253   QWidget* widget = new QWidget(m_defenseDialog);
1254   QGridLayout * mainLayout = new QGridLayout(widget);
1255 
1256   // Create the differents layout for buttons and label
1257   QGridLayout * bottomLayout = new QGridLayout();
1258   QGridLayout * topLayout = new QGridLayout();
1259 
1260   // Create and add the main Layout
1261   widget->setLayout(mainLayout);
1262   mainLayout->addLayout(bottomLayout, 1, 0, Qt::AlignCenter);
1263   mainLayout->addLayout(topLayout, 0, 0, Qt::AlignCenter);
1264   
1265   // Creat buttons and label of defense
1266   QPushButton * def1 = new QPushButton (i18n("Defend 1"));
1267   QPushButton * def2 = new QPushButton (i18n("Defend 2"));
1268   QPushButton * defAuto = new QPushButton (i18n("Defend-Auto"));
1269 
1270   m_labDef = new QLabel ();
1271   m_labDef->setText(defenseLabel());
1272 
1273   // Add icons on buttons
1274   QString skin = m_automaton->game()->theWorld()->skin();
1275   QString imageFileName;
1276 
1277   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/defendOne.png");
1278   def1->setIcon(QIcon(imageFileName));
1279   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/defendTwo.png");
1280   def2->setIcon(QIcon(imageFileName));
1281   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/attackAuto.png");
1282   defAuto->setIcon(QIcon(imageFileName));
1283 
1284 
1285   // Disable Defend 2 when attack with 1 army or defender have only 1 army
1286   if (this->firstCountry()->owner()->getNbAttack() == 1)
1287      def2->setEnabled(false);
1288 
1289   // Add buttons and layout
1290   bottomLayout->addWidget(def1,0,0);
1291   bottomLayout->addWidget(def2,0,1);
1292   bottomLayout->addWidget(defAuto,0,2);
1293   topLayout->addWidget(m_labDef, 0, 0);
1294 
1295   connect(def1, SIGNAL(clicked()), this, SLOT(slotWindowDef1()));
1296   connect(def2, SIGNAL(clicked()), this, SLOT(slotWindowDef2()));
1297   connect(defAuto, SIGNAL(clicked()), this, SLOT(slotDefAuto()));
1298 
1299   QVBoxLayout *dialogLayout = new QVBoxLayout(m_defenseDialog);
1300   dialogLayout->addWidget(widget);
1301 }
1302 
1303 void KGameWindow::displayDefenseWindow()
1304 {
1305   qCDebug(KSIRK_LOG);
1306   if (m_defenseDialog == nullptr)
1307     createDefenseDialog();
1308   else
1309     m_labDef->setText(defenseLabel());
1310   m_defenseDialog->exec();
1311 }
1312 
1313 void KGameWindow::startLocalCurrentAI()
1314 {
1315   qCDebug(KSIRK_LOG);
1316   if (currentPlayer() && currentPlayer()-> isAI()  && (!currentPlayer()->isVirtual()))
1317   {
1318     if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning())
1319       (static_cast<AIPlayer *>(currentPlayer()))-> start();
1320   }
1321 }
1322 
1323 void KGameWindow::setBarFlagButton(const Player* player)
1324 {
1325 //   qCDebug(KSIRK_LOG) << "KGameWindow::setBarFlagButton";
1326 
1327   if (player == nullptr)
1328   {
1329     if (currentPlayer() 
1330         && currentPlayer()-> getFlag())
1331     {
1332       if (!m_goalAction->isVisible())
1333         m_goalAction->setVisible(true);
1334       m_goalAction-> setIcon(QIcon(currentPlayer()->getFlag()-> image(0)));
1335       m_goalAction-> setIconText(i18n("Goal"));
1336       m_barFlag-> setPixmap(currentPlayer()->getFlag()-> image(0));
1337       m_barFlag->show();
1338     }
1339   }
1340   else
1341   {
1342     if (player-> getFlag())
1343     {
1344       if (!m_goalAction->isVisible())
1345         m_goalAction->setVisible(true);
1346       m_goalAction-> setIcon(QIcon(player-> getFlag()-> image(0)));
1347       m_goalAction-> setIconText(i18n("Goal"));
1348       m_barFlag-> setPixmap(player->getFlag()-> image(0));
1349       m_barFlag->show();
1350     }
1351   }
1352   m_frame->setFocus();
1353 }
1354 
1355 bool KGameWindow::finishSetupPlayers()
1356 {
1357   qCDebug(KSIRK_LOG);
1358   if (!(m_automaton->playerList()->isEmpty()))
1359   {
1360     m_automaton->playerList()->clear();
1361     m_automaton->currentPlayer(nullptr);
1362     qCDebug(KSIRK_LOG) << "  playerList size = " << m_automaton->playerList()->count();
1363   }
1364   theWorld()->reset();
1365   
1366   QMap< QString, QString > nations = nationsList();
1367   if (!(m_automaton->playerList()->isEmpty()))
1368   {
1369     m_automaton->playerList()->clear();
1370   }
1371   qCDebug(KSIRK_LOG) << "newPlayersNumber = " << m_newGameSetup->players().size();
1372   unsigned int nbAvailArmies = (unsigned int)(m_theWorld->getNbCountries() * 2.5 / m_newGameSetup->players().size());
1373   qCDebug(KSIRK_LOG) << "nbAvailArmies = " << nbAvailArmies << " ; nb countries = " << m_theWorld->getNbCountries();
1374   QString nomEntre = "";
1375   QString password = "";
1376   QString nationName = "";
1377   m_newPlayerWidget->init(m_automaton,m_theWorld,(int)1,nomEntre,password,false,nations,nationName, m_newGameSetup);
1378   m_centralWidget->setCurrentIndex(NEWPLAYER_INDEX);
1379   // Players names
1380   QString mes = "";
1381   if (m_newGameSetup->networkGameType() != GameAutomaton::None)
1382   {
1383     m_frame->setArenaOptionEnabled(false);
1384     unreduceChat();
1385     qCDebug(KSIRK_LOG) << "In setupPlayers: networkGame";
1386     KMessageParts messageParts;
1387     messageParts << I18N_NOOP("Waiting for %1 players to connect")
1388       << QString::number(m_newGameSetup->nbNetworkPlayers());
1389     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1390   }
1391   else
1392   {
1393     m_frame->setArenaOptionEnabled(true);
1394     reduceChat();
1395   }
1396   m_frame->setFocus();
1397   return true;
1398 }
1399 
1400 bool KGameWindow::setupOnePlayer()
1401 {
1402   qCDebug(KSIRK_LOG) << "KGameWindow::setupOnePlayer";
1403   
1404   qCDebug(KSIRK_LOG) << "  building the list of available nations";
1405   QMap< QString, QString > nations = nationsList();
1406   PlayersArray::iterator it = m_automaton->playerList()->begin();
1407   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1408   for (; it != it_end; it++)
1409   {
1410     Player* player = (Player*)(*it);
1411     qCDebug(KSIRK_LOG) << "    removing nation of player " << player-> name();
1412     /// Don't understand why if using Player::getNation below, the method is
1413     /// not executed (get 0) but if using the same named myNation, it works...
1414     /// Ideas anybody ????
1415     Nationality* nation = player-> getNation();
1416     qCDebug(KSIRK_LOG) << "    got player nation " << nation;
1417     QString nationName = nation->name();
1418     QMap<QString,QString>::iterator nationsIt;
1419     nationsIt = nations.find(nationName);
1420     if (nationsIt !=  nations.end())
1421     {
1422       nations.erase(nationsIt);
1423     }
1424   }
1425   qCDebug(KSIRK_LOG) << "  number of available nations: " << nations.size();
1426   unsigned int nbAvailArmies = (unsigned int)(m_theWorld->getNbCountries() * 2.5 / (m_automaton->nbPlayers()));
1427   qCDebug(KSIRK_LOG) << "KGameWindow::setupOnePlayer: nbAvailArmies = " << nbAvailArmies << " ; nb countries = " << m_theWorld->getNbCountries();
1428   // Players names
1429   QString mes = "";
1430   QString nationName;
1431     
1432   QString nomEntre = "";
1433   QString password;
1434   bool computer=false;
1435 
1436   m_newPlayerWidget->init(m_automaton, m_theWorld, 1, nomEntre, password, computer, nations, nationName, m_newGameSetup);
1437   m_centralWidget->setCurrentIndex(NEWPLAYER_INDEX);
1438   return true;
1439 }
1440 
1441 bool KGameWindow::setupOneWaitedPlayer()
1442 {
1443   qCDebug(KSIRK_LOG) << "KGameWindow::setupOneWaitedPlayer";
1444   
1445   QString password;
1446   int result;
1447   KWaitedPlayerSetupDialog(m_automaton, password, result, this).exec();
1448   qCDebug(KSIRK_LOG) << "After KWaitedPlayerSetupDialog. number: " << result << ", password: " << password;
1449   QByteArray buffer;
1450   QDataStream stream(&buffer, QIODevice::WriteOnly);
1451   stream << (quint32)result << password;
1452   m_automaton->sendMessage(buffer,ValidateWaitedPlayerPassword);
1453   return true;
1454 }
1455 
1456 bool KGameWindow::createWaitedPlayer(quint32 waitedPlayerId)
1457 {
1458   qCDebug(KSIRK_LOG) << "KGameWindow::createWaitedPlayer";
1459   
1460   PlayerMatrix& pm = m_waitedPlayers[waitedPlayerId];
1461   Player* player = addPlayer(pm.name, pm.nbAvailArmies,
1462                               pm.nbCountries, pm.nation,
1463                               pm.isAI, pm.password,
1464                               pm.nbAttack, pm.nbDefense);
1465 
1466   player->goal(pm.goal);
1467   QList<QString>::iterator it, it_end;
1468   it = pm.countries.begin(); it_end = pm.countries.end();
1469   for (; it != it_end; it++)
1470   {
1471     QByteArray buffer;
1472     QDataStream stream(&buffer, QIODevice::WriteOnly);
1473     stream << (*it) << pm.name;
1474     m_automaton->sendMessage(buffer,CountryOwner);
1475   }
1476   return true;
1477 }
1478 
1479 void KGameWindow::distributeArmies()
1480 {
1481   qCDebug(KSIRK_LOG) << "KGameWindow::distributeArmies";
1482   PlayersArray::iterator it = m_automaton->playerList()->begin();
1483   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1484   for (; it != it_end; it++)
1485   {
1486     unsigned int nb = nbNewArmies(dynamic_cast<Player*>(*it));
1487 //     qCDebug(KSIRK_LOG) << "    Giving " << nb << " armies to " << static_cast<Player*>(*it)->name();
1488     dynamic_cast<Player*>(*it)-> setNbAvailArmies(nb, true);
1489   }
1490 }
1491 
1492 int KGameWindow::nbNewArmies(Player *player)
1493 {
1494 //    qCDebug(KSIRK_LOG) << "KGameWindow::nbNewArmies for "  << player-> name();
1495 
1496   unsigned int res = 0;
1497 
1498   for (unsigned int i = 0; i<m_theWorld->getNbCountries(); i++)
1499       if (m_theWorld-> getCountries().at(i)-> owner() == player) res++;
1500   res = (res/3) < 3 ? 3 : res/3 ;
1501 
1502   QList<Continent*>& continents = m_theWorld-> getContinents();
1503   QList<Continent*>::iterator it = continents.begin();
1504   for (; it != continents.end(); it++)
1505   {
1506     Continent* currCont = *it;
1507     if (currCont-> owner() == player)
1508     {
1509 //            qCDebug(KSIRK_LOG) << ">>>>>>>>>>> Adding bonus for "  << currCont-> name();
1510       res += currCont-> getBonus();
1511     }
1512   }
1513 
1514   return res;
1515 }
1516 
1517 void KGameWindow::changeItem( const QString& text, int id, bool log )
1518 {
1519   if (id != ID_NO_STATUS_MSG)
1520   {
1521       //QT5 statusBar()-> changeItem(text, id);
1522   }
1523   if (log)
1524   {
1525     KsirkChatItem item;
1526     item << text;
1527 //     m_chatDlg->addMessage("",text);
1528 // to port
1529 //     m_chatDlg->addSystemMessage   ( "", text  ) ;
1530   }
1531 }
1532 
1533 void KGameWindow::changeItem( KMessageParts& strings, int id, bool log )
1534 {
1535 //  qCDebug(KSIRK_LOG) << "KGameWindow::changeItem(KMessageParts,int, log)" << strings.size() << id << log;
1536   if (strings.begin() == strings.end())
1537   {
1538 //     qCDebug(KSIRK_LOG) << "  nothing " << strings.size();
1539     return;
1540   }
1541   bool arguing = false;
1542   KLocalizedString argument;
1543   KsirkChatItem item;
1544   KMessageParts::iterator it, it_end;
1545   it = strings.begin(); it_end = strings.end();
1546   if (it.curIsStr())
1547   {
1548     if (!it.curStr().isEmpty())
1549     {
1550 //       qCDebug(KSIRK_LOG) << "setting argument to: '" << it.curStr() << "'";
1551       argument = ki18n(it.curStr().toUtf8().data());
1552     }
1553     else
1554     {
1555 //       qCDebug(KSIRK_LOG) << "setting argument to empty";
1556       argument = KLocalizedString();
1557     }
1558     arguing = true;
1559   }
1560   else if (it.curIsPix())
1561   {
1562 //     qCDebug(KSIRK_LOG) << "first item is pixmap";
1563     item << it.curPix();
1564   }
1565   
1566   it++;
1567   for (; it != it_end; it++)
1568   {
1569 //     qCDebug(KSIRK_LOG) << "next item";
1570     if (it.curIsStr())
1571     {
1572 //       qCDebug(KSIRK_LOG) << "item is: '" << it.curStr() << "'";
1573       if (arguing)
1574       {
1575 //         qCDebug(KSIRK_LOG) << "  substituting";
1576         argument=argument.subs(it.curStr());
1577       }
1578       else
1579       {
1580 //         qCDebug(KSIRK_LOG) << "  assigning new argument";
1581         if (!it.curStr().isEmpty())
1582         {
1583 //           qCDebug(KSIRK_LOG) << "setting argument to: '" << it.curStr() << "'";
1584           argument = ki18n(it.curStr().toUtf8().data());
1585         }
1586         else
1587         {
1588 //           qCDebug(KSIRK_LOG) << "setting argument to empty";
1589           argument = KLocalizedString();
1590         }
1591         arguing = true;
1592       }
1593     }
1594     else
1595     {
1596       if (arguing)
1597       {
1598 //         qCDebug(KSIRK_LOG) << "  storing";
1599         if (argument.isEmpty())
1600         {
1601           item << QString("");
1602         }
1603         else
1604         {
1605           item << argument.toString();
1606         }
1607       }
1608       item << it.curPix();
1609       arguing = false;
1610     }
1611   }
1612 //   qCDebug(KSIRK_LOG) << "no more items";
1613   if (arguing)
1614   {
1615     if (argument.isEmpty())
1616     {
1617       item << QString("");
1618     }
1619     else
1620     {
1621       item << argument.toString();
1622     }
1623   }
1624   if (log)
1625   {
1626     ((KsirkChatModel*)(m_chatDlg->model()))->addMessage(item);
1627   }
1628   if (id != ID_NO_STATUS_MSG)
1629   {
1630     if (argument.toString() == "(I18N_EMPTY_MESSAGE)")
1631     {
1632       qCCritical(KSIRK_LOG) << "received a (I18N_EMPTY_MESSAGE)";
1633     }
1634 //     qCDebug(KSIRK_LOG) << "  argument: " << argument.toString();
1635     //QT5 statusBar()-> changeItem(argument.toString(), id);
1636   }
1637 }
1638 
1639 void KGameWindow::broadcastChangeItem(KMessageParts& strings, int id, bool log)
1640 {
1641   if (strings.empty())
1642   {
1643     return;
1644   }
1645   QByteArray buffer;
1646   QDataStream stream(&buffer, QIODevice::WriteOnly);
1647 //   qCDebug(KSIRK_LOG) << "Broadcasting change item, size=" << strings.size();
1648   stream << (quint32)id << (quint32)log << (quint32)strings.size();
1649   
1650   KMessageParts::iterator it, it_end;
1651   it = strings.begin(); it_end = strings.end();
1652   if (it != it_end)
1653   {
1654 /*    // if first element is string, convert it to id 
1655     if (it.curIsStr())
1656     {
1657       qCDebug(KSIRK_LOG) << "Pushing first element: id "<<m_automaton->idForMsg(it.curStr())<<" for '" << it.curStr() << "'";
1658       stream << (quint32)KMessageParts::StringId << m_automaton->idForMsg(it.curStr());
1659     }
1660     else if (it.curIsPix())
1661     {
1662       qCDebug(KSIRK_LOG) << "Pushing first element pix";
1663       stream << (quint32)KMessageParts::Pixmap << it.curPix();
1664     }
1665     else
1666     {
1667       qCCritical(KSIRK_LOG) << "Unsupported KMessageParts elem type ";
1668     }
1669     it++;*/
1670     for (; it != it_end; it++)
1671     {
1672       if (it.curIsStr())
1673       {
1674 //         qCDebug(KSIRK_LOG) << "Pushing string '" << it.curStr() << "'";
1675         stream << (quint32)KMessageParts::Text << it.curStr();
1676       }
1677       else if (it.curIsPix())
1678       {
1679 //         qCDebug(KSIRK_LOG) << "Pushing pix";
1680         stream << (quint32)KMessageParts::Pixmap << it.curPix();
1681       }
1682       else
1683       {
1684         qCCritical(KSIRK_LOG) << "Unsupported KMessageParts elem type ";
1685       }
1686     }
1687   }
1688   m_automaton->sendMessage(buffer,ChangeItem);
1689   changeItem(strings, id, log );
1690 }
1691 
1692 void KGameWindow::enterEvent(QEvent* /*ev*/)
1693 {
1694 //   qCDebug(KSIRK_LOG) << "KGameWindow::enterEvent()";
1695   // Restart the AIs threads
1696   if ( currentPlayer() )
1697     if ( (currentPlayer()-> isAI()) && (!currentPlayer()->isVirtual()) && ( !((static_cast<AIPlayer*>(currentPlayer()))-> isRunning())) )
1698       (static_cast<AIPlayer*>(currentPlayer()))-> start();
1699           
1700 }
1701 
1702 void KGameWindow::leaveEvent(QEvent* /*ev*/)
1703 {
1704 //    qCDebug(KSIRK_LOG) << "KGameWindow::leaveEvent()";
1705     // Stops the AIs threads
1706   PlayersArray::iterator it = m_automaton->playerList()->begin();
1707   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1708   for (; it != it_end; it++)
1709   {
1710     if (static_cast<Player*>(*it)-> isAI())
1711     {
1712         (static_cast<AIPlayer*>(*it))-> stop();
1713     }
1714   }
1715 }
1716 
1717 
1718 /** Return true if the state of the game is the argument; false otherwise */
1719 bool KGameWindow::isMyState(GameLogic::GameAutomaton::GameState state) const
1720 {
1721   return (m_automaton->state() == state);
1722 }
1723 
1724 /**
1725   * returns the current state of the game
1726   */
1727 GameLogic::GameAutomaton::GameState KGameWindow::getState() const
1728 {
1729   return m_automaton->state();
1730 }
1731 
1732 void KGameWindow::moveArmies(Country& src, Country& dest, unsigned int nb)
1733 {
1734 //    qCDebug(KSIRK_LOG) << "KGameWindow::moveArmies()";
1735   if ((src.owner() == currentPlayer())
1736       && (dest.owner() == currentPlayer())
1737       && (src.communicateWith(&dest))
1738       && (src.nbArmies() > nb) )
1739   {
1740     QByteArray bufferSrc;
1741     QDataStream streamSrc(&bufferSrc, QIODevice::WriteOnly);
1742     streamSrc << src.name();
1743     m_automaton->sendMessage(bufferSrc,FirstCountry);
1744     
1745     QByteArray bufferDest;
1746     QDataStream streamDest(&bufferDest, QIODevice::WriteOnly);
1747     streamDest << src.name();
1748     m_automaton->sendMessage(bufferDest,SecondCountry);
1749     
1750     int toMove = nb;
1751     while ( toMove >= 10 )
1752     {
1753       toMove -= 10;
1754       slotInvade10();
1755     }
1756     while ( toMove >= 5 )
1757     {
1758       toMove -= 5;
1759       slotInvade5();
1760     }
1761     while ( toMove >= 1 )
1762     {
1763       toMove -= 1;
1764       slotInvade1();
1765     }
1766   }
1767 //    qCDebug(KSIRK_LOG) << "OUT KGameWindow::moveArmies()";
1768 }
1769 
1770 bool KGameWindow::isMoveValid(const QPointF& point)
1771 {
1772   bool res = false;
1773   KMessageParts messageParts;
1774   Country* secondCountry = clickIn(point); 
1775   if  ( ( m_firstCountry == nullptr ) || ( secondCountry == nullptr ) )
1776   {
1777     messageParts << I18N_NOOP("There is no country here!");
1778   }
1779   else if  ( m_firstCountry->owner() != currentPlayer() )
1780   {
1781     messageParts << I18N_NOOP("You are not the owner of the first country: %1!") << m_firstCountry->name();
1782   }
1783   else if ( secondCountry->owner() != currentPlayer() )
1784   {
1785     messageParts << I18N_NOOP("You are not the owner of the second country: %1!") << secondCountry->name();
1786   }
1787   else if (m_firstCountry == secondCountry)
1788   {
1789     messageParts << I18N_NOOP("You are trying to move armies from %1 to itself!") << m_firstCountry->name();
1790   }
1791   else if (!m_firstCountry->communicateWith(secondCountry))
1792   {
1793     messageParts
1794       << I18N_NOOP("%1 is not a neighbour of %2!") 
1795       << secondCountry-> name() 
1796       << m_firstCountry-> name();
1797   }
1798   else 
1799   {
1800     messageParts << I18N_NOOP("Moving armies from %1 to %2.") 
1801             << m_firstCountry->name() 
1802             << secondCountry->name();
1803     res = true;
1804   }
1805   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1806   return res;    
1807 }
1808 
1809 bool KGameWindow::isFightValid(const QPointF& point)
1810 {
1811   bool res = false;
1812   KMessageParts messageParts;
1813   Country* secondCountry = clickIn(point); 
1814   if  ( ( m_firstCountry == nullptr ) || ( secondCountry == nullptr ) )
1815   {
1816     qCDebug(KSIRK_LOG) << "There is no country here!";
1817     messageParts << I18N_NOOP("There is no country here!");
1818   }
1819   else if  ( m_firstCountry->owner() != currentPlayer() )
1820   {
1821     qCDebug(KSIRK_LOG) << "You are not the owner of the first country: "<< m_firstCountry->name();
1822     messageParts << I18N_NOOP("You are not the owner of the first country: %1!")
1823             << m_firstCountry->name();
1824   }
1825   else if ( secondCountry->owner() == currentPlayer() )
1826   {
1827     qCDebug(KSIRK_LOG) << "You are the owner of the second country: " << secondCountry->name();
1828     messageParts << I18N_NOOP("You are the owner of the second country: %1!") << secondCountry->name();
1829   }
1830   else if (m_firstCountry == secondCountry)
1831   {
1832     qCDebug(KSIRK_LOG) <<"You are trying to move armies from "<<m_firstCountry->name()<<" to itself ";
1833     messageParts << I18N_NOOP("You are trying to move armies from %1 to itself!") << m_firstCountry->name();
1834   }
1835   else if (!m_firstCountry->communicateWith(secondCountry))
1836   {
1837     qCDebug(KSIRK_LOG) << secondCountry-> name() << "is not a neighbour of " << secondCountry-> name();
1838     messageParts 
1839       << I18N_NOOP("%1 is not a neighbour of %2!") 
1840       << secondCountry-> name() 
1841       << m_firstCountry-> name();
1842   }
1843   else 
1844   {
1845     qCDebug(KSIRK_LOG) << "Ready to fight !";
1846     messageParts << I18N_NOOP("Ready to fight!");
1847     res = true;
1848   }
1849   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1850   return res;    
1851 }
1852 
1853 int KGameWindow::setCurrentPlayerToFirst()
1854 {
1855   if (currentPlayer() && currentPlayer()->isAI() 
1856                       && (static_cast<AIPlayer *>(currentPlayer())->isRunning()))
1857   {
1858         static_cast<AIPlayer *>(currentPlayer())->stop();
1859   }
1860   m_automaton->currentPlayer((Player*)(*m_automaton->playerList()->begin()));
1861 
1862 /*  if (currentPlayer() && currentPlayer()->isAI() && !currentPlayer()->isVirtual()
1863       && !(static_cast<AIPlayer *>(currentPlayer())->isRunning()))
1864   {
1865           static_cast<AIPlayer *>(currentPlayer())->start();
1866           qCDebug(KSIRK_LOG) <<"setCurrentPlayerToFirst : step 3";
1867   }*/
1868   m_frame->setFocus();
1869   return 0;
1870 }
1871 
1872 int KGameWindow::setCurrentPlayerToNext(bool restartRunningAIs)
1873 {
1874   qCDebug(KSIRK_LOG) << restartRunningAIs;
1875   m_rightDock->hide();
1876   int looped(0);
1877 //   qCDebug(KSIRK_LOG) << "KGameWindow::setCurrentPlayerToNext()";
1878   if ( currentPlayer() && ( currentPlayer()-> isAI())  && ( static_cast<AIPlayer *>(currentPlayer())-> isRunning() ) )
1879       static_cast<AIPlayer *>(currentPlayer())-> stop();
1880   
1881   PlayersArray::iterator it = m_automaton->playerList()->begin();
1882   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1883   for (;it != it_end; it++)
1884   {
1885     if (*it == currentPlayer())
1886     {
1887       it++;
1888       break;
1889     }
1890   }
1891   if (it == it_end)
1892   {
1893       setCurrentPlayerToFirst();
1894       looped = 1;
1895   }
1896   else
1897   {
1898     m_automaton->currentPlayer((Player*)(*it));
1899   }
1900 
1901   if ( restartRunningAIs && currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()) && !looped)
1902   {
1903     if ( ! (static_cast< AIPlayer* >(currentPlayer())-> isRunning()))
1904     {
1905       static_cast< AIPlayer* >(currentPlayer())-> start();
1906     }
1907   }
1908 
1909   if ( currentPlayer()->isAI() || currentPlayer()->isVirtual() )
1910   {
1911     m_nextPlayerAction->setEnabled(false);
1912   }
1913   else
1914   {
1915     m_nextPlayerAction->setEnabled(true);
1916   }
1917   
1918   qCDebug(KSIRK_LOG) << "New current player is " << currentPlayer()->name() << " ; return value is " << looped;
1919   return looped;
1920 }
1921 
1922 bool KGameWindow::terminateAttackSequence()
1923 {
1924   if (m_firstCountry != nullptr)
1925     m_firstCountry->clearHighlighting();
1926   if (m_secondCountry != nullptr)
1927     m_secondCountry->clearHighlighting();
1928   if (m_animFighters != nullptr)
1929     m_animFighters->hideAndRemoveAll();
1930   return attackEnd();
1931 }
1932 
1933 bool KGameWindow::attacker(const QPointF& point)
1934 {
1935   qCDebug(KSIRK_LOG);
1936   Country* clickedCountry = clickIn(point);
1937   KMessageParts messageParts;
1938   if (clickedCountry == nullptr)
1939   {
1940     messageParts << I18N_NOOP("<font color=\"orange\">No country here!</font>");
1941     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1942     clearHighlighting();
1943     return false;
1944   }
1945 
1946   if (clickedCountry-> owner() != currentPlayer())
1947   {
1948     messageParts << I18N_NOOP("<font color=\"orange\">You are not the owner of %1!</font>")  << clickedCountry-> name();
1949     clearHighlighting();
1950     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1951     return false;
1952   }
1953   else if (clickedCountry-> nbArmies() <= currentPlayer()-> getNbAttack())
1954   {
1955     messageParts << I18N_NOOP("<font color=\"orange\">There is only %1 armies in %2!</font>") 
1956       << QString::number(clickedCountry-> nbArmies())
1957       << clickedCountry-> name();
1958     clearHighlighting();
1959     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1960     return false;
1961   }
1962   else
1963   {
1964     QByteArray buffer;
1965     QDataStream stream(&buffer, QIODevice::WriteOnly);
1966     stream << clickedCountry->name();
1967     m_automaton->sendMessage(buffer,FirstCountry);
1968     QByteArray buffer2;
1969     QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1970     stream2 << "";
1971     m_automaton->sendMessage(buffer2,SecondCountry);
1972 
1973     QPixmap pm = currentPlayer()->getFlag()->image(0);
1974     /*messageParts
1975       << pm
1976       << I18N_NOOP("%1 attacks from %2 with <font color=\"red\">%3 armies</font>") 
1977       << currentPlayer()-> name()
1978       << clickedCountry-> name()
1979       << QString::number(currentPlayer()-> getNbAttack());
1980     broadcastChangeItem(messageParts, ID_STATUS_MSG2);*/
1981     return true;
1982   }
1983 }
1984 
1985 unsigned int KGameWindow::attacked(const QPointF& point)
1986 {
1987   qCDebug(KSIRK_LOG) << point << (void*)m_firstCountry << (void*)m_secondCountry;
1988   //if (currentPlayer()-> isAI()) return 3;
1989   // executed on the admin side only
1990   if (!m_automaton->isAdmin()) return 3;
1991 
1992   unsigned int res = 0;
1993   //Country* secondCountry = clickIn(point);
1994   //m_secondCountry = secondCountry;
1995   KMessageParts messageParts;
1996 
1997 //   qCDebug(KSIRK_LOG) << "2nd country is now set";
1998   if ( (m_firstCountry == nullptr) || (m_secondCountry == nullptr)
1999           || (m_firstCountry-> owner() != currentPlayer()) )
2000   {
2001     qCDebug(KSIRK_LOG) << ("Nothing to attack !");
2002     QByteArray buffer;
2003     QDataStream stream(&buffer, QIODevice::WriteOnly);
2004     m_automaton->sendMessage(buffer,ClearHighlighting);
2005   }
2006   else if (!m_secondCountry-> owner())
2007   {
2008     qCDebug(KSIRK_LOG) << ("Invalid attacked country.");
2009     QByteArray buffer;
2010     QDataStream stream(&buffer, QIODevice::WriteOnly);
2011     m_automaton->sendMessage(buffer,ClearHighlighting);
2012   }
2013 /*  else if (!m_secondCountry-> owner()->isVirtual())
2014   {
2015     // messageParts << I18N_NOOP("Invalid attacked country.");
2016     return 3;
2017   }*/
2018   else if (m_firstCountry == m_secondCountry)
2019   {
2020    qCDebug(KSIRK_LOG) << ("You are trying to attack %1 from itself !") << m_firstCountry-> name();
2021     QByteArray buffer;
2022     QDataStream stream(&buffer, QIODevice::WriteOnly);
2023     m_automaton->sendMessage(buffer,ClearHighlighting);
2024   }
2025   else if (!m_firstCountry-> communicateWith(m_secondCountry))
2026   {
2027     qCDebug(KSIRK_LOG) << ("%1 is not a neighbour of %2 !") << m_secondCountry-> name() << m_firstCountry-> name();
2028     QByteArray buffer;
2029     QDataStream stream(&buffer, QIODevice::WriteOnly);
2030     m_automaton->sendMessage(buffer,ClearHighlighting);
2031   }
2032   else if (m_firstCountry-> owner() == m_secondCountry-> owner())
2033   {
2034     qCDebug(KSIRK_LOG) << ("%1! You cannot attack %2! It is yours!") << currentPlayer()-> name()
2035            << m_secondCountry-> name();
2036     QByteArray buffer;
2037     QDataStream stream(&buffer, QIODevice::WriteOnly);
2038     m_automaton->sendMessage(buffer,ClearHighlighting);
2039   }
2040   else if (m_firstCountry-> owner() != currentPlayer()) 
2041   {
2042     qCDebug(KSIRK_LOG) << ("%1 ! You are not the owner of %2!") << currentPlayer()-> name() << m_firstCountry-> name();
2043     QByteArray buffer;
2044     QDataStream stream(&buffer, QIODevice::WriteOnly);
2045     m_automaton->sendMessage(buffer,ClearHighlighting);
2046   }
2047   else if (m_firstCountry->nbArmies() - currentPlayer()->getNbAttack() < 1)
2048   {
2049    qCDebug(KSIRK_LOG)
2050       << ("%1, you have to keep one army to defend %2.")
2051       << m_firstCountry->owner()-> name()
2052       << m_firstCountry-> name();
2053     QByteArray buffer;
2054     QDataStream stream(&buffer, QIODevice::WriteOnly);
2055     m_automaton->sendMessage(buffer,ClearHighlighting);
2056   }
2057   else if (m_secondCountry-> nbArmies() > 1)
2058   {
2059     QByteArray buffer;
2060     QDataStream stream(&buffer, QIODevice::WriteOnly);
2061     if (m_secondCountry != nullptr)
2062     {
2063       stream << m_secondCountry->name();
2064     }
2065     else
2066     {
2067       stream << QString("");
2068     }
2069     m_automaton->sendMessage(buffer,SecondCountry);
2070 
2071     qCDebug(KSIRK_LOG)
2072         << ("%1, with how many armies do you defend %2 ?")
2073         << m_secondCountry->owner()-> name()
2074         << m_secondCountry-> name();
2075     QByteArray buffer2;
2076     QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2077     stream2 << m_secondCountry->owner()->name();
2078     m_automaton->sendMessage(buffer2,DisplayDefenseButtons);
2079     res = 1;
2080   }
2081   else
2082   {
2083     QByteArray buffer;
2084     QDataStream stream(&buffer, QIODevice::WriteOnly);
2085     if (m_secondCountry != nullptr)
2086     {
2087       stream << m_secondCountry->name();
2088     }
2089     else
2090     {
2091       stream << QString("");
2092     }
2093     m_automaton->sendMessage(buffer,SecondCountry);
2094     messageParts
2095       << I18N_NOOP("%1, you defend with the only army you have in %2.") 
2096       << m_secondCountry->owner()-> name()
2097       << m_secondCountry-> name();
2098     res = 2;
2099   }
2100   qCDebug(KSIRK_LOG) << "will change item";
2101   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2102   qCDebug(KSIRK_LOG) << "change item broadcasted; returning " << res;
2103   return res;
2104 }
2105 
2106 bool KGameWindow::firstCountryAt(const QPointF& point)
2107 {
2108   Country* c = clickIn(point);
2109   if (c)
2110   {
2111     if (c-> owner() == currentPlayer())
2112     {
2113       QByteArray buffer;
2114       QDataStream stream(&buffer, QIODevice::WriteOnly);
2115       stream << c->name();
2116       m_automaton->sendMessage(buffer,FirstCountry);
2117       return true;
2118     }
2119   }
2120   return false;
2121 }
2122 
2123 bool KGameWindow::secondCountryAt(const QPointF& point)
2124 {
2125   if (clickIn(point))
2126   {
2127     QByteArray buffer;
2128     QDataStream stream(&buffer, QIODevice::WriteOnly);
2129     stream << clickIn(point)->name();
2130     m_automaton->sendMessage(buffer,SecondCountry);
2131     return true;
2132   }
2133   return false;
2134 }
2135 
2136 bool KGameWindow::playerPutsArmy(const QPointF& point, bool removable)
2137 {
2138   qCDebug(KSIRK_LOG) << removable;
2139   Country* clickedCountry = clickIn(point);
2140 
2141   if (clickedCountry)
2142   {
2143     qCDebug(KSIRK_LOG) << "clickedCountry name=" << clickedCountry->name() ;
2144     qCDebug(KSIRK_LOG) << "clickedCountry owner=" << clickedCountry-> owner()->name();
2145     qCDebug(KSIRK_LOG) << "currentPlayer=" << currentPlayer()->name();
2146     unsigned int nbAvailArmies = currentPlayer()->getNbAvailArmies();
2147     qCDebug(KSIRK_LOG) << "nbAvailArmies=" << nbAvailArmies;
2148     if (clickedCountry->owner() == currentPlayer() &&  nbAvailArmies > 0)
2149     {
2150       nbAvailArmies--;
2151       qCDebug(KSIRK_LOG) << "owner new available armies=" << nbAvailArmies;
2152       currentPlayer()->putArmiesInto(1, theWorld()->indexOfCountry(clickedCountry));
2153       clickedCountry-> incrNbArmies();
2154       clickedCountry-> createArmiesSprites();
2155       QPixmap pm = currentPlayer()->getFlag()->image(0);
2156       KMessageParts messageParts;
2157       messageParts 
2158         << pm 
2159         << I18N_NOOP("%1: %2 armies to place") 
2160         << currentPlayer()-> name()
2161         << QString::number(nbAvailArmies);
2162       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2163 
2164       getRightDialog()->updateRecycleDetails(clickedCountry,false,nbAvailArmies);
2165 
2166       if (m_automaton->isAdmin())
2167       {
2168         m_automaton->checkGoal();
2169       }
2170     }
2171   }
2172   return false;
2173 }
2174 
2175 bool KGameWindow::playerPutsInitialArmy(const QPointF& point)
2176 {
2177   {
2178     qCDebug(KSIRK_LOG) << point;
2179     Country* clickedCountry = clickIn(point);
2180     
2181     if ( (clickedCountry) )
2182     {
2183       qCDebug(KSIRK_LOG) << "clickedCountry name=" << clickedCountry->name() ;
2184       qCDebug(KSIRK_LOG) << "clickedCountry owner=" << clickedCountry-> owner()->name();
2185       qCDebug(KSIRK_LOG) << "clickedCountry had armies=" << clickedCountry-> nbArmies();
2186       qCDebug(KSIRK_LOG) << "currentPlayer=" << currentPlayer()->name();
2187       qCDebug(KSIRK_LOG) << "nbAvailArmies=" << currentPlayer()->getNbAvailArmies();
2188       
2189       if (
2190            (clickedCountry-> owner() == currentPlayer()) &&
2191            (((GameLogic::Player*)currentPlayer())-> getNbAvailArmies() > 0))
2192       {
2193         unsigned int currentAvailArmiesNumber = ((GameLogic::Player*)currentPlayer())-> getNbAvailArmies() - 1;
2194         bool last = (currentAvailArmiesNumber == 0);
2195         currentPlayer()->putArmiesInto(1, theWorld()->indexOfCountry(clickedCountry));
2196         qCDebug(KSIRK_LOG) << "owner new available armies=" << currentAvailArmiesNumber;
2197         clickedCountry-> incrNbArmies();
2198         clickedCountry-> createArmiesSprites();
2199 
2200         if ( last )
2201         {
2202           if (m_automaton->isAdmin())
2203           {
2204             PlayersArray::iterator it = m_automaton->playerList()->begin();
2205             PlayersArray::iterator it_end = m_automaton->playerList()->end();
2206             for (;it != it_end; it++)
2207             {
2208               if (*it == currentPlayer())
2209               {
2210                 it++;
2211                 break;
2212               }
2213             }
2214             if (it != it_end)
2215             {
2216               QPixmap pm= ((Player*)(*it))->getFlag()->image(0);
2217 
2218              /* KMessageParts messageParts;
2219               messageParts
2220                 << pm
2221                 << I18N_NOOP("%1: %2 armies to place") << ((Player*)(*it))-> name()
2222                 << QString::number(((Player*)(*it))-> getNbAvailArmies());
2223               broadcastChangeItem(messageParts, ID_STATUS_MSG2);*/
2224 /*            m_nbAvailArmies = ((Player*)(*it))-> getNbAvailArmies();
2225               QByteArray buffer;
2226               QDataStream stream(&buffer, QIODevice::WriteOnly);
2227               stream << (quint32)m_nbAvailArmies;
2228               m_automaton->sendMessage(buffer,KGameWinAvailArmies);*/
2229               getRightDialog()->close();
2230 
2231               QByteArray buffer2;
2232               QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2233               stream2 << ((GameLogic::Player*)(*it))->name();
2234               stream2 << (quint32) ((GameLogic::Player*)(*it))->getNbAvailArmies();
2235               qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2236                 << ((Player*)(*it))->name() << (quint32) ((GameLogic::Player*)(*it))->getNbAvailArmies()
2237                 << " at " << __FILE__ << ", line " << __LINE__;
2238               m_automaton->sendMessage(buffer2,DisplayRecycleDetails);
2239             }
2240             int ret = setCurrentPlayerToNext();
2241             setContextualHelpActionEnabled(getState(), currentPlayer() && currentPlayer()->isAI());
2242             return ret;
2243           }
2244           else
2245           {
2246             return false;
2247           }
2248         }
2249         else
2250         {
2251           getRightDialog()->updateRecycleDetails(clickedCountry,false,(quint32) ((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies());
2252           QPixmap pm = currentPlayer()->getFlag()->image(0);
2253           KMessageParts messageParts;
2254           messageParts << pm << I18N_NOOP("%1: %2 armies to place") 
2255             << currentPlayer()-> name()
2256             << QString::number((quint32) ((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies());
2257           changeItem(messageParts, ID_STATUS_MSG2, false);
2258         }
2259       }
2260     }
2261     return false;
2262   }
2263 }
2264 
2265 bool KGameWindow::playerRemovesArmy(const QPointF& point)
2266 {
2267   qCDebug(KSIRK_LOG) << point;
2268   
2269   Country *clickedCountry = clickIn(point);
2270   qCDebug(KSIRK_LOG) << "  currentPlayer=" << currentPlayer()->name();
2271   if (clickedCountry == nullptr)
2272   {
2273     return false;
2274   }
2275   qCDebug(KSIRK_LOG) << "  owner=" << clickedCountry-> owner()->name();
2276   qCDebug(KSIRK_LOG) << "  nbArmies=" << clickedCountry->nbArmies();
2277   qCDebug(KSIRK_LOG) << "  canRemoveArmiesFrom=" << clickedCountry-> owner()->canRemoveArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) );
2278   if ( clickedCountry
2279       && ( clickedCountry-> owner() == currentPlayer() )
2280       && ( clickedCountry-> nbArmies() > 1)
2281       && ( clickedCountry-> owner()->canRemoveArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) ) )
2282   )
2283   {
2284     clickedCountry-> owner()->removeArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) );
2285     unsigned int newNbAvailArmies = currentPlayer()-> getNbAvailArmies() /*+ 1*/;
2286 
2287     if ( m_automaton->isAdmin() )
2288     {
2289       QPixmap pm = currentPlayer()->getFlag()->image(0);
2290       KMessageParts messageParts;
2291       messageParts <<pm<< I18N_NOOP("%1: %2 armies to place") << currentPlayer()-> name() 
2292         << QString::number(newNbAvailArmies);
2293       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2294     }
2295     clickedCountry-> decrNbArmies();
2296     clickedCountry-> createArmiesSprites();
2297 
2298     getRightDialog()->updateRecycleDetails(clickedCountry,false,newNbAvailArmies);
2299     return true;
2300   }
2301   return false;
2302 }
2303 
2304 /**
2305   * @brief setups window for recycling
2306   */
2307 void KGameWindow::initRecycling()
2308 {
2309   qCDebug(KSIRK_LOG) << "Initiating recycling";
2310   m_nextPlayerAction->setEnabled(false);
2311 
2312   setCurrentPlayerToFirst();
2313   QByteArray buffer;
2314   QDataStream stream(&buffer, QIODevice::WriteOnly);
2315   stream << quint32(0);
2316   m_automaton->sendMessage(buffer,DisplayRecyclingButtons);
2317   
2318   KMessageParts messageParts;
2319   messageParts << I18N_NOOP("Exchange armies again or continue?");
2320   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2321 }
2322 
2323 void KGameWindow::clear()
2324 {
2325   m_nbMovedArmies = 0;
2326   m_firstCountry = m_secondCountry = nullptr;
2327   NKD = NKA = 0;
2328   if (m_message !=nullptr)
2329   {
2330     delete m_message;
2331   }
2332   m_message = nullptr;
2333 }
2334 
2335 bool KGameWindow::nextPlayerRecycling()
2336 {
2337   qCDebug(KSIRK_LOG);
2338   m_nextPlayerAction->setEnabled(false);
2339   if ( currentPlayer() && currentPlayer()-> getNbAvailArmies() > 0)
2340   {
2341     qCDebug(KSIRK_LOG) << "You must distribute all your armies";
2342     if (!currentPlayer()->isVirtual() && !currentPlayer()->isAI())
2343     {
2344       KMessageBox::error(nullptr, i18n("You must distribute\nall your armies"), i18n("KsirK"));
2345     }
2346     return false;
2347   }
2348   else
2349   {
2350     m_rightDock->hide();
2351     if (currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()))
2352     {
2353       if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning()) (static_cast<AIPlayer *>(currentPlayer()))-> start();
2354       m_nextPlayerAction->setEnabled(false);
2355     }
2356     else if (currentPlayer() && !currentPlayer()->isVirtual())
2357     {
2358       m_nextPlayerAction->setEnabled(true);
2359     }
2360     else
2361     {
2362       m_nextPlayerAction->setEnabled(false);
2363     }
2364     return true;
2365   }
2366 }
2367 
2368 /** 
2369   * @return if true next state will be NEWARMIES else it will be WAIT
2370   */
2371 bool KGameWindow::nextPlayerNormal()
2372 {
2373   qCDebug(KSIRK_LOG) << " (current is" << currentPlayer()->name()<<")";
2374   setCurrentPlayerToNext();
2375   distributeArmies();
2376 
2377   QByteArray buffer;
2378   m_automaton->sendMessage(buffer,ShowArmiesToPlace);
2379 
2380   clear();
2381   QByteArray buffer2;
2382   m_automaton->sendMessage(buffer2,StartLocalCurrentAI);
2383   getRightDialog()->close();
2384 
2385   QByteArray buffer3;
2386   QDataStream stream3(&buffer3, QIODevice::WriteOnly);
2387   stream3 << currentPlayer()-> name();
2388   stream3 << (quint32)nbNewArmies(currentPlayer());
2389   qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2390       << currentPlayer()->name() << nbNewArmies(currentPlayer())
2391       << " at " << __FILE__ << ", line " << __LINE__;
2392   m_automaton->sendMessage(buffer3,DisplayRecycleDetails);
2393   return true;
2394 }
2395 
2396 void KGameWindow::centerOnFight()
2397 {
2398   qCDebug(KSIRK_LOG);
2399 
2400   qreal aj=m_rightDialog->width();    //get the width of the right widget
2401   qreal ay=m_chatDlg->height();      //get the height of the bottom widget
2402 
2403 //Larg
2404   if (m_firstCountry==nullptr || m_secondCountry==nullptr)
2405   {
2406     qCCritical(KSIRK_LOG) << "countries should not be null ("<<(void*)m_firstCountry<<","<<(void*)m_secondCountry<<") at "<<__FILE__<<", line "<<__LINE__;
2407     return;
2408   }
2409   qreal larg=((m_secondCountry->centralPoint().x())-(m_firstCountry->centralPoint().x()));
2410   if (larg<0)
2411   {
2412    larg=-larg;    //si negatif alors on remet en positif
2413   }
2414 //Long
2415   qreal longu=((m_secondCountry->centralPoint().y())-(m_firstCountry->centralPoint().y()));
2416   if (longu<0)
2417   {
2418    longu=-longu;    //si negatif alors on remet en positif
2419   }
2420 //Point NordOuest
2421   qreal minx=m_secondCountry->centralPoint().x();  
2422   qreal miny=m_secondCountry->centralPoint().y();
2423   if (minx>m_firstCountry->centralPoint().x())
2424   {
2425   minx=m_firstCountry->centralPoint().x();
2426   }
2427   if (miny>m_firstCountry->centralPoint().y())
2428   {
2429   miny=m_firstCountry->centralPoint().y();
2430   }
2431 
2432   QSizeF size (larg,longu);   //creation de la size  (2x la largeur entre les deux pays)
2433   QPointF NO (minx,miny);  //creation du point Nord Ouest
2434   QRectF rect(NO,size);    //creation du rect
2435   m_frame->ensureVisible(rect);
2436 
2437 // centering on the middle point
2438   qreal xx=((m_secondCountry->centralPoint().x())+(m_firstCountry->centralPoint().x()))/2;
2439   if (xx<0)
2440   {
2441    xx=-xx;    //si negatif alors on remet en positif
2442   }
2443   qreal yy=((m_secondCountry->centralPoint().y())+(m_firstCountry->centralPoint().y()))/2;
2444   if (yy<0)
2445   {
2446    yy=-yy;    //si negatif alors on remet en positif
2447   }
2448 
2449   QPointF mid (xx,yy);
2450   m_frame->centerOn(mid);      //center on the point
2451 
2452   m_frame->translate(-aj/2,-ay/2);  //translate to center perfectly
2453 //end Benjamin M.
2454 
2455 
2456 }
2457 void KGameWindow::attack(unsigned int nb)
2458 {  
2459   centerOnFight();        //center the view on the fight Benj
2460   
2461   currentPlayer()-> setNbAttack(nb);
2462   /*KMessageParts messageParts;
2463   messageParts << I18N_NOOP("Attack with %1 armies: designate the belligerants") 
2464     << QString::number(nb);
2465   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);*/
2466   /*
2467   showMessage(i18n("To attack, press the mouse button in the attacking country<br>and then <b>drag and drop</b> on its neighbour your want to attack."), 5);
2468   */
2469 }
2470 
2471 void KGameWindow::defense(unsigned int nb)
2472 {
2473   qCDebug(KSIRK_LOG);
2474 
2475   if (!m_firstCountry) // anything left to do?
2476      return;
2477 
2478   m_secondCountry-> owner()-> setNbDefense(nb);
2479   
2480   QPixmap pmA = m_firstCountry-> owner()->getFlag()->image(0);
2481   QPixmap pmD = m_secondCountry-> owner()->getFlag()->image(0);
2482 
2483   KMessageParts messageParts;
2484   messageParts << I18N_NOOP("Battle ongoing.");
2485 //     << I18N_NOOP("Battle between <font color=\"red\">%1</font> (")
2486 //     << m_firstCountry-> name()
2487 //     << pmA
2488 //     << I18N_NOOP("%1) <font color=\"red\">with %2 armies</font> and <font color=\"blue\">%3</font> (")
2489 //     << m_firstCountry->owner()->name()
2490 //     << QString::number(currentPlayer()-> getNbAttack())
2491 //     << m_secondCountry-> name()
2492 //     << pmD
2493 //     << I18N_NOOP("%1) <font color=\"blue\">with %2 armies</font>.") 
2494 //     << m_secondCountry->owner()->name()
2495 //     << QString::number(nb);
2496 
2497   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2498 
2499   if (m_firstCountry-> owner() && m_firstCountry-> owner()-> getFlag())
2500   {
2501     if (!m_goalAction->isVisible())
2502       m_goalAction->setVisible(true);
2503     m_goalAction-> setIcon(QIcon(m_firstCountry-> owner()->getFlag()-> image(0)));
2504     m_goalAction-> setIconText(i18n("Goal"));
2505     m_barFlag-> setPixmap(m_firstCountry-> owner()->getFlag()-> image(0));
2506   }
2507   if (m_automaton->isAdmin())
2508   {
2509     QByteArray buffer;
2510     QDataStream stream(&buffer, QIODevice::WriteOnly);
2511     m_automaton->sendMessage(buffer,InitCombatMovement);
2512     m_automaton->state(GameLogic::GameAutomaton::FIGHT_BRING);
2513   }
2514 }
2515 
2516 int KGameWindow::nbMovedArmies()
2517 {
2518   return m_nbMovedArmies;
2519 }
2520 
2521 void KGameWindow::incrNbMovedArmies(unsigned int nb)
2522 {
2523   m_nbMovedArmies += nb;
2524 }
2525 
2526 void KGameWindow::decrNbMovedArmies(unsigned int nb)
2527 {
2528   m_nbMovedArmies -= nb;
2529 }
2530 
2531 bool KGameWindow::invade(unsigned int nb )
2532 {
2533   if (m_firstCountry==nullptr || m_secondCountry==nullptr)
2534   {
2535     qCDebug(KSIRK_LOG) << "invade("<<nb<<") returns " << false;
2536     return false;
2537   }
2538   bool res = initArmiesMovement(nb, m_firstCountry, m_secondCountry);
2539   qCDebug(KSIRK_LOG) << "invade("<<nb<<") returns " << res;
2540   return res;
2541 }
2542 
2543 AnimSprite* KGameWindow::simultaneousAttack(int nb, FightType state)
2544 {
2545   qCDebug(KSIRK_LOG) << nb << state << relativePosInArenaAttack << relativePosInArenaDefense;
2546   AnimSprite* res;
2547 
2548   if (state == Attack)
2549   {
2550     QPointF pointAttaquant(0,0);
2551     QPointF pointDefenseur(0,0);
2552     determinePointArriveeForArena(relativePosInArenaAttack, pointAttaquant,pointDefenseur);
2553 
2554     qCDebug(KSIRK_LOG) << "****point att****" << pointAttaquant;
2555 
2556     qCDebug(KSIRK_LOG) << "****SIMULTANEOUS ATTACK****" << pointAttaquant;
2557     res = initArmiesMultipleCombat(nb, firstCountry(), secondCountry(), pointAttaquant);
2558 
2559     relativePosInArenaAttack++;
2560   }
2561   else // Defense
2562   {
2563     QPointF pointAttaquant(0,0);
2564     QPointF pointDefenseur(0,0);
2565     determinePointArriveeForArena(/*secondCountry(), firstCountry(),*/
2566       relativePosInArenaDefense, pointDefenseur, pointAttaquant);
2567 
2568     qCDebug(KSIRK_LOG) << "****point def****" << pointAttaquant;
2569 
2570     qCDebug(KSIRK_LOG) << "****SIMULTANEOUS DEFENSE****" << pointDefenseur;
2571     res = initArmiesMultipleCombat(nb, secondCountry(), secondCountry(), pointDefenseur);
2572 
2573     relativePosInArenaDefense++;
2574   }
2575   qCDebug(KSIRK_LOG) << (void*)res;
2576   return res;
2577 }
2578 
2579 
2580 bool KGameWindow::retreat(unsigned int nb)
2581 {
2582   bool res;
2583   if (m_nbMovedArmies >= int(nb))
2584   {
2585     res = initArmiesMovement(nb, m_secondCountry, m_firstCountry);
2586   }
2587   else
2588   {
2589     res = false;
2590   }
2591   qCDebug(KSIRK_LOG) << "retreat("<<nb<<") returns " << res;
2592   return res;
2593 }
2594 
2595 void KGameWindow::invasionFinished()
2596 {
2597   qCDebug(KSIRK_LOG);
2598   clearHighlighting();
2599  //KMessageParts messageParts;
2600 
2601   QPixmap pm = currentPlayer()->getFlag()->image(0);
2602   KMessageParts messageParts;
2603   messageParts
2604     << pm 
2605     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2606   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2607 }
2608         
2609 void KGameWindow::shiftFinished()
2610 {
2611   clearHighlighting();
2612   QPixmap pm = currentPlayer()->getFlag()->image(0);
2613   KMessageParts messageParts;
2614   messageParts 
2615     << pm 
2616     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2617   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2618   slotNextPlayer();
2619 }
2620 
2621 void KGameWindow::cancelAction()
2622 {
2623   qCDebug(KSIRK_LOG) << "KGameWindow::cancelAction";
2624   QByteArray buffer;
2625   QDataStream stream(&buffer, QIODevice::WriteOnly);
2626   stream << "";
2627   m_automaton->sendMessage(buffer,FirstCountry);
2628   QByteArray buffer2;
2629   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2630   stream2 << "";
2631   m_automaton->sendMessage(buffer2,SecondCountry);
2632 
2633   clearHighlighting();
2634 
2635   KMessageParts messageParts;
2636   QPixmap pm = currentPlayer()->getFlag()->image(0);
2637   messageParts
2638     << pm 
2639     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2640   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2641 }
2642 
2643 void KGameWindow::cancelShiftSource()
2644 {
2645   if (m_nbMovedArmies < 0)
2646   {
2647     m_firstCountry-> decrNbArmies(m_nbMovedArmies);
2648     m_secondCountry-> incrNbArmies(m_nbMovedArmies);
2649     m_firstCountry-> createArmiesSprites();
2650     m_secondCountry-> createArmiesSprites();
2651     m_nbMovedArmies = 0;
2652   }
2653   if (m_nbMovedArmies > 0)
2654   {
2655     m_firstCountry-> incrNbArmies(m_nbMovedArmies);
2656     m_secondCountry-> decrNbArmies(m_nbMovedArmies);
2657     m_firstCountry-> createArmiesSprites();
2658     m_secondCountry-> createArmiesSprites();
2659     m_nbMovedArmies = 0;
2660   }
2661 }
2662 
2663 bool KGameWindow::actionNewGame(GameAutomaton::NetworkGameType socket)
2664 {
2665   qCDebug(KSIRK_LOG);
2666   if  ( ( m_automaton->playerList()->count() == 0 ) ||
2667   ( isMyState(GameLogic::GameAutomaton::GAME_OVER)  ) ||
2668         (KMessageBox::warningContinueCancel(this,i18n("Do you really want to end your current game and start a new one?"),i18n("New game confirmation"),KGuiItem(i18nc("@action:button", "Start New Game"))) == KMessageBox::Continue ) )
2669 
2670   {
2671     qCDebug(KSIRK_LOG) << "valid";
2672     m_automaton->setGameStatus(KGame::End);
2673     m_reinitializingGame = true;
2674     m_automaton->removeAllPlayers();
2675     // Bug 308527. Need to remove all goals on new game.
2676     m_automaton->removeAllGoals();
2677     m_automaton->state(GameLogic::GameAutomaton::INIT);
2678     m_automaton->savedState(GameLogic::GameAutomaton::INVALID);
2679     QObject::disconnect((QObject*)m_automaton->messageServer(),SIGNAL(connectionLost(KMessageIO*)),
2680                         (QObject*)m_automaton,SLOT(slotConnectionToClientBroken(KMessageIO*)));
2681 
2682     m_automaton->disconnect();
2683 
2684     m_newGameSetup->clear();
2685     m_automaton->setupPlayersNumberAndSkin(socket);
2686   }
2687   return false;
2688 }
2689 
2690 void KGameWindow::saveXml(QTextStream& xmlStream)
2691 {
2692   xmlStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
2693   xmlStream << "<ksirkSavedGame formatVersion=\"" << SAVE_GAME_FILE_FORMAT_VERSION << "\" >";
2694   xmlStream << "<game skin=\"" << m_automaton->skin() << "\" state=\"" << m_automaton->state() << "\" >";
2695   m_theWorld->saveXml(xmlStream);
2696   xmlStream << "<players nb=\""<<m_automaton->playerList()->count()<<"\">";
2697   PlayersArray::iterator it = m_automaton->playerList()->begin();
2698   PlayersArray::iterator it_end = m_automaton->playerList()->end();
2699   for (; it != it_end; it++)
2700   {
2701     static_cast<Player*>(*it)->saveXml(xmlStream);
2702   }
2703   xmlStream << "</players>";
2704   Player* player = m_automaton->currentPlayer();
2705   if (player)
2706   {
2707     QString name = player->name();
2708     name = name.replace('&',"&amp;");
2709     name = name.replace('<',"&lt;");
2710     name = name.replace('>',"&gt;");
2711     xmlStream << "<currentPlayer name=\"" << name << "\" />";
2712   }
2713   else
2714     xmlStream << "<currentPlayer name=\"\" />";
2715   xmlStream << "<goals>\n";
2716   it = m_automaton->playerList()->begin();
2717   it_end = m_automaton->playerList()->end();
2718   for (; it != it_end; it++)
2719   {
2720     static_cast<Player*>(*it)->goal().saveXml(xmlStream);
2721   }
2722   xmlStream << "</goals>\n";
2723   xmlStream << "</game>";
2724   xmlStream << "</ksirkSavedGame>";
2725 }
2726 
2727 /**
2728   * @brief Accessor to the world
2729   * @return A pointer to the world
2730   */
2731 ONU* KGameWindow::theWorld()
2732 {
2733   return m_theWorld;
2734 }
2735 
2736 /**
2737   * @brief Adds a player
2738   */
2739 Player* KGameWindow::addPlayer(const QString& playerName,
2740       unsigned int nbAvailArmies, 
2741       unsigned int nbCountries, 
2742       const QString& nationName, 
2743       bool isAI,
2744       const QString& password,
2745       unsigned int nbAttack,
2746       unsigned int nbDefense)
2747 {
2748   qCDebug(KSIRK_LOG) << "Adding player (AI: " << isAI << ")";
2749   Player* p = dynamic_cast<Player*>(m_automaton->createPlayer(isAI?2:1,0,false)); 
2750   if (p)
2751   {
2752     if (!isAI)
2753     {
2754       m_chatDlg->setFromPlayer(p);
2755     }
2756     p->setName(playerName);
2757     p->setNation(nationName);
2758     p->setNbCountries(nbCountries);
2759     p->setNbAvailArmies(nbAvailArmies, true);
2760     p->setNbAttack(nbAttack);
2761     p->setNbDefense(nbDefense);
2762     p->setPassword(password);
2763     if (!m_automaton->addPlayer(p))
2764     {
2765       qCDebug(KSIRK_LOG) << p->name() << "NOT added!";
2766       p = nullptr; // freed - weired API
2767     }
2768   }
2769   return p;
2770 }
2771 
2772 QMap< QString, QString > KGameWindow::nationsList()
2773 {
2774   QMap< QString, QString >  res;
2775   if (m_theWorld == nullptr)
2776   {
2777     return res;
2778   }
2779   QList<Nationality*>& nationsList = m_theWorld->getNationalities();
2780   qCDebug(KSIRK_LOG) << "There is " << nationsList.size() << " nations";
2781   QList<Nationality*>::iterator nationsIt = nationsList.begin();
2782   for (; nationsIt != nationsList.end(); nationsIt++ ) 
2783   {
2784     Nationality* nation = *nationsIt;
2785     qCDebug(KSIRK_LOG) << "Nation '" << nation->name() << "' = " << nation;
2786     res.insert(nation->name(),nation->flagFileName());
2787   } 
2788   return res;
2789 }
2790 
2791 /** @return true if the given player is the last one ; false otherwise */
2792 bool KGameWindow::isLastPlayer(const Player& player)
2793 {
2794   if (m_automaton->playerList()->begin() == m_automaton->playerList()->end())
2795   {
2796     qCCritical(KSIRK_LOG) << "No player ; should not be able to call isLastPlayer !";
2797     exit(1);
2798   }
2799   PlayersArray::iterator it = m_automaton->playerList()->end();
2800   //  it--;
2801   Player* lastPlayer = static_cast<Player*>(*it);
2802   return (player == (*lastPlayer));
2803 }
2804 
2805 void KGameWindow::actionRecycling()
2806 {
2807   qCDebug(KSIRK_LOG) << "KGameWindow::actionRecycling";
2808   setCurrentPlayerToFirst();
2809   QByteArray buffer;
2810   QDataStream stream(&buffer, QIODevice::WriteOnly);
2811   m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2812   QByteArray buffer2;
2813   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2814   stream2 << currentPlayer()->name();
2815   stream2 << (quint32)0;
2816   qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2817     << currentPlayer()->name() << 0
2818     << " at " << __FILE__ << ", line " << __LINE__;
2819   m_automaton->sendMessage(buffer2,DisplayRecycleDetails);
2820 
2821   QPixmap pm = currentPlayer()->getFlag()->image(0);
2822 }
2823 
2824 void KGameWindow::actionRecyclingFinished()
2825 {
2826   qCDebug(KSIRK_LOG);
2827   getRightDialog()->close();
2828   if (m_automaton->isAdmin())
2829   {
2830     setCurrentPlayerToFirst();
2831     distributeArmies();
2832 
2833     QByteArray buffer;
2834     m_automaton->sendMessage(buffer,ShowArmiesToPlace);
2835 
2836     clear();
2837     QByteArray buffer2;
2838     m_automaton->sendMessage(buffer2,StartLocalCurrentAI);
2839 
2840     QByteArray buffer3;
2841     QDataStream stream3(&buffer3, QIODevice::WriteOnly);
2842     stream3 << currentPlayer()-> name();
2843     stream3 << (quint32)nbNewArmies(currentPlayer());
2844     qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2845         << currentPlayer()->name() << nbNewArmies(currentPlayer())
2846         << " at " << __FILE__ << ", line " << __LINE__;
2847     m_automaton->sendMessage(buffer3,DisplayRecycleDetails);
2848     m_automaton->state(GameLogic::GameAutomaton::NEWARMIES);
2849   }
2850 }
2851 
2852 void KGameWindow::finishMoves()
2853 {
2854   qCDebug(KSIRK_LOG);
2855   m_animFighters->moveAllToDestinationNow();
2856 }
2857 
2858 void KGameWindow::displayButtonsForState(GameAutomaton::GameState state)
2859 {
2860   QByteArray buffer;
2861   QDataStream stream(&buffer, QIODevice::WriteOnly);
2862   switch (state)
2863   {
2864   case GameLogic::GameAutomaton::WAIT:;
2865     m_automaton->sendMessage(buffer,ClearHighlighting);
2866     break;
2867   case GameLogic::GameAutomaton::WAIT_RECYCLING:;
2868     m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2869     break;
2870   case GameLogic::GameAutomaton::NEWARMIES:;
2871     m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2872     break;
2873   case GameLogic::GameAutomaton::INIT:;
2874     break;
2875   case GameLogic::GameAutomaton::INTERLUDE:;
2876     break;
2877   case GameLogic::GameAutomaton::ATTACK:;
2878     break;
2879   case GameLogic::GameAutomaton::ATTACK2:;
2880     break;
2881   case GameLogic::GameAutomaton::INVADE:;
2882     break;
2883   case GameLogic::GameAutomaton::SHIFT1:;
2884     break;
2885   case GameLogic::GameAutomaton::SHIFT2:;
2886     break;
2887   case GameLogic::GameAutomaton::FIGHT_BRING:;
2888     break;
2889   case GameLogic::GameAutomaton::FIGHT_ANIMATE:;
2890     break;
2891   case GameLogic::GameAutomaton::FIGHT_BRINGBACK:;
2892     break;
2893   case GameLogic::GameAutomaton::WAITDEFENSE:;
2894     break;
2895   case GameLogic::GameAutomaton::EXPLOSION_ANIMATE:;
2896     break;
2897     
2898   default: 
2899     m_automaton->sendMessage(buffer,ClearHighlighting);
2900   }
2901 }
2902 
2903 void KGameWindow::optionsConfigure()
2904 {
2905   //An instance of your dialog could be already created and could be cached, 
2906   //in which case you want to display the cached dialog instead of creating 
2907   //another one 
2908   if ( KsirkConfigurationDialog::showDialog( "settings" ) ) 
2909     return; 
2910  
2911   //KConfigDialog didn't find an instance of this dialog, so lets create it : 
2912   KsirkConfigurationDialog* dialog = new KsirkConfigurationDialog( this, "settings", 
2913                                              KsirkSettings::self() ); 
2914 
2915   connect(dialog,SIGNAL(armiesNumberShowingChanged(int)),
2916       this,SLOT(slotArmiesNumberChanged(int)));
2917 
2918   dialog->show();
2919 }
2920 
2921 void KGameWindow::explain()
2922 {
2923   KMessageParts message0Parts;
2924   message0Parts << I18N_NOOP("<b>KsirK quick Introduction</b>");
2925   broadcastChangeItem(message0Parts, ID_NO_STATUS_MSG);
2926 
2927   KMessageParts message1Parts;
2928   message1Parts << I18N_NOOP("Attacks and moves are issued through drag & drop between neighbour countries.");
2929   broadcastChangeItem(message1Parts, ID_NO_STATUS_MSG);
2930 
2931   KMessageParts message2Parts;
2932   message2Parts << I18N_NOOP("Start a new game or join a network game with the menu or the toolbar...");
2933   broadcastChangeItem(message2Parts, ID_NO_STATUS_MSG);
2934 
2935   KMessageParts message5Parts;
2936   message5Parts << I18N_NOOP("and then let the system guide you through messages and tooltips appearing on buttons when hovering above them. You can disable bubble help in the options window.");
2937   broadcastChangeItem(message5Parts, ID_NO_STATUS_MSG);
2938 }
2939 
2940 void KGameWindow::showMessage(const QString& message, quint32 delay, MessageShowingType forcing)
2941 {
2942   qCDebug(KSIRK_LOG);
2943   QString lmessage = message + "<br><a href=\"dontshowagain\">"+i18n("Don't show messages anymore") + "</a>";
2944   if(KsirkSettings::helpEnabled() || forcing == ForceShowing)
2945   {
2946     if (m_message == nullptr)
2947     {
2948       qCDebug(KSIRK_LOG) << "Creating KGamePopupItem";
2949       m_message  = new KGamePopupItem();
2950       connect(m_message,SIGNAL(linkActivated(QString)),this,SLOT(slotDisableHelp(QString)));
2951       m_scene_world->addItem(m_message);
2952       m_message->setSharpness(KGamePopupItem::Soft);
2953       m_message->setZValue(1000);
2954     }
2955     m_message->setMessageTimeout(delay*1000);
2956     m_message->showMessage(lmessage, KGamePopupItem::TopLeft, KGamePopupItem::ReplacePrevious);
2957 
2958 //   m_message->setPos(m_frame-> mapToScene(QPoint(30,30)));
2959   }
2960 }
2961 
2962 
2963 void KGameWindow::firstCountry(GameLogic::Country* country)
2964 {
2965   qCDebug(KSIRK_LOG) << (void*)country;
2966   if (m_firstCountry != nullptr)
2967   {
2968     m_firstCountry->releaseHighlightingLock();
2969     m_firstCountry->clearHighlighting();
2970   }
2971   m_firstCountry = country;
2972   if (country == nullptr)
2973   {
2974     return;
2975   }
2976   qCDebug(KSIRK_LOG) << country->name();
2977   country->highlightAsAttacker();
2978 }
2979 
2980 void KGameWindow::secondCountry(GameLogic::Country* country)
2981 {
2982   if (m_secondCountry != nullptr)
2983   {
2984     m_secondCountry->clearHighlighting();
2985   }
2986   m_secondCountry = country;
2987   if (country == nullptr)
2988   {
2989     return;
2990   }
2991   qCDebug(KSIRK_LOG) << country->name();
2992   country->highlightAsDefender();
2993 }
2994 
2995 
2996 GameLogic::Country* KGameWindow::firstCountry()
2997 {
2998   if (m_currentDisplayedWidget == Arena) {
2999      return m_arena->countryAttack();
3000   }
3001   return m_firstCountry;
3002 }
3003 
3004 
3005 GameLogic::Country* KGameWindow::secondCountry()
3006 {
3007   if (m_currentDisplayedWidget == Arena) {
3008     return m_arena->countryDefense();
3009   }
3010   return m_secondCountry;
3011 }
3012 
3013 
3014 void KGameWindow::showArena()
3015 {
3016   qCDebug(KSIRK_LOG);
3017   if (m_currentDisplayedWidget != Arena)
3018   {
3019     // synchronize the arena countries
3020     m_currentDisplayedWidget = Arena;
3021     m_arena->initFightArena(m_firstCountry,m_secondCountry,m_backGnd_arena);
3022   }
3023   qCDebug(KSIRK_LOG) << "before setCurrentIndex";
3024   m_centralWidget->setCurrentIndex(ARENA_INDEX);
3025 }
3026 
3027 
3028 void KGameWindow::showMap()
3029 {
3030   qCDebug(KSIRK_LOG);
3031   m_centralWidget->setCurrentIndex(MAP_INDEX);
3032   m_currentDisplayedWidget = Map;
3033   statusBar()->show();
3034   m_zoomInAction->setEnabled(true);
3035   m_zoomOutAction->setEnabled(true);
3036 }
3037 
3038 void KGameWindow::showMainMenu()
3039 {
3040   qCDebug(KSIRK_LOG);
3041   m_centralWidget->setCurrentIndex(MAINMENU_INDEX);
3042   m_currentDisplayedWidget = MainMenu;
3043 }
3044 
3045 
3046 KGameWindow::WidgetType KGameWindow::currentWidgetType()
3047 {
3048   return m_currentDisplayedWidget;
3049 }
3050 
3051 
3052 QGraphicsView* KGameWindow::currentWidget()
3053 {
3054   switch (currentWidgetType())
3055   {
3056     case Arena:
3057       return dynamic_cast <QGraphicsView*>(arena());
3058       break;
3059     case MainMenu:
3060       return nullptr;
3061       break;
3062     case Map:
3063       return dynamic_cast <QGraphicsView*>(frame());
3064       break;
3065     default:
3066       return nullptr;
3067   }
3068   return nullptr;
3069 }
3070 
3071 
3072 BackGnd* KGameWindow::backGnd() {
3073   if (currentWidgetType() == Arena) {
3074     return backGndArena();
3075   } else {
3076     return backGndWorld();
3077   }
3078 }
3079 
3080 void KGameWindow::slideInvade(GameLogic::Country * attack, GameLogic::Country * defender, InvasionSlider::InvasionType invasionType)
3081 {
3082   if (m_wSlide != nullptr)
3083   {
3084     m_wSlide->hide();
3085     delete m_wSlide;
3086   }
3087   m_wSlide = new InvasionSlider(this,attack,defender,invasionType);
3088   m_wSlide->show();
3089 }
3090 
3091 bool KGameWindow::isArena()
3092 {
3093   return m_useArena;
3094 }
3095 
3096 void KGameWindow::reduceChat()
3097 {
3098   qCDebug(KSIRK_LOG);
3099   m_chatIsReduced = true;
3100 
3101   m_lastWidthChat = m_bottomDock->width();
3102 
3103   // reduce the chat
3104   QPixmap upChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/upArrow.png"));
3105   m_reduceChatButton->setIcon(upChatReducePix);
3106   m_chatDlg->hide();
3107   m_titleChatMsg->show();
3108 }
3109 
3110 void KGameWindow::unreduceChat()
3111 {
3112   qCDebug(KSIRK_LOG);
3113   m_chatIsReduced = false;
3114 
3115   // restore the chat
3116   QPixmap downChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/downArrow.png"));
3117   m_reduceChatButton->setIcon(downChatReducePix);
3118   m_chatDlg->show();
3119   m_titleChatMsg->hide();
3120   m_bottomDock->setMaximumSize(16777215,16777215);
3121   m_bottomDock->resize(m_lastWidthChat,38+m_chatDlg->height());
3122 }
3123 
3124 void KGameWindow::setNextPlayerActionEnabled(bool value)
3125 {
3126   qCDebug(KSIRK_LOG) << value;
3127   m_nextPlayerAction->setEnabled(value);
3128 }
3129 
3130 void KGameWindow::setSaveGameActionEnabled(bool value)
3131 {
3132   qCDebug(KSIRK_LOG) << value;
3133   m_saveGameAction->setEnabled(value);
3134 }
3135 
3136 void KGameWindow::setContextualHelpActionEnabled(GameLogic::GameAutomaton::GameState gameState, bool isPlayerAI)
3137 {
3138   qCDebug(KSIRK_LOG) << isPlayerAI << gameState;
3139   bool enabled = (gameState == GameLogic::GameAutomaton::WAIT || gameState == GameLogic::GameAutomaton::NEWARMIES || gameState == GameLogic::GameAutomaton::INTERLUDE) &&
3140                  !isPlayerAI &&
3141                  KsirkSettings::helpEnabled();
3142   m_contextualHelpAction->setEnabled(enabled);
3143 }
3144 
3145 void KGameWindow::setupPopupMessage()
3146 {
3147   if (m_message == nullptr)
3148   {
3149     qCDebug(KSIRK_LOG);
3150     m_message  = new KGamePopupItem();
3151     connect(m_message,SIGNAL(linkActivated(QString)),this,SLOT(slotDisableHelp(QString)));
3152     m_scene_world->addItem(m_message);
3153     m_message->setSharpness(KGamePopupItem::Soft);
3154     QColor color = QColor(102,102,255);
3155     m_message->setBackgroundBrush(color);
3156     m_message->setZValue(1000);
3157   }
3158 }
3159 
3160 bool KGameWindow::newGameDialog(const QString& skin, GameAutomaton::NetworkGameType netGameType)
3161 {
3162   qCDebug(KSIRK_LOG) << "state is" << m_automaton->stateName();
3163   m_automaton->setGameStatus( KGame::Pause );
3164   m_stateBeforeNewGame = m_automaton->state();
3165   m_automaton->state(GameAutomaton::STARTING_GAME);
3166   m_rightDock->hide();
3167   statusBar()->hide();
3168   m_zoomInAction->setEnabled(false);
3169   m_zoomOutAction->setEnabled(false);
3170   m_nextPlayerAction->setEnabled(false);
3171   m_goalAction->setVisible(false);;
3172   m_newGameDialog->init(skin, netGameType);
3173   m_stackWidgetBeforeNewGame = m_centralWidget->currentIndex();
3174   m_centralWidget->setCurrentIndex(NEWGAME_INDEX);
3175   return false;
3176 }
3177 
3178 /* Set presence (usually called by dialog widget). */
3179 void KGameWindow::setPresence ( const XMPP::Status &status )
3180 {
3181   qCDebug(KSIRK_LOG) << "Status: " << status.show () << ", Reason: " << status.status ();
3182   
3183   // fetch input status
3184   XMPP::Status newStatus = status;
3185   
3186   // TODO: Check if Caps is enabled
3187   // Send entity capabilities
3188   if( m_jabberClient )
3189   {
3190     newStatus.setCapsNode( m_jabberClient->capsNode() );
3191     newStatus.setCapsVersion( m_jabberClient->capsVersion() );
3192     newStatus.setCapsExt( m_jabberClient->capsExt() );
3193   }
3194   
3195   // make sure the status gets the correct priority
3196   newStatus.setPriority ( 5 );
3197   
3198 /*  XMPP::Jid jid ( this->contactId() );
3199   XMPP::Resource newResource ( resource (), newStatus );
3200   
3201   // update our resource in the resource pool
3202   resourcePool()->addResource ( jid, newResource );
3203   
3204   // make sure that we only consider our own resource locally
3205   resourcePool()->lockToResource ( jid, newResource );*/
3206   
3207   /*
3208   * Unless we are in the connecting status, send a presence packet to the server
3209   */
3210   if(status.show () != QString("connecting") )
3211   {
3212     /*
3213     * Make sure we are actually connected before sending out a packet.
3214     */
3215     if (true/*isConnected()*/)
3216     {
3217       qCDebug(KSIRK_LOG) << "Sending new presence to the server.";
3218       
3219       XMPP::JT_Presence * task = new XMPP::JT_Presence ( m_jabberClient->rootTask ());
3220       
3221       task->pres ( newStatus );
3222       task->go ( true );
3223     }
3224     else
3225     {
3226       qCDebug(KSIRK_LOG) << "We were not connected, presence update aborted.";
3227     }
3228   }
3229   
3230 }
3231 
3232 void KGameWindow::askForJabberGames()
3233 {
3234   if (m_jabberClient && m_jabberClient->isConnected())
3235   {
3236     XMPP::Message message(QString(m_groupchatRoom+'@'+m_groupchatHost));
3237     message.setType("groupchat");
3238     message.setId(QUuid::createUuid().toString().remove('{').remove('}').remove('-'));
3239     QString body("Who propose online KsirK games here?");
3240     message.setBody(body);
3241     qCDebug(KSIRK_LOG) << "Sending message: <<" << body << ">> to" << (m_groupchatRoom+'@'+m_groupchatHost);
3242     m_jabberClient->sendMessage(message);
3243   }
3244 }
3245 
3246 void KGameWindow::sendGameInfoToJabber()
3247 {
3248   qCDebug(KSIRK_LOG);
3249   if (m_jabberClient
3250     && m_jabberClient->isConnected()
3251     && m_automaton->startingGame())
3252   {
3253     qCDebug(KSIRK_LOG) << "Sending 'I'm starting a game with ...'";
3254     XMPP::Message message(QString(m_groupchatRoom+'@'+m_groupchatHost));
3255     message.setType("groupchat");
3256     message.setId(QUuid::createUuid().toString().remove('{').remove('}').remove('-'));
3257     QString body;
3258     QTextStream qts(&body);
3259     qts <<"I'm starting a game with skin '" << m_automaton->skin() << "' and '" << m_automaton->nbPlayers() << "' players";
3260     message.setBody(body);
3261     qCDebug(KSIRK_LOG) << "Sending message: <<" << body << ">> to" << (m_groupchatRoom+'@'+m_groupchatHost);
3262     m_jabberClient->sendMessage(message);
3263   }
3264 }
3265 
3266 void KGameWindow::joinNetworkGame()
3267 {
3268   qCDebug(KSIRK_LOG);
3269   /// @TODO show the network connect screen
3270   m_centralWidget->setCurrentIndex(TCPCONNECT_INDEX);
3271 }
3272 
3273 void KGameWindow::updateNewGameSummary()
3274 {
3275   qCDebug(KSIRK_LOG);
3276   m_newGameSummaryWidget->show(this);
3277 }
3278 
3279 void KGameWindow::showNewGameSummary()
3280 {
3281   qCDebug(KSIRK_LOG);
3282   m_centralWidget->setCurrentIndex(NEWGAMESUMMARY_INDEX);
3283 }
3284 
3285 } // closing namespace Ksirk
3286 
3287