File indexing completed on 2024-10-06 06:48:47
0001 /* This file is part of KsirK. 0002 Copyright (C) 2004-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 #include "gameautomaton.h" 0021 0022 #include "ksirksettings.h" 0023 #include "kgamewin.h" 0024 #include "aiplayer.h" 0025 #include "aiColsonPlayer.h" 0026 #include "aiplayerio.h" 0027 #include "onu.h" 0028 #include "dice.h" 0029 #include "goal.h" 0030 #include "country.h" 0031 #include "KMessageParts.h" 0032 #include "newgamesetup.h" 0033 #include "krightdialog.h" 0034 #include "Dialogs/joingame.h" 0035 #if HAVE_JABBER_SUPPORT 0036 #include "Jabber/kmessagejabber.h" 0037 #endif 0038 #include "newplayerdata.h" 0039 #include "gamesequence.h" 0040 0041 #include <QLayout> 0042 #include <QSpinBox> 0043 #include <QPixmap> 0044 #include <QMouseEvent> 0045 #include <QFile> 0046 #include <QUuid> 0047 #include <QInputDialog> 0048 0049 #include <KLazyLocalizedString> 0050 #include <KLocalizedString> 0051 #include <KLineEdit> 0052 #include <KMessageBox> 0053 0054 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API 0055 #include <libkdegamesprivate/kgame/kmessageclient.h> 0056 #include <libkdegamesprivate/kgame/kmessageserver.h> 0057 #include <libkdegamesprivate/kgame/kgamechat.h> 0058 0059 #include <errno.h> 0060 #include <sys/types.h> 0061 #include <signal.h> 0062 #include <QCache> 0063 0064 namespace Ksirk{ 0065 namespace GameLogic { 0066 0067 const char* GameAutomaton::GameStateNames[] = { 0068 "INIT", 0069 "INTERLUDE", 0070 "NEWARMIES", 0071 "WAIT", 0072 "WAIT1", 0073 "WAIT_RECYCLING", 0074 "ATTACK", 0075 "ATTACK2", 0076 "INVADE", 0077 "SHIFT1", 0078 "SHIFT2", 0079 "FIGHT_BRING", 0080 "FIGHT_ANIMATE", 0081 "FIGHT_BRINGBACK", 0082 "WAITDEFENSE", 0083 "EXPLOSION_ANIMATE", 0084 "WAIT_PLAYERS", 0085 "GAME_OVER", 0086 "INVALID", 0087 "STARTING_GAME" 0088 }; 0089 0090 const char* GameAutomaton::KsirkMessagesIdsNames[] = { 0091 "CountryOwner", // 257 0092 "PlayerPutsArmy", // 258 0093 "StateChange", // 259 0094 "PlayerChange", // 260 0095 "RegisterCountry", // 261 0096 "PlayerAvailArmies", // 262 0097 "ResetPlayersDistributionData", // 263 0098 "ChangeItem", // 264 0099 "DisplayRecyclingButtons", // 265 0100 "ClearHighlighting", // 266 0101 "ActionRecycling", // 267 0102 "ClearGameActionsToolbar", // 268 0103 "DisplayDefenseButtons", // 269 0104 "ActionDefense", // 270 0105 "FirstCountry", // 271 0106 "SecondCountry", // 272 0107 "InitCombatMovement", // 273 0108 "AnimCombat", // 274 0109 // 275 0110 "TerminateAttackSequence", // 276 0111 "DecrNbArmies", // 277 0112 "StartLocalCurrentAI", // 278 0113 "Invade", // 279 0114 "Retreat", // 280 0115 "NextPlayerNormal", // 281 0116 "NextPlayerRecycling", // 282 0117 "ShowArmiesToPlace", // 283 0118 "PlayerPutsInitialArmy", // 284 0119 "PlayerRemovesArmy", //285 0120 "VoteRecyclingFinished", // 286 0121 "CancelShiftSource", // 287 0122 "ChangePlayerNation", // 288 0123 "ChangePlayerName", // 289 0124 "StartGame", // 290 0125 "SetNation", // 291 0126 "SetBarFlagButton", // 292 0127 "FinishMoves", // 293 0128 "AnimExplosion", // 294 0129 "SetupOnePlayer", // 295 0130 "SetupWaitedPlayer", // 296 0131 "ValidateWaitedPlayerPassword", // 297 0132 "ValidPassword", // 298 0133 "InvalidPassword", // 299 0134 "SetupCountries", // 300 0135 "AddMsgIdPair", // 301 0136 "CheckGoal", // 302 0137 "SetGoalFor", // 303 0138 "GoalForIs", // 304 0139 "Winner", // 305 0140 "NbPlayers", // 306 0141 "FinalizePlayers", // 307 0142 "Acknowledge", // 308 0143 "DisplayGoals", // 309 0144 "DisplayFightResult", // 310 0145 "MoveSlide", // 311 0146 "InvasionFinished", // 312 0147 "AttackAuto", // 313 0148 "DisplayRecycleDetails", // 314 0149 "CurrentPlayerPlayed", // 315 0150 "NewGameSetupMsg", // 316 0151 }; 0152 0153 #define KSIRK_DEFAULT_PORT 20000 0154 0155 GameAutomaton::GameAutomaton() : 0156 KGame(), 0157 m_aicannotrunhack(true), 0158 m_state(INIT), 0159 m_game(nullptr), 0160 m_networkPlayersNumber(0), 0161 m_currentPlayer(""), 0162 m_currentPlayerPlayed(false), 0163 m_savedState(INVALID), 0164 m_goals(), 0165 m_useGoals(true), 0166 m_attackAuto(false), 0167 m_defenseAuto(false), 0168 m_port(KSIRK_DEFAULT_PORT), 0169 m_startingGame(false) 0170 { 0171 m_skin = "skins/default"; 0172 // qCDebug(KSIRK_LOG); 0173 // m_stateId = m_state.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_state")); 0174 m_skinId = m_skin.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_skin")); 0175 // m_currentPlayerId = m_currentPlayer.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_currentPlayer")); 0176 // m_events.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_events")); 0177 0178 setGameSequence(new GameSequence(this)); 0179 0180 // Connect the most important slot which tells us which properties are 0181 // changed 0182 connect(this,&KGame::signalPropertyChanged, 0183 this,&GameAutomaton::slotPropertyChanged); 0184 0185 connect(this,&KGame::signalPlayerJoinedGame, 0186 this,&GameAutomaton::slotPlayerJoinedGame); 0187 0188 connect(this,&KGame::signalNetworkData, 0189 this,&GameAutomaton::slotNetworkData); 0190 0191 connect(this,&KGame::signalClientJoinedGame, 0192 this,&GameAutomaton::slotClientJoinedGame); 0193 0194 connect(messageClient(),&KMessageClient::connectionBroken, 0195 this,&GameAutomaton::slotConnectionToServerBroken); 0196 0197 connect(messageServer(),&KMessageServer::connectionLost, 0198 this,&GameAutomaton::slotConnectionToClientBroken); 0199 0200 setPolicy(KGame::PolicyDirty,true); 0201 0202 // qCDebug(KSIRK_LOG) << "finished"; 0203 } 0204 0205 GameAutomaton::~GameAutomaton() 0206 { 0207 qCDebug(KSIRK_LOG); 0208 qDeleteAll(m_goals); 0209 } 0210 0211 void GameAutomaton::init(KGameWindow* gw) 0212 { 0213 m_game = gw; 0214 } 0215 0216 GameAutomaton::GameState GameAutomaton::state() const 0217 { 0218 return m_state; 0219 } 0220 0221 void GameAutomaton::state(GameAutomaton::GameState state) 0222 { 0223 qCDebug(KSIRK_LOG) << "new state (id=" << state << ") is " << GameStateNames[state]; 0224 m_state = state; 0225 m_game->setSaveGameActionEnabled(m_state == WAIT); 0226 m_game->setContextualHelpActionEnabled(m_state, currentPlayer() && currentPlayer()->isAI()); 0227 QByteArray buffer; 0228 QDataStream stream(&buffer, QIODevice::WriteOnly); 0229 stream << state; 0230 sendMessage(buffer,StateChange); 0231 } 0232 0233 Player* GameAutomaton::getAnyLocalPlayer() 0234 { 0235 PlayersArray::iterator it = playerList()->begin(); 0236 PlayersArray::iterator it_end = playerList()->end(); 0237 for (; it != it_end; it++) 0238 { 0239 if ( !((Player*)(*it))->isVirtual() ) 0240 { 0241 return (Player*)(*it); 0242 } 0243 } 0244 return nullptr; 0245 } 0246 0247 GameAutomaton::GameState GameAutomaton::run() 0248 { 0249 // qCDebug(KSIRK_LOG) << "(KGame running=" << (gameStatus()==KGame::Run) << ")"; 0250 if (m_game == nullptr || gameStatus() == KGame::Pause) 0251 { 0252 QTimer::singleShot(200, this, &GameAutomaton::run); 0253 return m_state; 0254 } 0255 0256 activateNeededAIPlayers(); 0257 0258 QString event = ""; 0259 QPointF point; 0260 if (!m_events.empty()) 0261 { 0262 QPair< QString, QPointF > pair = m_events.front(); 0263 event = pair.first; 0264 point = pair.second; 0265 m_events.pop_front(); 0266 } 0267 0268 // qCDebug(KSIRK_LOG) << "Handling " << stateName() << " ; " << event << " ; " << point; 0269 // if (currentPlayer()) 0270 // { 0271 // qCDebug(KSIRK_LOG) << "current player=" << currentPlayer()->name() << " is active=" << currentPlayer()->isActive(); 0272 // } 0273 if (event == "requestForAck") 0274 { 0275 qCDebug(KSIRK_LOG) << "requestForAck"; 0276 } 0277 if((event == "actionRButtonDown" || event == "actionLButtonDown") && (m_state != INIT && m_state != NEWARMIES && m_state != INTERLUDE && m_state != WAIT_RECYCLING)) 0278 { 0279 if (m_game->getRightDialog()->isOpen()) 0280 { 0281 m_game->getRightDialog()->close(); 0282 } 0283 } 0284 0285 if (event == "actionNewGame") 0286 { 0287 if (m_game->actionNewGame(GameAutomaton::None)) 0288 { 0289 state(INIT); 0290 QTimer::singleShot(200, this, &GameAutomaton::run); 0291 return INIT; 0292 } 0293 else 0294 { 0295 QTimer::singleShot(200, this, &GameAutomaton::run); 0296 return m_state; 0297 } 0298 } 0299 if (event == "actionOpenGame") 0300 { 0301 if (m_game->actionOpenGame()) 0302 { 0303 qCDebug(KSIRK_LOG) << "opened"; 0304 bool ok; 0305 m_port = QInputDialog::getInt(m_game, 0306 i18n("KsirK - Network configuration"), 0307 i18n("Please type in the port number on which to offer connections:"), 0308 m_port, 0, 32000, 1, &ok); 0309 offerConnections(m_port); 0310 state(WAIT_PLAYERS); 0311 QTimer::singleShot(200, this, &GameAutomaton::run); 0312 return WAIT_PLAYERS; 0313 } 0314 else 0315 { 0316 qCDebug(KSIRK_LOG) << "opened"; 0317 QTimer::singleShot(200, this, &GameAutomaton::run); 0318 return m_state; 0319 } 0320 } 0321 if (event == "actionJoinNetworkGame") 0322 { 0323 joinNetworkGame(); 0324 QTimer::singleShot(200, this, &GameAutomaton::run); 0325 return m_state; 0326 } 0327 0328 switch (m_state) 0329 { 0330 case INIT: 0331 if (currentPlayer() != nullptr && isAdmin()) 0332 { 0333 if ( (event == "actionLButtonDown") && (m_game->playerPutsInitialArmy(point)) ) 0334 { 0335 m_choosedToRecycleNumber = 0; 0336 m_game->initRecycling(); 0337 state(WAIT_RECYCLING); 0338 } 0339 } 0340 break; 0341 case ATTACK: 0342 state(ATTACK2); 0343 break; 0344 case ATTACK2: 0345 qCDebug(KSIRK_LOG) << "Handling ATTACK2"; 0346 if (isAdmin()) 0347 { 0348 QByteArray buffer; 0349 switch ( m_game->attacked(point) ) 0350 { 0351 case 0: 0352 qCDebug(KSIRK_LOG) << "handling attacked value; 0"; 0353 state(WAIT); 0354 break; 0355 case 1: 0356 qCDebug(KSIRK_LOG) << "handling attacked value; 1"; 0357 sendMessage(buffer,CurrentPlayerPlayed); 0358 state(WAITDEFENSE); 0359 break; 0360 case 2: 0361 qCDebug(KSIRK_LOG) << "handling attacked value; 2"; 0362 sendMessage(buffer,CurrentPlayerPlayed); 0363 qCDebug(KSIRK_LOG) << "calling defense(1)"; 0364 m_game-> defense(1); 0365 qCDebug(KSIRK_LOG) << "setting state to FIGHT_BRING"; 0366 state(FIGHT_BRING); 0367 break; 0368 case 3: 0369 qCDebug(KSIRK_LOG) << "handling attacked value; 3"; 0370 // AI action: nothing to do. 0371 break; 0372 default: 0373 qCCritical(KSIRK_LOG) << "Unknown return value from attacked"; 0374 exit(1); 0375 } 0376 } 0377 qCDebug(KSIRK_LOG) << "handling of ATTACK2 finished !"; 0378 break; 0379 case EXPLOSION_ANIMATE: 0380 break; 0381 case FIGHT_ANIMATE: 0382 break; 0383 case FIGHT_BRING: 0384 break; 0385 case FIGHT_BRINGBACK: 0386 // no more moving fighter returning home 0387 0388 // qCDebug(KSIRK_LOG) << "$$$$$$$STATE FIGHT_BRINGBACK $$$$$$$$$$$" << m_game->haveAnimFighters(); 0389 0390 if (!m_game->haveAnimFighters() && isAdmin()) 0391 { 0392 QByteArray buffer; 0393 QDataStream stream(&buffer, QIODevice::WriteOnly); 0394 sendMessage(buffer,TerminateAttackSequence); 0395 } 0396 break; 0397 case INTERLUDE: 0398 if (event == "playersLooped") 0399 { 0400 m_choosedToRecycleNumber = 0; 0401 m_game->initRecycling(); 0402 state(WAIT_RECYCLING); 0403 } 0404 else if (event == "actionLButtonDown" ) 0405 { 0406 QByteArray buffer; 0407 QDataStream stream(&buffer, QIODevice::WriteOnly); 0408 stream << point; 0409 // qCDebug(KSIRK_LOG) << "Sending message PlayerPutsArmy " << point ; 0410 sendMessage(buffer,PlayerPutsInitialArmy); 0411 } 0412 else if (event == "actionRButtonDown") 0413 { 0414 QByteArray buffer; 0415 QDataStream stream(&buffer, QIODevice::WriteOnly); 0416 stream << point; 0417 sendMessage(buffer,PlayerRemovesArmy); 0418 } 0419 else if (event == "actionNextPlayer") 0420 { 0421 QByteArray buffer; 0422 QDataStream stream(&buffer, QIODevice::WriteOnly); 0423 stream << -1; 0424 sendMessage(buffer,NextPlayerRecycling); 0425 } 0426 else if (event == "actionRecycling") 0427 { 0428 QByteArray buffer; 0429 sendMessage(buffer,ActionRecycling); 0430 } 0431 else if (event == "actionRecyclingFinished") 0432 { 0433 qCDebug(KSIRK_LOG) << "actionRecyclingFinished"; 0434 QByteArray buffer; 0435 QDataStream stream(&buffer, QIODevice::WriteOnly); 0436 // stream << currentPlayer()->name(); 0437 PlayersArray::iterator it = playerList()->begin(); 0438 PlayersArray::iterator it_end = playerList()->end(); 0439 quint32 nbLocal = 0; 0440 for (; it != it_end; it++) 0441 { 0442 if ( !((Player*)(*it))->isVirtual() ) 0443 { 0444 qCDebug(KSIRK_LOG) << "Local:" << ((Player*)(*it))->name(); 0445 nbLocal++; 0446 } 0447 } 0448 qCDebug(KSIRK_LOG) << "Nb Local:" << nbLocal; 0449 stream << nbLocal; 0450 0451 for (it = playerList()->begin(); it != it_end; ++it) 0452 { 0453 if ( !((Player*)(*it))->isVirtual() ) 0454 { 0455 stream << ((Player*)(*it))->id(); 0456 } 0457 } 0458 sendMessage(buffer,VoteRecyclingFinished); 0459 } 0460 else 0461 { 0462 // if (!event.isEmpty()) 0463 // qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0464 } 0465 break; 0466 case INVADE: 0467 // qCDebug(KSIRK_LOG) << "$$$$$$$STATE INVADE$$$$$$$$$$$"; 0468 if (event == "actionInvade1") 0469 { 0470 QByteArray buffer; 0471 QDataStream stream(&buffer, QIODevice::WriteOnly); 0472 stream << quint32(1); 0473 sendMessage(buffer,Invade); 0474 } 0475 else if (event == "actionInvade5") 0476 { 0477 QByteArray buffer; 0478 QDataStream stream(&buffer, QIODevice::WriteOnly); 0479 stream << quint32(5); 0480 sendMessage(buffer,Invade); 0481 } 0482 else if (event == "actionInvade10") 0483 { 0484 QByteArray buffer; 0485 QDataStream stream(&buffer, QIODevice::WriteOnly); 0486 stream << quint32(10); 0487 sendMessage(buffer,Invade); 0488 } 0489 else if (event == "actionRetreat1") 0490 { 0491 QByteArray buffer; 0492 QDataStream stream(&buffer, QIODevice::WriteOnly); 0493 stream << quint32(1); 0494 sendMessage(buffer,Retreat); 0495 } 0496 else if (event == "actionRetreat5") 0497 { 0498 QByteArray buffer; 0499 QDataStream stream(&buffer, QIODevice::WriteOnly); 0500 stream << quint32(5); 0501 sendMessage(buffer,Retreat); 0502 } 0503 else if (event == "actionRetreat10") 0504 { 0505 QByteArray buffer; 0506 QDataStream stream(&buffer, QIODevice::WriteOnly); 0507 stream << quint32(10); 0508 sendMessage(buffer,Retreat); 0509 } 0510 else if (event == "actionInvasionFinished") 0511 { 0512 state(WAIT); 0513 m_game-> invasionFinished(); 0514 } 0515 else 0516 { 0517 // if (!event.isEmpty()) 0518 // qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0519 } 0520 break; 0521 case NEWARMIES: 0522 if (event == "actionLButtonDown") 0523 { 0524 QByteArray buffer; 0525 QDataStream stream(&buffer, QIODevice::WriteOnly); 0526 stream << point << quint32(true); 0527 sendMessage(buffer,PlayerPutsArmy); 0528 } 0529 else if (event == "actionRButtonDown") 0530 { 0531 QByteArray buffer; 0532 QDataStream stream(&buffer, QIODevice::WriteOnly); 0533 stream << point; 0534 sendMessage(buffer,PlayerRemovesArmy); 0535 } 0536 else if (event == "actionNextPlayer") 0537 { 0538 QByteArray buffer; 0539 QDataStream stream(&buffer, QIODevice::WriteOnly); 0540 stream << quint32(WAIT); 0541 sendMessage(buffer,NextPlayerRecycling); 0542 } 0543 // else 0544 // { 0545 // if (!event.isEmpty()) 0546 // qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0547 // } 0548 break; 0549 case SHIFT1: 0550 if (event == "actionCancel") 0551 { 0552 m_game-> cancelAction(); 0553 state(WAIT); 0554 } 0555 else if (event == "actionLButtonDown") 0556 { 0557 m_game->firstCountryAt(point); 0558 } 0559 else if (event == "actionLButtonUp") 0560 { 0561 m_game->secondCountryAt(point); 0562 if (m_game->isMoveValid(point)) 0563 { 0564 m_game->startLocalCurrentAI(); 0565 QByteArray buffer; 0566 sendMessage(buffer,CurrentPlayerPlayed); 0567 state(SHIFT2); 0568 } 0569 else 0570 { 0571 // state(WAIT); 0572 } 0573 } 0574 else 0575 { 0576 // if (!event.isEmpty()) 0577 // qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0578 } 0579 break; 0580 case SHIFT2: 0581 // qCDebug(KSIRK_LOG) << "$$$$$$$STATE SHIFT2$$$$$$$$$$$"; 0582 if (event == "actionInvade1") 0583 { 0584 // qCDebug(KSIRK_LOG) << "actionInvade1"; 0585 QByteArray buffer; 0586 QDataStream stream(&buffer, QIODevice::WriteOnly); 0587 stream << quint32(1); 0588 sendMessage(buffer,Invade); 0589 } 0590 else if (event == "actionInvade5") 0591 { 0592 QByteArray buffer; 0593 QDataStream stream(&buffer, QIODevice::WriteOnly); 0594 stream << quint32(5); 0595 sendMessage(buffer,Invade); 0596 } 0597 else if (event == "actionInvade10") 0598 { 0599 QByteArray buffer; 0600 QDataStream stream(&buffer, QIODevice::WriteOnly); 0601 stream << quint32(10); 0602 sendMessage(buffer,Invade); 0603 } 0604 else if (event == "actionRetreat1") 0605 { 0606 QByteArray buffer; 0607 QDataStream stream(&buffer, QIODevice::WriteOnly); 0608 stream << quint32(1); 0609 sendMessage(buffer,Retreat); 0610 } 0611 else if (event == "actionRetreat5") 0612 { 0613 QByteArray buffer; 0614 QDataStream stream(&buffer, QIODevice::WriteOnly); 0615 stream << quint32(5); 0616 sendMessage(buffer,Retreat); 0617 } 0618 else if (event == "actionRetreat10") 0619 { 0620 QByteArray buffer; 0621 QDataStream stream(&buffer, QIODevice::WriteOnly); 0622 stream << quint32(10); 0623 sendMessage(buffer,Retreat); 0624 } 0625 else if (event == "actionInvasionFinished") 0626 { 0627 m_game-> shiftFinished(); 0628 state(WAIT); 0629 } 0630 else if (event == "actionCancel") 0631 { 0632 QByteArray buffer; 0633 QDataStream stream(&buffer, QIODevice::WriteOnly); 0634 sendMessage(buffer,CancelShiftSource); 0635 } 0636 else 0637 { 0638 //qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0639 } 0640 break; 0641 case WAIT_RECYCLING: 0642 if (event == "actionRecycling") 0643 { 0644 QByteArray buffer; 0645 sendMessage(buffer,ActionRecycling); 0646 } 0647 else if (event == "actionRecyclingFinished") 0648 { 0649 QByteArray buffer; 0650 QDataStream stream(&buffer, QIODevice::WriteOnly); 0651 // stream << currentPlayer()->name(); 0652 PlayersArray::iterator it = playerList()->begin(); 0653 PlayersArray::iterator it_end = playerList()->end(); 0654 quint32 nbLocal = 0; 0655 for (; it != it_end; it++) 0656 { 0657 if ( !((Player*)(*it))->isVirtual() ) 0658 { 0659 nbLocal++; 0660 } 0661 } 0662 stream << nbLocal; 0663 it = playerList()->begin(); 0664 it_end = playerList()->end(); 0665 for (; it != it_end; it++) 0666 { 0667 if ( !((Player*)(*it))->isVirtual() ) 0668 { 0669 stream << (*it)->id(); 0670 } 0671 } 0672 sendMessage(buffer,VoteRecyclingFinished); 0673 } 0674 else 0675 { 0676 if (!event.isEmpty()) 0677 qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0678 else 0679 { 0680 if (allLocalPlayersComputer()) 0681 { 0682 m_game->getRightDialog()->updateRecycleDetails(nullptr,true,0); 0683 m_game->displayRecyclingButtons(); 0684 } 0685 } 0686 } 0687 break; 0688 case WAITDEFENSE: 0689 if (event == "actionDefense1") 0690 { 0691 QByteArray buffer; 0692 QDataStream stream(&buffer, QIODevice::WriteOnly); 0693 stream << quint32(1); 0694 sendMessage(buffer,ActionDefense); 0695 } 0696 else if (event == "actionDefense2") 0697 { 0698 QByteArray buffer; 0699 QDataStream stream(&buffer, QIODevice::WriteOnly); 0700 stream << quint32(2); 0701 sendMessage(buffer,ActionDefense); 0702 } 0703 else if ( m_game->secondCountry() != nullptr 0704 && !m_game->secondCountry()->owner()->isVirtual() 0705 && isDefenseAuto() 0706 && (m_game->secondCountry()->owner()->getNbDefense() == 0) ) 0707 { 0708 quint32 nbDefense = 1; 0709 if (m_game->secondCountry()->nbArmies() > 1) 0710 { 0711 nbDefense = 2; 0712 } 0713 m_game->secondCountry()->owner()->setNbDefense(nbDefense); 0714 QByteArray buffer; 0715 QDataStream stream(&buffer, QIODevice::WriteOnly); 0716 stream << nbDefense; 0717 sendMessage(buffer,ActionDefense); 0718 } 0719 else 0720 { 0721 // if (!event.isEmpty()) 0722 qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0723 } 0724 break; 0725 case WAIT: 0726 if (event == "actionNextPlayer") 0727 { 0728 actionNextPlayer(); 0729 } 0730 else if (event == "actionLButtonDown") 0731 { 0732 if (m_game->firstCountryAt(point)) 0733 state(WAIT1); 0734 } 0735 else 0736 { 0737 // if (!event.isEmpty()) 0738 // qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName(); 0739 } 0740 // other case : state doesn't change 0741 break; 0742 case WAIT1: 0743 if (event == "actionNextPlayer") 0744 { 0745 actionNextPlayer(); 0746 } 0747 else if (event == "actionAttack1") 0748 { 0749 m_game->attack(1); 0750 state(ATTACK); 0751 } 0752 else if (event == "actionAttack2") 0753 { 0754 m_game->attack(2); 0755 state(ATTACK); 0756 } 0757 else if (event == "actionAttack3") 0758 { 0759 m_game->attack(3); 0760 state(ATTACK); 0761 } 0762 else if (event == "actionInvade1") 0763 { 0764 // qCDebug(KSIRK_LOG) << "actionInvade1"; 0765 QByteArray buffer2; 0766 sendMessage(buffer2,CurrentPlayerPlayed); 0767 QByteArray buffer; 0768 QDataStream stream(&buffer, QIODevice::WriteOnly); 0769 stream << quint32(1); 0770 sendMessage(buffer,Invade); 0771 // state(WAIT); 0772 } 0773 else if (event == "actionInvade5") 0774 { 0775 QByteArray buffer2; 0776 sendMessage(buffer2,CurrentPlayerPlayed); 0777 QByteArray buffer; 0778 QDataStream stream(&buffer, QIODevice::WriteOnly); 0779 stream << quint32(5); 0780 sendMessage(buffer,Invade); 0781 // state(WAIT); 0782 } 0783 else if (event == "actionInvade10") 0784 { 0785 QByteArray buffer2; 0786 sendMessage(buffer2,CurrentPlayerPlayed); 0787 QByteArray buffer; 0788 QDataStream stream(&buffer, QIODevice::WriteOnly); 0789 stream << quint32(10); 0790 sendMessage(buffer,Invade); 0791 // state(WAIT); 0792 } 0793 else if (event == "actionInvasionFinished") 0794 { 0795 m_game-> shiftFinished(); 0796 state(WAIT); 0797 } 0798 else if (event == "actionLButtonUp") 0799 { 0800 qCDebug(KSIRK_LOG) << "actionLButtonUp in WAIT1"; 0801 0802 if (!currentPlayer()-> isAI()) 0803 { 0804 if (m_game->isMoveValid(point) && m_game->firstCountry()->nbArmies() !=1) 0805 { 0806 m_game->secondCountryAt(point); 0807 state(WAIT); 0808 qCDebug(KSIRK_LOG) << "Sending MoveSlide"; 0809 QByteArray buffer; 0810 QDataStream stream(&buffer, QIODevice::WriteOnly); 0811 sendMessage(buffer,MoveSlide); 0812 } 0813 else if (m_game->isFightValid(point) 0814 && m_game->firstCountry()->nbArmies() != 1) 0815 { 0816 m_game->secondCountryAt(point); 0817 if (m_game->firstCountry()->nbArmies() > 3) 0818 { 0819 m_game->frame()->getAttack1Action()->setVisible(true); 0820 m_game->frame()->getAttack2Action()->setVisible(true); 0821 m_game->frame()->getAttack3Action()->setVisible(true); 0822 0823 } 0824 else if (m_game->firstCountry()->nbArmies() > 2) 0825 { 0826 m_game->frame()->getAttack1Action()->setVisible(true); 0827 m_game->frame()->getAttack2Action()->setVisible(true); 0828 m_game->frame()->getAttack3Action()->setVisible(false); 0829 } 0830 else if (m_game->firstCountry()->nbArmies() > 1) 0831 { 0832 m_game->frame()->getAttack1Action()->setVisible(true); 0833 m_game->frame()->getAttack2Action()->setVisible(false); 0834 m_game->frame()->getAttack3Action()->setVisible(false); 0835 } 0836 m_game->frame()->setMenuPoint(QCursor::pos()); 0837 m_game->frame()->getAttackContextMenu()->exec(QCursor::pos()); 0838 } 0839 else 0840 { 0841 m_game-> cancelAction(); 0842 state(WAIT); 0843 } 0844 } 0845 else 0846 { 0847 m_game->secondCountryAt(point); 0848 } 0849 } 0850 else if (event == "actionLButtonDown") 0851 { 0852 m_game-> cancelAction(); 0853 if (m_game->firstCountryAt(point)) 0854 { 0855 state(WAIT1); 0856 } 0857 state(WAIT); 0858 } 0859 break; 0860 /*case WAIT_INPUT: 0861 0862 break;*/ 0863 case WAIT_PLAYERS: 0864 break; 0865 case GAME_OVER: 0866 break; 0867 case STARTING_GAME: 0868 break; 0869 default: 0870 qCCritical(KSIRK_LOG) << "Unhandled state: " << stateName() << ". Event was: " << event ; 0871 exit(1); // @todo handle this error 0872 } 0873 0874 QTimer::singleShot(200, this, &GameAutomaton::run); 0875 0876 // m_game->initTimer(); 0877 return m_state; 0878 } 0879 0880 void GameAutomaton::activateNeededAIPlayers() 0881 { 0882 // qCDebug(KSIRK_LOG); 0883 if ( currentPlayer() 0884 && (currentPlayer()-> isAI() ) 0885 && (!currentPlayer()->isVirtual()) 0886 && (!(dynamic_cast< AIPlayer* >(currentPlayer())-> isRunning())) 0887 ) 0888 { 0889 dynamic_cast< AIPlayer* >(currentPlayer())-> start(); 0890 } 0891 if ( ( m_state == WAITDEFENSE ) 0892 && ( m_game->secondCountry()) 0893 && ( m_game->secondCountry()->owner()) 0894 && ( m_game->secondCountry()->owner()->isAI() ) 0895 && ( !m_game->secondCountry()->owner()->isVirtual()) 0896 && ( !(dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> isRunning())) 0897 ) 0898 { 0899 dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> start(); 0900 } 0901 } 0902 0903 void GameAutomaton::gameEvent(const QString& event, const QPointF& point) 0904 { 0905 m_events.push_back(qMakePair(event, point)); 0906 } 0907 0908 0909 /** returns the name of the current state */ 0910 QString GameAutomaton::stateName() const 0911 { 0912 if (m_state >= (int) sizeof(GameStateNames)) 0913 { 0914 QString string; 0915 QTextStream oss(&string); 0916 oss << "Invalid stored state id: " << m_state; 0917 qCCritical(KSIRK_LOG) << string ; 0918 return string; 0919 } 0920 else 0921 { 0922 return QString::fromUtf8(GameStateNames[m_state]); 0923 } 0924 } 0925 0926 void GameAutomaton::saveXml(QTextStream& xmlStream) 0927 { 0928 xmlStream << "<gameautomaton state=\"" << GameStateNames[m_state] << "\" />"; 0929 } 0930 0931 const QString& GameAutomaton::skin() const 0932 { 0933 return m_skin.value(); 0934 } 0935 0936 void GameAutomaton::skin(const QString& newSkin) 0937 { 0938 m_skin = newSkin; 0939 } 0940 0941 // Called when a player input (e.g. a mouse event) is received from the KGame 0942 // object 0943 // This is obviously the central function in the game as all player moves, 0944 // whether network or local, end up here. So do something sensible here. 0945 bool GameAutomaton::playerInput(QDataStream &msg, KPlayer* player) 0946 { 0947 qCDebug(KSIRK_LOG); 0948 // if (player->isVirtual()) 0949 if (!isAdmin()) 0950 { 0951 // qCDebug(KSIRK_LOG) << "Network player: nothing to do"; 0952 return false; 0953 } 0954 0955 // Convert the player to the right class 0956 Player* p = dynamic_cast<Player*>(player); 0957 0958 QString action; 0959 QPointF point; 0960 msg >> action >> point; 0961 0962 qCDebug(KSIRK_LOG) << " ======================================================="; 0963 qCDebug(KSIRK_LOG) << "Player " << p->name() << " id=" << player->id() 0964 << " uid=" << player->userId() << " : " << action << " at " << point 0965 << "current is" << currentPlayer()->name(); 0966 0967 if (p->name() == currentPlayer()->name() 0968 || (m_state == WAITDEFENSE) ) 0969 { 0970 if (action == "actionLButtonDown") 0971 m_game->slotLeftButtonDown( point ); 0972 else if (action == "actionLButtonUp") 0973 m_game->slotLeftButtonUp( point ); 0974 else if (action == "actionRButtonDown") 0975 m_game->slotRightButtonDown( point ); 0976 else if (action == "actionRButtonUp") 0977 m_game->slotRightButtonUp( point ); 0978 else if (action == "zoomInAction") 0979 m_game->slotZoomIn(); 0980 else if (action == "zoomOutAction") 0981 m_game->slotZoomOut(); 0982 else if (action == "actionAttack1") 0983 m_game->slotAttack1(); 0984 else if (action == "actionAttack2") 0985 m_game->slotAttack2(); 0986 else if (action == "actionAttack3") 0987 m_game->slotAttack3(); 0988 else if (action == "actionMove") 0989 m_game->slotMove(); 0990 else if (action == "slotRecyclingFinished") 0991 m_game->slotRecyclingFinished(); 0992 else if (action == "actionInvade10") 0993 m_game->slotInvade10(); 0994 else if (action == "actionInvade5") 0995 m_game->slotInvade5(); 0996 else if (action == "actionInvade1") 0997 m_game->slotInvade1(); 0998 else if (action == "actionInvasionFinished") 0999 m_game->slotInvasionFinished(); 1000 else if (action == "slotDefense1") 1001 m_game->slotDefense1(); 1002 else if (action == "slotDefense2") 1003 m_game->slotDefense2(); 1004 else if (action == "actionNextPlayer") 1005 m_game->slotNextPlayer(); 1006 } 1007 if (action == "requestForAck") 1008 { 1009 QString ack; 1010 msg >> ack; 1011 qCDebug(KSIRK_LOG) << "acknowledging " << ack; 1012 if (p->isVirtual()) 1013 { 1014 qCDebug(KSIRK_LOG) << p->name() << "is virtual; sending message"; 1015 QByteArray buffer; 1016 QDataStream stream(&buffer, QIODevice::WriteOnly); 1017 stream << p->id() << ack; 1018 sendMessage(buffer,Acknowledge); 1019 } 1020 else 1021 { 1022 qCDebug(KSIRK_LOG) << p->name() << "is local; acknowledging"; 1023 p->acknowledge(ack); 1024 } 1025 } 1026 return false; 1027 } 1028 1029 // Create an IO device for the player. We could create any 1030 // device here, e.g. mouse, keyboard, computer player. In the 1031 // demo game here we have only the mouse player available. 1032 void GameAutomaton::createIO(KPlayer *player,KGameIO::IOMode io) 1033 { 1034 // Error check 1035 if (!player) return; 1036 1037 qCDebug(KSIRK_LOG) << "createIO for " << player->name(); 1038 1039 if (io&KGameIO::MouseIO) 1040 { 1041 // Create new game mouse input 1042 KGameMouseIO *input; 1043 // We want the player to work over mouse 1044 // in our canvas view 1045 input=new KGameMouseIO(m_game->frame()->scene()); 1046 1047 // Connect mouse input to a function to process the actual input 1048 connect( 1049 input, 1050 &KGameMouseIO::signalMouseEvent, 1051 m_game->frame(), 1052 &DecoratedGameFrame::slotMouseInput); 1053 1054 // Add the device to the player 1055 player->addGameIO(input); 1056 } 1057 else if (io&AIPLAYERIO) 1058 { 1059 if (dynamic_cast<AIPlayer*>(player) != nullptr) 1060 { 1061 /*AIPlayerIO* input =*/ new AIPlayerIO(dynamic_cast<AIPlayer*>(player)); 1062 } 1063 else 1064 { 1065 qCCritical(KSIRK_LOG) << "Can create an AIPlayerIO only for AI players: " << io ; 1066 } 1067 } 1068 else 1069 { 1070 qCCritical(KSIRK_LOG) << "Cannot create the requested IO device " << io ; 1071 } 1072 qCDebug(KSIRK_LOG) << "Done createIO for " << player->name(); 1073 } 1074 1075 // Find out who will be the next player 1076 // Note: The default behaviour as we have it here is done automatically 1077 // by the lib, too. So if all players player one after the other 1078 // this functions is NOT needed at all. 1079 KPlayer * GameAutomaton::doNextPlayer(KPlayer */*last*/,bool /*exclusive*/) 1080 { 1081 // qCDebug(KSIRK_LOG) << last->name(); 1082 // m_game->setCurrentPlayerToNext(); 1083 // If a last player is given switch the player 1084 1085 // Should be enough if the admin sets the turn (unclear) 1086 if (isAdmin()) 1087 { 1088 currentPlayer()->setTurn(true,true); 1089 // last->setTurn(true,true); 1090 // qCDebug(KSIRK_LOG) << "nextPlayer::Setting turn to " << last->name() << ", " << last->id() << "("<<last->userId()<<")"; 1091 } 1092 1093 // Notify the world that whose turn it is. The main window uses 1094 // this to show a little message 1095 // emit signalNextPlayer(next->userId().value(),next,this); 1096 1097 // Return the next player 1098 return dynamic_cast<KPlayer *>(currentPlayer()); 1099 } 1100 1101 QDataStream& operator>>(QDataStream& s, GameAutomaton::GameState& state) 1102 { 1103 int istate; 1104 s >> istate; 1105 state = GameAutomaton::GameState(istate); 1106 return s; 1107 } 1108 1109 1110 bool GameAutomaton::setupPlayersNumberAndSkin(NetworkGameType netGameType) 1111 { 1112 qCDebug(KSIRK_LOG) << netGameType; 1113 m_netGameType = netGameType; 1114 m_game->newGameDialog(m_skin.value(), m_netGameType); 1115 1116 // m_networkPlayersNumber = ???; 1117 return false; 1118 } 1119 1120 bool GameAutomaton::finishSetupPlayersNumberAndSkin() 1121 { 1122 qCDebug(KSIRK_LOG); 1123 1124 setUseGoals(m_game->newGameSetup()->useGoals()); 1125 state(GameLogic::GameAutomaton::INIT); 1126 savedState(GameLogic::GameAutomaton::INVALID); 1127 setNetworkPlayersNumber(m_game->newGameSetup()->nbNetworkPlayers()); 1128 m_startingGame = true; 1129 state(INIT); 1130 setMinPlayers(m_game->newGameSetup()->nbPlayers()); 1131 setMaxPlayers(m_game->newGameSetup()->nbPlayers()); 1132 m_nbPlayers = m_game->newGameSetup()->nbPlayers(); 1133 1134 return true; 1135 } 1136 1137 void GameAutomaton::setGoalFor(Player* player) 1138 { 1139 qCDebug(KSIRK_LOG) << player->name(); 1140 unsigned int max = m_goals.size(); 1141 unsigned int goalId = Dice::roll(max); 1142 QList< Goal* >::iterator it = m_goals.begin(); 1143 for (unsigned int i = 1 ; i < goalId; it++,i++) {} 1144 Goal* goal = (*it); 1145 qCDebug(KSIRK_LOG) << "Goal for " << player->name() << " is of type " << goal->type(); 1146 if (goal->type() == Goal::GoalPlayer) 1147 { 1148 Player* target = nullptr; 1149 while (target==nullptr || target->id() == player->id()) 1150 { 1151 unsigned int max = playerList()->count(); 1152 unsigned int playerNum = Dice::roll(max); 1153 // qCDebug(KSIRK_LOG) << "Choice player num " << playerNum << " on " << max ; 1154 PlayersArray::iterator itp = playerList()->begin(); 1155 unsigned int j = 1; 1156 for (; j < playerNum; j++,itp++) {} 1157 target = dynamic_cast< Player* >(*itp); 1158 } 1159 if (target != nullptr) 1160 { 1161 // qCDebug(KSIRK_LOG) << "Target choice for " << player->name() << ": " << target->name(); 1162 goal->players().push_back(target->name()); 1163 } 1164 else 1165 { 1166 // qCDebug(KSIRK_LOG) << "No target chosen for " << player->name(); 1167 } 1168 } 1169 /// @note hack to avoid too easy countries goal when there is only two players 1170 else if (goal->type() == Goal::Countries 1171 && playerList()->count() == 2) 1172 { 1173 goal->nbCountries(int(goal->nbCountries()*1.5)); 1174 } 1175 QByteArray buffer; 1176 QDataStream stream(&buffer, QIODevice::WriteOnly); 1177 stream << player->id(); 1178 stream << (*goal); 1179 qCDebug(KSIRK_LOG) << "Sending message GoalForIs ("<<GoalForIs<<") for " << player->name(); 1180 sendMessage(buffer,GoalForIs); 1181 // delete goal; 1182 m_goals.erase(it); 1183 } 1184 1185 Country * GameAutomaton::getDefCountry () 1186 { 1187 return this->defCountry; 1188 } 1189 1190 bool GameAutomaton::joinNetworkGame() 1191 { 1192 qCDebug(KSIRK_LOG); 1193 if (stateName() == "INIT" 1194 || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KGuiItem(i18nc("@action:button", "Join New Game"))) == KMessageBox::Continue)) 1195 { 1196 m_game->joinNetworkGame(); 1197 } 1198 return false; 1199 } 1200 1201 bool GameAutomaton::connectToServ() 1202 { 1203 qCDebug(KSIRK_LOG); 1204 if (messageServer() != nullptr) 1205 { 1206 QObject::disconnect(messageServer(),&KMessageServer::connectionLost, 1207 this,&GameAutomaton::slotConnectionToClientBroken); 1208 } 1209 qCDebug(KSIRK_LOG) << "Before connectToServer"; 1210 QString host = m_game->newGameSetup()->host(); 1211 int port = m_game->newGameSetup()->tcpPort(); 1212 bool status = connectToServer(host, port); 1213 qCDebug(KSIRK_LOG) << "After connectToServer" << status; 1214 if (messageServer()) 1215 connect(messageServer(),&KMessageServer::connectionLost, 1216 this,&GameAutomaton::slotConnectionToClientBroken); 1217 return status; 1218 } 1219 1220 #if HAVE_JABBER_SUPPORT 1221 bool GameAutomaton::joinJabberGame(const QString& nick) 1222 { 1223 if (stateName() == "INIT" || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KGuiItem(i18nc("@action:button", "Join New Game"))) == KMessageBox::Continue)) 1224 { 1225 // stop game 1226 setGameStatus(KGame::End); 1227 state(INIT); 1228 savedState(INVALID); 1229 1230 if (messageServer() != nullptr) 1231 { 1232 QObject::disconnect(messageServer(),&KMessageServer::connectionLost, 1233 this,&GameAutomaton::slotConnectionToClientBroken); 1234 } 1235 1236 qCDebug(KSIRK_LOG) << "Before connectToServer"; 1237 m_game->setServerJid(nick); 1238 KMessageJabber* messageIO = new KMessageJabber(m_game->serverJid().full(), m_game->jabberClient(), this); 1239 bool status = connectToServer(messageIO); 1240 // bool status = connectToServer(host, port); 1241 qCDebug(KSIRK_LOG) << "After connectToServer" << status; 1242 if (status) 1243 { 1244 QByteArray msg("connect"); 1245 XMPP::Message message(m_game->serverJid().full()); 1246 message.setType("ksirkgame"); 1247 message.setId(QUuid::createUuid().toString().remove("{").remove("}").remove("-")); 1248 message.setBody(msg); 1249 m_game->jabberClient()->sendMessage(message); 1250 } 1251 // connect(messageServer(),SIGNAL(connectionLost(KMessageIO*)), 1252 // this,SLOT(slotConnectionToClientBroken(KMessageIO*))); 1253 return status; 1254 } 1255 return false; 1256 } 1257 #endif 1258 1259 KPlayer * GameAutomaton::createPlayer(int rtti, 1260 int /*io*/, 1261 bool isVirtual) 1262 { 1263 qCDebug(KSIRK_LOG) << "(" << rtti << ", " << isVirtual << ")"; 1264 if (rtti == 1) 1265 { 1266 Player* p = new Player(this, "", 0, nullptr); 1267 p->setVirtual(isVirtual); 1268 if (!isVirtual) 1269 { 1270 qCDebug(KSIRK_LOG) << "Calling player createIO"; 1271 createIO(p,KGameIO::IOMode(KGameIO::MouseIO)); 1272 } 1273 return (KPlayer*) p; 1274 } 1275 else if (rtti == 2) 1276 { 1277 AIPlayer* aip = new AIColsonPlayer("", 0, nullptr, *playerList(), m_game->theWorld(), 1278 this); 1279 aip->stop(); 1280 aip->setVirtual(isVirtual); 1281 if (!isVirtual) 1282 { 1283 qCDebug(KSIRK_LOG) << "Calling player createIO"; 1284 createIO(aip, KGameIO::IOMode(AIPLAYERIO)); 1285 } 1286 return (KPlayer*) aip; 1287 } 1288 else 1289 { 1290 qCCritical(KSIRK_LOG) << "No rtti given... creating a Player"; 1291 Player* p = new Player(this, "", 0, nullptr); 1292 p->setVirtual(isVirtual); 1293 if (!isVirtual) 1294 { 1295 qCDebug(KSIRK_LOG) << "Calling player createIO"; 1296 createIO(p,KGameIO::IOMode(KGameIO::MouseIO)); 1297 } 1298 return (KPlayer*) p; 1299 } 1300 } 1301 1302 /** 1303 * @return A pointer to the given's named player ; 0 if there is no such player 1304 */ 1305 Player* GameAutomaton::playerNamed(const QString& playerName) 1306 { 1307 PlayersArray::iterator it = playerList()->begin(); 1308 PlayersArray::iterator it_end = playerList()->end(); 1309 for (; it != it_end; it++) 1310 { 1311 if ( (*it)-> name() == playerName) 1312 { 1313 return dynamic_cast<Player*>(*it); 1314 } 1315 } 1316 qCCritical(KSIRK_LOG) << "GameAutomaton::playerNamed: there is no player named " 1317 << playerName ; 1318 return nullptr; 1319 } 1320 1321 Player* GameAutomaton::currentPlayer() 1322 { 1323 if (m_game && !m_currentPlayer.isEmpty()) 1324 { 1325 return playerNamed(m_currentPlayer); 1326 } 1327 else return nullptr; 1328 } 1329 1330 void GameAutomaton::currentPlayer(Player* player) 1331 { 1332 qCDebug(KSIRK_LOG); 1333 if (player) 1334 { 1335 qCDebug(KSIRK_LOG) << " name = " << player->name(); 1336 m_currentPlayer = player->name(); 1337 m_currentPlayerPlayed = false; 1338 if (isAdmin()) 1339 { 1340 QByteArray buffer; 1341 QDataStream stream(&buffer, QIODevice::WriteOnly); 1342 stream << m_currentPlayer; 1343 sendMessage(buffer,PlayerChange); 1344 player->setTurn(true,true); 1345 } 1346 QByteArray buffer; 1347 QDataStream stream(&buffer, QIODevice::WriteOnly); 1348 stream << player->name(); 1349 sendMessage(buffer,SetBarFlagButton); 1350 if (!player->isVirtual()) 1351 { 1352 m_game->chatWidget()->setFromPlayer(player); 1353 } 1354 } 1355 else 1356 m_currentPlayer = ""; 1357 } 1358 1359 void GameAutomaton::slotPlayerJoinedGame(KPlayer* player) 1360 { 1361 qCDebug(KSIRK_LOG) << "currently " << playerList()->count() << " / " << maxPlayers(); 1362 Player* p = dynamic_cast<Player*>(player); 1363 Q_ASSERT(p); 1364 1365 if (isAdmin()) 1366 { 1367 unsigned int nbWithNation = 0; 1368 unsigned int nbWithName = 0; 1369 PlayersArray::iterator it = playerList()->begin(); 1370 PlayersArray::iterator it_end = playerList()->end(); 1371 for (; it != it_end; it++) 1372 { 1373 if (p->getNation()->name() == ((Player*)(*it))->getNation()->name()) 1374 { 1375 nbWithNation++; 1376 } 1377 if (p->name() == ((Player*)(*it))->name()) 1378 { 1379 nbWithName++; 1380 } 1381 } 1382 if (nbWithName != 1) 1383 { 1384 QByteArray buffer; 1385 QDataStream stream(&buffer, QIODevice::WriteOnly); 1386 stream << quint32(player->id()); 1387 qCDebug(KSIRK_LOG) << "Sending ChangePlayerName for player id " << player->id(); 1388 sendMessage(buffer,ChangePlayerName); 1389 1390 return; 1391 } 1392 else if (nbWithNation != 1) 1393 { 1394 QByteArray buffer; 1395 QDataStream stream(&buffer, QIODevice::WriteOnly); 1396 stream << player->id(); 1397 qCDebug(KSIRK_LOG) << "Sending ChangePlayerNation for player id " << player->id(); 1398 sendMessage(buffer,ChangePlayerNation); 1399 1400 return; 1401 } 1402 KMessageParts messageParts; 1403 messageParts 1404 << kli18n("%1 (%2) joined game ; waiting for %3 players to connect").untranslatedText() 1405 << p-> name() << p->getNation()->name() 1406 << QString::number(maxPlayers() - int(playerList()->count())); 1407 m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2); 1408 QByteArray buffer; 1409 QDataStream stream(&buffer, QIODevice::WriteOnly); 1410 qCDebug(KSIRK_LOG) << "Sending StartGame"; 1411 sendMessage(buffer,StartGame); 1412 } 1413 else 1414 { 1415 if (!player->isVirtual()) 1416 { 1417 m_game->showNewGameSummary(); 1418 } 1419 m_game->newGameSetup()->setNbPlayers(maxPlayers()); 1420 } 1421 NewPlayerData* pd = new NewPlayerData(p->name(),p->getNation()->name(),"",p->isAI(),true); 1422 if (!m_game->newGameSetup()->addPlayer(pd)) 1423 { 1424 delete pd; 1425 } 1426 m_game->updateNewGameSummary(); 1427 } 1428 1429 bool GameAutomaton::startGame() 1430 { 1431 qCDebug(KSIRK_LOG) << stateName() << "nb players = " << playerList()->count() << " / " << maxPlayers(); 1432 m_aicannotrunhack = true; 1433 // qCDebug(KSIRK_LOG) << " state is " << GameStateNames[m_state]; 1434 // qCDebug(KSIRK_LOG) << " saved state is " << GameStateNames[m_savedState]; 1435 if (isAdmin() && int(playerList()->count()) == maxPlayers() 1436 && gameStatus()!=KGame::Run) 1437 { 1438 // m_game->haltTimer(); 1439 1440 if (m_state == INIT && m_savedState == INVALID) 1441 { 1442 firstCountriesDistribution(); 1443 1444 if (useGoals()) 1445 { 1446 PlayersArray::iterator it = playerList()->begin(); 1447 PlayersArray::iterator it_end = playerList()->end(); 1448 for (; it != it_end; it++) 1449 { 1450 QByteArray buffer; 1451 QDataStream stream(&buffer, QIODevice::WriteOnly); 1452 stream << (*it)->id(); 1453 sendMessage(buffer,SetGoalFor); 1454 } 1455 } 1456 } 1457 else if (m_state == WAIT_PLAYERS) 1458 { 1459 sendCountries(); 1460 qCDebug(KSIRK_LOG) << "at " << __FILE__ << ", line " << __LINE__ << ", setting state to " << m_savedState ; 1461 state(m_savedState); 1462 currentPlayer(playerNamed(m_savedPlayer)); 1463 m_game->displayButtonsForState(m_savedState); 1464 m_savedPlayer = ""; 1465 m_savedState = INVALID; 1466 } 1467 1468 qCDebug(KSIRK_LOG) << "Sending message FinalizePlayers"; 1469 QByteArray buffer; 1470 QDataStream stream(&buffer, QIODevice::WriteOnly); 1471 sendMessage(buffer,FinalizePlayers); 1472 1473 qCDebug(KSIRK_LOG) << "Setting game status to Run"; 1474 setGameStatus(KGame::Run); 1475 // m_game->initTimer(); 1476 // qCDebug(KSIRK_LOG) << " true"; 1477 return true; 1478 } 1479 else 1480 { 1481 // qCDebug(KSIRK_LOG) << " false"; 1482 return false; 1483 } 1484 } 1485 1486 void GameAutomaton::changePlayerName(Player* player) 1487 { 1488 // qCDebug(KSIRK_LOG); 1489 1490 QMap< QString, QString > nations = m_game->nationsList(); 1491 PlayersArray::iterator it = playerList()->begin(); 1492 PlayersArray::iterator it_end = playerList()->end(); 1493 for (; it != it_end; it++) 1494 { 1495 QMap<QString,QString>::iterator nationsIt; 1496 nationsIt = nations.find(((Player*)(*it))-> getNation()->name()); 1497 if (nationsIt != nations.end()) 1498 { 1499 nations.erase(nationsIt); 1500 } 1501 } 1502 1503 // Players names 1504 QString mes = ""; 1505 QString nationName; 1506 1507 QString nomEntre = player->name(); 1508 1509 bool found = true; 1510 KMessageBox::information(m_game, i18n("Please choose another name"), i18n("KsirK - Name already used!")); 1511 while(found) 1512 { 1513 bool emptyName = true; 1514 while (emptyName) 1515 { 1516 mes = i18n("Player number %1, what's your name?", 1); 1517 QString password; 1518 if (nomEntre.isEmpty()) 1519 { 1520 mes = i18n("Error - Player %1, you have to choose a name.", 1); 1521 KMessageBox::error(m_game, mes); 1522 nomEntre = i18nc("@info Forged player name", "Player%1", 1); 1523 } 1524 else 1525 { 1526 emptyName = false; 1527 } 1528 } 1529 found = false; 1530 PlayersArray::iterator it = playerList()->begin(); 1531 PlayersArray::iterator it_end = playerList()->end(); 1532 for (; it != it_end; it++) 1533 { 1534 if ( (*it)-> name() == nomEntre) 1535 { 1536 found = true; 1537 it = it_end; 1538 } 1539 } 1540 if (!found) 1541 { 1542 // qCDebug(KSIRK_LOG) << "Creating player " << nomEntre << "(computer: " << computer << "): " << nationName ; 1543 player->setName(nomEntre); 1544 } 1545 } 1546 QByteArray buffer; 1547 QDataStream stream(&buffer, QIODevice::WriteOnly); 1548 sendMessage(buffer,StartGame); 1549 } 1550 1551 void GameAutomaton::changePlayerNation(Player* player) 1552 { 1553 // qCDebug(KSIRK_LOG); 1554 1555 QMap< QString, QString > nations = m_game->nationsList(); 1556 PlayersArray::iterator it = playerList()->begin(); 1557 PlayersArray::iterator it_end = playerList()->end(); 1558 for (; it != it_end; it++) 1559 { 1560 QMap<QString,QString>::iterator nationsIt; 1561 nationsIt = nations.find(((Player*)(*it))-> getNation()->name()); 1562 if (nationsIt != nations.end()) 1563 { 1564 nations.erase(nationsIt); 1565 } 1566 } 1567 1568 // Players names 1569 QString mes = ""; 1570 QString nationName; 1571 1572 QString nomEntre = player->name(); 1573 KMessageBox::information(m_game, i18n("Please choose another nation"), i18n("KsirK - Nation already used!")); 1574 QString password; 1575 QByteArray buffer; 1576 QDataStream stream(&buffer, QIODevice::WriteOnly); 1577 stream << player->name() << nationName; 1578 sendMessage(buffer,SetNation); 1579 QByteArray buffer2; 1580 QDataStream stream2(&buffer2, QIODevice::WriteOnly); 1581 sendMessage(buffer2,StartGame); 1582 } 1583 1584 quint32 GameAutomaton::idForMsg(const QString& msg) 1585 { 1586 QMap<QString,quint32>::iterator it = m_msgs2ids.find(msg); 1587 if (it != m_msgs2ids.end()) 1588 { 1589 return (*it); 1590 } 1591 else 1592 { 1593 quint32 id = m_msgs2ids.size(); 1594 QByteArray buffer; 1595 QDataStream stream(&buffer, QIODevice::WriteOnly); 1596 stream << msg << id; 1597 sendMessage(buffer,AddMsgIdPair); 1598 return id; 1599 } 1600 } 1601 1602 QString& GameAutomaton::msgForId(quint32 id) 1603 { 1604 return m_ids2msgs[id]; 1605 } 1606 1607 void GameAutomaton::slotPropertyChanged(KGamePropertyBase *prop,KGame *) 1608 { 1609 qCDebug(KSIRK_LOG) << prop->id() << " (skin is " << m_skinId << ")"; 1610 if (prop->id() == m_skinId) 1611 { 1612 qCDebug(KSIRK_LOG) << "skin changed to: " << m_skin ; 1613 m_game->newSkin(); 1614 if (m_game->theWorld()!=nullptr) 1615 { 1616 m_game->theWorld()->reset(); 1617 } 1618 } 1619 qCDebug(KSIRK_LOG) << "END GameAutomaton::slotPropertyChanged " << prop->id() << " (skin is " << m_skinId << ")"; 1620 } 1621 1622 void GameAutomaton::slotClientJoinedGame(quint32 clientid, KGame* /*me*/) 1623 { 1624 qCDebug(KSIRK_LOG) << clientid; 1625 if (isAdmin() && clientid!=gameId()) 1626 { 1627 QByteArray buffernbp; 1628 QDataStream streamnbp(&buffernbp, QIODevice::WriteOnly); 1629 streamnbp << m_nbPlayers; 1630 sendMessage(buffernbp,NbPlayers,clientid); 1631 1632 QByteArray bufferngs; 1633 QDataStream streamngs(&bufferngs, QIODevice::WriteOnly); 1634 streamngs << *m_game->newGameSetup(); 1635 sendMessage(bufferngs,NewGameSetupMsg,clientid); 1636 1637 QByteArray buffer; 1638 QDataStream stream(&buffer, QIODevice::WriteOnly); 1639 if (m_game->waitedPlayers().empty()) 1640 { 1641 sendMessage(buffer,SetupOnePlayer,clientid); 1642 } 1643 else 1644 { 1645 stream << quint32(m_game->waitedPlayers().size()); 1646 QList<PlayerMatrix>::iterator it, it_end; 1647 it = m_game->waitedPlayers().begin(); it_end = m_game->waitedPlayers().end(); 1648 for (; it != it_end; it++) 1649 { 1650 stream << (*it); 1651 } 1652 sendMessage(buffer,SetupWaitedPlayer,clientid); 1653 } 1654 } 1655 } 1656 1657 void GameAutomaton::slotConnectionToServerBroken() 1658 { 1659 qCDebug(KSIRK_LOG); 1660 1661 // m_game->haltTimer(); 1662 if (m_state != GAME_OVER) 1663 { 1664 int answer = KMessageBox::questionTwoActionsCancel(m_game, 1665 i18n("KsirK - Lost connection to server!\nWhat do you want to do?"), 1666 i18n("Starting a new game or exit."), 1667 KGuiItem(i18n("New Game")), 1668 KGuiItem(i18n("Exit")), 1669 KGuiItem(i18n("Do nothing"))); 1670 if (answer == KMessageBox::PrimaryAction) 1671 { 1672 m_game->showMainMenu(); 1673 } 1674 else if (answer == KMessageBox::SecondaryAction) 1675 { 1676 exit(0); 1677 } 1678 else 1679 { 1680 } 1681 } 1682 } 1683 1684 void GameAutomaton::slotConnectionToClientBroken(KMessageIO *) 1685 { 1686 qCDebug(KSIRK_LOG); 1687 // m_game->haltTimer(); 1688 if (m_state != GAME_OVER) 1689 { 1690 KMessageBox::information(m_game, 1691 i18n("Lost connection to a client.\nFor the moment, you can only save the game and start a new one or quit.\nThis will be improved in a future version."), 1692 i18n("KsirK - Lost connection to client!")); 1693 switch ( KMessageBox::warningTwoActions( m_game, 1694 i18n("Do want to save your game?"), 1695 QString(), 1696 KStandardGuiItem::save(), KStandardGuiItem::discard()) ) 1697 { 1698 case KMessageBox::PrimaryAction : 1699 m_game->slotSaveGame(); 1700 break; 1701 case KMessageBox::SecondaryAction :; 1702 default: ; 1703 } 1704 if (!m_game->actionNewGame(GameAutomaton::None)) 1705 exit(1); 1706 } 1707 // else 1708 // { 1709 // m_game->haltTimer(); 1710 // } 1711 } 1712 1713 void GameAutomaton::finalizePlayers() 1714 { 1715 qCDebug(KSIRK_LOG); 1716 PlayersArray::iterator it = playerList()->begin(); 1717 PlayersArray::iterator it_end = playerList()->end(); 1718 for (; it != it_end; it++) 1719 { 1720 dynamic_cast<Player*>(*it)-> finalize(); 1721 } 1722 QByteArray buffer; 1723 if (isAdmin()) 1724 { 1725 sendMessage(buffer,DisplayGoals); 1726 } 1727 m_game->showMap(); 1728 m_startingGame = false; 1729 } 1730 1731 /** @return true if all players are played by computer ; false otherwise */ 1732 bool GameAutomaton::allComputerPlayers() 1733 { 1734 PlayersArray::iterator it = playerList()->begin(); 1735 PlayersArray::iterator it_end = playerList()->end(); 1736 for (; it != it_end; it++) 1737 { 1738 if ( ! dynamic_cast<Player*>(*it)-> isAI() ) 1739 { 1740 return false; 1741 } 1742 } 1743 return true; 1744 } 1745 1746 bool GameAutomaton::allLocalPlayersComputer() 1747 { 1748 PlayersArray::iterator it = playerList()->begin(); 1749 PlayersArray::iterator it_end = playerList()->end(); 1750 for (; it != it_end; it++) 1751 { 1752 if ( ( ! dynamic_cast<Player*>(*it)-> isVirtual() ) && ( ! dynamic_cast<Player*>(*it)-> isAI() ) ) 1753 { 1754 return false; 1755 } 1756 } 1757 return true; 1758 } 1759 1760 void GameAutomaton::firstCountriesDistribution() 1761 { 1762 qCDebug(KSIRK_LOG); 1763 1764 if (isAdmin()) 1765 { 1766 PlayersArray::iterator it = playerList()->begin(); 1767 PlayersArray::iterator it_end = playerList()->end(); 1768 for (; it != it_end; it++) 1769 { 1770 ((Player*)(*it))->setNbAvailArmies((unsigned int)(m_game->theWorld()->getNbCountries() * 2.5 / nbPlayers() ), true); 1771 } 1772 m_game->setCurrentPlayerToFirst(); 1773 qCDebug(KSIRK_LOG) << "Setup players: distributing countries"; 1774 countriesDistribution(); 1775 1776 1777 // qCDebug(KSIRK_LOG) << " KGameWindow::setupPlayers: before initTimer"; 1778 // m_game->initTimer(); 1779 m_game->setCurrentPlayerToFirst(); 1780 if ( currentPlayer()-> isAI() && (!currentPlayer()->isVirtual()) ) 1781 if ( ! ( dynamic_cast<AIPlayer *>(currentPlayer())-> isRunning()) ) 1782 dynamic_cast<AIPlayer *>(currentPlayer())-> start(); 1783 1784 QByteArray buffer; 1785 QDataStream stream(&buffer, QIODevice::WriteOnly); 1786 stream << currentPlayer()->name(); 1787 // stream << (quint32)m_game->availArmies(); 1788 stream << (quint32)currentPlayer()->getNbAvailArmies(); 1789 qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << (quint32)currentPlayer()->getNbAvailArmies() 1790 << " at " << __FILE__ << ", line " << __LINE__; 1791 // qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << m_game->availArmies() 1792 // << " at " << __FILE__ << ", line " << __LINE__; 1793 sendMessage(buffer,DisplayRecycleDetails); 1794 1795 1796 // qCDebug(KSIRK_LOG) << "OUT KGameWindow::setupPlayers"; 1797 1798 } 1799 } 1800 1801 void GameAutomaton::countriesDistribution() 1802 { 1803 qCDebug(KSIRK_LOG); 1804 unsigned int initialNbArmies; 1805 QList< int > vect; 1806 QMap<QString,unsigned int> distributedCountriesNumberMap; 1807 PlayersArray::iterator it = playerList()->begin(); 1808 initialNbArmies = ((Player*)(*playerList()->begin()))->getNbAvailArmies(); 1809 PlayersArray::iterator it_end = playerList()->end(); 1810 for (; it != it_end; it++) 1811 { 1812 distributedCountriesNumberMap[(*it)-> name()] = 0; 1813 } 1814 // creates a vector containing the numbers of the countries 1815 for (unsigned int i = 0; i < m_game->theWorld()->getNbCountries() ; i++) vect.push_back(i); 1816 1817 // do while the vector not empty (will distribute one country each turn and 1818 // remove its number from the vector) 1819 while (vect.size()) 1820 { 1821 // chooses randomly a position in the remaining countries vector 1822 int h = Dice::roll(vect.size()) - 1; 1823 1824 // moves an iterator up to the position chosen 1825 QList< int >::iterator it = vect.begin(); 1826 for (int itPos = 0; itPos < h-1; itPos++) it++; 1827 1828 // affect the country that have the number at this position 1829 QByteArray buffer; 1830 QDataStream stream(&buffer, QIODevice::WriteOnly); 1831 stream << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name(); 1832 qCDebug(KSIRK_LOG) << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name(); 1833 distributedCountriesNumberMap[currentPlayer()-> name()] = distributedCountriesNumberMap[currentPlayer()-> name()]+1; 1834 sendMessage(buffer,CountryOwner); 1835 //m_game->theWorld()->getCountries().at(*it)-> owner(currentPlayer()); 1836 m_game->setCurrentPlayerToNext(false); 1837 1838 // removes the chosen country number from the vector, thus reducing its size 1839 vect.erase(it); 1840 } 1841 it = playerList()->begin(); 1842 it_end = playerList()->end(); 1843 for (; it != it_end; it++) 1844 { 1845 ((GameLogic::Player*)(*it))->setNbAvailArmies(((GameLogic::Player*)(*it))->getNbAvailArmies() - distributedCountriesNumberMap[(*it)-> name()], true); 1846 1847 ((GameLogic::Player*)(*it))->incrNbCountries(distributedCountriesNumberMap[(*it)-> name()]); 1848 } 1849 // qCDebug(KSIRK_LOG) << "All countries are now distributed."; 1850 m_game->setCurrentPlayerToFirst(); 1851 QString nextPlayerName = currentPlayer()->name(); 1852 QByteArray buffer; 1853 QDataStream stream(&buffer, QIODevice::WriteOnly); 1854 stream << (quint32)((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies(); 1855 // qCDebug(KSIRK_LOG) << " Setting status " << nextPlayerName << " / " << m_game->availArmies(); 1856 QPixmap pm = playerNamed(nextPlayerName)->getFlag()->image(0); 1857 KMessageParts messageParts; 1858 messageParts 1859 << pm 1860 << kli18n("%1: %2 armies to place").untranslatedText() 1861 << nextPlayerName 1862 << QString::number( initialNbArmies - distributedCountriesNumberMap[nextPlayerName]); 1863 qCDebug(KSIRK_LOG) << "Message parts size= " << messageParts.size(); 1864 m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2); 1865 m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries.")); 1866 state(INTERLUDE); 1867 m_game->setNextPlayerActionEnabled(false); 1868 } 1869 1870 void GameAutomaton::sendCountries() 1871 { 1872 QByteArray buffer; 1873 QDataStream stream(&buffer, QIODevice::WriteOnly); 1874 1875 m_game->theWorld()->sendCountries(stream); 1876 sendMessage(buffer,SetupCountries); 1877 } 1878 1879 void GameAutomaton::movingFigthersArrived() 1880 { 1881 qCDebug(KSIRK_LOG); 1882 state(FIGHT_ANIMATE); 1883 QByteArray buffer; 1884 QDataStream stream(&buffer, QIODevice::WriteOnly); 1885 sendMessage(buffer,AnimCombat); 1886 } 1887 1888 void GameAutomaton::movingArmiesArrived() 1889 { 1890 qCDebug(KSIRK_LOG); 1891 // m_game->terminateAttackSequence(); 1892 } 1893 1894 void GameAutomaton::movingArmyArrived(Country* country, unsigned int number) 1895 { 1896 qCDebug(KSIRK_LOG) << number ; 1897 country->incrNbArmies(number); 1898 country->createArmiesSprites(); 1899 checkGoal(country->owner()); 1900 } 1901 1902 void GameAutomaton::firingFinished() 1903 { 1904 qCDebug(KSIRK_LOG); 1905 if (isAdmin()) 1906 { 1907 m_game->resolveAttack(); 1908 state(EXPLOSION_ANIMATE); 1909 } 1910 } 1911 1912 void GameAutomaton::explosionFinished() 1913 { 1914 qCDebug(KSIRK_LOG); 1915 if (isAdmin()) 1916 { 1917 switch (gameStatus()) 1918 { 1919 case KGame::Pause: 1920 m_game->setStateBeforeNewGame(FIGHT_BRINGBACK); 1921 break; 1922 case KGame::Run:; 1923 default: 1924 state(FIGHT_BRINGBACK); 1925 } 1926 } 1927 } 1928 1929 void GameAutomaton::displayGoals() 1930 { 1931 qCDebug(KSIRK_LOG); 1932 PlayersArray::iterator it = playerList()->begin(); 1933 PlayersArray::iterator it_end = playerList()->end(); 1934 for (; it != it_end; it++) 1935 { 1936 if ( (dynamic_cast<Player*>(*it) != nullptr) 1937 && ( ! dynamic_cast<Player*>(*it)-> isVirtual() ) 1938 && ( ! dynamic_cast<Player*>(*it)-> isAI() ) ) 1939 { 1940 KMessageBox::information( 1941 game(), 1942 i18n("%1, your goal will be displayed. Please<br>" 1943 "make sure that no other player can see it!",(*it)->name()), 1944 i18n("KsirK - Displaying Goal")); 1945 dynamic_cast<Player*>(*it)->goal().show(); 1946 } 1947 } 1948 m_aicannotrunhack = false; 1949 } 1950 1951 void GameAutomaton::moveSlide() 1952 { 1953 qCDebug(KSIRK_LOG); 1954 if (!currentPlayer()->isVirtual()) 1955 m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry(),InvasionSlider::Moving); 1956 } 1957 1958 /** 1959 * Change the automatic attack state. 1960 * @param activated new state 1961 */ 1962 void GameAutomaton::setAttackAuto(bool activated) 1963 { 1964 QByteArray buffer; 1965 QDataStream stream(&buffer, QIODevice::WriteOnly); 1966 stream << (quint32)activated; 1967 1968 sendMessage(buffer,AttackAuto); 1969 } 1970 1971 void GameAutomaton::slotNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender) 1972 { 1973 qCDebug(KSIRK_LOG) << "msg " << msgid << " ; rec="<<receiver << " snd=" << sender ; 1974 if (m_game == nullptr) 1975 { 1976 exit(0); 1977 } 1978 1979 if (msgid < CountryOwner || msgid>= UnusedLastMessageId) 1980 { 1981 return; 1982 } 1983 qCDebug(KSIRK_LOG) << "("<<KsirkMessagesIdsNames[msgid-(KGameMessage::IdUser+1)]<<", " << receiver << ", " << sender << ")"; 1984 QDataStream stream(const_cast<QByteArray*>(&buffer), QIODevice::ReadOnly); 1985 QString countryName, playerName, nationName; 1986 QPointF point; 1987 quint32 removable; 1988 quint32 theState; 1989 quint32 nbArmies; 1990 quint32 newState; 1991 quint32 statusBarId, messagePartsNb, messagePartsCounter, logStatus; 1992 quint32 propId, prop2Id; 1993 quint32 playerId; 1994 quint32 nbVotes = 0; 1995 quint32 explosing; 1996 KMessageParts messageParts; 1997 QString messagePart; 1998 Player* player; 1999 PlayerMatrix waitedPlayerDef(this); 2000 quint32 nbWaitedPlayers; 2001 quint32 waitedPlayerId; 2002 QString waitedPlayerPassword; 2003 quint32 nbCountries; 2004 Country* country; 2005 quint32 msgId; 2006 QString ack; 2007 QString msg; 2008 Goal goal(this); 2009 QString playersNames; 2010 QPixmap pm; 2011 quint32 A1, A2, A3, D1, D2, NKA, NKD; 2012 quint32 win; 2013 quint32 attackAutoValue; 2014 quint32 availArmies; 2015 quint32 elemType; 2016 quint32 nb; 2017 2018 if (currentPlayer() != nullptr && currentPlayer()->getFlag() != nullptr) 2019 { 2020 pm = currentPlayer()->getFlag()->image(0); 2021 } 2022 2023 QByteArray sendBuffer; 2024 QDataStream sendStream(&sendBuffer, QIODevice::WriteOnly); 2025 switch (msgid) 2026 { 2027 case CountryOwner: 2028 stream >> countryName >> playerName; 2029 qCDebug(KSIRK_LOG) << "CountryOwner for " << (void*)m_game->theWorld()->countryNamed(countryName) << " " << countryName << " and " << (void*)playerNamed(playerName) << playerName ; 2030 m_game->theWorld()->countryNamed(countryName)-> owner(playerNamed(playerName)); 2031 break; 2032 case PlayerPutsInitialArmy: 2033 stream >> point; 2034 if (m_game->playerPutsInitialArmy(point)) 2035 { 2036 if (isAdmin()) 2037 gameEvent("playersLooped", point); 2038 } 2039 break; 2040 case PlayerPutsArmy: 2041 stream >> point >> removable; 2042 if (m_game->playerPutsArmy(point, removable) && isAdmin()) 2043 { 2044 gameEvent("playersLooped", point); 2045 } 2046 break; 2047 case StateChange: 2048 stream >> theState; 2049 qCDebug(KSIRK_LOG) << "Got new state id: " << theState << 2050 " ("<<GameStateNames[theState]<<")"; 2051 m_state = GameState(theState); 2052 break; 2053 case PlayerChange: 2054 stream >> playerName; 2055 if (!isAdmin()) 2056 { 2057 m_currentPlayer = playerName; 2058 m_currentPlayerPlayed = false; 2059 } 2060 break; 2061 case RegisterCountry: 2062 stream >> countryName >> propId >> prop2Id; 2063 m_nbArmiesIdsNamesCountriesMap.insert(int(propId),countryName); 2064 m_namesNbArmiesIdsCountriesMap.insert(countryName,int(propId));; 2065 // m_nbAddedArmiesIdsNamesCountriesMap.insert(int(prop2Id),countryName); 2066 // m_namesNbAddedArmiesIdsCountriesMap.insert(countryName,int(prop2Id)); 2067 break; 2068 case PlayerAvailArmies: 2069 if (sender == gameId()) break; 2070 stream >> playerName >> nbArmies; 2071 if (playerNamed(playerName) != nullptr) 2072 playerNamed(playerName)->setNbAvailArmies((unsigned int)nbArmies, false); 2073 break; 2074 /* case KGameWinAvailArmies: 2075 if (sender == gameId()) break; 2076 stream >> nbArmies; 2077 m_game->availArmies(nbArmies);*/ 2078 break; 2079 case ChangeItem: 2080 if (sender == gameId()) break; 2081 stream >> statusBarId >> logStatus >> messagePartsNb; 2082 qCDebug(KSIRK_LOG) << "Got ChangeItem on " << statusBarId << " ; nb= " << messagePartsNb; 2083 for (messagePartsCounter = 0; messagePartsCounter < messagePartsNb; ++messagePartsCounter) 2084 { 2085 stream >> elemType; 2086 if (elemType == KMessageParts::Text) 2087 { 2088 stream >> messagePart; 2089 messageParts << messagePart; 2090 qCDebug(KSIRK_LOG) << " message part: " << messagePart; 2091 } 2092 else if (elemType == KMessageParts::StringId) 2093 { 2094 stream >> msgId; 2095 messageParts << msgForId(msgId); 2096 qCDebug(KSIRK_LOG) << " message part for id "<<msgId<<": " << msgForId(msgId); 2097 } 2098 else if (elemType == KMessageParts::Pixmap) 2099 { 2100 stream >> pm; 2101 messageParts << pm; 2102 } 2103 } 2104 m_game->changeItem(messageParts,statusBarId, logStatus); 2105 break; 2106 case DisplayRecyclingButtons: 2107 m_game->getRightDialog()->updateRecycleDetails(nullptr,true,0); 2108 m_game->displayRecyclingButtons(); 2109 break; 2110 case ClearHighlighting: 2111 m_game->clearHighlighting(); 2112 break; 2113 case ActionRecycling: 2114 if (isAdmin()) 2115 { 2116 m_game->actionRecycling(); 2117 state(NEWARMIES); 2118 } 2119 break; 2120 case ClearGameActionsToolbar: 2121 break; 2122 case DisplayDefenseButtons: 2123 stream >> playerName; 2124 if ( (!playerNamed(playerName)->isVirtual()) 2125 && (!playerNamed(playerName)->isAI()) && (!isDefenseAuto())) 2126 { 2127 defCountry = this->game()->secondCountry(); 2128 m_game->displayDefenseWindow(); 2129 } 2130 messageParts << kli18n("%1 chooses its defense").untranslatedText() << playerName; 2131 m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2); 2132 break; 2133 case ActionDefense: 2134 stream >> nbArmies; 2135 if (isAdmin()) 2136 m_game->defense((unsigned int)nbArmies); 2137 break; 2138 case FirstCountry: 2139 stream >> countryName; 2140 qCDebug(KSIRK_LOG) << "FirstCountry " << countryName ; 2141 m_game->firstCountry(m_game->theWorld()->countryNamed(countryName)); 2142 break; 2143 case SecondCountry: 2144 stream >> countryName; 2145 qCDebug(KSIRK_LOG) << "SecondCountry " << countryName ; 2146 m_game->secondCountry(m_game->theWorld()->countryNamed(countryName)); 2147 break; 2148 case InitCombatMovement: 2149 m_game->initCombatMovement(); 2150 break; 2151 case AnimCombat: 2152 m_game->animCombat(); 2153 break; 2154 case TerminateAttackSequence: 2155 { 2156 // update country display 2157 if (m_game->terminateAttackSequence()) 2158 { 2159 // Re-display the world view 2160 m_game->showMap(); 2161 2162 setAttackAuto(false); 2163 // setDefenseAuto(false); 2164 if(!currentPlayer()->isAI() && !currentPlayer()->isVirtual()) 2165 { 2166 m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry()); 2167 } 2168 if (isAdmin()) 2169 { 2170 state(INVADE); 2171 } 2172 } 2173 else if (isAdmin()) 2174 { 2175 // if there is more than 1 army on my country and automatic 2176 // attack is activated 2177 if (m_game->firstCountry()->nbArmies() > 1 && m_attackAuto) 2178 { 2179 // continue automatically attacking by making the same attack 2180 state(WAIT1); 2181 if (m_game->firstCountry()->nbArmies() > 3) 2182 { 2183 gameEvent("actionAttack3", m_game->secondCountry()->centralPoint()); 2184 } 2185 else if (m_game->firstCountry()->nbArmies() > 2) 2186 { 2187 gameEvent("actionAttack2", m_game->secondCountry()->centralPoint()); 2188 } 2189 else 2190 { 2191 gameEvent("actionAttack1", m_game->secondCountry()->centralPoint()); 2192 } 2193 2194 // else wait user choice 2195 } 2196 else 2197 { 2198 // Re-display the world view 2199 m_game->showMap(); 2200 2201 setAttackAuto(false); 2202 // setDefenseAuto(false); 2203 state(WAIT); 2204 } 2205 } 2206 m_game->firstCountry()-> createArmiesSprites(); 2207 m_game->secondCountry()-> createArmiesSprites(); 2208 } 2209 break; 2210 case DecrNbArmies: 2211 stream >> countryName >> nbArmies; 2212 m_game->theWorld()->countryNamed(countryName)->decrNbArmies(nbArmies); 2213 [[fallthrough]]; 2214 case StartLocalCurrentAI: 2215 m_game->startLocalCurrentAI(); 2216 break; 2217 case Invade: 2218 stream >> nbArmies; 2219 nb = nbArmies; 2220 while (nb >= 10) 2221 { 2222 if (m_game-> invade(10)) 2223 m_game-> incrNbMovedArmies(10); 2224 nb -= 10; 2225 } 2226 while (nb >= 5) 2227 { 2228 if (m_game-> invade(5)) 2229 m_game-> incrNbMovedArmies(5); 2230 nb -= 5; 2231 } 2232 while (nb > 0) 2233 { 2234 if (m_game-> invade(1)) 2235 m_game-> incrNbMovedArmies(1); 2236 nb--; 2237 } 2238 2239 break; 2240 case Retreat: 2241 stream >> nbArmies; 2242 if (m_game-> retreat(nbArmies)) 2243 m_game-> decrNbMovedArmies(nbArmies); 2244 break; 2245 case NextPlayerNormal: 2246 if (isAdmin()) 2247 { 2248 stream >> playerName; 2249 stream >> newState; 2250 if (playerName == currentPlayer()->name() && m_game->nextPlayerNormal()) 2251 { 2252 if (newState > 0) 2253 { 2254 qCDebug(KSIRK_LOG) << "at " << __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ; 2255 state(GameState(newState)); 2256 } 2257 } 2258 } 2259 break; 2260 case NextPlayerRecycling: 2261 if (isAdmin()) 2262 { 2263 stream >> newState; 2264 if (m_game->nextPlayerRecycling()) 2265 { 2266 m_choosedToRecycleNumber = 0; 2267 if (newState > 0) 2268 { 2269 qCDebug(KSIRK_LOG) << "at " << __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ; 2270 state(GameState(newState)); 2271 m_game->slotContextualHelp(); 2272 } 2273 } 2274 } 2275 break; 2276 case ShowArmiesToPlace: 2277 messageParts << pm << kli18n("%1: %2 armies to place").untranslatedText() << (currentPlayer()-> name()) 2278 << QString::number(currentPlayer()-> getNbAvailArmies()); 2279 m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2); 2280 m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries.")); 2281 break; 2282 case PlayerRemovesArmy: 2283 stream >> point; 2284 m_game->playerRemovesArmy(point); 2285 break; 2286 case VoteRecyclingFinished: 2287 if (isAdmin()) 2288 { 2289 // stream >> playerName; 2290 messageParts << kli18n("%1 choose to end recycling; there are now %2 players who want so").untranslatedText(); 2291 stream >> nbVotes; 2292 stream >> playerId; 2293 playersNames = ((Player*)(findPlayer(playerId)))->name(); 2294 if (!m_choosedToRecycle.contains(playerId)) 2295 { 2296 m_choosedToRecycle.push_back(playerId); 2297 } 2298 else 2299 { 2300 nbVotes--; 2301 } 2302 2303 for (quint32 i = 1 ; i < nbVotes; i++) 2304 { 2305 stream >> playerId; 2306 playersNames += QString(", ") + ((Player*)(findPlayer(playerId)))->name(); 2307 if (!m_choosedToRecycle.contains(playerId)) 2308 { 2309 m_choosedToRecycle.push_back(playerId); 2310 } 2311 else 2312 { 2313 nbVotes--; 2314 } 2315 } 2316 qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb before: " << m_choosedToRecycleNumber ; 2317 m_choosedToRecycleNumber+=nbVotes; 2318 qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb after : " << m_choosedToRecycleNumber ; 2319 messageParts << playersNames << QString::number(m_choosedToRecycleNumber); 2320 m_game->broadcastChangeItem(messageParts, ID_NO_STATUS_MSG); 2321 if (m_choosedToRecycleNumber == (unsigned int)(playerList()->count())) 2322 { 2323 m_game->actionRecyclingFinished(); 2324 m_choosedToRecycle.clear(); 2325 } 2326 } 2327 break; 2328 case CancelShiftSource: 2329 m_game-> cancelShiftSource(); 2330 if (isAdmin()) 2331 { 2332 state(SHIFT1); 2333 } 2334 break; 2335 case ChangePlayerNation: 2336 stream >> playerId; 2337 // qCDebug(KSIRK_LOG) << "Got ChangePlayerNation for player id " << playerId ; 2338 player = (Player*)(findPlayer(playerId)); 2339 // qCDebug(KSIRK_LOG) << "Found player id " << player; 2340 if (player && !player->isVirtual()) 2341 { 2342 changePlayerNation(player); 2343 } 2344 break; 2345 case ChangePlayerName: 2346 stream >> playerId; 2347 player = (Player*)(findPlayer(playerId)); 2348 if (player && !player->isVirtual()) 2349 { 2350 changePlayerName(player); 2351 } 2352 break; 2353 case StartGame: 2354 if (isAdmin()) 2355 startGame(); 2356 break; 2357 case SetNation: 2358 stream >> playerName >> nationName; 2359 playerNamed(playerName)->setNation(nationName); 2360 break; 2361 case SetBarFlagButton: 2362 stream >> playerName; 2363 qCDebug(KSIRK_LOG) << "Calling setBarFlagButton for player " << playerNamed(playerName) << " named " << playerName ; 2364 m_game->setBarFlagButton(playerNamed(playerName)); 2365 break; 2366 case FinishMoves: 2367 m_game->finishMoves(); 2368 break; 2369 case AnimExplosion: 2370 stream >> explosing; 2371 qCDebug(KSIRK_LOG) << "AnimExplosion" << explosing; 2372 if (m_game->backGnd()->bgIsArena()) 2373 { 2374 m_game->animExplosionForArena(); 2375 } 2376 else 2377 { 2378 if (explosing != 0 && explosing != 1 && explosing != 2) 2379 { 2380 KMessageBox::information(m_game, i18n("Problem : no one destroyed"), i18n("KsirK - Error!")); 2381 } 2382 else 2383 { 2384 m_game->animExplosion(explosing); 2385 } 2386 } 2387 break; 2388 case SetupOnePlayer: 2389 if (receiver == gameId()) 2390 { 2391 m_game->setupOnePlayer(); 2392 } 2393 break; 2394 case SetupWaitedPlayer: 2395 stream >> nbWaitedPlayers; 2396 for (quint32 i = 0; i < nbWaitedPlayers; i++) 2397 { 2398 stream >> waitedPlayerDef; 2399 m_game->waitedPlayers().push_back(waitedPlayerDef); 2400 } 2401 m_game->setupOneWaitedPlayer(); 2402 break; 2403 case ValidateWaitedPlayerPassword: 2404 if (isAdmin()) 2405 { 2406 stream >> waitedPlayerId >> waitedPlayerPassword; 2407 // qCDebug(KSIRK_LOG) << "Validating password for waited player " << waitedPlayerId << " : " << m_game->waitedPlayers()[waitedPlayerId].password << " / " << waitedPlayerPassword ; 2408 if (m_game->waitedPlayers()[waitedPlayerId].password == waitedPlayerPassword) 2409 { 2410 sendStream << waitedPlayerId; 2411 sendMessage(sendBuffer,ValidPassword, sender); 2412 } 2413 else 2414 { 2415 sendMessage(sendBuffer,InvalidPassword, sender); 2416 } 2417 } 2418 break; 2419 case ValidPassword: 2420 if (receiver == gameId()) 2421 { 2422 stream >> waitedPlayerId; 2423 m_game->createWaitedPlayer(waitedPlayerId); 2424 } 2425 break; 2426 case InvalidPassword: 2427 if (receiver == gameId()) 2428 { 2429 KMessageBox::information(m_game, i18n("You entered an invalid password.\nPlease try again."), i18n("KsirK - Invalid password!")); 2430 m_game->setupOneWaitedPlayer(); 2431 } 2432 break; 2433 case SetupCountries: 2434 stream >> nbCountries; 2435 for (unsigned int i = 0; i < nbCountries; i++) 2436 { 2437 stream >> countryName; 2438 country = m_game->theWorld()->countryNamed(countryName); 2439 qCDebug(KSIRK_LOG) << "Setting up country n°" << i << " on " << nbCountries << ", " << (void*)country << " named " << countryName ; 2440 if (country) 2441 { 2442 stream >> country; 2443 } 2444 } 2445 break; 2446 case AddMsgIdPair: 2447 stream >> msg >> msgId; 2448 m_msgs2ids.insert(msg,msgId); 2449 m_ids2msgs.insert(msgId,msg); 2450 break; 2451 case CheckGoal: 2452 if (isAdmin()) 2453 { 2454 qCDebug(KSIRK_LOG) << "CheckGoal: "; 2455 stream >> playerId; 2456 player = dynamic_cast< Player* >(findPlayer(playerId)); 2457 if (player) 2458 { 2459 if (player->checkGoal()) 2460 { 2461 qCDebug(KSIRK_LOG) << " goal reached for " << player->name(); 2462 qCDebug(KSIRK_LOG) << " setting state to " << GameStateNames[GAME_OVER]; 2463 // m_game->haltTimer(); 2464 setGameStatus(KGame::End); 2465 state(GAME_OVER); 2466 sendStream << player->id(); 2467 qCDebug(KSIRK_LOG) << " sending Winner"; 2468 sendMessage(sendBuffer,Winner); 2469 } 2470 } 2471 } 2472 break; 2473 case SetGoalFor: 2474 if (isAdmin()) 2475 { 2476 stream >> playerId; 2477 setGoalFor(dynamic_cast<Player*>(findPlayer(playerId))); 2478 } 2479 break; 2480 case GoalForIs: 2481 qCDebug(KSIRK_LOG) << "GoalForIs: "; 2482 stream >> playerId; 2483 qCDebug(KSIRK_LOG) << " player id: " << playerId ; 2484 stream >> goal; 2485 player = dynamic_cast<Player*>(findPlayer(playerId)); 2486 if (player != nullptr) 2487 { 2488 player->goal(goal); 2489 } 2490 break; 2491 case FinalizePlayers: 2492 qCDebug(KSIRK_LOG) << "Got message FinalizePlayers"; 2493 finalizePlayers(); 2494 break; 2495 case Winner: 2496 QObject::disconnect(messageServer(),&KMessageServer::connectionLost, 2497 this,&GameAutomaton::slotConnectionToClientBroken); 2498 stream >> playerId; 2499 m_game->winner(dynamic_cast<Player*>(findPlayer(playerId))); 2500 break; 2501 case NbPlayers: 2502 stream >> m_nbPlayers; 2503 break; 2504 case Acknowledge: 2505 stream >> playerId; 2506 stream >> ack; 2507 if (!isAdmin() && !dynamic_cast<Player*>(findPlayer(playerId))->isVirtual()) 2508 { 2509 qCDebug(KSIRK_LOG) << "Got message Acknowledge" << playerId << ack; 2510 dynamic_cast<Player*>(findPlayer(playerId))->acknowledge(ack); 2511 } 2512 break; 2513 case DisplayGoals: 2514 qCDebug(KSIRK_LOG) << "Got message DisplayGoals"; 2515 QTimer::singleShot(0,this,&GameAutomaton::displayGoals); 2516 break; 2517 case DisplayFightResult: 2518 qCDebug(KSIRK_LOG) << "Got message DisplayFightResult"; 2519 stream >> A1 >> A2 >> A3 >> D1 >> D2 >> NKA >> NKD >> win; 2520 m_game->getRightDialog()->displayFightResult(A1,A2,A3,D1,D2,NKA,NKD,win); 2521 break; 2522 case MoveSlide: 2523 qCDebug(KSIRK_LOG) << "Got message MoveSlide"; 2524 moveSlide(); 2525 break; 2526 case InvasionFinished: 2527 qCDebug(KSIRK_LOG) << "Got message InvasionFinished"; 2528 if (isAdmin()) 2529 { 2530 gameEvent("actionInvasionFinished", point); 2531 } 2532 break; 2533 case AttackAuto: 2534 qCDebug(KSIRK_LOG) << "Got message AttackAuto"; 2535 stream >> attackAutoValue; 2536 m_attackAuto = attackAutoValue; 2537 break; 2538 case DisplayRecycleDetails: 2539 stream >> playerName; 2540 stream >> availArmies; 2541 qCDebug(KSIRK_LOG) << "Got message DisplayRecycleDetails " 2542 << playerName << availArmies; 2543 m_game->getRightDialog()->displayRecycleDetails(playerNamed(playerName),availArmies); 2544 // bool value; 2545 // if (playerNamed(playerName)->isAI() || playerNamed(playerName)->isVirtual()) 2546 // { 2547 // value = false; 2548 // } 2549 // else 2550 // { 2551 // value = true; 2552 // } 2553 m_game->setNextPlayerActionEnabled(false); 2554 break; 2555 case CurrentPlayerPlayed: 2556 m_currentPlayerPlayed = true; 2557 break; 2558 case ResetPlayersDistributionData: 2559 resetPlayersDistributionData(); 2560 break; 2561 case NewGameSetupMsg: 2562 qCDebug(KSIRK_LOG) << "Got message NewGameSetupMsg"; 2563 stream >> *m_game->newGameSetup(); 2564 break; 2565 default: ; 2566 } 2567 } 2568 2569 #if HAVE_JABBER_SUPPORT 2570 void GameAutomaton::askForJabberGames() 2571 { 2572 m_game->askForJabberGames(); 2573 } 2574 #endif 2575 2576 QSvgRenderer& GameAutomaton::rendererFor(const QString& skinName) 2577 { 2578 if (!m_renderers.contains(skinName)) 2579 { 2580 m_renderers.insert(skinName,new QSvgRenderer(this)); 2581 } 2582 return *m_renderers[skinName]; 2583 } 2584 2585 KGameSvgDocument& GameAutomaton::svgDomFor(const QString& skinName) 2586 { 2587 if (!m_svgDoms.contains(skinName)) 2588 { 2589 m_svgDoms.insert(skinName,KGameSvgDocument()); 2590 } 2591 return m_svgDoms[skinName]; 2592 } 2593 2594 bool GameAutomaton::startingGame() const 2595 { 2596 qCDebug(KSIRK_LOG) << m_startingGame; 2597 return m_startingGame; 2598 } 2599 2600 bool GameAutomaton::isDefenseAuto() 2601 { 2602 return m_defenseAuto.isDefenseAuto(m_game->firstCountry(),m_game->secondCountry()); 2603 } 2604 2605 void GameAutomaton::setDefenseAuto(bool activated) 2606 { 2607 m_defenseAuto.value = activated; 2608 if (activated) 2609 { 2610 m_defenseAuto.firstCountry = m_game->firstCountry(); 2611 m_defenseAuto.secondCountry= m_game->secondCountry(); 2612 } 2613 else 2614 { 2615 m_defenseAuto.firstCountry = nullptr; 2616 m_defenseAuto.secondCountry= nullptr; 2617 } 2618 } 2619 2620 void GameAutomaton::resetPlayersDistributionData() 2621 { 2622 foreach (KPlayer* p, *playerList()) 2623 { 2624 if ( !p->isVirtual() ) 2625 { 2626 ((GameLogic::Player*)p)->reset(); 2627 } 2628 } 2629 } 2630 2631 void GameAutomaton::actionNextPlayer() 2632 { 2633 if ( currentPlayer()->isVirtual() 2634 || currentPlayer()->isAI() 2635 || m_currentPlayerPlayed 2636 || (KMessageBox::questionTwoActions (m_game, 2637 i18n("%1, you have not played anything this turn.\nDo you really want to lose your turn?",m_currentPlayer), 2638 i18n("Really Next Player?"), 2639 KGuiItem(i18nc("@action:button", "Next Player")), 2640 KStandardGuiItem::cancel()) 2641 == KMessageBox::PrimaryAction) ) 2642 { 2643 QByteArray buffer; 2644 QDataStream stream(&buffer, QIODevice::WriteOnly); 2645 stream << currentPlayer()->name(); 2646 stream << (quint32)NEWARMIES; 2647 qCDebug(KSIRK_LOG) << "(state " << stateName() << ") sending NextPlayerNormal" << currentPlayer()->name() << NEWARMIES; 2648 sendMessage(buffer,NextPlayerNormal); 2649 m_game-> cancelAction(); 2650 } 2651 } 2652 2653 void GameAutomaton::removeAllPlayers() 2654 { 2655 qCDebug(KSIRK_LOG); 2656 m_currentPlayer = ""; 2657 2658 /* Bug 304362. KPlayer destructor removes 2659 * player from the list and makes iterators invalid. 2660 * qDeleteAll crashes in that case. */ 2661 while (!playerList()->isEmpty()) 2662 { 2663 delete playerList()->takeFirst(); 2664 } 2665 // qDeleteAll(*playerList()); 2666 // playerList()->clear(); 2667 } 2668 2669 // Bug 308527. 2670 void GameAutomaton::removeAllGoals() 2671 { 2672 qCDebug(KSIRK_LOG); 2673 while (!goals().isEmpty()) 2674 delete goals().takeFirst(); 2675 } 2676 2677 void GameAutomaton::newGameNext() 2678 { 2679 qCDebug(KSIRK_LOG); 2680 m_startingGame = true; 2681 state(INIT); 2682 2683 qCDebug(KSIRK_LOG) << "Changing skin"; 2684 m_skin = m_game->newGameSetup()->skin(); 2685 if (m_game->newGameSetup()->networkGameType() == Socket) 2686 { 2687 offerConnections(m_game->newGameSetup()->tcpPort()); 2688 } 2689 m_game->finishSetupPlayers(); 2690 } 2691 2692 void GameAutomaton::checkGoal(Player* player) 2693 { 2694 QByteArray buffer; 2695 QDataStream stream(&buffer, QIODevice::WriteOnly); 2696 if (player == nullptr) 2697 stream << currentPlayer()->id(); 2698 else 2699 stream << player->id(); 2700 qCDebug(KSIRK_LOG) << "sending CheckGoal"; 2701 sendMessage(buffer,CheckGoal); 2702 } 2703 2704 2705 } // closing namespace GameLogic 2706 } // closing namespace Ksirk 2707 2708 #include "moc_gameautomaton.cpp"