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