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('&',"&");
2680 name = name.replace('<',"<");
2681 name = name.replace('>',">");
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