1 /* This file is part of KsirK.
2    Copyright (C) 2001-2007 Gael de Chalendar <kleag@free.fr>
3 
4    KsirK is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public
6    License as published by the Free Software Foundation, either version 2
7    of the License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA
18 */
19 
20 /*  begin                : mer jui 11 22:27:28 EDT 2001   */
21 
22 // application specific includes
23 #include "kgamewin.h"
24 #include "ksirkConfigDialog.h"
25 #include "ksirksettings.h"
26 #include "Sprites/animspritesgroup.h"
27 #include "Sprites/arrowsprite.h"
28 #include "GameLogic/aiplayer.h"
29 #include "GameLogic/aiColsonPlayer.h"
30 #include "GameLogic/aiplayerio.h"
31 #include "GameLogic/dice.h"
32 #include "GameLogic/KMessageParts.h"
33 #include "GameLogic/goal.h"
34 #include "GameLogic/KsirkChatItem.h"
35 #include "GameLogic/KsirkChatModel.h"
36 #include "GameLogic/KsirkChatDelegate.h"
37 #include "SaveLoad/ksirkgamexmlloader.h"
38 #include "Sprites/backgnd.h"
39 #include "Dialogs/kplayersetupwidget.h"
40 #include "Dialogs/kwaitedplayersetupdialog.h"
41 #include "Dialogs/restartOrExitDialogImpl.h"
42 #include "Dialogs/newGameDialogImpl.h"
43 #include "Dialogs/newGameSummaryWidget.h"
44 #include "Dialogs/jabbergameui.h"
45 #include "Dialogs/tcpconnectwidget.h"
46 #include "im.h"
47 #include "xmpp_tasks.h"
48 
49 
50 //include files for QT
51 #include <QAction>
52 #include <QDialog>
53 #include <QDockWidget>
54 #include <QFileDialog>
55 #include <QGridLayout>
56 #include <QHostInfo>
57 #include <QIcon>
58 #include <QMenuBar>
59 #include <QMovie>
60 #include <QStatusBar>
61 #include <QString>
62 #include <QSvgRenderer>
63 #include <QTreeView>
64 #include <QUuid>
65 
66 // include files for KDE
67 #include <KMessageBox>
68 #include <KLocalizedString>
69 #include <KConfig>
70 #include <KStandardGameAction>
71 #include <KStandardAction>
72 #include <KActionCollection>
73 #include "ksirk_debug.h"
74 #include <phonon/mediaobject.h>
75 #include <KGamePopupItem>
76 #include <KToolBar>
77 #include <KAboutData>
78 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
79 #include <libkdegamesprivate/kgame/kgamechat.h>
80 #include <sys/utsname.h>
81 
82 namespace Ksirk
83 {
84 using namespace GameLogic;
85 
86 // port all occurrences of m_accels
87 // port all occurrences of setBarPos
88 
KGameWindow(QWidget * parent)89 KGameWindow::KGameWindow(QWidget* parent) :
90   KXmlGuiWindow(parent),
91   m_rightDock(0),
92   m_rightDialog(0),
93   m_automaton(new GameAutomaton()),
94   m_wSlide(0),
95   m_currentDisplayedWidget(MainMenu),
96   NKD(0), NKA(0),
97   m_useArena(false),
98   nbSpriteAttacking(0),
99   nbSpriteDefending(0),
100   relativePosInArenaAttack(0),
101   relativePosInArenaDefense(0),
102   m_theWorld(0),
103   m_scene_world(0), m_scene_arena(0),
104   m_backGnd_world(0), m_backGnd_arena(0),
105   m_animFighters(new AnimSpritesGroup(this,SLOT(slotMovingFightersArrived(AnimSpritesGroup*)))),
106   m_nbMovedArmies(0),
107   m_firstCountry(0), m_secondCountry(0),
108   m_frame(0),
109   m_arena(0),
110   m_mainMenu(0),
111   m_goalAction(0),
112   m_barFlag(new QLabel(this)),
113   m_chatDlg(0),
114   m_audioPlayer(Phonon::createPlayer( Phonon::NotificationCategory )),
115   m_timer(this),
116   m_message(0),
117   m_mouseLocalisation(0),
118   m_defenseDialog(0),
119   m_fileName(),
120   m_uparrow(0),
121   m_downarrow(0),
122   m_leftarrow(0),
123   m_rightarrow(0),
124   m_reinitializingGame(false),
125   m_newGameDialog(0),
126   m_newPlayerWidget(0),
127   m_stateBeforeNewGame(GameAutomaton::INVALID),
128   m_stackWidgetBeforeNewGame(-1),
129   m_jabberClient(new JabberClient()),
130   m_advertizedHostName(QHostInfo::localHostName()),
131   m_jabberGameWidget(0),
132   m_presents(),
133   m_newGameSetup(new NewGameSetup(m_automaton))
134   {
135   qCDebug(KSIRK_LOG) << "KGameWindow constructor begin";
136 
137   statusBar()->addWidget(m_barFlag);
138 
139 //   m_accels.setEnabled(true);
140 
141   QString iconFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/soldierKneeling.png");
142   if (iconFileName.isNull())
143   {
144       KMessageBox::error(0, i18n("Cannot load icon<br>Program cannot continue"), i18n("Error!"));
145       exit(2);
146   }
147   QPixmap icon(iconFileName);
148 
149   m_bottomDock = new QDockWidget(this);
150   m_bottomDock->setObjectName("bottom-dock");
151   m_bottomDock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetFloatable);
152   m_bottomDock->setAllowedAreas(Qt::BottomDockWidgetArea|Qt::TopDockWidgetArea);
153 
154   QWidget* titleChatWidget = new QWidget(m_bottomDock);
155   QHBoxLayout* titleChatLayout = new QHBoxLayout(titleChatWidget);
156   titleChatWidget->setLayout(titleChatLayout);
157   titleChatWidget->setFixedHeight(35);
158 
159   QWidget* newMessageChat = new QWidget(titleChatWidget);
160   QHBoxLayout* newMessageChatLayout = new QHBoxLayout(newMessageChat);
161   newMessageChat->setLayout(newMessageChatLayout);
162 
163   KsirkChatModel* chatModel = new KsirkChatModel(m_bottomDock,this);
164   KsirkChatDelegate* chatDelegate = new KsirkChatDelegate(m_bottomDock);
165   // m_bottomDock is the KGameChat parent widget
166   m_chatDlg = new KGameChat(m_automaton, 10000, m_bottomDock,chatModel,chatDelegate);
167   connect(m_chatDlg,
168           SIGNAL(signalReturnPressed(QString)),
169           this,
170           SLOT(slotChatMessage()));
171 
172 
173   m_upChatFloatPix.load(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/2UpArrow.png"));
174   m_downChatFloatPix.load(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/2DownArrow.png"));
175   m_chatIsReduced = false;
176 
177   m_titleChatMsg = new QLabel(i18n("No message..."));
178   QPixmap downChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/downArrow.png"));
179   m_reduceChatButton = new QPushButton(downChatReducePix,"");
180   m_floatChatButton = new QPushButton(m_upChatFloatPix,"");
181   m_reduceChatButton->setFixedSize(30,30);
182   m_floatChatButton->setFixedSize(30,30);
183   connect(m_floatChatButton,
184           SIGNAL(clicked()),
185           this,
186           SLOT(slotChatFloatButtonPressed()));
187   connect(m_bottomDock,
188           SIGNAL(topLevelChanged(bool)),
189           this,
190           SLOT(slotChatFloatChanged(bool)));
191   connect(m_reduceChatButton,
192           SIGNAL(clicked()),
193           this,
194           SLOT(slotChatReduceButton()));
195 
196   newMessageChatLayout->addWidget(m_titleChatMsg);
197   m_titleChatMsg->hide();
198 
199   titleChatLayout->addWidget(newMessageChat);
200   titleChatLayout->addWidget(m_reduceChatButton);
201   titleChatLayout->addWidget(m_floatChatButton);
202 
203   m_bottomDock->setWidget(m_chatDlg);
204   m_bottomDock->setTitleBarWidget(titleChatWidget);
205   addDockWidget(Qt::BottomDockWidgetArea, m_bottomDock); // master dockwidget
206 
207 //    qCDebug(KSIRK_LOG) << "Before initActions";
208   initActions();
209 
210   qCDebug(KSIRK_LOG) << "Setting up GUI";
211   setupGUI();
212 
213   qCDebug(KSIRK_LOG) << "Creating automaton";
214   m_automaton->init(this);
215 
216   // create a central widget if it doesent' exists
217   m_centralWidget = new QStackedWidget(this);
218   setCentralWidget(m_centralWidget);
219   m_mainMenu = new mainMenu(this, m_centralWidget);
220   m_mainMenu->init(m_theWorld);
221 
222   /// @FIXME Hides the "Play KsirK over Jabber Network" button while Jabber
223   /// connection does not work
224   m_mainMenu->pbJabberGame->hide();
225 
226   m_newGameDialog = new NewGameWidget(m_newGameSetup, m_centralWidget);
227   connect(m_newGameDialog,SIGNAL(newGameOK()), this, SLOT(slotNewGameNext()));
228   connect(m_newGameDialog,SIGNAL(newGameKO()), this, SLOT(slotNewGameKO()));
229   m_newPlayerWidget = new KPlayerSetupWidget(m_centralWidget);
230   connect(m_newPlayerWidget,SIGNAL(next()),this,SLOT(slotNewPlayerNext()));
231   connect(m_newPlayerWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
232   connect(m_newPlayerWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
233   connect(m_newPlayerWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
234   connect(m_newPlayerWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
235   qCDebug(KSIRK_LOG) << "create the Jabber widget if it doesn't exist";
236   m_jabberGameWidget = new KsirkJabberGameWidget(m_centralWidget);
237   m_centralWidget->addWidget(m_mainMenu); // MAINMENU_INDEX 0
238   m_centralWidget->addWidget(m_newGameDialog); // NEWGAME_INDEX 1
239   m_centralWidget->addWidget(m_jabberGameWidget); // JABBERGAME_INDEX 2
240   m_centralWidget->addWidget(m_newPlayerWidget);  // NEWPLAYER_INDEX 3
241   m_newGameSummaryWidget = new NewGameSummaryWidget(m_centralWidget);
242   connect(m_newGameSummaryWidget->finishButton,SIGNAL(clicked(bool)),this,SLOT(slotStartNewGame()));
243   connect(m_newGameSummaryWidget,SIGNAL(previous()),this,SLOT(slotNewPlayerPrevious()));
244   connect(m_newGameSummaryWidget,SIGNAL(cancel()),this,SLOT(slotNewPlayerCancel()));
245   m_centralWidget->addWidget(m_newGameSummaryWidget);  // NEWGAMESUMMARY_INDEX 4
246   m_tcpConnectWidget = new TcpConnectWidget(this);
247   m_centralWidget->addWidget(m_tcpConnectWidget);  // TCPCONNECT_INDEX 5
248   connect(m_tcpConnectWidget,SIGNAL(next()),this,SLOT(slotConnectToServer()));
249   connect(m_tcpConnectWidget,SIGNAL(previous()),this,SLOT(slotTcpConnectPrevious()));
250   connect(m_tcpConnectWidget,SIGNAL(cancel()),this,SLOT(slotTcpConnectCancel()));
251   m_centralWidget->setCurrentIndex(MAINMENU_INDEX);
252   m_currentDisplayedWidget = MainMenu;
253   m_bottomDock->hide();
254 
255 
256 //    qCDebug(KSIRK_LOG) << "Before initStatusBar";
257   initStatusBar();
258 
259   menuBar()-> show();
260 
261   explain();
262   m_automaton->run();
263   setMouseTracking(true);
264 
265   m_timer.setSingleShot(true);
266   connect(&m_timer,SIGNAL(timeout()),this,SLOT(evenementTimer()));
267 
268   m_initialPresence = XMPP::Status ( "", "", 5, true );
269 
270   qCDebug(KSIRK_LOG) << "Connecting Jabber signals";
271   QObject::connect ( m_jabberClient, SIGNAL (csDisconnected()), this, SLOT (slotCSDisconnected()) );
272   QObject::connect ( m_jabberClient, SIGNAL (csError(int)), this, SLOT (slotCSError(int)) );
273   QObject::connect ( m_jabberClient, SIGNAL (tlsWarning(QCA::TLS::IdentityResult,QCA::Validity)), this, SLOT (slotHandleTLSWarning(QCA::TLS::IdentityResult,QCA::Validity)) );
274   QObject::connect ( m_jabberClient, SIGNAL (connected()), this, SLOT (slotConnected()) );
275   QObject::connect ( m_jabberClient, SIGNAL (error(JabberClient::ErrorCode)), this, SLOT (slotClientError(JabberClient::ErrorCode)) );
276 
277 //   QObject::connect ( m_jabberClient, SIGNAL (subscription(XMPP::Jid,QString)), this, SLOT (slotSubscription(XMPP::Jid,QString)) );
278   QObject::connect ( m_jabberClient, SIGNAL (rosterRequestFinished(bool)), this, SLOT (slotRosterRequestFinished(bool)) );
279 //   QObject::connect ( m_jabberClient, SIGNAL (newContact(XMPP::RosterItem)), this, SLOT (slotContactUpdated(XMPP::RosterItem)) );
280 //   QObject::connect ( m_jabberClient, SIGNAL (contactUpdated(XMPP::RosterItem)), this, SLOT (slotContactUpdated(XMPP::RosterItem)) );
281 //   QObject::connect ( m_jabberClient, SIGNAL (contactDeleted(XMPP::RosterItem)), this, SLOT (slotContactDeleted(XMPP::RosterItem)) );
282 //   QObject::connect ( m_jabberClient, SIGNAL (resourceAvailable(XMPP::Jid,XMPP::Resource)), this, SLOT (slotResourceAvailable(XMPP::Jid,XMPP::Resource)) );
283 //   QObject::connect ( m_jabberClient, SIGNAL (resourceUnavailable(XMPP::Jid,XMPP::Resource)), this, SLOT (slotResourceUnavailable(XMPP::Jid,XMPP::Resource)) );
284   QObject::connect ( m_jabberClient, SIGNAL (messageReceived(XMPP::Message)), this, SLOT (slotReceivedMessage(XMPP::Message)) );
285 //   QObject::connect ( m_jabberClient, SIGNAL (incomingFileTransfer()), this, SLOT (slotIncomingFileTransfer()) );
286   QObject::connect ( m_jabberClient, SIGNAL (groupChatJoined(XMPP::Jid)), this, SLOT (slotGroupChatJoined(XMPP::Jid)) );
287   QObject::connect ( m_jabberClient, SIGNAL (groupChatLeft(XMPP::Jid)), this, SLOT (slotGroupChatLeft(XMPP::Jid)) );
288   QObject::connect ( m_jabberClient, SIGNAL (groupChatPresence(XMPP::Jid,XMPP::Status)), this, SLOT (slotGroupChatPresence(XMPP::Jid,XMPP::Status)) );
289 
290   QObject::connect ( m_jabberClient, SIGNAL (groupChatError(XMPP::Jid,int,QString)), this, SLOT (slotGroupChatError(XMPP::Jid,int,QString)) );
291   QObject::connect ( m_jabberClient, SIGNAL (debugMessage(QString)), this, SLOT (slotClientDebugMessage(QString)) );
292 
293   m_jabberClient->setUseXMPP09 ( true );
294 //     m_jabberClient->setUseSSL ( true );
295   m_jabberClient->setAllowPlainTextPassword ( true );
296 
297   struct utsname utsBuf;
298   uname (&utsBuf);
299   m_jabberClient->setClientName ("KsirK");
300   m_jabberClient->setClientVersion (KAboutData::applicationData().version());
301   m_jabberClient->setOSName (QString ("%1 %2").arg (utsBuf.sysname, 1).arg (utsBuf.release, 2));
302 
303   // Set caps node information
304   m_jabberClient->setCapsNode("http://ksirk.kde.org/jabber/caps");
305   m_jabberClient->setCapsVersion(KAboutData::applicationData().version());
306 
307   // Set Disco Identity information
308   DiscoItem::Identity identity;
309   identity.category = "client";
310   identity.type = "pc";
311   identity.name = "KsirK";
312   m_jabberClient->setDiscoIdentity(identity);
313 
314   connect (this, SIGNAL(newJabberGame(QString,int,QString)), m_automaton, SIGNAL(newJabberGame(QString,int,QString)));
315 
316   m_automaton->skin("skins/default");
317 }
318 
~KGameWindow()319 KGameWindow::~KGameWindow()
320 {
321   qCDebug(KSIRK_LOG);
322 
323   if (m_jabberClient != 0)
324   {
325     delete m_jabberClient;
326     m_jabberClient = 0;
327   }
328   if (m_automaton != 0)
329   {
330     m_automaton->setGameStatus( KGame::End );
331     delete m_automaton; m_automaton = 0;
332   }
333   delete m_backGnd_world; m_backGnd_world = 0;
334   delete m_scene_world; m_scene_world = 0;
335 //   if (m_barFlagButton) {delete m_barFlagButton; m_barFlagButton = 0;}
336   delete m_frame; m_frame = 0;
337   delete m_backGnd_arena; m_backGnd_arena = 0;
338   delete m_arena; m_arena = 0;
339   delete m_scene_arena; m_scene_arena = 0;
340   delete m_mainMenu; m_mainMenu = 0;
341   delete m_audioPlayer;
342   delete m_rightDialog;
343   delete m_defenseDialog;
344   delete m_newGameSetup;
345 }
346 
initActions()347 void KGameWindow::initActions()
348 {
349   QAction *action;
350 
351   // standard game actions
352   action = KStandardGameAction::gameNew(this, SLOT(slotNewGame()), this);
353   actionCollection()->addAction(action->objectName(), action);
354   action = KStandardGameAction::load(this, SLOT(slotOpenGame()), this);
355   actionCollection()->addAction(action->objectName(), action);
356   m_saveGameAction = KStandardGameAction::save(this, SLOT(slotSaveGame()), this);
357   m_saveGameAction->setEnabled(false);
358   actionCollection()->addAction(m_saveGameAction->objectName(), m_saveGameAction);
359   action = KStandardGameAction::quit(this, SLOT(close()), this);
360   actionCollection()->addAction(action->objectName(), action);
361 
362   m_zoomInAction = KStandardAction::zoomIn(this, SLOT(slotZoomIn()), this);
363   m_zoomInAction->setEnabled(false);
364   actionCollection()->addAction(m_zoomInAction->objectName(), m_zoomInAction);
365 
366   m_zoomOutAction = KStandardAction::zoomOut(this, SLOT(slotZoomOut()), this);
367   m_zoomOutAction->setEnabled(false);
368   actionCollection()->addAction(m_zoomOutAction->objectName(), m_zoomOutAction);
369 
370   KStandardAction::preferences( this, SLOT(optionsConfigure()), actionCollection() );
371 
372   // specific ksirk action
373   QString imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, "jabber.png");
374   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
375   if (imageFileName.isNull())
376   {
377     KMessageBox::error(0, i18n("Cannot load button image %1<br>Program cannot continue",QString("jabber.png")), i18n("Error!"));
378     exit(2);
379   }
380   m_jabberAction = new QAction(QIcon(QPixmap(imageFileName)), i18n("Play over Jabber"), this);
381   m_jabberAction-> setText(i18n("Play KsirK over the Jabber Network"));
382   m_jabberAction-> setIconText(i18n("Jabber"));
383   actionCollection()->setDefaultShortcut(m_jabberAction, Qt::CTRL+Qt::Key_J);
384   m_jabberAction->setStatusTip(i18n("Allow to connect to a KsirK Jabber Multi User Gaming Room to create new games or to join present games"));
385   connect(m_jabberAction,SIGNAL(triggered(bool)),this,SLOT(slotJabberGame()));
386   qCDebug(KSIRK_LOG) << "Adding action game_jabber";
387   actionCollection()->addAction("game_jabber", m_jabberAction);
388 
389   // specific ksirk action
390   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEWNETGAME);
391   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
392   if (imageFileName.isNull())
393   {
394     KMessageBox::error(0, i18n("Cannot load button image %1<br>Program cannot continue",QString(CM_NEWNETGAME)), i18n("Error!"));
395     exit(2);
396   }
397   QAction * newSocketAction = new QAction(QIcon(QPixmap(imageFileName)), i18n("New Standard TCP/IP Network Game"), this);
398   newSocketAction->setIconText(i18n("New TCP/IP"));
399   actionCollection()->setDefaultShortcut(newSocketAction, Qt::CTRL+Qt::Key_T);
400   newSocketAction->setStatusTip(i18n("Create a new standard TCP/IP network game"));
401   connect(newSocketAction,SIGNAL(triggered(bool)),this,SLOT(slotNewSocketGame()));
402   qCDebug(KSIRK_LOG) << "Adding action game_new_socket";
403   actionCollection()->addAction("game_new_socket", newSocketAction);
404 
405 
406   // specific ksirk action
407   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEWNETGAME);
408   //   qCDebug(KSIRK_LOG) << "Trying to load button image file: " << imageFileName;
409   if (imageFileName.isNull())
410   {
411     KMessageBox::error(0, i18n("Cannot load button image %1<br>Program cannot continue",QString(CM_NEWNETGAME)), i18n("Error!"));
412     exit(2);
413   }
414   QAction * joinAction = new QAction(QIcon(QPixmap(imageFileName)),
415         i18n("Join a Standard TCP/IP Network Game"), this);
416   joinAction->setIconText(i18n("Join TCP/IP"));
417   actionCollection()->setDefaultShortcut(joinAction, Qt::CTRL+Qt::SHIFT+Qt::Key_J);
418   joinAction->setStatusTip(i18n("Join a standard TCP/IP network game"));
419   connect(joinAction,SIGNAL(triggered(bool)),this,SLOT(slotJoinNetworkGame()));
420    qCDebug(KSIRK_LOG) << "Adding action game_join_socket";
421   actionCollection()->addAction("game_join_socket", joinAction);
422 
423   m_goalAction = new QAction(i18n("Goal"), this);
424   m_goalAction-> setText(i18n("Display the Current Player's Goal"));
425   m_goalAction-> setIconText("  ");
426   actionCollection()->setDefaultShortcut(m_goalAction, Qt::CTRL+Qt::Key_G);
427   m_goalAction->setStatusTip(i18n("Display the current player's goal"));
428   connect(m_goalAction,SIGNAL(triggered(bool)),this,SLOT(slotShowGoal()));
429   m_goalAction->setVisible(false);
430   qCDebug(KSIRK_LOG) << "Adding action game_goal";
431   actionCollection()->addAction("game_goal", m_goalAction);
432 
433   m_contextualHelpAction = new QAction(
434         i18n("Contextual Help"), this);
435   m_contextualHelpAction->setEnabled(false);
436   actionCollection()->setDefaultShortcut(m_contextualHelpAction, Qt::CTRL+Qt::Key_F1);
437   connect(m_contextualHelpAction,SIGNAL(triggered(bool)),this,SLOT(slotContextualHelp()));
438   actionCollection()->addAction("help_contextual", m_contextualHelpAction);
439 
440 
441   QString nextPlayerActionImageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + '/' + CM_NEXTPLAYER);
442   m_nextPlayerAction =  new QAction(QIcon(nextPlayerActionImageFileName),
443         i18n("Next Player"), this);
444   connect(m_nextPlayerAction, SIGNAL(triggered(bool)), this, SLOT(slotNextPlayer()));
445   m_contextualHelpAction->setStatusTip(i18n("Lets the next player play"));
446   m_nextPlayerAction->setEnabled(false);
447   actionCollection()->addAction("game_nextplayer", m_nextPlayerAction);
448 
449   QAction * finishMovesAction = new QAction(
450         i18n("Finish moves"), this);
451   actionCollection()->setDefaultShortcut(finishMovesAction, Qt::Key_Space);
452   finishMovesAction->setStatusTip(i18n("Finish moving the current sprites"));
453   connect(finishMovesAction,SIGNAL(triggered(bool)),this,SLOT(slotFinishMoves()));
454   actionCollection()->addAction("game_finish_moves", finishMovesAction);
455 
456 
457 }
458 
initStatusBar()459 void KGameWindow::initStatusBar()
460 {
461   statusBar()-> setSizeGripEnabled(true);
462   //QT5 statusBar()->insertPermanentItem("", ID_STATUS_MSG, 2);
463   //QT5 statusBar()-> setItemAlignment(ID_STATUS_MSG, Qt::AlignLeft | Qt::AlignVCenter);
464 
465   //QT5 statusBar()->insertPermanentItem("", ID_STATUS_MSG2, 3);
466   //QT5 statusBar()-> setItemAlignment(ID_STATUS_MSG2, Qt::AlignLeft | Qt::AlignVCenter);
467   //QT5 statusBar()->addPermanentWidget(m_barFlag);
468 }
469 
clickIn(const QPointF & pointf)470 Country* KGameWindow::clickIn(const QPointF &pointf)
471 {
472 //   qCDebug(KSIRK_LOG) << "KGameWindow::clickIn " << pointf;
473  /* if(isMyState(GameLogic::GameAutomaton::INIT) || m_theWorld-> countryAt( pointf )==0)
474   {
475     m_rightDock->hide();
476   }*/
477   return m_theWorld-> countryAt( pointf );
478 }
479 
currentPlayer()480 Player* KGameWindow::currentPlayer()
481 {
482 //   qCDebug(KSIRK_LOG) << "KGameWindow::currentPlayer";
483   Player* current = m_automaton->currentPlayer();
484 
485   return current;
486 }
487 
loadDices()488 void KGameWindow::loadDices()
489 {
490   qCDebug(KSIRK_LOG);
491 
492   m_dices[Blue] = QList<QPixmap>();
493   m_dices[Red] = QList<QPixmap>();
494   m_dices[Blue].push_back(buildDice("bluedice1"));
495   m_dices[Blue].push_back(buildDice("bluedice2"));
496   m_dices[Blue].push_back(buildDice("bluedice3"));
497   m_dices[Blue].push_back(buildDice("bluedice4"));
498   m_dices[Blue].push_back(buildDice("bluedice5"));
499   m_dices[Blue].push_back(buildDice("bluedice6"));
500   m_dices[Red].push_back(buildDice("reddice1"));
501   m_dices[Red].push_back(buildDice("reddice2"));
502   m_dices[Red].push_back(buildDice("reddice3"));
503   m_dices[Red].push_back(buildDice("reddice4"));
504   m_dices[Red].push_back(buildDice("reddice5"));
505   m_dices[Red].push_back(buildDice("reddice6"));
506 }
507 
buildDice(const QString & id)508 QPixmap KGameWindow::buildDice(const QString& id)
509 {
510   qCDebug(KSIRK_LOG);
511 
512   QSize size(32,32);
513   QImage image(size, QImage::Format_ARGB32_Premultiplied);
514   image.fill(0);
515   QPainter p(&image);
516   if (m_theWorld != 0)
517   {
518     m_theWorld->renderer()->render(&p, id);
519   }
520 
521   return QPixmap::fromImage(image);
522 }
523 
getDice(DiceColor color,int num)524 QPixmap KGameWindow::getDice(DiceColor color, int num)
525 {
526   if(num==0 || num==-1)
527 {return QPixmap();}
528   else {return m_dices[color][num-1];}
529 }
530 
newSkin(const QString & onuFileName)531 void KGameWindow::newSkin(const QString& onuFileName)
532 {
533   qCDebug(KSIRK_LOG) << onuFileName;
534   clear();
535 
536   m_animFighters->clear();
537   foreach(AnimSpritesGroup* sprites, m_animSpritesGroups)
538   {
539     sprites->clear();
540     delete sprites;
541   }
542   m_animSpritesGroups.clear();
543 
544   if (m_centralWidget != 0)
545   {
546     m_centralWidget->setCurrentIndex(-1);
547   }
548 
549 // NOTE:I wanted to recreate the automaton here. But it isn't possible as this
550 // method is called from inside a GameAutomaton method. Furthermore, it isn't
551 // a good solution because the central KGame object should not be recreated
552 // but reinitialized as needed
553 //   m_automaton->init(0);
554 //   delete m_automaton;
555 //   m_automaton = new GameAutomaton();
556 //   m_automaton->init(this);
557 
558   m_mouseLocalisation = 0;
559   if (m_theWorld != 0)
560   {
561 //     m_theWorld-> reset();
562     delete m_theWorld;
563     m_theWorld = 0;
564   }
565 
566   QString onuDefinitionFileName = onuFileName;
567   if (onuDefinitionFileName.isEmpty())
568   {
569     onuDefinitionFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Data/world.desktop");
570   }
571   else if (!QFile::exists(onuDefinitionFileName))
572   {
573     onuDefinitionFileName.clear();
574   }
575   if (onuDefinitionFileName.isEmpty())
576   {
577       KMessageBox::error(0,
578           i18n("World definition file not found - Verify your installation<br>Program cannot continue"), i18n("Error!"));
579       exit(2);
580   }
581   // Bug 308527. Need to remove all goals on new game. Only goals for selected skin will be loaded.
582   m_automaton->removeAllGoals();
583   qCDebug(KSIRK_LOG) << "Got World definition file name: " <<  onuDefinitionFileName;
584   m_theWorld = new ONU(m_automaton, onuDefinitionFileName);
585   if (m_theWorld->skin().isEmpty())
586   {
587     delete m_theWorld;
588     m_theWorld = 0;
589   }
590   loadDices();
591 
592   // put the size to the window size if it's the main menu
593   int width;
594   int height;
595   if (m_scene_arena == 0 || m_theWorld == 0)
596   {
597      width = 2000;
598      height = 2000;
599   }
600   else
601   {
602      width = m_theWorld->width();
603      height = m_theWorld->height();
604   }
605 
606   //Creation of the arena background
607   if (m_backGnd_arena != 0)
608   {
609     qCDebug(KSIRK_LOG) << "Before m_backGnd_arena delete";
610     delete m_backGnd_arena;
611   }
612   //Creation of the background
613   if (m_backGnd_world != 0)
614   {
615     qCDebug(KSIRK_LOG) << "Before m_backGnd_world delete";
616     delete m_backGnd_world;
617   }
618 
619   // create the arena view
620   if (m_scene_arena != 0)
621   {
622     qCDebug(KSIRK_LOG) << "Before m_scene_arena delete";
623     delete m_scene_arena;
624   }
625   m_scene_arena = new QGraphicsScene(0, 0, width, height,this);
626 
627   if (m_frame != 0)
628   {
629     m_frame->setUpdatesEnabled(false);
630     m_uparrow = 0;
631     m_downarrow = 0;
632     m_leftarrow = 0;
633     m_rightarrow = 0;
634     m_centralWidget->removeWidget(m_frame);
635     delete m_frame;
636     m_frame = 0;
637   }
638   if (m_scene_world != 0)
639   {
640     qCDebug(KSIRK_LOG) << "Before m_scene_world delete";
641     delete m_scene_world;
642   }
643   m_scene_world = new QGraphicsScene(0, 0, width, height,this);
644 
645   qCDebug(KSIRK_LOG) << "create the world map view";
646   if (m_theWorld != 0)
647   {
648     m_frame = new DecoratedGameFrame(m_centralWidget, width, height, m_automaton);
649     m_frame->setMaximumWidth(width);
650     m_frame->setMaximumHeight(height);
651     m_frame->setCacheMode( QGraphicsView::CacheBackground );
652     m_frame->setIcon();
653   }
654 
655   if (m_arena != 0)
656   {
657     m_centralWidget->removeWidget(m_arena);
658     delete m_arena;
659     m_arena = 0;
660   }
661   if (m_theWorld != 0)
662   {
663     m_arena = new FightArena(m_centralWidget, width, height, m_scene_arena, m_theWorld, m_automaton);
664     m_arena->setMaximumWidth(width);
665     m_arena->setMaximumHeight(height);
666     m_arena->setCacheMode( QGraphicsView::CacheBackground );
667   }
668 
669   qCDebug(KSIRK_LOG) << "put the menu, map and arena in the central widget";
670   if (m_frame != 0)
671   {
672     m_centralWidget->addWidget(m_frame); // MAP_INDEX 6
673   }
674   if (m_arena != 0)
675   {
676     m_centralWidget->addWidget(m_arena); // ARENA_INDEX 7
677   }
678 
679   if (m_theWorld == 0)
680   {
681     return;
682   }
683   m_backGnd_arena = new BackGnd(m_scene_arena, m_theWorld, true);
684   m_backGnd_world = new BackGnd(m_scene_world, m_theWorld);
685 
686 //   m_scene_world->setDoubleBuffering(true);
687   qCDebug(KSIRK_LOG) << "Before initView";
688   initView();
689   qCDebug(KSIRK_LOG) <<"After m_backGnd new="<< m_backGnd_world;
690   m_frame->setFocus();
691 
692   m_uparrow = new Sprites::ArrowSprite(Qt::UpArrow, m_backGnd_world);
693   m_uparrow->setZValue(1000);
694   QPointF pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,0));
695   pos = pos + QPointF(-(m_uparrow->boundingRect().width()/2),m_uparrow->boundingRect().height());
696   m_uparrow->setPos(pos);
697   m_uparrow->setActive(false);
698 
699   m_downarrow = new Sprites::ArrowSprite(Qt::DownArrow, m_backGnd_world);
700   m_downarrow->setZValue(1000);
701   pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width()/2,m_frame->viewport()->height()));
702   pos = pos - QPointF(m_downarrow->boundingRect().width()/2,m_downarrow->boundingRect().height());
703   m_downarrow->setPos(pos);
704   m_downarrow->setActive(false);
705   pos = m_frame->mapToScene(QPoint(0,m_frame->viewport()->height()/2));
706 
707   m_leftarrow = new Sprites::ArrowSprite(Qt::LeftArrow, m_backGnd_world);
708   m_leftarrow->setZValue(1000);
709   pos = pos + QPointF(m_leftarrow->boundingRect().width(),-(m_leftarrow->boundingRect().height()/2));
710   m_leftarrow->setPos(pos);
711   m_leftarrow->setActive(false);
712 
713   m_rightarrow = new Sprites::ArrowSprite(Qt::RightArrow, m_backGnd_world);
714   m_rightarrow->setZValue(1000);
715   pos = m_frame->mapToScene(QPoint(m_frame->viewport()->width(),m_frame->viewport()->height()/2));
716   pos = pos - QPointF(m_rightarrow->boundingRect().width(),m_rightarrow->boundingRect().height()/2);
717   m_rightarrow->setPos(pos);
718   m_rightarrow->setActive(false);
719 
720   qCDebug(KSIRK_LOG) <<"End new skin";
721 }
722 
getRightDialog()723 KRightDialog * KGameWindow::getRightDialog()
724 {
725   return m_rightDialog;
726 }
727 
initView()728 void KGameWindow::initView()
729 {
730   qCDebug(KSIRK_LOG);
731   QString iconFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/soldierKneeling.png");
732   if (iconFileName.isNull())
733   {
734       KMessageBox::error(0, i18n("Cannot load icon<br>Program cannot continue"), i18n("Error!"));
735       exit(2);
736   }
737 // to port : still necessary ?
738 //   m_frame->setIcon(QPixmap(iconFileName));
739 
740   disconnectMouse();
741   reconnectMouse();
742   setCaption("KsirK",false);
743   m_scene_world-> update();
744   m_frame->setScene(m_scene_world);
745 
746   m_scene_arena-> update();
747   m_arena->setScene(m_scene_arena);
748 
749   //ADD a dock widget on the right
750 
751   if (m_rightDialog != 0)
752   {
753     m_rightDialog->hide();
754     delete m_rightDialog;
755   }
756 
757   if (m_rightDock != 0)
758   {
759     m_rightDock->hide();
760     delete m_rightDock;
761   }
762   m_rightDock = new QDockWidget(this);
763   m_rightDock->setObjectName("right-dock");
764   m_rightDock->setAllowedAreas(Qt::RightDockWidgetArea | Qt::LeftDockWidgetArea);
765   m_rightDock->setFeatures(QDockWidget::NoDockWidgetFeatures);
766 
767   m_rightDialog = new KRightDialog(m_rightDock,theWorld(),this);
768   m_rightDock->setWidget(m_rightDialog);
769   qCDebug(KSIRK_LOG) << "hiding right dock";
770   m_rightDock->hide();
771   addDockWidget(Qt::RightDockWidgetArea, m_rightDock);
772   m_frame->setFocus();
773 }
774 
attackEnd()775 bool KGameWindow::attackEnd()
776 {
777   qCDebug(KSIRK_LOG);
778   if (m_firstCountry==0 || m_secondCountry == 0)
779   {
780     return false;
781   }
782 
783   m_firstCountry->releaseHighlightingLock();
784   m_firstCountry->clearHighlighting();
785   m_secondCountry->releaseHighlightingLock();
786   m_secondCountry->clearHighlighting();
787 
788   // Bug 315491.
789   bool playerDeleted = false;
790   bool res = false;
791   QString mes = "";
792   qCDebug(KSIRK_LOG) << "There is now " << m_secondCountry-> nbArmies() << " armies in " << m_secondCountry->name() << ".";
793   if (m_secondCountry-> nbArmies() < 1)
794   {
795     QPixmap pm = currentPlayer()->getFlag()->image(0);
796 
797     KMessageParts messageParts;
798     messageParts << pm << I18N_NOOP("<font color=\"red\">%1 conquered %2 from %3</font>") << currentPlayer()->name() << m_secondCountry-> name() << m_firstCountry-> name();
799     broadcastChangeItem(messageParts, ID_NO_STATUS_MSG);
800 
801     Player* oldOwner = m_secondCountry-> owner();
802     unsigned int newOldOwnerNbCountries = oldOwner-> getNbCountries() - 1;
803 
804     if (m_automaton->isAdmin())
805     {
806       currentPlayer()-> incrNbCountries();
807       oldOwner-> decrNbCountries();
808     }
809 
810     m_secondCountry-> owner(currentPlayer());
811     m_secondCountry-> nbArmies(currentPlayer()->getNbAttack());
812     m_firstCountry-> decrNbArmies(currentPlayer()->getNbAttack());
813     m_scene_world-> update();
814     if (m_firstCountry->nbArmies() > 1)
815     {
816       res = true;
817     }
818     qCDebug(KSIRK_LOG) << oldOwner-> name() << " now owns " << newOldOwnerNbCountries << " countries.";
819     if (newOldOwnerNbCountries == 0)
820     {
821       QString oldOwnerId = oldOwner->name();
822       showMessage(i18n("%1, you are defeated! Bye, bye...",oldOwner->name()), 10, ForceShowing);
823 /*      KMessageBox::information(this,
824                                i18n("%1, you are defeated! Bye, bye...",oldOwner->name()),
825                                i18n("KsirK - Game Over!"));*/
826       if (m_automaton->isAdmin())
827       {
828         // Bug 315491.
829         playerDeleted = true;
830         qCDebug(KSIRK_LOG) << "Removing player " << oldOwner-> name();
831         int i = m_automaton->playerList()->indexOf(oldOwner);
832         if (i != -1)
833           delete m_automaton->playerList()->takeAt(i);
834         qCDebug(KSIRK_LOG) << "There is now " << m_automaton->playerList()->count() << " players";
835         m_automaton->setMinPlayers(m_automaton->playerList()->count());
836         m_automaton->setGameStatus(KGame::Run);
837       }
838       if ( m_automaton->isAdmin()
839         && ( ( m_automaton->useGoals()
840              && ( currentPlayer()->goal().type() == GameLogic::Goal::GoalPlayer)
841              && ( *currentPlayer()->goal().players().begin() == oldOwnerId ) )
842            || (m_automaton->playerList()->count() == 1) ) )
843       {
844         m_automaton->state(GameLogic::GameAutomaton::GAME_OVER);
845         QByteArray buffer;
846         QDataStream stream(&buffer, QIODevice::WriteOnly);
847         stream << currentPlayer()->id();
848         m_automaton->sendMessage(buffer,Winner);
849         res = false;
850       }
851       else if (m_automaton->isAdmin())
852       {
853         foreach (KPlayer* player, *m_automaton->playerList())
854         {
855           m_automaton->checkGoal((Player*)player);
856         }
857       }
858     }
859     else if (m_automaton->isAdmin())
860     {
861       m_automaton->checkGoal();
862     }
863   }
864   // Bug 315491.
865   if (!playerDeleted)
866   {
867     if (backGnd()->bgIsArena())
868     {
869       m_arena->countryAttack()->createArmiesSprites();
870       m_arena->countryDefense()->createArmiesSprites();
871     }
872     else
873     {
874       m_firstCountry->createArmiesSprites();
875       m_secondCountry->createArmiesSprites();
876     }
877   }
878   if (m_automaton->isAdmin())
879   {
880     if (res)
881     {
882       QByteArray buffer;
883       QDataStream stream(&buffer, QIODevice::WriteOnly);
884       m_automaton->sendMessage(buffer,StartLocalCurrentAI);
885     }
886     else
887     {
888       if (m_firstCountry->nbArmies() < 2 || !m_automaton->isAttackAuto())
889       {
890         QByteArray buffer;
891         QDataStream stream(&buffer, QIODevice::WriteOnly);
892         m_automaton->sendMessage(buffer,ClearHighlighting);
893         KMessageParts messageParts;
894         messageParts << I18N_NOOP("%1: it is up to you again") << currentPlayer()-> name();
895         broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
896       }
897     }
898   }
899   m_automaton->setGameStatus(KGame::Run);
900   return res;
901 }
902 
winner(const Player * player)903 void KGameWindow::winner(const Player* player)
904 {
905   qCDebug(KSIRK_LOG) << player->name();
906   QString msg = i18n("%1 won!");
907   if (!player->isVirtual())
908   {
909     msg = i18n("<big><b>%1</b>, you won!</big>");
910   }
911   if (m_automaton->useGoals())
912   {
913     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());
914   }
915   else
916   {
917     if (!player->isVirtual())
918     {
919       msg += i18n("<br>You conquered all the world!");
920     }
921     else
922     {
923       msg += i18n("<br>He conquered all the world!");
924     }
925   }
926   RestartOrExitDialogImpl* restartDia = new RestartOrExitDialogImpl(i18n(msg.toUtf8().data(),player->name()));
927 
928   connect((QObject*)restartDia->newGameButton,
929               SIGNAL(clicked()),
930               this,
931               SLOT(slotNewGame()));
932 
933   connect((QObject*)restartDia->exitButton,
934               SIGNAL(clicked()),
935               this,
936               SLOT(slotExit()));
937 
938   restartDia->show();
939 }
940 
resolveAttack()941 void KGameWindow::resolveAttack()
942 {
943 
944 //    qCDebug(KSIRK_LOG) << "KGameWindow::resolveAttack";
945 
946   int A1 = -1; int A2 = -1; int A3 = -1; int AE = -1;
947   int D1 = -1; int D2 = -1; int DE = -1;
948 
949   NKD = NKA = 0;
950   if (currentPlayer() == 0 || m_secondCountry == 0 || m_secondCountry->owner() == 0 || m_firstCountry == 0)
951     return;
952 
953   int secondOldNbArmies = m_secondCountry->nbArmies();
954 
955   A1 = Dice::roll();
956   if (currentPlayer()-> getNbAttack() > 1) A2 = Dice::roll();
957   if (currentPlayer()-> getNbAttack() > 2) A3 = Dice::roll();
958   if ((A1>=A2)&&(A1>=A3))  // A1 is the greater ; don't move it; look at the two others
959     if (A2>=A3) {} // A2 greater than A3 ; don't move
960     else {AE = A2;A2 = A3;A3 = AE;} // A2 lesser than A3 ; swap them
961   else
962   { // A1 is not the greater
963     if (A2>=A3) {AE=A1;A1=A2;A2=AE;}  // A2 is greater than A3, so it is the greater; swap it with A1
964     else {AE=A1;A1=A3;A3=AE;} // A3 is greater than A2, so it is the greater; swap it with A1
965                                             // now the new A1 is the greater, look at the 2 others
966     if (A2>=A3) {} // A2 greater than A3, nothing to do
967     else {AE=A2;A2=A3;A3=AE;} // A2 lesser than A3; swap them
968   }
969   D1 = Dice::roll();
970   if (m_secondCountry-> owner()-> getNbDefense() > 1)
971     D2 = Dice::roll();
972   if (D2>D1) {DE=D1;D1=D2;D2=DE;}
973   if (A1>D1)
974   {
975     QByteArray buffer;
976     QDataStream stream(&buffer, QIODevice::WriteOnly);
977     stream << m_secondCountry->name() << quint32(1);
978     m_automaton->sendMessage(buffer,DecrNbArmies);
979     NKD++;
980   }
981   else
982   {
983     QByteArray buffer;
984     QDataStream stream(&buffer, QIODevice::WriteOnly);
985     stream << m_firstCountry->name() << quint32(1);
986     m_automaton->sendMessage(buffer,DecrNbArmies);
987     NKA++;
988   }
989   if ((A2>0)&&(D2>0))
990   {
991     if (A2>D2)
992     {
993       QByteArray buffer;
994       QDataStream stream(&buffer, QIODevice::WriteOnly);
995       stream << m_secondCountry->name() << quint32(1);
996       m_automaton->sendMessage(buffer,DecrNbArmies);
997       NKD++;
998     }
999     else
1000     {
1001       QByteArray buffer;
1002       QDataStream stream(&buffer, QIODevice::WriteOnly);
1003       stream << m_firstCountry->name() << quint32(1);
1004       m_automaton->sendMessage(buffer,DecrNbArmies);
1005       NKA++;
1006     }
1007   }
1008 //   qCDebug(KSIRK_LOG) << "(" << A1<<", "<<A2<<", "<<A3<<") <-> ("<<D1<<", "<<D2<<")" ;
1009 //   qCDebug(KSIRK_LOG) << "Attacker loses " << NKA<<" armies; Defender loses "<<NKD<<" armies." ;
1010 
1011   QByteArray buffer3;
1012   QDataStream stream3(&buffer3, QIODevice::WriteOnly);
1013   stream3 << (quint32)A1 << (quint32)A2 << (quint32)A3 << (quint32)D1 << (quint32)D2 << (quint32)NKA << (quint32)NKD << (quint32)(secondOldNbArmies-NKD < 1);
1014   qCDebug(KSIRK_LOG) << "sending DisplayFightResult";
1015   m_automaton->sendMessage(buffer3,DisplayFightResult);
1016 
1017   QByteArray buffer2;
1018   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1019 
1020   if ((NKD != 0)&&(NKA != 0)) stream2 << quint32(2);
1021   else if (NKA != 0) stream2 << quint32(0);
1022   else if (NKD != 0) stream2 << quint32(1);
1023   m_automaton->sendMessage(buffer2,AnimExplosion);
1024 
1025   //qCDebug(KSIRK_LOG)<< "A1:"<< A1<<", A2: " <<A2 <<"A3:" << A3;
1026   //qCDebug(KSIRK_LOG)<< "D1:"<< D1<<", D2: " <<D2;
1027   // if arena is displayed, update the arena countries too
1028   if (currentWidgetType() == Arena) {
1029     arena()->countryAttack()->decrNbArmies(NKA);
1030     arena()->countryDefense()->decrNbArmies(NKD);
1031   }
1032   m_secondCountry-> owner()-> setNbDefense(0);
1033 }
1034 
1035 
1036 
1037 /**
1038   * Reimplementation of the inherited function called when a window close event arise
1039   */
queryClose()1040 bool KGameWindow::queryClose()
1041 {
1042   qCDebug(KSIRK_LOG);
1043 
1044   if ((m_automaton->state() == GameAutomaton::INIT) || (m_automaton->state() ==  GameAutomaton::INTERLUDE))
1045   {
1046     switch ( KMessageBox::warningYesNo( this, i18n("Do you want to quit the game?")) )
1047     {
1048     case KMessageBox::Yes :
1049         break;
1050     default:
1051         return false;
1052     }
1053   }
1054   else
1055   {
1056     switch ( KMessageBox::warningYesNoCancel( this, i18n("Before you quit, do you want to save your game?")) )
1057     {
1058     case KMessageBox::Yes :
1059         slotSaveGame();
1060         break;
1061     case KMessageBox::No :
1062         break;
1063     default: // cancel
1064         return false;
1065     }
1066   }
1067 //   hide();
1068   disconnect(&m_timer,SIGNAL(timeout()),this,SLOT(evenementTimer()));
1069   disconnectMouse();
1070   m_mouseLocalisation = 0;
1071   m_automaton->setGameStatus(KGame::End);
1072 
1073 /*  if (m_theWorld != 0)
1074   {
1075     delete m_theWorld;
1076     m_theWorld = 0;
1077   }
1078   while (!m_automaton->playerList()->isEmpty())
1079   {
1080     delete m_automaton->playerList()->takeFirst();
1081   }
1082   delete m_automaton; m_automaton = 0;*/
1083   KSharedConfig::openConfig()->sync();
1084   return true;
1085 }
1086 
actionOpenGame()1087 bool KGameWindow::actionOpenGame()
1088 {
1089   qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame";
1090 
1091   QString fileName = QFileDialog::getOpenFileName(this, i18nc("@title:window", "KsirK - Load Game"), QString(), "*.xml");
1092   if (!fileName.isEmpty())
1093   {
1094     m_fileName = fileName;
1095     m_automaton->setGameStatus(KGame::End);
1096     m_waitedPlayers.clear();
1097     qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame loader";
1098     Ksirk::SaveLoad::GameXmlLoader loader(fileName, *this, m_waitedPlayers);
1099     qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame loading done";
1100     for (unsigned int i = 0; i < m_theWorld->getNbCountries(); i++)
1101     {
1102       Country* country = m_theWorld-> getCountries().at(i);
1103       qCDebug(KSIRK_LOG) << "Adding sprites to " << country->name();
1104       country-> createArmiesSprites();
1105       Player *player = country-> owner();
1106       if (player)
1107       {
1108         country-> flag(player->flagFileName(), m_backGnd_world);
1109       }
1110     }
1111     m_backGnd_world->hide();
1112     m_backGnd_world->show();
1113     if (m_waitedPlayers.empty())
1114     {
1115       QByteArray buffer;
1116       QDataStream stream(&buffer, QIODevice::WriteOnly);
1117       m_automaton->sendMessage(buffer,StartGame);
1118       m_automaton->sendMessage(buffer,ClearHighlighting);
1119       m_frame->setFocus();
1120       qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame false1";
1121       m_frame->setArenaOptionEnabled(true);
1122       reduceChat();
1123 
1124       return false;
1125     }
1126     else
1127     {
1128       KMessageParts messageParts;
1129       messageParts << I18N_NOOP("Waiting for the connection of %1 network players.") << QString::number(m_waitedPlayers.size());
1130       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1131       qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame true";
1132       unreduceChat();
1133       m_frame->setArenaOptionEnabled(false);
1134       return true;
1135     }
1136   }
1137   qCDebug(KSIRK_LOG) << "KGameWindow::actionOpenGame false2";
1138   return false;
1139 }
1140 
displayRecyclingButtons()1141 void KGameWindow::displayRecyclingButtons()
1142 {
1143   qCDebug(KSIRK_LOG);
1144   if (m_automaton->allLocalPlayersComputer())
1145   {
1146 //     qCDebug(KSIRK_LOG) << "There is only computer local players";
1147     PlayersArray::iterator it = m_automaton->playerList()->begin();
1148     PlayersArray::iterator it_end = m_automaton->playerList()->end();
1149     for (; it != it_end; it++)
1150     {
1151 //       qCDebug(KSIRK_LOG) << "Looking at player " << (*it)->name()
1152 //               << ". is AI  : " << ((Player*)(*it))->isAI()
1153 //               << ". isRunning: " << ((static_cast<AIPlayer *>(*it))-> isRunning())
1154 //               << ". virtual: " << (*it)->isVirtual()
1155 //                      ;
1156       if ( ((Player*)(*it))->isAI()
1157            && (!(static_cast<AIPlayer *>(*it))-> isRunning())
1158         && (!(*it)->isVirtual()) )
1159       {
1160 //         qCDebug(KSIRK_LOG) << "Starting computer player " << (*it)->name();
1161         (static_cast<AIPlayer *>(*it))-> start();
1162         break;
1163       }
1164     }
1165   }
1166   else
1167   {
1168     m_rightDock->show();
1169   }
1170   m_nextPlayerAction->setEnabled(false);
1171 }
1172 
clearHighlighting()1173 void KGameWindow::clearHighlighting()
1174 {
1175   qCDebug(KSIRK_LOG);
1176   if (m_firstCountry != 0)
1177   {
1178     m_firstCountry->releaseHighlightingLock();
1179     m_firstCountry->clearHighlighting();
1180     m_firstCountry = 0;
1181   }
1182   if (m_secondCountry != 0)
1183   {
1184     m_secondCountry->releaseHighlightingLock();
1185     m_secondCountry->clearHighlighting();
1186     m_secondCountry = 0;
1187   }
1188 
1189   if (currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()))
1190   {
1191     if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning()) (static_cast<AIPlayer *>(currentPlayer()))-> start();
1192     m_nextPlayerAction->setEnabled(false);
1193   }
1194   else if (currentPlayer() && !currentPlayer()->isVirtual())
1195   {
1196     slotContextualHelp();
1197     m_nextPlayerAction->setEnabled(true);
1198   }
1199   else
1200   {
1201     m_nextPlayerAction->setEnabled(false);
1202   }
1203 }
1204 
defenseLabel()1205 QString KGameWindow::defenseLabel()
1206 {
1207   if (firstCountry() && firstCountry()->owner() && secondCountry())
1208     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>?",
1209                         "<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>?",
1210                         QString::number(this->firstCountry()->owner()->getNbAttack()),
1211                         this->firstCountry()->owner()->name(),
1212                         this->firstCountry()->name(),
1213                         this->secondCountry()->name());
1214   else
1215     return "";
1216 }
1217 
createDefenseDialog()1218 void KGameWindow::createDefenseDialog()
1219 {
1220   qCDebug(KSIRK_LOG);
1221   // Create Window Dialog
1222   m_defenseDialog = new QDialog ();
1223 
1224   QWidget* widget = new QWidget(m_defenseDialog);
1225   QGridLayout * mainLayout = new QGridLayout(widget);
1226 
1227   // Create the differents layout for buttons and label
1228   QGridLayout * bottomLayout = new QGridLayout();
1229   QGridLayout * topLayout = new QGridLayout();
1230 
1231   // Create and add the main Layout
1232   widget->setLayout(mainLayout);
1233   mainLayout->addLayout(bottomLayout, 1, 0, Qt::AlignCenter);
1234   mainLayout->addLayout(topLayout, 0, 0, Qt::AlignCenter);
1235 
1236   // Creat buttons and label of defense
1237   QPushButton * def1 = new QPushButton (i18n("Defend 1"));
1238   QPushButton * def2 = new QPushButton (i18n("Defend 2"));
1239   QPushButton * defAuto = new QPushButton (i18n("Defend-Auto"));
1240 
1241   m_labDef = new QLabel ();
1242   m_labDef->setText(defenseLabel());
1243 
1244   // Add icons on buttons
1245   QString skin = m_automaton->game()->theWorld()->skin();
1246   QString imageFileName;
1247 
1248   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/defendOne.png");
1249   def1->setIcon(QIcon(imageFileName));
1250   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/defendTwo.png");
1251   def2->setIcon(QIcon(imageFileName));
1252   imageFileName = QStandardPaths::locate(QStandardPaths::AppDataLocation, skin + "/Images/attackAuto.png");
1253   defAuto->setIcon(QIcon(imageFileName));
1254 
1255 
1256   // Disable Defend 2 when attack with 1 army or defender have only 1 army
1257   if (this->firstCountry()->owner()->getNbAttack() == 1)
1258      def2->setEnabled(false);
1259 
1260   // Add buttons and layout
1261   bottomLayout->addWidget(def1,0,0);
1262   bottomLayout->addWidget(def2,0,1);
1263   bottomLayout->addWidget(defAuto,0,2);
1264   topLayout->addWidget(m_labDef, 0, 0);
1265 
1266   connect(def1, SIGNAL(clicked()), this, SLOT(slotWindowDef1()));
1267   connect(def2, SIGNAL(clicked()), this, SLOT(slotWindowDef2()));
1268   connect(defAuto, SIGNAL(clicked()), this, SLOT(slotDefAuto()));
1269 
1270   QVBoxLayout *dialogLayout = new QVBoxLayout(m_defenseDialog);
1271   dialogLayout->addWidget(widget);
1272 }
1273 
displayDefenseWindow()1274 void KGameWindow::displayDefenseWindow()
1275 {
1276   qCDebug(KSIRK_LOG);
1277   if (m_defenseDialog == 0)
1278     createDefenseDialog();
1279   else
1280     m_labDef->setText(defenseLabel());
1281   m_defenseDialog->exec();
1282 }
1283 
startLocalCurrentAI()1284 void KGameWindow::startLocalCurrentAI()
1285 {
1286   qCDebug(KSIRK_LOG);
1287   if (currentPlayer() && currentPlayer()-> isAI()  && (!currentPlayer()->isVirtual()))
1288   {
1289     if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning())
1290       (static_cast<AIPlayer *>(currentPlayer()))-> start();
1291   }
1292 }
1293 
setBarFlagButton(const Player * player)1294 void KGameWindow::setBarFlagButton(const Player* player)
1295 {
1296 //   qCDebug(KSIRK_LOG) << "KGameWindow::setBarFlagButton";
1297 
1298   if (player == 0)
1299   {
1300     if (currentPlayer()
1301         && currentPlayer()-> getFlag())
1302     {
1303       if (!m_goalAction->isVisible())
1304         m_goalAction->setVisible(true);
1305       m_goalAction-> setIcon(QIcon(currentPlayer()->getFlag()-> image(0)));
1306       m_goalAction-> setIconText(i18n("Goal"));
1307       m_barFlag-> setPixmap(currentPlayer()->getFlag()-> image(0));
1308       m_barFlag->show();
1309     }
1310   }
1311   else
1312   {
1313     if (player-> getFlag())
1314     {
1315       if (!m_goalAction->isVisible())
1316         m_goalAction->setVisible(true);
1317       m_goalAction-> setIcon(QIcon(player-> getFlag()-> image(0)));
1318       m_goalAction-> setIconText(i18n("Goal"));
1319       m_barFlag-> setPixmap(player->getFlag()-> image(0));
1320       m_barFlag->show();
1321     }
1322   }
1323   m_frame->setFocus();
1324 }
1325 
finishSetupPlayers()1326 bool KGameWindow::finishSetupPlayers()
1327 {
1328   qCDebug(KSIRK_LOG);
1329   if (!(m_automaton->playerList()->isEmpty()))
1330   {
1331     m_automaton->playerList()->clear();
1332     m_automaton->currentPlayer(0);
1333     qCDebug(KSIRK_LOG) << "  playerList size = " << m_automaton->playerList()->count();
1334   }
1335   theWorld()->reset();
1336 
1337   QMap< QString, QString > nations = nationsList();
1338   if (!(m_automaton->playerList()->isEmpty()))
1339   {
1340     m_automaton->playerList()->clear();
1341   }
1342   qCDebug(KSIRK_LOG) << "newPlayersNumber = " << m_newGameSetup->players().size();
1343   unsigned int nbAvailArmies = (unsigned int)(m_theWorld->getNbCountries() * 2.5 / m_newGameSetup->players().size());
1344   qCDebug(KSIRK_LOG) << "nbAvailArmies = " << nbAvailArmies << " ; nb countries = " << m_theWorld->getNbCountries();
1345   QString nomEntre = "";
1346   QString password = "";
1347   QString nationName = "";
1348   m_newPlayerWidget->init(m_automaton,m_theWorld,(int)1,nomEntre,password,false,nations,nationName, m_newGameSetup);
1349   m_centralWidget->setCurrentIndex(NEWPLAYER_INDEX);
1350   // Players names
1351   QString mes = "";
1352   if (m_newGameSetup->networkGameType() != GameAutomaton::None)
1353   {
1354     m_frame->setArenaOptionEnabled(false);
1355     unreduceChat();
1356     qCDebug(KSIRK_LOG) << "In setupPlayers: networkGame";
1357     KMessageParts messageParts;
1358     messageParts << I18N_NOOP("Waiting for %1 players to connect")
1359       << QString::number(m_newGameSetup->nbNetworkPlayers());
1360     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1361   }
1362   else
1363   {
1364     m_frame->setArenaOptionEnabled(true);
1365     reduceChat();
1366   }
1367   m_frame->setFocus();
1368   return true;
1369 }
1370 
setupOnePlayer()1371 bool KGameWindow::setupOnePlayer()
1372 {
1373   qCDebug(KSIRK_LOG) << "KGameWindow::setupOnePlayer";
1374 
1375   qCDebug(KSIRK_LOG) << "  building the list of available nations";
1376   QMap< QString, QString > nations = nationsList();
1377   PlayersArray::iterator it = m_automaton->playerList()->begin();
1378   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1379   for (; it != it_end; it++)
1380   {
1381     Player* player = (Player*)(*it);
1382     qCDebug(KSIRK_LOG) << "    removing nation of player " << player-> name();
1383     /// Don't understand why if using Player::getNation below, the method is
1384     /// not executed (get 0) but if using the same named myNation, it works...
1385     /// Ideas anybody ????
1386     Nationality* nation = player-> getNation();
1387     qCDebug(KSIRK_LOG) << "    got player nation " << nation;
1388     QString nationName = nation->name();
1389     QMap<QString,QString>::iterator nationsIt;
1390     nationsIt = nations.find(nationName);
1391     if (nationsIt !=  nations.end())
1392     {
1393       nations.erase(nationsIt);
1394     }
1395   }
1396   qCDebug(KSIRK_LOG) << "  number of available nations: " << nations.size();
1397   unsigned int nbAvailArmies = (unsigned int)(m_theWorld->getNbCountries() * 2.5 / (m_automaton->nbPlayers()));
1398   qCDebug(KSIRK_LOG) << "KGameWindow::setupOnePlayer: nbAvailArmies = " << nbAvailArmies << " ; nb countries = " << m_theWorld->getNbCountries();
1399   // Players names
1400   QString mes = "";
1401   QString nationName;
1402 
1403   QString nomEntre = "";
1404   QString password;
1405   bool computer=false;
1406 
1407   m_newPlayerWidget->init(m_automaton, m_theWorld, 1, nomEntre, password, computer, nations, nationName, m_newGameSetup);
1408   m_centralWidget->setCurrentIndex(NEWPLAYER_INDEX);
1409   return true;
1410 }
1411 
setupOneWaitedPlayer()1412 bool KGameWindow::setupOneWaitedPlayer()
1413 {
1414   qCDebug(KSIRK_LOG) << "KGameWindow::setupOneWaitedPlayer";
1415 
1416   QString password;
1417   int result;
1418   KWaitedPlayerSetupDialog(m_automaton, password, result, this).exec();
1419   qCDebug(KSIRK_LOG) << "After KWaitedPlayerSetupDialog. number: " << result << ", password: " << password;
1420   QByteArray buffer;
1421   QDataStream stream(&buffer, QIODevice::WriteOnly);
1422   stream << (quint32)result << password;
1423   m_automaton->sendMessage(buffer,ValidateWaitedPlayerPassword);
1424   return true;
1425 }
1426 
createWaitedPlayer(quint32 waitedPlayerId)1427 bool KGameWindow::createWaitedPlayer(quint32 waitedPlayerId)
1428 {
1429   qCDebug(KSIRK_LOG) << "KGameWindow::createWaitedPlayer";
1430 
1431   PlayerMatrix& pm = m_waitedPlayers[waitedPlayerId];
1432   Player* player = addPlayer(pm.name, pm.nbAvailArmies,
1433                               pm.nbCountries, pm.nation,
1434                               pm.isAI, pm.password,
1435                               pm.nbAttack, pm.nbDefense);
1436 
1437   player->goal(pm.goal);
1438   QList<QString>::iterator it, it_end;
1439   it = pm.countries.begin(); it_end = pm.countries.end();
1440   for (; it != it_end; it++)
1441   {
1442     QByteArray buffer;
1443     QDataStream stream(&buffer, QIODevice::WriteOnly);
1444     stream << (*it) << pm.name;
1445     m_automaton->sendMessage(buffer,CountryOwner);
1446   }
1447   return true;
1448 }
1449 
distributeArmies()1450 void KGameWindow::distributeArmies()
1451 {
1452   qCDebug(KSIRK_LOG) << "KGameWindow::distributeArmies";
1453   PlayersArray::iterator it = m_automaton->playerList()->begin();
1454   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1455   for (; it != it_end; it++)
1456   {
1457     unsigned int nb = nbNewArmies(dynamic_cast<Player*>(*it));
1458 //     qCDebug(KSIRK_LOG) << "    Giving " << nb << " armies to " << static_cast<Player*>(*it)->name();
1459     dynamic_cast<Player*>(*it)-> setNbAvailArmies(nb, true);
1460   }
1461 }
1462 
nbNewArmies(Player * player)1463 int KGameWindow::nbNewArmies(Player *player)
1464 {
1465 //    qCDebug(KSIRK_LOG) << "KGameWindow::nbNewArmies for "  << player-> name();
1466 
1467   unsigned int res = 0;
1468 
1469   for (unsigned int i = 0; i<m_theWorld->getNbCountries(); i++)
1470       if (m_theWorld-> getCountries().at(i)-> owner() == player) res++;
1471   res = (res/3) < 3 ? 3 : res/3 ;
1472 
1473   QList<Continent*>& continents = m_theWorld-> getContinents();
1474   QList<Continent*>::iterator it = continents.begin();
1475   for (; it != continents.end(); it++)
1476   {
1477     Continent* currCont = *it;
1478     if (currCont-> owner() == player)
1479     {
1480 //            qCDebug(KSIRK_LOG) << ">>>>>>>>>>> Adding bonus for "  << currCont-> name();
1481       res += currCont-> getBonus();
1482     }
1483   }
1484 
1485   return res;
1486 }
1487 
changeItem(const QString & text,int id,bool log)1488 void KGameWindow::changeItem( const QString& text, int id, bool log )
1489 {
1490   if (id != ID_NO_STATUS_MSG)
1491   {
1492       //QT5 statusBar()-> changeItem(text, id);
1493   }
1494   if (log)
1495   {
1496     KsirkChatItem item;
1497     item << text;
1498 //     m_chatDlg->addMessage("",text);
1499 // to port
1500 //     m_chatDlg->addSystemMessage   ( "", text  ) ;
1501   }
1502 }
1503 
changeItem(KMessageParts & strings,int id,bool log)1504 void KGameWindow::changeItem( KMessageParts& strings, int id, bool log )
1505 {
1506 //  qCDebug(KSIRK_LOG) << "KGameWindow::changeItem(KMessageParts,int, log)" << strings.size() << id << log;
1507   if (strings.begin() == strings.end())
1508   {
1509 //     qCDebug(KSIRK_LOG) << "  nothing " << strings.size();
1510     return;
1511   }
1512   bool arguing = false;
1513   KLocalizedString argument;
1514   KsirkChatItem item;
1515   KMessageParts::iterator it, it_end;
1516   it = strings.begin(); it_end = strings.end();
1517   if (it.curIsStr())
1518   {
1519     if (!it.curStr().isEmpty())
1520     {
1521 //       qCDebug(KSIRK_LOG) << "setting argument to: '" << it.curStr() << "'";
1522       argument = ki18n(it.curStr().toUtf8().data());
1523     }
1524     else
1525     {
1526 //       qCDebug(KSIRK_LOG) << "setting argument to empty";
1527       argument = KLocalizedString();
1528     }
1529     arguing = true;
1530   }
1531   else if (it.curIsPix())
1532   {
1533 //     qCDebug(KSIRK_LOG) << "first item is pixmap";
1534     item << it.curPix();
1535   }
1536 
1537   it++;
1538   for (; it != it_end; it++)
1539   {
1540 //     qCDebug(KSIRK_LOG) << "next item";
1541     if (it.curIsStr())
1542     {
1543 //       qCDebug(KSIRK_LOG) << "item is: '" << it.curStr() << "'";
1544       if (arguing)
1545       {
1546 //         qCDebug(KSIRK_LOG) << "  substituting";
1547         argument=argument.subs(it.curStr());
1548       }
1549       else
1550       {
1551 //         qCDebug(KSIRK_LOG) << "  assigning new argument";
1552         if (!it.curStr().isEmpty())
1553         {
1554 //           qCDebug(KSIRK_LOG) << "setting argument to: '" << it.curStr() << "'";
1555           argument = ki18n(it.curStr().toUtf8().data());
1556         }
1557         else
1558         {
1559 //           qCDebug(KSIRK_LOG) << "setting argument to empty";
1560           argument = KLocalizedString();
1561         }
1562         arguing = true;
1563       }
1564     }
1565     else
1566     {
1567       if (arguing)
1568       {
1569 //         qCDebug(KSIRK_LOG) << "  storing";
1570         if (argument.isEmpty())
1571         {
1572           item << QString("");
1573         }
1574         else
1575         {
1576           item << argument.toString();
1577         }
1578       }
1579       item << it.curPix();
1580       arguing = false;
1581     }
1582   }
1583 //   qCDebug(KSIRK_LOG) << "no more items";
1584   if (arguing)
1585   {
1586     if (argument.isEmpty())
1587     {
1588       item << QString("");
1589     }
1590     else
1591     {
1592       item << argument.toString();
1593     }
1594   }
1595   if (log)
1596   {
1597     ((KsirkChatModel*)(m_chatDlg->model()))->addMessage(item);
1598   }
1599   if (id != ID_NO_STATUS_MSG)
1600   {
1601     if (argument.toString() == "(I18N_EMPTY_MESSAGE)")
1602     {
1603       qCCritical(KSIRK_LOG) << "received a (I18N_EMPTY_MESSAGE)";
1604     }
1605 //     qCDebug(KSIRK_LOG) << "  argument: " << argument.toString();
1606     //QT5 statusBar()-> changeItem(argument.toString(), id);
1607   }
1608 }
1609 
broadcastChangeItem(KMessageParts & strings,int id,bool log)1610 void KGameWindow::broadcastChangeItem(KMessageParts& strings, int id, bool log)
1611 {
1612   if (strings.empty())
1613   {
1614     return;
1615   }
1616   QByteArray buffer;
1617   QDataStream stream(&buffer, QIODevice::WriteOnly);
1618 //   qCDebug(KSIRK_LOG) << "Broadcasting change item, size=" << strings.size();
1619   stream << (quint32)id << (quint32)log << (quint32)strings.size();
1620 
1621   KMessageParts::iterator it, it_end;
1622   it = strings.begin(); it_end = strings.end();
1623   if (it != it_end)
1624   {
1625 /*    // if first element is string, convert it to id
1626     if (it.curIsStr())
1627     {
1628       qCDebug(KSIRK_LOG) << "Pushing first element: id "<<m_automaton->idForMsg(it.curStr())<<" for '" << it.curStr() << "'";
1629       stream << (quint32)KMessageParts::StringId << m_automaton->idForMsg(it.curStr());
1630     }
1631     else if (it.curIsPix())
1632     {
1633       qCDebug(KSIRK_LOG) << "Pushing first element pix";
1634       stream << (quint32)KMessageParts::Pixmap << it.curPix();
1635     }
1636     else
1637     {
1638       qCCritical(KSIRK_LOG) << "Unsupported KMessageParts elem type ";
1639     }
1640     it++;*/
1641     for (; it != it_end; it++)
1642     {
1643       if (it.curIsStr())
1644       {
1645 //         qCDebug(KSIRK_LOG) << "Pushing string '" << it.curStr() << "'";
1646         stream << (quint32)KMessageParts::Text << it.curStr();
1647       }
1648       else if (it.curIsPix())
1649       {
1650 //         qCDebug(KSIRK_LOG) << "Pushing pix";
1651         stream << (quint32)KMessageParts::Pixmap << it.curPix();
1652       }
1653       else
1654       {
1655         qCCritical(KSIRK_LOG) << "Unsupported KMessageParts elem type ";
1656       }
1657     }
1658   }
1659   m_automaton->sendMessage(buffer,ChangeItem);
1660   changeItem(strings, id, log );
1661 }
1662 
enterEvent(QEvent *)1663 void KGameWindow::enterEvent(QEvent* /*ev*/)
1664 {
1665 //   qCDebug(KSIRK_LOG) << "KGameWindow::enterEvent()";
1666   // Restart the AIs threads
1667   if ( currentPlayer() )
1668     if ( (currentPlayer()-> isAI()) && (!currentPlayer()->isVirtual()) && ( !((static_cast<AIPlayer*>(currentPlayer()))-> isRunning())) )
1669       (static_cast<AIPlayer*>(currentPlayer()))-> start();
1670 
1671 }
1672 
leaveEvent(QEvent *)1673 void KGameWindow::leaveEvent(QEvent* /*ev*/)
1674 {
1675 //    qCDebug(KSIRK_LOG) << "KGameWindow::leaveEvent()";
1676     // Stops the AIs threads
1677   PlayersArray::iterator it = m_automaton->playerList()->begin();
1678   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1679   for (; it != it_end; it++)
1680   {
1681     if (static_cast<Player*>(*it)-> isAI())
1682     {
1683         (static_cast<AIPlayer*>(*it))-> stop();
1684     }
1685   }
1686 }
1687 
1688 
1689 /** Return true if the state of the game is the argument; false otherwise */
isMyState(GameLogic::GameAutomaton::GameState state) const1690 bool KGameWindow::isMyState(GameLogic::GameAutomaton::GameState state) const
1691 {
1692   return (m_automaton->state() == state);
1693 }
1694 
1695 /**
1696   * returns the current state of the game
1697   */
getState() const1698 GameLogic::GameAutomaton::GameState KGameWindow::getState() const
1699 {
1700   return m_automaton->state();
1701 }
1702 
moveArmies(Country & src,Country & dest,unsigned int nb)1703 void KGameWindow::moveArmies(Country& src, Country& dest, unsigned int nb)
1704 {
1705 //    qCDebug(KSIRK_LOG) << "KGameWindow::moveArmies()";
1706   if ((src.owner() == currentPlayer())
1707       && (dest.owner() == currentPlayer())
1708       && (src.communicateWith(&dest))
1709       && (src.nbArmies() > nb) )
1710   {
1711     QByteArray bufferSrc;
1712     QDataStream streamSrc(&bufferSrc, QIODevice::WriteOnly);
1713     streamSrc << src.name();
1714     m_automaton->sendMessage(bufferSrc,FirstCountry);
1715 
1716     QByteArray bufferDest;
1717     QDataStream streamDest(&bufferDest, QIODevice::WriteOnly);
1718     streamDest << src.name();
1719     m_automaton->sendMessage(bufferDest,SecondCountry);
1720 
1721     int toMove = nb;
1722     while ( toMove >= 10 )
1723     {
1724       toMove -= 10;
1725       slotInvade10();
1726     }
1727     while ( toMove >= 5 )
1728     {
1729       toMove -= 5;
1730       slotInvade5();
1731     }
1732     while ( toMove >= 1 )
1733     {
1734       toMove -= 1;
1735       slotInvade1();
1736     }
1737   }
1738 //    qCDebug(KSIRK_LOG) << "OUT KGameWindow::moveArmies()";
1739 }
1740 
isMoveValid(const QPointF & point)1741 bool KGameWindow::isMoveValid(const QPointF& point)
1742 {
1743   bool res = false;
1744   KMessageParts messageParts;
1745   Country* secondCountry = clickIn(point);
1746   if  ( ( m_firstCountry == 0 ) || ( secondCountry == 0 ) )
1747   {
1748     messageParts << I18N_NOOP("There is no country here!");
1749   }
1750   else if  ( m_firstCountry->owner() != currentPlayer() )
1751   {
1752     messageParts << I18N_NOOP("You are not the owner of the first country: %1!") << m_firstCountry->name();
1753   }
1754   else if ( secondCountry->owner() != currentPlayer() )
1755   {
1756     messageParts << I18N_NOOP("You are not the owner of the second country: %1!") << secondCountry->name();
1757   }
1758   else if (m_firstCountry == secondCountry)
1759   {
1760     messageParts << I18N_NOOP("You are trying to move armies from %1 to itself!") << m_firstCountry->name();
1761   }
1762   else if (!m_firstCountry->communicateWith(secondCountry))
1763   {
1764     messageParts
1765       << I18N_NOOP("%1 is not a neighbour of %2!")
1766       << secondCountry-> name()
1767       << m_firstCountry-> name();
1768   }
1769   else
1770   {
1771     messageParts << I18N_NOOP("Moving armies from %1 to %2.")
1772             << m_firstCountry->name()
1773             << secondCountry->name();
1774     res = true;
1775   }
1776   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1777   return res;
1778 }
1779 
isFightValid(const QPointF & point)1780 bool KGameWindow::isFightValid(const QPointF& point)
1781 {
1782   bool res = false;
1783   KMessageParts messageParts;
1784   Country* secondCountry = clickIn(point);
1785   if  ( ( m_firstCountry == 0 ) || ( secondCountry == 0 ) )
1786   {
1787     qCDebug(KSIRK_LOG) << "There is no country here!";
1788     messageParts << I18N_NOOP("There is no country here!");
1789   }
1790   else if  ( m_firstCountry->owner() != currentPlayer() )
1791   {
1792     qCDebug(KSIRK_LOG) << "You are not the owner of the first country: "<< m_firstCountry->name();
1793     messageParts << I18N_NOOP("You are not the owner of the first country: %1!")
1794             << m_firstCountry->name();
1795   }
1796   else if ( secondCountry->owner() == currentPlayer() )
1797   {
1798     qCDebug(KSIRK_LOG) << "You are the owner of the second country: " << secondCountry->name();
1799     messageParts << I18N_NOOP("You are the owner of the second country: %1!") << secondCountry->name();
1800   }
1801   else if (m_firstCountry == secondCountry)
1802   {
1803     qCDebug(KSIRK_LOG) <<"You are trying to move armies from "<<m_firstCountry->name()<<" to itself ";
1804     messageParts << I18N_NOOP("You are trying to move armies from %1 to itself!") << m_firstCountry->name();
1805   }
1806   else if (!m_firstCountry->communicateWith(secondCountry))
1807   {
1808     qCDebug(KSIRK_LOG) << secondCountry-> name() << "is not a neighbour of " << secondCountry-> name();
1809     messageParts
1810       << I18N_NOOP("%1 is not a neighbour of %2!")
1811       << secondCountry-> name()
1812       << m_firstCountry-> name();
1813   }
1814   else
1815   {
1816     qCDebug(KSIRK_LOG) << "Ready to fight !";
1817     messageParts << I18N_NOOP("Ready to fight!");
1818     res = true;
1819   }
1820   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1821   return res;
1822 }
1823 
setCurrentPlayerToFirst()1824 int KGameWindow::setCurrentPlayerToFirst()
1825 {
1826   if (currentPlayer() && currentPlayer()->isAI()
1827                       && (static_cast<AIPlayer *>(currentPlayer())->isRunning()))
1828   {
1829         static_cast<AIPlayer *>(currentPlayer())->stop();
1830   }
1831   m_automaton->currentPlayer((Player*)(*m_automaton->playerList()->begin()));
1832 
1833 /*  if (currentPlayer() && currentPlayer()->isAI() && !currentPlayer()->isVirtual()
1834       && !(static_cast<AIPlayer *>(currentPlayer())->isRunning()))
1835   {
1836           static_cast<AIPlayer *>(currentPlayer())->start();
1837           qCDebug(KSIRK_LOG) <<"setCurrentPlayerToFirst : step 3";
1838   }*/
1839   m_frame->setFocus();
1840   return 0;
1841 }
1842 
setCurrentPlayerToNext(bool restartRunningAIs)1843 int KGameWindow::setCurrentPlayerToNext(bool restartRunningAIs)
1844 {
1845   qCDebug(KSIRK_LOG) << restartRunningAIs;
1846   m_rightDock->hide();
1847   int looped(0);
1848 //   qCDebug(KSIRK_LOG) << "KGameWindow::setCurrentPlayerToNext()";
1849   if ( currentPlayer() && ( currentPlayer()-> isAI())  && ( static_cast<AIPlayer *>(currentPlayer())-> isRunning() ) )
1850       static_cast<AIPlayer *>(currentPlayer())-> stop();
1851 
1852   PlayersArray::iterator it = m_automaton->playerList()->begin();
1853   PlayersArray::iterator it_end = m_automaton->playerList()->end();
1854   for (;it != it_end; it++)
1855   {
1856     if (*it == currentPlayer())
1857     {
1858       it++;
1859       break;
1860     }
1861   }
1862   if (it == it_end)
1863   {
1864       setCurrentPlayerToFirst();
1865       looped = 1;
1866   }
1867   else
1868   {
1869     m_automaton->currentPlayer((Player*)(*it));
1870   }
1871 
1872   if ( restartRunningAIs && currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()) && !looped)
1873   {
1874     if ( ! (static_cast< AIPlayer* >(currentPlayer())-> isRunning()))
1875     {
1876       static_cast< AIPlayer* >(currentPlayer())-> start();
1877     }
1878   }
1879 
1880   if ( currentPlayer()->isAI() || currentPlayer()->isVirtual() )
1881   {
1882     m_nextPlayerAction->setEnabled(false);
1883   }
1884   else
1885   {
1886     m_nextPlayerAction->setEnabled(true);
1887   }
1888 
1889   qCDebug(KSIRK_LOG) << "New current player is " << currentPlayer()->name() << " ; return value is " << looped;
1890   return looped;
1891 }
1892 
terminateAttackSequence()1893 bool KGameWindow::terminateAttackSequence()
1894 {
1895   if (m_firstCountry != 0)
1896     m_firstCountry->clearHighlighting();
1897   if (m_secondCountry != 0)
1898     m_secondCountry->clearHighlighting();
1899   if (m_animFighters != 0)
1900     m_animFighters->hideAndRemoveAll();
1901   return attackEnd();
1902 }
1903 
attacker(const QPointF & point)1904 bool KGameWindow::attacker(const QPointF& point)
1905 {
1906   qCDebug(KSIRK_LOG);
1907   Country* clickedCountry = clickIn(point);
1908   KMessageParts messageParts;
1909   if (clickedCountry == 0)
1910   {
1911     messageParts << I18N_NOOP("<font color=\"orange\">No country here!</font>");
1912     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1913     clearHighlighting();
1914     return false;
1915   }
1916 
1917   if (clickedCountry-> owner() != currentPlayer())
1918   {
1919     messageParts << I18N_NOOP("<font color=\"orange\">You are not the owner of %1!</font>")  << clickedCountry-> name();
1920     clearHighlighting();
1921     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1922     return false;
1923   }
1924   else if (clickedCountry-> nbArmies() <= currentPlayer()-> getNbAttack())
1925   {
1926     messageParts << I18N_NOOP("<font color=\"orange\">There is only %1 armies in %2!</font>")
1927       << QString::number(clickedCountry-> nbArmies())
1928       << clickedCountry-> name();
1929     clearHighlighting();
1930     broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
1931     return false;
1932   }
1933   else
1934   {
1935     QByteArray buffer;
1936     QDataStream stream(&buffer, QIODevice::WriteOnly);
1937     stream << clickedCountry->name();
1938     m_automaton->sendMessage(buffer,FirstCountry);
1939     QByteArray buffer2;
1940     QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1941     stream2 << "";
1942     m_automaton->sendMessage(buffer2,SecondCountry);
1943 
1944     QPixmap pm = currentPlayer()->getFlag()->image(0);
1945     /*messageParts
1946       << pm
1947       << I18N_NOOP("%1 attacks from %2 with <font color=\"red\">%3 armies</font>")
1948       << currentPlayer()-> name()
1949       << clickedCountry-> name()
1950       << QString::number(currentPlayer()-> getNbAttack());
1951     broadcastChangeItem(messageParts, ID_STATUS_MSG2);*/
1952     return true;
1953   }
1954 }
1955 
attacked(const QPointF & point)1956 unsigned int KGameWindow::attacked(const QPointF& point)
1957 {
1958   qCDebug(KSIRK_LOG) << point << (void*)m_firstCountry << (void*)m_secondCountry;
1959   //if (currentPlayer()-> isAI()) return 3;
1960   // executed on the admin side only
1961   if (!m_automaton->isAdmin()) return 3;
1962 
1963   unsigned int res = 0;
1964   //Country* secondCountry = clickIn(point);
1965   //m_secondCountry = secondCountry;
1966   KMessageParts messageParts;
1967 
1968 //   qCDebug(KSIRK_LOG) << "2nd country is now set";
1969   if ( (m_firstCountry == NULL) || (m_secondCountry == NULL)
1970           || (m_firstCountry-> owner() != currentPlayer()) )
1971   {
1972     qCDebug(KSIRK_LOG) << ("Nothing to attack !");
1973     QByteArray buffer;
1974     QDataStream stream(&buffer, QIODevice::WriteOnly);
1975     m_automaton->sendMessage(buffer,ClearHighlighting);
1976   }
1977   else if (!m_secondCountry-> owner())
1978   {
1979     qCDebug(KSIRK_LOG) << ("Invalid attacked country.");
1980     QByteArray buffer;
1981     QDataStream stream(&buffer, QIODevice::WriteOnly);
1982     m_automaton->sendMessage(buffer,ClearHighlighting);
1983   }
1984 /*  else if (!m_secondCountry-> owner()->isVirtual())
1985   {
1986     // messageParts << I18N_NOOP("Invalid attacked country.");
1987     return 3;
1988   }*/
1989   else if (m_firstCountry == m_secondCountry)
1990   {
1991    qCDebug(KSIRK_LOG) << ("You are trying to attack %1 from itself !") << m_firstCountry-> name();
1992     QByteArray buffer;
1993     QDataStream stream(&buffer, QIODevice::WriteOnly);
1994     m_automaton->sendMessage(buffer,ClearHighlighting);
1995   }
1996   else if (!m_firstCountry-> communicateWith(m_secondCountry))
1997   {
1998     qCDebug(KSIRK_LOG) << ("%1 is not a neighbour of %2 !") << m_secondCountry-> name() << m_firstCountry-> name();
1999     QByteArray buffer;
2000     QDataStream stream(&buffer, QIODevice::WriteOnly);
2001     m_automaton->sendMessage(buffer,ClearHighlighting);
2002   }
2003   else if (m_firstCountry-> owner() == m_secondCountry-> owner())
2004   {
2005     qCDebug(KSIRK_LOG) << ("%1! You cannot attack %2! It is yours!") << currentPlayer()-> name()
2006            << m_secondCountry-> name();
2007     QByteArray buffer;
2008     QDataStream stream(&buffer, QIODevice::WriteOnly);
2009     m_automaton->sendMessage(buffer,ClearHighlighting);
2010   }
2011   else if (m_firstCountry-> owner() != currentPlayer())
2012   {
2013     qCDebug(KSIRK_LOG) << ("%1 ! You are not the owner of %2!") << currentPlayer()-> name() << m_firstCountry-> name();
2014     QByteArray buffer;
2015     QDataStream stream(&buffer, QIODevice::WriteOnly);
2016     m_automaton->sendMessage(buffer,ClearHighlighting);
2017   }
2018   else if (m_firstCountry->nbArmies() - currentPlayer()->getNbAttack() < 1)
2019   {
2020    qCDebug(KSIRK_LOG)
2021       << ("%1, you have to keep one army to defend %2.")
2022       << m_firstCountry->owner()-> name()
2023       << m_firstCountry-> name();
2024     QByteArray buffer;
2025     QDataStream stream(&buffer, QIODevice::WriteOnly);
2026     m_automaton->sendMessage(buffer,ClearHighlighting);
2027   }
2028   else if (m_secondCountry-> nbArmies() > 1)
2029   {
2030     QByteArray buffer;
2031     QDataStream stream(&buffer, QIODevice::WriteOnly);
2032     if (m_secondCountry != 0)
2033     {
2034       stream << m_secondCountry->name();
2035     }
2036     else
2037     {
2038       stream << QString("");
2039     }
2040     m_automaton->sendMessage(buffer,SecondCountry);
2041 
2042     qCDebug(KSIRK_LOG)
2043         << ("%1, with how many armies do you defend %2 ?")
2044         << m_secondCountry->owner()-> name()
2045         << m_secondCountry-> name();
2046     QByteArray buffer2;
2047     QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2048     stream2 << m_secondCountry->owner()->name();
2049     m_automaton->sendMessage(buffer2,DisplayDefenseButtons);
2050     res = 1;
2051   }
2052   else
2053   {
2054     QByteArray buffer;
2055     QDataStream stream(&buffer, QIODevice::WriteOnly);
2056     if (m_secondCountry != 0)
2057     {
2058       stream << m_secondCountry->name();
2059     }
2060     else
2061     {
2062       stream << QString("");
2063     }
2064     m_automaton->sendMessage(buffer,SecondCountry);
2065     messageParts
2066       << I18N_NOOP("%1, you defend with the only army you have in %2.")
2067       << m_secondCountry->owner()-> name()
2068       << m_secondCountry-> name();
2069     res = 2;
2070   }
2071   qCDebug(KSIRK_LOG) << "will change item";
2072   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2073   qCDebug(KSIRK_LOG) << "change item broadcasted; returning " << res;
2074   return res;
2075 }
2076 
firstCountryAt(const QPointF & point)2077 bool KGameWindow::firstCountryAt(const QPointF& point)
2078 {
2079   Country* c = clickIn(point);
2080   if (c)
2081   {
2082     if (c-> owner() == currentPlayer())
2083     {
2084       QByteArray buffer;
2085       QDataStream stream(&buffer, QIODevice::WriteOnly);
2086       stream << c->name();
2087       m_automaton->sendMessage(buffer,FirstCountry);
2088       return true;
2089     }
2090   }
2091   return false;
2092 }
2093 
secondCountryAt(const QPointF & point)2094 bool KGameWindow::secondCountryAt(const QPointF& point)
2095 {
2096   if (clickIn(point))
2097   {
2098     QByteArray buffer;
2099     QDataStream stream(&buffer, QIODevice::WriteOnly);
2100     stream << clickIn(point)->name();
2101     m_automaton->sendMessage(buffer,SecondCountry);
2102     return true;
2103   }
2104   return false;
2105 }
2106 
playerPutsArmy(const QPointF & point,bool removable)2107 bool KGameWindow::playerPutsArmy(const QPointF& point, bool removable)
2108 {
2109   qCDebug(KSIRK_LOG) << removable;
2110   Country* clickedCountry = clickIn(point);
2111 
2112   if (clickedCountry)
2113   {
2114     qCDebug(KSIRK_LOG) << "clickedCountry name=" << clickedCountry->name() ;
2115     qCDebug(KSIRK_LOG) << "clickedCountry owner=" << clickedCountry-> owner()->name();
2116     qCDebug(KSIRK_LOG) << "currentPlayer=" << currentPlayer()->name();
2117     unsigned int nbAvailArmies = currentPlayer()->getNbAvailArmies();
2118     qCDebug(KSIRK_LOG) << "nbAvailArmies=" << nbAvailArmies;
2119     if (clickedCountry->owner() == currentPlayer() &&  nbAvailArmies > 0)
2120     {
2121       nbAvailArmies--;
2122       qCDebug(KSIRK_LOG) << "owner new available armies=" << nbAvailArmies;
2123       currentPlayer()->putArmiesInto(1, theWorld()->indexOfCountry(clickedCountry));
2124       clickedCountry-> incrNbArmies();
2125       clickedCountry-> createArmiesSprites();
2126       QPixmap pm = currentPlayer()->getFlag()->image(0);
2127       KMessageParts messageParts;
2128       messageParts
2129         << pm
2130         << I18N_NOOP("%1: %2 armies to place")
2131         << currentPlayer()-> name()
2132         << QString::number(nbAvailArmies);
2133       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2134 
2135       getRightDialog()->updateRecycleDetails(clickedCountry,false,nbAvailArmies);
2136 
2137       if (m_automaton->isAdmin())
2138       {
2139         m_automaton->checkGoal();
2140       }
2141     }
2142   }
2143   return false;
2144 }
2145 
playerPutsInitialArmy(const QPointF & point)2146 bool KGameWindow::playerPutsInitialArmy(const QPointF& point)
2147 {
2148   {
2149     qCDebug(KSIRK_LOG) << point;
2150     Country* clickedCountry = clickIn(point);
2151 
2152     if ( (clickedCountry) )
2153     {
2154       qCDebug(KSIRK_LOG) << "clickedCountry name=" << clickedCountry->name() ;
2155       qCDebug(KSIRK_LOG) << "clickedCountry owner=" << clickedCountry-> owner()->name();
2156       qCDebug(KSIRK_LOG) << "clickedCountry had armies=" << clickedCountry-> nbArmies();
2157       qCDebug(KSIRK_LOG) << "currentPlayer=" << currentPlayer()->name();
2158       qCDebug(KSIRK_LOG) << "nbAvailArmies=" << currentPlayer()->getNbAvailArmies();
2159 
2160       if (
2161            (clickedCountry-> owner() == currentPlayer()) &&
2162            (((GameLogic::Player*)currentPlayer())-> getNbAvailArmies() > 0))
2163       {
2164         unsigned int currentAvailArmiesNumber = ((GameLogic::Player*)currentPlayer())-> getNbAvailArmies() - 1;
2165         bool last = (currentAvailArmiesNumber == 0);
2166         currentPlayer()->putArmiesInto(1, theWorld()->indexOfCountry(clickedCountry));
2167         qCDebug(KSIRK_LOG) << "owner new available armies=" << currentAvailArmiesNumber;
2168         clickedCountry-> incrNbArmies();
2169         clickedCountry-> createArmiesSprites();
2170 
2171         if ( last )
2172         {
2173           if (m_automaton->isAdmin())
2174           {
2175             PlayersArray::iterator it = m_automaton->playerList()->begin();
2176             PlayersArray::iterator it_end = m_automaton->playerList()->end();
2177             for (;it != it_end; it++)
2178             {
2179               if (*it == currentPlayer())
2180               {
2181                 it++;
2182                 break;
2183               }
2184             }
2185             if (it != it_end)
2186             {
2187               QPixmap pm= ((Player*)(*it))->getFlag()->image(0);
2188 
2189              /* KMessageParts messageParts;
2190               messageParts
2191                 << pm
2192                 << I18N_NOOP("%1: %2 armies to place") << ((Player*)(*it))-> name()
2193                 << QString::number(((Player*)(*it))-> getNbAvailArmies());
2194               broadcastChangeItem(messageParts, ID_STATUS_MSG2);*/
2195 /*            m_nbAvailArmies = ((Player*)(*it))-> getNbAvailArmies();
2196               QByteArray buffer;
2197               QDataStream stream(&buffer, QIODevice::WriteOnly);
2198               stream << (quint32)m_nbAvailArmies;
2199               m_automaton->sendMessage(buffer,KGameWinAvailArmies);*/
2200               getRightDialog()->close();
2201 
2202               QByteArray buffer2;
2203               QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2204               stream2 << ((GameLogic::Player*)(*it))->name();
2205               stream2 << (quint32) ((GameLogic::Player*)(*it))->getNbAvailArmies();
2206               qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2207                 << ((Player*)(*it))->name() << (quint32) ((GameLogic::Player*)(*it))->getNbAvailArmies()
2208                 << " at " << __FILE__ << ", line " << __LINE__;
2209               m_automaton->sendMessage(buffer2,DisplayRecycleDetails);
2210             }
2211             int ret = setCurrentPlayerToNext();
2212             setContextualHelpActionEnabled(getState(), currentPlayer() && currentPlayer()->isAI());
2213             return ret;
2214           }
2215           else
2216           {
2217             return false;
2218           }
2219         }
2220         else
2221         {
2222           getRightDialog()->updateRecycleDetails(clickedCountry,false,(quint32) ((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies());
2223           QPixmap pm = currentPlayer()->getFlag()->image(0);
2224           KMessageParts messageParts;
2225           messageParts << pm << I18N_NOOP("%1: %2 armies to place")
2226             << currentPlayer()-> name()
2227             << QString::number((quint32) ((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies());
2228           changeItem(messageParts, ID_STATUS_MSG2, false);
2229         }
2230       }
2231     }
2232     return false;
2233   }
2234 }
2235 
playerRemovesArmy(const QPointF & point)2236 bool KGameWindow::playerRemovesArmy(const QPointF& point)
2237 {
2238   qCDebug(KSIRK_LOG) << point;
2239 
2240   Country *clickedCountry = clickIn(point);
2241   qCDebug(KSIRK_LOG) << "  currentPlayer=" << currentPlayer()->name();
2242   if (clickedCountry == 0)
2243   {
2244     return false;
2245   }
2246   qCDebug(KSIRK_LOG) << "  owner=" << clickedCountry-> owner()->name();
2247   qCDebug(KSIRK_LOG) << "  nbArmies=" << clickedCountry->nbArmies();
2248   qCDebug(KSIRK_LOG) << "  canRemoveArmiesFrom=" << clickedCountry-> owner()->canRemoveArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) );
2249   if ( clickedCountry
2250       && ( clickedCountry-> owner() == currentPlayer() )
2251       && ( clickedCountry-> nbArmies() > 1)
2252       && ( clickedCountry-> owner()->canRemoveArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) ) )
2253   )
2254   {
2255     clickedCountry-> owner()->removeArmiesFrom(1, theWorld()->indexOfCountry(clickedCountry) );
2256     unsigned int newNbAvailArmies = currentPlayer()-> getNbAvailArmies() /*+ 1*/;
2257 
2258     if ( m_automaton->isAdmin() )
2259     {
2260       QPixmap pm = currentPlayer()->getFlag()->image(0);
2261       KMessageParts messageParts;
2262       messageParts <<pm<< I18N_NOOP("%1: %2 armies to place") << currentPlayer()-> name()
2263         << QString::number(newNbAvailArmies);
2264       broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2265     }
2266     clickedCountry-> decrNbArmies();
2267     clickedCountry-> createArmiesSprites();
2268 
2269     getRightDialog()->updateRecycleDetails(clickedCountry,false,newNbAvailArmies);
2270     return true;
2271   }
2272   return false;
2273 }
2274 
2275 /**
2276   * @brief setups window for recycling
2277   */
initRecycling()2278 void KGameWindow::initRecycling()
2279 {
2280   qCDebug(KSIRK_LOG) << "Initiating recycling";
2281   m_nextPlayerAction->setEnabled(false);
2282 
2283   setCurrentPlayerToFirst();
2284   QByteArray buffer;
2285   QDataStream stream(&buffer, QIODevice::WriteOnly);
2286   stream << quint32(0);
2287   m_automaton->sendMessage(buffer,DisplayRecyclingButtons);
2288 
2289   KMessageParts messageParts;
2290   messageParts << I18N_NOOP("Exchange armies again or continue?");
2291   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2292 }
2293 
clear()2294 void KGameWindow::clear()
2295 {
2296   m_nbMovedArmies = 0;
2297   m_firstCountry = m_secondCountry = 0;
2298   NKD = NKA = 0;
2299   if (m_message !=0)
2300   {
2301     delete m_message;
2302   }
2303   m_message = 0;
2304 }
2305 
nextPlayerRecycling()2306 bool KGameWindow::nextPlayerRecycling()
2307 {
2308   qCDebug(KSIRK_LOG);
2309   m_nextPlayerAction->setEnabled(false);
2310   if ( currentPlayer() && currentPlayer()-> getNbAvailArmies() > 0)
2311   {
2312     qCDebug(KSIRK_LOG) << "You must distribute all your armies";
2313     if (!currentPlayer()->isVirtual() && !currentPlayer()->isAI())
2314     {
2315       KMessageBox::sorry(0, i18n("You must distribute\nall your armies"), i18n("KsirK"));
2316     }
2317     return false;
2318   }
2319   else
2320   {
2321     m_rightDock->hide();
2322     if (currentPlayer() && currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()))
2323     {
2324       if (!(static_cast<AIPlayer *>(currentPlayer()))-> isRunning()) (static_cast<AIPlayer *>(currentPlayer()))-> start();
2325       m_nextPlayerAction->setEnabled(false);
2326     }
2327     else if (currentPlayer() && !currentPlayer()->isVirtual())
2328     {
2329       m_nextPlayerAction->setEnabled(true);
2330     }
2331     else
2332     {
2333       m_nextPlayerAction->setEnabled(false);
2334     }
2335     return true;
2336   }
2337 }
2338 
2339 /**
2340   * @return if true next state will be NEWARMIES else it will be WAIT
2341   */
nextPlayerNormal()2342 bool KGameWindow::nextPlayerNormal()
2343 {
2344   qCDebug(KSIRK_LOG) << " (current is" << currentPlayer()->name()<<")";
2345   setCurrentPlayerToNext();
2346   distributeArmies();
2347 
2348   QByteArray buffer;
2349   m_automaton->sendMessage(buffer,ShowArmiesToPlace);
2350 
2351   clear();
2352   QByteArray buffer2;
2353   m_automaton->sendMessage(buffer2,StartLocalCurrentAI);
2354   getRightDialog()->close();
2355 
2356   QByteArray buffer3;
2357   QDataStream stream3(&buffer3, QIODevice::WriteOnly);
2358   stream3 << currentPlayer()-> name();
2359   stream3 << (quint32)nbNewArmies(currentPlayer());
2360   qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2361       << currentPlayer()->name() << nbNewArmies(currentPlayer())
2362       << " at " << __FILE__ << ", line " << __LINE__;
2363   m_automaton->sendMessage(buffer3,DisplayRecycleDetails);
2364   return true;
2365 }
2366 
centerOnFight()2367 void KGameWindow::centerOnFight()
2368 {
2369   qCDebug(KSIRK_LOG);
2370 
2371   qreal aj=m_rightDialog->width();    //get the width of the right widget
2372   qreal ay=m_chatDlg->height();      //get the height of the bottom widget
2373 
2374 //Larg
2375   if (m_firstCountry==0 || m_secondCountry==0)
2376   {
2377     qCCritical(KSIRK_LOG) << "countries should not be null ("<<(void*)m_firstCountry<<","<<(void*)m_secondCountry<<") at "<<__FILE__<<", line "<<__LINE__;
2378     return;
2379   }
2380   qreal larg=((m_secondCountry->centralPoint().x())-(m_firstCountry->centralPoint().x()));
2381   if (larg<0)
2382   {
2383    larg=-larg;    //si negatif alors on remet en positif
2384   }
2385 //Long
2386   qreal longu=((m_secondCountry->centralPoint().y())-(m_firstCountry->centralPoint().y()));
2387   if (longu<0)
2388   {
2389    longu=-longu;    //si negatif alors on remet en positif
2390   }
2391 //Point NordOuest
2392   qreal minx=m_secondCountry->centralPoint().x();
2393   qreal miny=m_secondCountry->centralPoint().y();
2394   if (minx>m_firstCountry->centralPoint().x())
2395   {
2396   minx=m_firstCountry->centralPoint().x();
2397   }
2398   if (miny>m_firstCountry->centralPoint().y())
2399   {
2400   miny=m_firstCountry->centralPoint().y();
2401   }
2402 
2403   QSizeF size (larg,longu);   //creation de la size  (2x la largeur entre les deux pays)
2404   QPointF NO (minx,miny);  //creation du point Nord Ouest
2405   QRectF rect(NO,size);    //creation du rect
2406   m_frame->ensureVisible(rect);
2407 
2408 // centering on the middle point
2409   qreal xx=((m_secondCountry->centralPoint().x())+(m_firstCountry->centralPoint().x()))/2;
2410   if (xx<0)
2411   {
2412    xx=-xx;    //si negatif alors on remet en positif
2413   }
2414   qreal yy=((m_secondCountry->centralPoint().y())+(m_firstCountry->centralPoint().y()))/2;
2415   if (yy<0)
2416   {
2417    yy=-yy;    //si negatif alors on remet en positif
2418   }
2419 
2420   QPointF mid (xx,yy);
2421   m_frame->centerOn(mid);      //center on the point
2422 
2423   m_frame->translate(-aj/2,-ay/2);  //translate to center perfectly
2424 //end Benjamin M.
2425 
2426 
2427 }
attack(unsigned int nb)2428 void KGameWindow::attack(unsigned int nb)
2429 {
2430   centerOnFight();        //center the view on the fight Benj
2431 
2432   currentPlayer()-> setNbAttack(nb);
2433   /*KMessageParts messageParts;
2434   messageParts << I18N_NOOP("Attack with %1 armies: designate the belligerants")
2435     << QString::number(nb);
2436   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);*/
2437   /*
2438   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);
2439   */
2440 }
2441 
defense(unsigned int nb)2442 void KGameWindow::defense(unsigned int nb)
2443 {
2444   qCDebug(KSIRK_LOG);
2445 
2446   if (!m_firstCountry) // anything left to do?
2447      return;
2448 
2449   m_secondCountry-> owner()-> setNbDefense(nb);
2450 
2451   QPixmap pmA = m_firstCountry-> owner()->getFlag()->image(0);
2452   QPixmap pmD = m_secondCountry-> owner()->getFlag()->image(0);
2453 
2454   KMessageParts messageParts;
2455   messageParts << I18N_NOOP("Battle ongoing.");
2456 //     << I18N_NOOP("Battle between <font color=\"red\">%1</font> (")
2457 //     << m_firstCountry-> name()
2458 //     << pmA
2459 //     << I18N_NOOP("%1) <font color=\"red\">with %2 armies</font> and <font color=\"blue\">%3</font> (")
2460 //     << m_firstCountry->owner()->name()
2461 //     << QString::number(currentPlayer()-> getNbAttack())
2462 //     << m_secondCountry-> name()
2463 //     << pmD
2464 //     << I18N_NOOP("%1) <font color=\"blue\">with %2 armies</font>.")
2465 //     << m_secondCountry->owner()->name()
2466 //     << QString::number(nb);
2467 
2468   broadcastChangeItem(messageParts, ID_STATUS_MSG2, false);
2469 
2470   if (m_firstCountry-> owner() && m_firstCountry-> owner()-> getFlag())
2471   {
2472     if (!m_goalAction->isVisible())
2473       m_goalAction->setVisible(true);
2474     m_goalAction-> setIcon(QIcon(m_firstCountry-> owner()->getFlag()-> image(0)));
2475     m_goalAction-> setIconText(i18n("Goal"));
2476     m_barFlag-> setPixmap(m_firstCountry-> owner()->getFlag()-> image(0));
2477   }
2478   if (m_automaton->isAdmin())
2479   {
2480     QByteArray buffer;
2481     QDataStream stream(&buffer, QIODevice::WriteOnly);
2482     m_automaton->sendMessage(buffer,InitCombatMovement);
2483     m_automaton->state(GameLogic::GameAutomaton::FIGHT_BRING);
2484   }
2485 }
2486 
nbMovedArmies()2487 int KGameWindow::nbMovedArmies()
2488 {
2489   return m_nbMovedArmies;
2490 }
2491 
incrNbMovedArmies(unsigned int nb)2492 void KGameWindow::incrNbMovedArmies(unsigned int nb)
2493 {
2494   m_nbMovedArmies += nb;
2495 }
2496 
decrNbMovedArmies(unsigned int nb)2497 void KGameWindow::decrNbMovedArmies(unsigned int nb)
2498 {
2499   m_nbMovedArmies -= nb;
2500 }
2501 
invade(unsigned int nb)2502 bool KGameWindow::invade(unsigned int nb )
2503 {
2504   if (m_firstCountry==0 || m_secondCountry==0)
2505   {
2506     qCDebug(KSIRK_LOG) << "invade("<<nb<<") returns " << false;
2507     return false;
2508   }
2509   bool res = initArmiesMovement(nb, m_firstCountry, m_secondCountry);
2510   qCDebug(KSIRK_LOG) << "invade("<<nb<<") returns " << res;
2511   return res;
2512 }
2513 
simultaneousAttack(int nb,FightType state)2514 AnimSprite* KGameWindow::simultaneousAttack(int nb, FightType state)
2515 {
2516   qCDebug(KSIRK_LOG) << nb << state << relativePosInArenaAttack << relativePosInArenaDefense;
2517   AnimSprite* res;
2518 
2519   if (state == Attack)
2520   {
2521     QPointF pointAttaquant(0,0);
2522     QPointF pointDefenseur(0,0);
2523     determinePointArriveeForArena(relativePosInArenaAttack, pointAttaquant,pointDefenseur);
2524 
2525     qCDebug(KSIRK_LOG) << "****point att****" << pointAttaquant;
2526 
2527     qCDebug(KSIRK_LOG) << "****SIMULTANEOUS ATTACK****" << pointAttaquant;
2528     res = initArmiesMultipleCombat(nb, firstCountry(), secondCountry(), pointAttaquant);
2529 
2530     relativePosInArenaAttack++;
2531   }
2532   else // Defense
2533   {
2534     QPointF pointAttaquant(0,0);
2535     QPointF pointDefenseur(0,0);
2536     determinePointArriveeForArena(/*secondCountry(), firstCountry(),*/
2537       relativePosInArenaDefense, pointDefenseur, pointAttaquant);
2538 
2539     qCDebug(KSIRK_LOG) << "****point def****" << pointAttaquant;
2540 
2541     qCDebug(KSIRK_LOG) << "****SIMULTANEOUS DEFENSE****" << pointDefenseur;
2542     res = initArmiesMultipleCombat(nb, secondCountry(), secondCountry(), pointDefenseur);
2543 
2544     relativePosInArenaDefense++;
2545   }
2546   qCDebug(KSIRK_LOG) << (void*)res;
2547   return res;
2548 }
2549 
2550 
retreat(unsigned int nb)2551 bool KGameWindow::retreat(unsigned int nb)
2552 {
2553   bool res;
2554   if (m_nbMovedArmies >= int(nb))
2555   {
2556     res = initArmiesMovement(nb, m_secondCountry, m_firstCountry);
2557   }
2558   else
2559   {
2560     res = false;
2561   }
2562   qCDebug(KSIRK_LOG) << "retreat("<<nb<<") returns " << res;
2563   return res;
2564 }
2565 
invasionFinished()2566 void KGameWindow::invasionFinished()
2567 {
2568   qCDebug(KSIRK_LOG);
2569   clearHighlighting();
2570  //KMessageParts messageParts;
2571 
2572   QPixmap pm = currentPlayer()->getFlag()->image(0);
2573   KMessageParts messageParts;
2574   messageParts
2575     << pm
2576     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2577   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2578 }
2579 
shiftFinished()2580 void KGameWindow::shiftFinished()
2581 {
2582   clearHighlighting();
2583   QPixmap pm = currentPlayer()->getFlag()->image(0);
2584   KMessageParts messageParts;
2585   messageParts
2586     << pm
2587     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2588   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2589   slotNextPlayer();
2590 }
2591 
cancelAction()2592 void KGameWindow::cancelAction()
2593 {
2594   qCDebug(KSIRK_LOG) << "KGameWindow::cancelAction";
2595   QByteArray buffer;
2596   QDataStream stream(&buffer, QIODevice::WriteOnly);
2597   stream << "";
2598   m_automaton->sendMessage(buffer,FirstCountry);
2599   QByteArray buffer2;
2600   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2601   stream2 << "";
2602   m_automaton->sendMessage(buffer2,SecondCountry);
2603 
2604   clearHighlighting();
2605 
2606   KMessageParts messageParts;
2607   QPixmap pm = currentPlayer()->getFlag()->image(0);
2608   messageParts
2609     << pm
2610     << I18N_NOOP("%1, it is up to you.") << currentPlayer()->name();
2611   broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2612 }
2613 
cancelShiftSource()2614 void KGameWindow::cancelShiftSource()
2615 {
2616   if (m_nbMovedArmies < 0)
2617   {
2618     m_firstCountry-> decrNbArmies(m_nbMovedArmies);
2619     m_secondCountry-> incrNbArmies(m_nbMovedArmies);
2620     m_firstCountry-> createArmiesSprites();
2621     m_secondCountry-> createArmiesSprites();
2622     m_nbMovedArmies = 0;
2623   }
2624   if (m_nbMovedArmies > 0)
2625   {
2626     m_firstCountry-> incrNbArmies(m_nbMovedArmies);
2627     m_secondCountry-> decrNbArmies(m_nbMovedArmies);
2628     m_firstCountry-> createArmiesSprites();
2629     m_secondCountry-> createArmiesSprites();
2630     m_nbMovedArmies = 0;
2631   }
2632 }
2633 
actionNewGame(GameAutomaton::NetworkGameType socket)2634 bool KGameWindow::actionNewGame(GameAutomaton::NetworkGameType socket)
2635 {
2636   qCDebug(KSIRK_LOG);
2637   if  ( ( m_automaton->playerList()->count() == 0 ) ||
2638   ( isMyState(GameLogic::GameAutomaton::GAME_OVER)  ) ||
2639         (KMessageBox::warningContinueCancel(this,i18n("Do you really want to end your current game and start a new one?"),i18n("New game confirmation"),KStandardGuiItem::yes()) == KMessageBox::Continue ) )
2640 
2641   {
2642     qCDebug(KSIRK_LOG) << "valid";
2643     m_automaton->setGameStatus(KGame::End);
2644     m_reinitializingGame = true;
2645     m_automaton->removeAllPlayers();
2646     // Bug 308527. Need to remove all goals on new game.
2647     m_automaton->removeAllGoals();
2648     m_automaton->state(GameLogic::GameAutomaton::INIT);
2649     m_automaton->savedState(GameLogic::GameAutomaton::INVALID);
2650     QObject::disconnect((QObject*)m_automaton->messageServer(),SIGNAL(connectionLost(KMessageIO*)),
2651                         (QObject*)m_automaton,SLOT(slotConnectionToClientBroken(KMessageIO*)));
2652 
2653     m_automaton->disconnect();
2654 
2655     m_newGameSetup->clear();
2656     m_automaton->setupPlayersNumberAndSkin(socket);
2657   }
2658   return false;
2659 }
2660 
saveXml(QTextStream & xmlStream)2661 void KGameWindow::saveXml(QTextStream& xmlStream)
2662 {
2663   xmlStream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
2664   xmlStream << "<ksirkSavedGame formatVersion=\"" << SAVE_GAME_FILE_FORMAT_VERSION << "\" >";
2665   xmlStream << "<game skin=\"" << m_automaton->skin() << "\" state=\"" << m_automaton->state() << "\" >";
2666   m_theWorld->saveXml(xmlStream);
2667   xmlStream << "<players nb=\""<<m_automaton->playerList()->count()<<"\">";
2668   PlayersArray::iterator it = m_automaton->playerList()->begin();
2669   PlayersArray::iterator it_end = m_automaton->playerList()->end();
2670   for (; it != it_end; it++)
2671   {
2672     static_cast<Player*>(*it)->saveXml(xmlStream);
2673   }
2674   xmlStream << "</players>";
2675   Player* player = m_automaton->currentPlayer();
2676   if (player)
2677   {
2678     QString name = player->name();
2679     name = name.replace('&',"&amp;");
2680     name = name.replace('<',"&lt;");
2681     name = name.replace('>',"&gt;");
2682     xmlStream << "<currentPlayer name=\"" << name << "\" />";
2683   }
2684   else
2685     xmlStream << "<currentPlayer name=\"\" />";
2686   xmlStream << "<goals>\n";
2687   it = m_automaton->playerList()->begin();
2688   it_end = m_automaton->playerList()->end();
2689   for (; it != it_end; it++)
2690   {
2691     static_cast<Player*>(*it)->goal().saveXml(xmlStream);
2692   }
2693   xmlStream << "</goals>\n";
2694   xmlStream << "</game>";
2695   xmlStream << "</ksirkSavedGame>";
2696 }
2697 
2698 /**
2699   * @brief Accessor to the world
2700   * @return A pointer to the world
2701   */
theWorld()2702 ONU* KGameWindow::theWorld()
2703 {
2704   return m_theWorld;
2705 }
2706 
2707 /**
2708   * @brief Adds a player
2709   */
addPlayer(const QString & playerName,unsigned int nbAvailArmies,unsigned int nbCountries,const QString & nationName,bool isAI,const QString & password,unsigned int nbAttack,unsigned int nbDefense)2710 Player* KGameWindow::addPlayer(const QString& playerName,
2711       unsigned int nbAvailArmies,
2712       unsigned int nbCountries,
2713       const QString& nationName,
2714       bool isAI,
2715       const QString& password,
2716       unsigned int nbAttack,
2717       unsigned int nbDefense)
2718 {
2719   qCDebug(KSIRK_LOG) << "Adding player (AI: " << isAI << ")";
2720   Player* p = dynamic_cast<Player*>(m_automaton->createPlayer(isAI?2:1,0,false));
2721   if (p)
2722   {
2723     if (!isAI)
2724     {
2725       m_chatDlg->setFromPlayer(p);
2726     }
2727     p->setName(playerName);
2728     p->setNation(nationName);
2729     p->setNbCountries(nbCountries);
2730     p->setNbAvailArmies(nbAvailArmies, true);
2731     p->setNbAttack(nbAttack);
2732     p->setNbDefense(nbDefense);
2733     p->setPassword(password);
2734     if (!m_automaton->addPlayer(p))
2735     {
2736       qCDebug(KSIRK_LOG) << p->name() << "NOT added!";
2737       p = 0; // freed - weired API
2738     }
2739   }
2740   return p;
2741 }
2742 
nationsList()2743 QMap< QString, QString > KGameWindow::nationsList()
2744 {
2745   QMap< QString, QString >  res;
2746   if (m_theWorld == 0)
2747   {
2748     return res;
2749   }
2750   QList<Nationality*>& nationsList = m_theWorld->getNationalities();
2751   qCDebug(KSIRK_LOG) << "There is " << nationsList.size() << " nations";
2752   QList<Nationality*>::iterator nationsIt = nationsList.begin();
2753   for (; nationsIt != nationsList.end(); nationsIt++ )
2754   {
2755     Nationality* nation = *nationsIt;
2756     qCDebug(KSIRK_LOG) << "Nation '" << nation->name() << "' = " << nation;
2757     res.insert(nation->name(),nation->flagFileName());
2758   }
2759   return res;
2760 }
2761 
2762 /** @return true if the given player is the last one ; false otherwise */
isLastPlayer(const Player & player)2763 bool KGameWindow::isLastPlayer(const Player& player)
2764 {
2765   if (m_automaton->playerList()->begin() == m_automaton->playerList()->end())
2766   {
2767     qCCritical(KSIRK_LOG) << "No player ; should not be able to call isLastPlayer !";
2768     exit(1);
2769   }
2770   PlayersArray::iterator it = m_automaton->playerList()->end();
2771   //  it--;
2772   Player* lastPlayer = static_cast<Player*>(*it);
2773   return (player == (*lastPlayer));
2774 }
2775 
actionRecycling()2776 void KGameWindow::actionRecycling()
2777 {
2778   qCDebug(KSIRK_LOG) << "KGameWindow::actionRecycling";
2779   setCurrentPlayerToFirst();
2780   QByteArray buffer;
2781   QDataStream stream(&buffer, QIODevice::WriteOnly);
2782   m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2783   QByteArray buffer2;
2784   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
2785   stream2 << currentPlayer()->name();
2786   stream2 << (quint32)0;
2787   qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2788     << currentPlayer()->name() << 0
2789     << " at " << __FILE__ << ", line " << __LINE__;
2790   m_automaton->sendMessage(buffer2,DisplayRecycleDetails);
2791 
2792   QPixmap pm = currentPlayer()->getFlag()->image(0);
2793 }
2794 
actionRecyclingFinished()2795 void KGameWindow::actionRecyclingFinished()
2796 {
2797   qCDebug(KSIRK_LOG);
2798   getRightDialog()->close();
2799   if (m_automaton->isAdmin())
2800   {
2801     setCurrentPlayerToFirst();
2802     distributeArmies();
2803 
2804     QByteArray buffer;
2805     m_automaton->sendMessage(buffer,ShowArmiesToPlace);
2806 
2807     clear();
2808     QByteArray buffer2;
2809     m_automaton->sendMessage(buffer2,StartLocalCurrentAI);
2810 
2811     QByteArray buffer3;
2812     QDataStream stream3(&buffer3, QIODevice::WriteOnly);
2813     stream3 << currentPlayer()-> name();
2814     stream3 << (quint32)nbNewArmies(currentPlayer());
2815     qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails "
2816         << currentPlayer()->name() << nbNewArmies(currentPlayer())
2817         << " at " << __FILE__ << ", line " << __LINE__;
2818     m_automaton->sendMessage(buffer3,DisplayRecycleDetails);
2819     m_automaton->state(GameLogic::GameAutomaton::NEWARMIES);
2820   }
2821 }
2822 
finishMoves()2823 void KGameWindow::finishMoves()
2824 {
2825   qCDebug(KSIRK_LOG);
2826   m_animFighters->moveAllToDestinationNow();
2827 }
2828 
displayButtonsForState(GameAutomaton::GameState state)2829 void KGameWindow::displayButtonsForState(GameAutomaton::GameState state)
2830 {
2831   QByteArray buffer;
2832   QDataStream stream(&buffer, QIODevice::WriteOnly);
2833   switch (state)
2834   {
2835   case GameLogic::GameAutomaton::WAIT:;
2836     m_automaton->sendMessage(buffer,ClearHighlighting);
2837     break;
2838   case GameLogic::GameAutomaton::WAIT_RECYCLING:;
2839     m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2840     break;
2841   case GameLogic::GameAutomaton::NEWARMIES:;
2842     m_automaton->sendMessage(buffer,StartLocalCurrentAI);
2843     break;
2844   case GameLogic::GameAutomaton::INIT:;
2845     break;
2846   case GameLogic::GameAutomaton::INTERLUDE:;
2847     break;
2848   case GameLogic::GameAutomaton::ATTACK:;
2849     break;
2850   case GameLogic::GameAutomaton::ATTACK2:;
2851     break;
2852   case GameLogic::GameAutomaton::INVADE:;
2853     break;
2854   case GameLogic::GameAutomaton::SHIFT1:;
2855     break;
2856   case GameLogic::GameAutomaton::SHIFT2:;
2857     break;
2858   case GameLogic::GameAutomaton::FIGHT_BRING:;
2859     break;
2860   case GameLogic::GameAutomaton::FIGHT_ANIMATE:;
2861     break;
2862   case GameLogic::GameAutomaton::FIGHT_BRINGBACK:;
2863     break;
2864   case GameLogic::GameAutomaton::WAITDEFENSE:;
2865     break;
2866   case GameLogic::GameAutomaton::EXPLOSION_ANIMATE:;
2867     break;
2868 
2869   default:
2870     m_automaton->sendMessage(buffer,ClearHighlighting);
2871   }
2872 }
2873 
optionsConfigure()2874 void KGameWindow::optionsConfigure()
2875 {
2876   //An instance of your dialog could be already created and could be cached,
2877   //in which case you want to display the cached dialog instead of creating
2878   //another one
2879   if ( KsirkConfigurationDialog::showDialog( "settings" ) )
2880     return;
2881 
2882   //KConfigDialog didn't find an instance of this dialog, so lets create it :
2883   KsirkConfigurationDialog* dialog = new KsirkConfigurationDialog( this, "settings",
2884                                              KsirkSettings::self() );
2885 
2886   connect(dialog,SIGNAL(armiesNumberShowingChanged(int)),
2887       this,SLOT(slotArmiesNumberChanged(int)));
2888 
2889   dialog->show();
2890 }
2891 
explain()2892 void KGameWindow::explain()
2893 {
2894   KMessageParts message0Parts;
2895   message0Parts << I18N_NOOP("<b>KsirK quick Introduction</b>");
2896   broadcastChangeItem(message0Parts, ID_NO_STATUS_MSG);
2897 
2898   KMessageParts message1Parts;
2899   message1Parts << I18N_NOOP("Attacks and moves are issued through drag & drop between neighbour countries.");
2900   broadcastChangeItem(message1Parts, ID_NO_STATUS_MSG);
2901 
2902   KMessageParts message2Parts;
2903   message2Parts << I18N_NOOP("Start a new game or join a network game with the menu or the toolbar...");
2904   broadcastChangeItem(message2Parts, ID_NO_STATUS_MSG);
2905 
2906   KMessageParts message5Parts;
2907   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.");
2908   broadcastChangeItem(message5Parts, ID_NO_STATUS_MSG);
2909 }
2910 
showMessage(const QString & message,quint32 delay,MessageShowingType forcing)2911 void KGameWindow::showMessage(const QString& message, quint32 delay, MessageShowingType forcing)
2912 {
2913   qCDebug(KSIRK_LOG);
2914   QString lmessage = message + "<br><a href=\"dontshowagain\">"+i18n("Don't show messages anymore") + "</a>";
2915   if(KsirkSettings::helpEnabled() || forcing == ForceShowing)
2916   {
2917     if (m_message == 0)
2918     {
2919       qCDebug(KSIRK_LOG) << "Creating KGamePopupItem";
2920       m_message  = new KGamePopupItem();
2921       connect(m_message,SIGNAL(linkActivated(QString)),this,SLOT(slotDisableHelp(QString)));
2922       m_scene_world->addItem(m_message);
2923       m_message->setSharpness(KGamePopupItem::Soft);
2924       m_message->setZValue(1000);
2925     }
2926     m_message->setMessageTimeout(delay*1000);
2927     m_message->showMessage(lmessage, KGamePopupItem::TopLeft, KGamePopupItem::ReplacePrevious);
2928 
2929 //   m_message->setPos(m_frame-> mapToScene(QPoint(30,30)));
2930   }
2931 }
2932 
2933 
firstCountry(GameLogic::Country * country)2934 void KGameWindow::firstCountry(GameLogic::Country* country)
2935 {
2936   qCDebug(KSIRK_LOG) << (void*)country;
2937   if (m_firstCountry != 0)
2938   {
2939     m_firstCountry->releaseHighlightingLock();
2940     m_firstCountry->clearHighlighting();
2941   }
2942   m_firstCountry = country;
2943   if (country == 0)
2944   {
2945     return;
2946   }
2947   qCDebug(KSIRK_LOG) << country->name();
2948   country->highlightAsAttacker();
2949 }
2950 
secondCountry(GameLogic::Country * country)2951 void KGameWindow::secondCountry(GameLogic::Country* country)
2952 {
2953   if (m_secondCountry != 0)
2954   {
2955     m_secondCountry->clearHighlighting();
2956   }
2957   m_secondCountry = country;
2958   if (country == 0)
2959   {
2960     return;
2961   }
2962   qCDebug(KSIRK_LOG) << country->name();
2963   country->highlightAsDefender();
2964 }
2965 
2966 
firstCountry()2967 GameLogic::Country* KGameWindow::firstCountry()
2968 {
2969   if (m_currentDisplayedWidget == Arena) {
2970      return m_arena->countryAttack();
2971   }
2972   return m_firstCountry;
2973 }
2974 
2975 
secondCountry()2976 GameLogic::Country* KGameWindow::secondCountry()
2977 {
2978   if (m_currentDisplayedWidget == Arena) {
2979     return m_arena->countryDefense();
2980   }
2981   return m_secondCountry;
2982 }
2983 
2984 
showArena()2985 void KGameWindow::showArena()
2986 {
2987   qCDebug(KSIRK_LOG);
2988   if (m_currentDisplayedWidget != Arena)
2989   {
2990     // synchronize the arena countries
2991     m_currentDisplayedWidget = Arena;
2992     m_arena->initFightArena(m_firstCountry,m_secondCountry,m_backGnd_arena);
2993   }
2994   qCDebug(KSIRK_LOG) << "before setCurrentIndex";
2995   m_centralWidget->setCurrentIndex(ARENA_INDEX);
2996 }
2997 
2998 
showMap()2999 void KGameWindow::showMap()
3000 {
3001   qCDebug(KSIRK_LOG);
3002   m_centralWidget->setCurrentIndex(MAP_INDEX);
3003   m_currentDisplayedWidget = Map;
3004   statusBar()->show();
3005   m_zoomInAction->setEnabled(true);
3006   m_zoomOutAction->setEnabled(true);
3007 }
3008 
showMainMenu()3009 void KGameWindow::showMainMenu()
3010 {
3011   qCDebug(KSIRK_LOG);
3012   m_centralWidget->setCurrentIndex(MAINMENU_INDEX);
3013   m_currentDisplayedWidget = MainMenu;
3014 }
3015 
3016 
currentWidgetType()3017 KGameWindow::WidgetType KGameWindow::currentWidgetType()
3018 {
3019   return m_currentDisplayedWidget;
3020 }
3021 
3022 
currentWidget()3023 QGraphicsView* KGameWindow::currentWidget()
3024 {
3025   switch (currentWidgetType())
3026   {
3027     case Arena:
3028       return dynamic_cast <QGraphicsView*>(arena());
3029       break;
3030     case MainMenu:
3031       return 0;
3032       break;
3033     case Map:
3034       return dynamic_cast <QGraphicsView*>(frame());
3035       break;
3036     default:
3037       return 0;
3038   }
3039   return 0;
3040 }
3041 
3042 
backGnd()3043 BackGnd* KGameWindow::backGnd() {
3044   if (currentWidgetType() == Arena) {
3045     return backGndArena();
3046   } else {
3047     return backGndWorld();
3048   }
3049 }
3050 
slideInvade(GameLogic::Country * attack,GameLogic::Country * defender,InvasionSlider::InvasionType invasionType)3051 void KGameWindow::slideInvade(GameLogic::Country * attack, GameLogic::Country * defender, InvasionSlider::InvasionType invasionType)
3052 {
3053   if (m_wSlide != 0)
3054   {
3055     m_wSlide->hide();
3056     delete m_wSlide;
3057   }
3058   m_wSlide = new InvasionSlider(this,attack,defender,invasionType);
3059   m_wSlide->show();
3060 }
3061 
isArena()3062 bool KGameWindow::isArena()
3063 {
3064   return m_useArena;
3065 }
3066 
reduceChat()3067 void KGameWindow::reduceChat()
3068 {
3069   qCDebug(KSIRK_LOG);
3070   m_chatIsReduced = true;
3071 
3072   m_lastWidthChat = m_bottomDock->width();
3073 
3074   // reduce the chat
3075   QPixmap upChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/upArrow.png"));
3076   m_reduceChatButton->setIcon(upChatReducePix);
3077   m_chatDlg->hide();
3078   m_titleChatMsg->show();
3079 }
3080 
unreduceChat()3081 void KGameWindow::unreduceChat()
3082 {
3083   qCDebug(KSIRK_LOG);
3084   m_chatIsReduced = false;
3085 
3086   // restore the chat
3087   QPixmap downChatReducePix(QStandardPaths::locate(QStandardPaths::AppDataLocation, m_automaton->skin() + "/Images/downArrow.png"));
3088   m_reduceChatButton->setIcon(downChatReducePix);
3089   m_chatDlg->show();
3090   m_titleChatMsg->hide();
3091   m_bottomDock->setMaximumSize(16777215,16777215);
3092   m_bottomDock->resize(m_lastWidthChat,38+m_chatDlg->height());
3093 }
3094 
setNextPlayerActionEnabled(bool value)3095 void KGameWindow::setNextPlayerActionEnabled(bool value)
3096 {
3097   qCDebug(KSIRK_LOG) << value;
3098   m_nextPlayerAction->setEnabled(value);
3099 }
3100 
setSaveGameActionEnabled(bool value)3101 void KGameWindow::setSaveGameActionEnabled(bool value)
3102 {
3103   qCDebug(KSIRK_LOG) << value;
3104   m_saveGameAction->setEnabled(value);
3105 }
3106 
setContextualHelpActionEnabled(GameLogic::GameAutomaton::GameState gameState,bool isPlayerAI)3107 void KGameWindow::setContextualHelpActionEnabled(GameLogic::GameAutomaton::GameState gameState, bool isPlayerAI)
3108 {
3109   qCDebug(KSIRK_LOG) << isPlayerAI << gameState;
3110   bool enabled = (gameState == GameLogic::GameAutomaton::WAIT || gameState == GameLogic::GameAutomaton::NEWARMIES || gameState == GameLogic::GameAutomaton::INTERLUDE) &&
3111                  !isPlayerAI &&
3112                  KsirkSettings::helpEnabled();
3113   m_contextualHelpAction->setEnabled(enabled);
3114 }
3115 
setupPopupMessage()3116 void KGameWindow::setupPopupMessage()
3117 {
3118   if (m_message == 0)
3119   {
3120     qCDebug(KSIRK_LOG);
3121     m_message  = new KGamePopupItem();
3122     connect(m_message,SIGNAL(linkActivated(QString)),this,SLOT(slotDisableHelp(QString)));
3123     m_scene_world->addItem(m_message);
3124     m_message->setSharpness(KGamePopupItem::Soft);
3125     QColor color = QColor(102,102,255);
3126     m_message->setBackgroundBrush(color);
3127     m_message->setZValue(1000);
3128   }
3129 }
3130 
newGameDialog(const QString & skin,GameAutomaton::NetworkGameType netGameType)3131 bool KGameWindow::newGameDialog(const QString& skin, GameAutomaton::NetworkGameType netGameType)
3132 {
3133   qCDebug(KSIRK_LOG) << "state is" << m_automaton->stateName();
3134   m_automaton->setGameStatus( KGame::Pause );
3135   m_stateBeforeNewGame = m_automaton->state();
3136   m_automaton->state(GameAutomaton::STARTING_GAME);
3137   m_rightDock->hide();
3138   statusBar()->hide();
3139   m_zoomInAction->setEnabled(false);
3140   m_zoomOutAction->setEnabled(false);
3141   m_nextPlayerAction->setEnabled(false);
3142   m_goalAction->setVisible(false);;
3143   m_newGameDialog->init(skin, netGameType);
3144   m_stackWidgetBeforeNewGame = m_centralWidget->currentIndex();
3145   m_centralWidget->setCurrentIndex(NEWGAME_INDEX);
3146   return false;
3147 }
3148 
3149 /* Set presence (usually called by dialog widget). */
setPresence(const XMPP::Status & status)3150 void KGameWindow::setPresence ( const XMPP::Status &status )
3151 {
3152   qCDebug(KSIRK_LOG) << "Status: " << status.show () << ", Reason: " << status.status ();
3153 
3154   // fetch input status
3155   XMPP::Status newStatus = status;
3156 
3157   // TODO: Check if Caps is enabled
3158   // Send entity capabilities
3159   if( m_jabberClient )
3160   {
3161     newStatus.setCapsNode( m_jabberClient->capsNode() );
3162     newStatus.setCapsVersion( m_jabberClient->capsVersion() );
3163     newStatus.setCapsExt( m_jabberClient->capsExt() );
3164   }
3165 
3166   // make sure the status gets the correct priority
3167   newStatus.setPriority ( 5 );
3168 
3169 /*  XMPP::Jid jid ( this->contactId() );
3170   XMPP::Resource newResource ( resource (), newStatus );
3171 
3172   // update our resource in the resource pool
3173   resourcePool()->addResource ( jid, newResource );
3174 
3175   // make sure that we only consider our own resource locally
3176   resourcePool()->lockToResource ( jid, newResource );*/
3177 
3178   /*
3179   * Unless we are in the connecting status, send a presence packet to the server
3180   */
3181   if(status.show () != QString("connecting") )
3182   {
3183     /*
3184     * Make sure we are actually connected before sending out a packet.
3185     */
3186     if (true/*isConnected()*/)
3187     {
3188       qCDebug(KSIRK_LOG) << "Sending new presence to the server.";
3189 
3190       XMPP::JT_Presence * task = new XMPP::JT_Presence ( m_jabberClient->rootTask ());
3191 
3192       task->pres ( newStatus );
3193       task->go ( true );
3194     }
3195     else
3196     {
3197       qCDebug(KSIRK_LOG) << "We were not connected, presence update aborted.";
3198     }
3199   }
3200 
3201 }
3202 
askForJabberGames()3203 void KGameWindow::askForJabberGames()
3204 {
3205   if (m_jabberClient && m_jabberClient->isConnected())
3206   {
3207     XMPP::Message message(QString(m_groupchatRoom+'@'+m_groupchatHost));
3208     message.setType("groupchat");
3209     message.setId(QUuid::createUuid().toString().remove('{').remove('}').remove('-'));
3210     QString body("Who propose online KsirK games here?");
3211     message.setBody(body);
3212     qCDebug(KSIRK_LOG) << "Sending message: <<" << body << ">> to" << (m_groupchatRoom+'@'+m_groupchatHost);
3213     m_jabberClient->sendMessage(message);
3214   }
3215 }
3216 
sendGameInfoToJabber()3217 void KGameWindow::sendGameInfoToJabber()
3218 {
3219   qCDebug(KSIRK_LOG);
3220   if (m_jabberClient
3221     && m_jabberClient->isConnected()
3222     && m_automaton->startingGame())
3223   {
3224     qCDebug(KSIRK_LOG) << "Sending 'I'm starting a game with ...'";
3225     XMPP::Message message(QString(m_groupchatRoom+'@'+m_groupchatHost));
3226     message.setType("groupchat");
3227     message.setId(QUuid::createUuid().toString().remove('{').remove('}').remove('-'));
3228     QString body;
3229     QTextStream qts(&body);
3230     qts <<"I'm starting a game with skin '" << m_automaton->skin() << "' and '" << m_automaton->nbPlayers() << "' players";
3231     message.setBody(body);
3232     qCDebug(KSIRK_LOG) << "Sending message: <<" << body << ">> to" << (m_groupchatRoom+'@'+m_groupchatHost);
3233     m_jabberClient->sendMessage(message);
3234   }
3235 }
3236 
joinNetworkGame()3237 void KGameWindow::joinNetworkGame()
3238 {
3239   qCDebug(KSIRK_LOG);
3240   /// @TODO show the network connect screen
3241   m_centralWidget->setCurrentIndex(TCPCONNECT_INDEX);
3242 }
3243 
updateNewGameSummary()3244 void KGameWindow::updateNewGameSummary()
3245 {
3246   qCDebug(KSIRK_LOG);
3247   m_newGameSummaryWidget->show(this);
3248 }
3249 
showNewGameSummary()3250 void KGameWindow::showNewGameSummary()
3251 {
3252   qCDebug(KSIRK_LOG);
3253   m_centralWidget->setCurrentIndex(NEWGAMESUMMARY_INDEX);
3254 }
3255 
3256 } // closing namespace Ksirk
3257 
3258 
3259