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