1 /* This file is part of KsirK.
2    Copyright (C) 2004-2007 Gael de Chalendar <kleag@free.fr>
3 
4    KsirK is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public
6    License as published by the Free Software Foundation, either version 2
7    of the License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13 
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17    02110-1301, USA
18 */
19 
20 #include "gameautomaton.h"
21 
22 #include "ksirksettings.h"
23 #include "kgamewin.h"
24 #include "aiplayer.h"
25 #include "aiColsonPlayer.h"
26 #include "aiplayerio.h"
27 #include "onu.h"
28 #include "dice.h"
29 #include "goal.h"
30 #include "country.h"
31 #include "KMessageParts.h"
32 #include "newgamesetup.h"
33 #include "krightdialog.h"
34 #include "Dialogs/joingame.h"
35 #include "Jabber/kmessagejabber.h"
36 #include "newplayerdata.h"
37 
38 #include <QLayout>
39 #include <QSpinBox>
40 #include <QPixmap>
41 #include <QMouseEvent>
42 #include <QFile>
43 #include <QUuid>
44 #include <QInputDialog>
45 #include <KLocalizedString>
46 #include <KLineEdit>
47 #include <KMessageBox>
48 
49 #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API
50 #include <libkdegamesprivate/kgame/kmessageclient.h>
51 #include <libkdegamesprivate/kgame/kmessageserver.h>
52 #include <libkdegamesprivate/kgame/kgamechat.h>
53 
54 #include <errno.h>
55 #include <sys/types.h>
56 #include <signal.h>
57 #include <QCache>
58 
59 namespace Ksirk{
60 namespace GameLogic {
61 
62 const char* GameAutomaton::GameStateNames[] = {
63     "INIT",
64     "INTERLUDE",
65     "NEWARMIES",
66     "WAIT",
67     "WAIT1",
68     "WAIT_RECYCLING",
69     "ATTACK",
70     "ATTACK2",
71     "INVADE",
72     "SHIFT1",
73     "SHIFT2",
74     "FIGHT_BRING",
75     "FIGHT_ANIMATE",
76     "FIGHT_BRINGBACK",
77     "WAITDEFENSE",
78     "EXPLOSION_ANIMATE",
79     "WAIT_PLAYERS",
80     "GAME_OVER",
81     "INVALID",
82     "STARTING_GAME"
83 };
84 
85 const char* GameAutomaton::KsirkMessagesIdsNames[] = {
86 "CountryOwner", // 257
87 "PlayerPutsArmy", // 258
88 "StateChange", // 259
89 "PlayerChange", // 260
90 "RegisterCountry", // 261
91 "PlayerAvailArmies", // 262
92 "ResetPlayersDistributionData", // 263
93 "ChangeItem", // 264
94 "DisplayRecyclingButtons", // 265
95 "ClearHighlighting", // 266
96 "ActionRecycling", // 267
97 "ClearGameActionsToolbar", // 268
98 "DisplayDefenseButtons", // 269
99 "ActionDefense", // 270
100 "FirstCountry", // 271
101 "SecondCountry", // 272
102 "InitCombatMovement", // 273
103 "AnimCombat", // 274
104  // 275
105 "TerminateAttackSequence", // 276
106 "DecrNbArmies", // 277
107 "StartLocalCurrentAI", // 278
108 "Invade", // 279
109 "Retreat", // 280
110 "NextPlayerNormal", // 281
111 "NextPlayerRecycling", // 282
112 "ShowArmiesToPlace", // 283
113 "PlayerPutsInitialArmy", // 284
114 "PlayerRemovesArmy", //285
115 "VoteRecyclingFinished", // 286
116 "CancelShiftSource", // 287
117 "ChangePlayerNation", // 288
118 "ChangePlayerName", // 289
119 "StartGame", // 290
120 "SetNation", // 291
121 "SetBarFlagButton", // 292
122 "FinishMoves", // 293
123 "AnimExplosion", // 294
124 "SetupOnePlayer", // 295
125 "SetupWaitedPlayer", // 296
126 "ValidateWaitedPlayerPassword", // 297
127 "ValidPassword", // 298
128 "InvalidPassword", // 299
129 "SetupCountries", // 300
130 "AddMsgIdPair", // 301
131 "CheckGoal", // 302
132 "SetGoalFor", // 303
133 "GoalForIs", // 304
134 "Winner", // 305
135 "NbPlayers", // 306
136 "FinalizePlayers", // 307
137 "Acknowledge", // 308
138 "DisplayGoals", // 309
139 "DisplayFightResult", // 310
140 "MoveSlide", // 311
141 "InvasionFinished", // 312
142 "AttackAuto", // 313
143 "DisplayRecycleDetails", // 314
144 "CurrentPlayerPlayed", // 315
145 "NewGameSetupMsg", // 316
146 };
147 
148 #define KSIRK_DEFAULT_PORT 20000
149 
GameAutomaton()150 GameAutomaton::GameAutomaton() :
151     KGame(),
152     m_aicannotrunhack(true),
153     m_state(INIT),
154     m_game(0),
155     m_networkPlayersNumber(0),
156     m_currentPlayer(""),
157     m_currentPlayerPlayed(false),
158     m_savedState(INVALID),
159     m_goals(),
160     m_useGoals(true),
161     m_attackAuto(false),
162     m_defenseAuto(false),
163     m_port(KSIRK_DEFAULT_PORT),
164     m_startingGame(false)
165 {
166   m_skin = "skins/default";
167   //   qCDebug(KSIRK_LOG);
168 //   m_stateId = m_state.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_state"));
169   m_skinId = m_skin.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_skin"));
170 //   m_currentPlayerId = m_currentPlayer.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_currentPlayer"));
171 //   m_events.registerData(dataHandler(),KGamePropertyBase::PolicyDirty,QString("m_events"));
172 
173   // Connect the most important slot which tells us which properties are
174   // changed
175   connect(this,&KGame::signalPropertyChanged,
176           this,&GameAutomaton::slotPropertyChanged);
177 
178   connect(this,&KGame::signalPlayerJoinedGame,
179           this,&GameAutomaton::slotPlayerJoinedGame);
180 
181   connect(this,&KGame::signalNetworkData,
182           this,&GameAutomaton::slotNetworkData);
183 
184   connect(this,&KGame::signalClientJoinedGame,
185           this,&GameAutomaton::slotClientJoinedGame);
186 
187   connect(messageClient(),&KMessageClient::connectionBroken,
188           this,&GameAutomaton::slotConnectionToServerBroken);
189 
190   connect(messageServer(),&KMessageServer::connectionLost,
191           this,&GameAutomaton::slotConnectionToClientBroken);
192 
193   setPolicy(KGame::PolicyDirty,true);
194 
195 //   qCDebug(KSIRK_LOG) << "finished";
196 }
197 
~GameAutomaton()198 GameAutomaton::~GameAutomaton()
199 {
200   qCDebug(KSIRK_LOG);
201   qDeleteAll(m_goals);
202 }
203 
init(KGameWindow * gw)204 void GameAutomaton::init(KGameWindow* gw)
205 {
206   m_game = gw;
207 }
208 
state() const209 GameAutomaton::GameState GameAutomaton::state() const
210 {
211   return m_state;
212 }
213 
state(GameAutomaton::GameState state)214 void GameAutomaton::state(GameAutomaton::GameState state)
215 {
216   qCDebug(KSIRK_LOG) << "new state (id=" << state << ") is " << GameStateNames[state];
217   m_state = state;
218   m_game->setSaveGameActionEnabled(m_state == WAIT);
219   m_game->setContextualHelpActionEnabled(m_state, currentPlayer() && currentPlayer()->isAI());
220   QByteArray buffer;
221   QDataStream stream(&buffer, QIODevice::WriteOnly);
222   stream << state;
223   sendMessage(buffer,StateChange);
224 }
225 
getAnyLocalPlayer()226 Player* GameAutomaton::getAnyLocalPlayer()
227 {
228   PlayersArray::iterator it = playerList()->begin();
229   PlayersArray::iterator it_end = playerList()->end();
230   for (; it != it_end; it++)
231   {
232     if ( !((Player*)(*it))->isVirtual() )
233     {
234       return (Player*)(*it);
235     }
236   }
237   return 0;
238 }
239 
run()240 GameAutomaton::GameState GameAutomaton::run()
241 {
242 //   qCDebug(KSIRK_LOG) << "(KGame running=" <<  (gameStatus()==KGame::Run) << ")";
243   if (m_game == 0 || gameStatus() == KGame::Pause)
244   {
245     QTimer::singleShot(200, this, &GameAutomaton::run);
246     return m_state;
247   }
248 
249   activateNeededAIPlayers();
250 
251   QString event = "";
252   QPointF point;
253   if (!m_events.empty())
254   {
255     QPair< QString, QPointF > pair = m_events.front();
256     event = pair.first;
257     point = pair.second;
258     m_events.pop_front();
259   }
260 
261 //   qCDebug(KSIRK_LOG) << "Handling " << stateName() << " ; " << event << " ; " << point;
262 //   if (currentPlayer())
263 //   {
264 //     qCDebug(KSIRK_LOG) << "current player=" << currentPlayer()->name() << " is active=" << currentPlayer()->isActive();
265 //   }
266   if (event == "requestForAck")
267   {
268     qCDebug(KSIRK_LOG) << "requestForAck";
269   }
270   if((event == "actionRButtonDown" || event == "actionLButtonDown") && (m_state != INIT && m_state != NEWARMIES && m_state != INTERLUDE && m_state != WAIT_RECYCLING))
271   {
272      if (m_game->getRightDialog()->isOpen())
273      {
274         m_game->getRightDialog()->close();
275      }
276   }
277 
278   if (event == "actionNewGame")
279   {
280     if (m_game->actionNewGame(GameAutomaton::None))
281     {
282       state(INIT);
283       QTimer::singleShot(200, this, &GameAutomaton::run);
284       return INIT;
285     }
286     else
287     {
288       QTimer::singleShot(200, this, &GameAutomaton::run);
289       return m_state;
290     }
291   }
292   if (event == "actionOpenGame")
293   {
294     if (m_game->actionOpenGame())
295     {
296       qCDebug(KSIRK_LOG) << "opened";
297       bool ok;
298       m_port = QInputDialog::getInt(m_game,
299               i18n("KsirK - Network configuration"),
300               i18n("Please type in the port number on which to offer connections:"),
301               m_port, 0, 32000, 1, &ok);
302       offerConnections(m_port);
303       state(WAIT_PLAYERS);
304       QTimer::singleShot(200, this, &GameAutomaton::run);
305       return WAIT_PLAYERS;
306     }
307     else
308     {
309       qCDebug(KSIRK_LOG) << "opened";
310       QTimer::singleShot(200, this, &GameAutomaton::run);
311       return m_state;
312     }
313   }
314   if (event == "actionJoinNetworkGame")
315   {
316     joinNetworkGame();
317     QTimer::singleShot(200, this, &GameAutomaton::run);
318     return m_state;
319   }
320 
321   switch (m_state)
322   {
323   case INIT:
324     if (currentPlayer() != 0 && isAdmin())
325     {
326       if  ( (event == "actionLButtonDown") && (m_game->playerPutsInitialArmy(point)) )
327       {
328         m_choosedToRecycleNumber = 0;
329         m_game->initRecycling();
330         state(WAIT_RECYCLING);
331       }
332     }
333     break;
334   case ATTACK:
335         state(ATTACK2);
336     break;
337   case ATTACK2:
338     qCDebug(KSIRK_LOG) << "Handling ATTACK2";
339     if (isAdmin())
340     {
341       QByteArray buffer;
342       switch ( m_game->attacked(point) )
343       {
344         case 0:
345           qCDebug(KSIRK_LOG) << "handling attacked value; 0";
346           state(WAIT);
347         break;
348         case 1:
349           qCDebug(KSIRK_LOG) << "handling attacked value; 1";
350           sendMessage(buffer,CurrentPlayerPlayed);
351           state(WAITDEFENSE);
352         break;
353         case 2:
354           qCDebug(KSIRK_LOG) << "handling attacked value; 2";
355           sendMessage(buffer,CurrentPlayerPlayed);
356           qCDebug(KSIRK_LOG) << "calling defense(1)";
357           m_game-> defense(1);
358           qCDebug(KSIRK_LOG) << "setting state to FIGHT_BRING";
359           state(FIGHT_BRING);
360         break;
361         case 3:
362           qCDebug(KSIRK_LOG) << "handling attacked value; 3";
363           // AI action: nothing to do.
364         break;
365         default:
366           qCCritical(KSIRK_LOG) << "Unknown return value from attacked";
367           exit(1);
368       }
369     }
370     qCDebug(KSIRK_LOG) << "handling of ATTACK2 finished !";
371   break;
372   case EXPLOSION_ANIMATE:
373   break;
374   case FIGHT_ANIMATE:
375   break;
376   case FIGHT_BRING:
377   break;
378   case FIGHT_BRINGBACK:
379     // no more moving fighter returning home
380 
381 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE FIGHT_BRINGBACK $$$$$$$$$$$" << m_game->haveAnimFighters();
382 
383     if (!m_game->haveAnimFighters() && isAdmin())
384     {
385       QByteArray buffer;
386       QDataStream stream(&buffer, QIODevice::WriteOnly);
387       sendMessage(buffer,TerminateAttackSequence);
388     }
389     break;
390   case INTERLUDE:
391     if  (event == "playersLooped")
392     {
393       m_choosedToRecycleNumber = 0;
394       m_game->initRecycling();
395       state(WAIT_RECYCLING);
396     }
397     else if  (event == "actionLButtonDown" )
398     {
399       QByteArray buffer;
400       QDataStream stream(&buffer, QIODevice::WriteOnly);
401       stream << point;
402 //       qCDebug(KSIRK_LOG) << "Sending message PlayerPutsArmy " << point ;
403       sendMessage(buffer,PlayerPutsInitialArmy);
404     }
405     else if (event == "actionRButtonDown")
406     {
407       QByteArray buffer;
408       QDataStream stream(&buffer, QIODevice::WriteOnly);
409       stream << point;
410       sendMessage(buffer,PlayerRemovesArmy);
411     }
412     else if (event == "actionNextPlayer")
413     {
414       QByteArray buffer;
415       QDataStream stream(&buffer, QIODevice::WriteOnly);
416       stream << -1;
417       sendMessage(buffer,NextPlayerRecycling);
418     }
419     else if (event == "actionRecycling")
420     {
421       QByteArray buffer;
422       sendMessage(buffer,ActionRecycling);
423     }
424     else if (event == "actionRecyclingFinished")
425     {
426       qCDebug(KSIRK_LOG) << "actionRecyclingFinished";
427       QByteArray buffer;
428       QDataStream stream(&buffer, QIODevice::WriteOnly);
429 //       stream << currentPlayer()->name();
430       PlayersArray::iterator it = playerList()->begin();
431       PlayersArray::iterator it_end = playerList()->end();
432       quint32 nbLocal = 0;
433       for (; it != it_end; it++)
434       {
435         if ( !((Player*)(*it))->isVirtual() )
436         {
437           qCDebug(KSIRK_LOG) << "Local:" << ((Player*)(*it))->name();
438           nbLocal++;
439         }
440       }
441       qCDebug(KSIRK_LOG) << "Nb Local:" << nbLocal;
442       stream << nbLocal;
443 
444       for (it = playerList()->begin(); it != it_end; ++it)
445       {
446         if ( !((Player*)(*it))->isVirtual() )
447         {
448           stream << ((Player*)(*it))->id();
449         }
450       }
451       sendMessage(buffer,VoteRecyclingFinished);
452     }
453     else
454     {
455       //        if (!event.isEmpty())
456 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
457     }
458   break;
459   case INVADE:
460 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE INVADE$$$$$$$$$$$";
461     if (event == "actionInvade1")
462     {
463       QByteArray buffer;
464       QDataStream stream(&buffer, QIODevice::WriteOnly);
465       stream << quint32(1);
466       sendMessage(buffer,Invade);
467     }
468     else if (event == "actionInvade5")
469     {
470       QByteArray buffer;
471       QDataStream stream(&buffer, QIODevice::WriteOnly);
472       stream << quint32(5);
473       sendMessage(buffer,Invade);
474     }
475     else if (event == "actionInvade10")
476     {
477       QByteArray buffer;
478       QDataStream stream(&buffer, QIODevice::WriteOnly);
479       stream << quint32(10);
480       sendMessage(buffer,Invade);
481     }
482     else if (event == "actionRetreat1")
483     {
484       QByteArray buffer;
485       QDataStream stream(&buffer, QIODevice::WriteOnly);
486       stream << quint32(1);
487       sendMessage(buffer,Retreat);
488     }
489     else if (event == "actionRetreat5")
490     {
491       QByteArray buffer;
492       QDataStream stream(&buffer, QIODevice::WriteOnly);
493       stream << quint32(5);
494       sendMessage(buffer,Retreat);
495     }
496     else if (event == "actionRetreat10")
497     {
498       QByteArray buffer;
499       QDataStream stream(&buffer, QIODevice::WriteOnly);
500       stream << quint32(10);
501       sendMessage(buffer,Retreat);
502     }
503     else if (event == "actionInvasionFinished")
504     {
505       state(WAIT);
506       m_game-> invasionFinished();
507     }
508     else
509     {
510       //        if (!event.isEmpty())
511 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
512     }
513   break;
514   case NEWARMIES:
515     if  (event == "actionLButtonDown")
516     {
517       QByteArray buffer;
518       QDataStream stream(&buffer, QIODevice::WriteOnly);
519       stream << point << quint32(true);
520       sendMessage(buffer,PlayerPutsArmy);
521     }
522     else if  (event == "actionRButtonDown")
523     {
524       QByteArray buffer;
525       QDataStream stream(&buffer, QIODevice::WriteOnly);
526       stream << point;
527       sendMessage(buffer,PlayerRemovesArmy);
528     }
529     else if (event == "actionNextPlayer")
530     {
531       QByteArray buffer;
532       QDataStream stream(&buffer, QIODevice::WriteOnly);
533       stream << quint32(WAIT);
534       sendMessage(buffer,NextPlayerRecycling);
535     }
536 //     else
537 //     {
538 //              if (!event.isEmpty())
539 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
540 //     }
541   break;
542   case SHIFT1:
543     if (event == "actionCancel")
544     {
545       m_game-> cancelAction();
546       state(WAIT);
547     }
548     else if (event == "actionLButtonDown")
549     {
550       m_game->firstCountryAt(point);
551     }
552     else if (event == "actionLButtonUp")
553     {
554       m_game->secondCountryAt(point);
555       if (m_game->isMoveValid(point))
556       {
557         m_game->startLocalCurrentAI();
558         QByteArray buffer;
559         sendMessage(buffer,CurrentPlayerPlayed);
560         state(SHIFT2);
561       }
562       else
563       {
564 //         state(WAIT);
565       }
566     }
567     else
568     {
569       //        if (!event.isEmpty())
570 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
571     }
572   break;
573   case SHIFT2:
574 //     qCDebug(KSIRK_LOG) << "$$$$$$$STATE SHIFT2$$$$$$$$$$$";
575     if (event == "actionInvade1")
576     {
577 //       qCDebug(KSIRK_LOG) << "actionInvade1";
578       QByteArray buffer;
579       QDataStream stream(&buffer, QIODevice::WriteOnly);
580       stream << quint32(1);
581       sendMessage(buffer,Invade);
582     }
583     else if (event == "actionInvade5")
584     {
585       QByteArray buffer;
586       QDataStream stream(&buffer, QIODevice::WriteOnly);
587       stream << quint32(5);
588       sendMessage(buffer,Invade);
589     }
590     else if (event == "actionInvade10")
591     {
592       QByteArray buffer;
593       QDataStream stream(&buffer, QIODevice::WriteOnly);
594       stream << quint32(10);
595       sendMessage(buffer,Invade);
596     }
597     else if (event == "actionRetreat1")
598     {
599       QByteArray buffer;
600       QDataStream stream(&buffer, QIODevice::WriteOnly);
601       stream << quint32(1);
602       sendMessage(buffer,Retreat);
603     }
604     else if (event == "actionRetreat5")
605     {
606       QByteArray buffer;
607       QDataStream stream(&buffer, QIODevice::WriteOnly);
608       stream << quint32(5);
609       sendMessage(buffer,Retreat);
610     }
611     else if (event == "actionRetreat10")
612     {
613       QByteArray buffer;
614       QDataStream stream(&buffer, QIODevice::WriteOnly);
615       stream << quint32(10);
616       sendMessage(buffer,Retreat);
617     }
618     else if (event == "actionInvasionFinished")
619     {
620       m_game-> shiftFinished();
621       state(WAIT);
622     }
623     else if (event == "actionCancel")
624     {
625       QByteArray buffer;
626       QDataStream stream(&buffer, QIODevice::WriteOnly);
627       sendMessage(buffer,CancelShiftSource);
628     }
629     else
630     {
631       //qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
632     }
633   break;
634   case WAIT_RECYCLING:
635     if (event == "actionRecycling")
636     {
637       QByteArray buffer;
638       sendMessage(buffer,ActionRecycling);
639     }
640     else if (event == "actionRecyclingFinished")
641     {
642       QByteArray buffer;
643       QDataStream stream(&buffer, QIODevice::WriteOnly);
644 //       stream << currentPlayer()->name();
645       PlayersArray::iterator it = playerList()->begin();
646       PlayersArray::iterator it_end = playerList()->end();
647       quint32 nbLocal = 0;
648       for (; it != it_end; it++)
649       {
650         if ( !((Player*)(*it))->isVirtual() )
651         {
652           nbLocal++;
653         }
654       }
655       stream << nbLocal;
656       it = playerList()->begin();
657       it_end = playerList()->end();
658       for (; it != it_end; it++)
659       {
660         if ( !((Player*)(*it))->isVirtual() )
661         {
662           stream << (*it)->id();
663         }
664       }
665       sendMessage(buffer,VoteRecyclingFinished);
666     }
667     else
668     {
669       if (!event.isEmpty())
670         qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
671       else
672       {
673       if (allLocalPlayersComputer())
674         {
675           m_game->getRightDialog()->updateRecycleDetails(NULL,true,0);
676           m_game->displayRecyclingButtons();
677         }
678       }
679     }
680     break;
681   case WAITDEFENSE:
682     if (event == "actionDefense1")
683     {
684       QByteArray buffer;
685       QDataStream stream(&buffer, QIODevice::WriteOnly);
686       stream << quint32(1);
687       sendMessage(buffer,ActionDefense);
688     }
689     else if (event == "actionDefense2")
690     {
691       QByteArray buffer;
692       QDataStream stream(&buffer, QIODevice::WriteOnly);
693       stream << quint32(2);
694       sendMessage(buffer,ActionDefense);
695     }
696     else if ( m_game->secondCountry() != 0
697           && !m_game->secondCountry()->owner()->isVirtual()
698           && isDefenseAuto()
699           && (m_game->secondCountry()->owner()->getNbDefense() == 0) )
700     {
701       quint32 nbDefense = 1;
702       if (m_game->secondCountry()->nbArmies() > 1)
703       {
704         nbDefense = 2;
705       }
706       m_game->secondCountry()->owner()->setNbDefense(nbDefense);
707       QByteArray buffer;
708       QDataStream stream(&buffer, QIODevice::WriteOnly);
709       stream << nbDefense;
710       sendMessage(buffer,ActionDefense);
711     }
712     else
713     {
714       //        if (!event.isEmpty())
715          qCDebug(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
716     }
717   break;
718   case WAIT:
719     if (event == "actionNextPlayer")
720     {
721       actionNextPlayer();
722     }
723     else if (event == "actionLButtonDown")
724     {
725       if (m_game->firstCountryAt(point))
726         state(WAIT1);
727     }
728     else
729     {
730       //        if (!event.isEmpty())
731 //          qCCritical(KSIRK_LOG) << "Unhandled event " << event << " during handling of " << stateName();
732     }
733     // other case : state doesn't change
734     break;
735   case WAIT1:
736     if (event == "actionNextPlayer")
737     {
738       actionNextPlayer();
739     }
740     else if (event == "actionAttack1")
741     {
742       m_game->attack(1);
743       state(ATTACK);
744     }
745     else if (event == "actionAttack2")
746     {
747       m_game->attack(2);
748       state(ATTACK);
749     }
750     else if (event == "actionAttack3")
751     {
752       m_game->attack(3);
753       state(ATTACK);
754     }
755     else if (event == "actionInvade1")
756     {
757 //       qCDebug(KSIRK_LOG) << "actionInvade1";
758       QByteArray buffer2;
759       sendMessage(buffer2,CurrentPlayerPlayed);
760       QByteArray buffer;
761       QDataStream stream(&buffer, QIODevice::WriteOnly);
762       stream << quint32(1);
763       sendMessage(buffer,Invade);
764 //       state(WAIT);
765     }
766     else if (event == "actionInvade5")
767     {
768       QByteArray buffer2;
769       sendMessage(buffer2,CurrentPlayerPlayed);
770       QByteArray buffer;
771       QDataStream stream(&buffer, QIODevice::WriteOnly);
772       stream << quint32(5);
773       sendMessage(buffer,Invade);
774 //       state(WAIT);
775     }
776     else if (event == "actionInvade10")
777     {
778       QByteArray buffer2;
779       sendMessage(buffer2,CurrentPlayerPlayed);
780       QByteArray buffer;
781       QDataStream stream(&buffer, QIODevice::WriteOnly);
782       stream << quint32(10);
783       sendMessage(buffer,Invade);
784 //       state(WAIT);
785     }
786     else if (event == "actionInvasionFinished")
787     {
788       m_game-> shiftFinished();
789       state(WAIT);
790     }
791     else if (event == "actionLButtonUp")
792     {
793       qCDebug(KSIRK_LOG) << "actionLButtonUp in WAIT1";
794 
795       if (!currentPlayer()-> isAI())
796       {
797         if (m_game->isMoveValid(point) && m_game->firstCountry()->nbArmies() !=1)
798         {
799           m_game->secondCountryAt(point);
800           state(WAIT);
801           qCDebug(KSIRK_LOG) << "Sending MoveSlide";
802           QByteArray buffer;
803           QDataStream stream(&buffer, QIODevice::WriteOnly);
804           sendMessage(buffer,MoveSlide);
805         }
806         else if (m_game->isFightValid(point)
807                 && m_game->firstCountry()->nbArmies() != 1)
808         {
809           m_game->secondCountryAt(point);
810           if (m_game->firstCountry()->nbArmies() > 3)
811           {
812             m_game->frame()->getAttack1Action()->setVisible(true);
813             m_game->frame()->getAttack2Action()->setVisible(true);
814             m_game->frame()->getAttack3Action()->setVisible(true);
815 
816           }
817           else if (m_game->firstCountry()->nbArmies() > 2)
818           {
819             m_game->frame()->getAttack1Action()->setVisible(true);
820             m_game->frame()->getAttack2Action()->setVisible(true);
821             m_game->frame()->getAttack3Action()->setVisible(false);
822           }
823           else if (m_game->firstCountry()->nbArmies() > 1)
824           {
825             m_game->frame()->getAttack1Action()->setVisible(true);
826             m_game->frame()->getAttack2Action()->setVisible(false);
827             m_game->frame()->getAttack3Action()->setVisible(false);
828           }
829           m_game->frame()->setMenuPoint(QCursor::pos());
830           m_game->frame()->getAttackContextMenu()->exec(QCursor::pos());
831         }
832         else
833         {
834           m_game-> cancelAction();
835           state(WAIT);
836         }
837       }
838       else
839       {
840         m_game->secondCountryAt(point);
841       }
842     }
843     else if (event == "actionLButtonDown")
844     {
845       m_game-> cancelAction();
846       if (m_game->firstCountryAt(point))
847       {
848         state(WAIT1);
849       }
850       state(WAIT);
851     }
852    break;
853   /*case WAIT_INPUT:
854 
855     break;*/
856   case WAIT_PLAYERS:
857     break;
858   case GAME_OVER:
859     break;
860   case STARTING_GAME:
861     break;
862   default:
863     qCCritical(KSIRK_LOG) << "Unhandled state: " << stateName() << ". Event was: " << event ;
864     exit(1); // @todo handle this error
865   }
866 
867   QTimer::singleShot(200, this, &GameAutomaton::run);
868 
869 //   m_game->initTimer();
870   return m_state;
871 }
872 
activateNeededAIPlayers()873 void GameAutomaton::activateNeededAIPlayers()
874 {
875 //   qCDebug(KSIRK_LOG);
876   if ( currentPlayer()
877        && (currentPlayer()-> isAI() )
878        && (!currentPlayer()->isVirtual())
879        && (!(dynamic_cast< AIPlayer* >(currentPlayer())-> isRunning()))
880      )
881   {
882     dynamic_cast< AIPlayer* >(currentPlayer())-> start();
883   }
884   if (    ( m_state == WAITDEFENSE )
885        && ( m_game->secondCountry())
886        && ( m_game->secondCountry()->owner())
887        && ( m_game->secondCountry()->owner()->isAI() )
888        && ( !m_game->secondCountry()->owner()->isVirtual())
889        && ( !(dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> isRunning()))
890      )
891   {
892     dynamic_cast< AIPlayer* >(m_game->secondCountry()->owner())-> start();
893   }
894 }
895 
gameEvent(const QString & event,const QPointF & point)896 void GameAutomaton::gameEvent(const QString& event, const QPointF& point)
897 {
898   m_events.push_back(qMakePair(event, point));
899 }
900 
901 
902 /** returns the name of the current state */
stateName() const903 QString GameAutomaton::stateName() const
904 {
905   if (m_state >= (int) sizeof(GameStateNames))
906   {
907     QString string;
908     QTextStream oss(&string);
909     oss << "Invalid stored state id: " << m_state;
910     qCCritical(KSIRK_LOG) << string ;
911     return string;
912   }
913   else
914   {
915     return QString::fromUtf8(GameStateNames[m_state]);
916   }
917 }
918 
saveXml(QTextStream & xmlStream)919 void GameAutomaton::saveXml(QTextStream& xmlStream)
920 {
921     xmlStream << "<gameautomaton state=\"" << GameStateNames[m_state] << "\" />";
922 }
923 
skin() const924 const QString& GameAutomaton::skin() const
925 {
926   return m_skin.value();
927 }
928 
skin(const QString & newSkin)929 void GameAutomaton::skin(const QString& newSkin)
930 {
931   m_skin = newSkin;
932 }
933 
934 // Called when a player input (e.g. a mouse event) is received from the KGame
935 // object
936 // This is obviously the central function in the game as all player moves,
937 // whether network or local, end up here. So do something sensible here.
playerInput(QDataStream & msg,KPlayer * player)938 bool GameAutomaton::playerInput(QDataStream &msg, KPlayer* player)
939 {
940   qCDebug(KSIRK_LOG);
941 //   if (player->isVirtual())
942   if (!isAdmin())
943   {
944 //     qCDebug(KSIRK_LOG) << "Network player: nothing to do";
945     return false;
946   }
947 
948   // Convert the player to the right class
949   Player* p = dynamic_cast<Player*>(player);
950 
951   QString action;
952   QPointF point;
953   msg >> action >> point;
954 
955   qCDebug(KSIRK_LOG) << " =======================================================";
956   qCDebug(KSIRK_LOG)  << "Player " << p->name() << " id=" << player->id()
957   << " uid=" << player->userId() << " : " << action << " at " << point
958   << "current is" << currentPlayer()->name();
959 
960   if (p->name() == currentPlayer()->name()
961     || (m_state == WAITDEFENSE) )
962   {
963     if (action == "actionLButtonDown")
964       m_game->slotLeftButtonDown( point );
965     else if (action == "actionLButtonUp")
966       m_game->slotLeftButtonUp( point );
967     else if (action == "actionRButtonDown")
968       m_game->slotRightButtonDown( point );
969     else if (action == "actionRButtonUp")
970       m_game->slotRightButtonUp( point );
971     else if (action == "zoomInAction")
972       m_game->slotZoomIn();
973     else if (action == "zoomOutAction")
974       m_game->slotZoomOut();
975     else if (action == "actionAttack1")
976       m_game->slotAttack1();
977     else if (action == "actionAttack2")
978       m_game->slotAttack2();
979     else if (action == "actionAttack3")
980       m_game->slotAttack3();
981     else if (action == "actionMove")
982       m_game->slotMove();
983     else if (action == "slotRecyclingFinished")
984       m_game->slotRecyclingFinished();
985     else if (action == "actionInvade10")
986       m_game->slotInvade10();
987     else if (action == "actionInvade5")
988       m_game->slotInvade5();
989     else if (action == "actionInvade1")
990       m_game->slotInvade1();
991     else if (action == "actionInvasionFinished")
992       m_game->slotInvasionFinished();
993     else if (action == "slotDefense1")
994       m_game->slotDefense1();
995     else if (action == "slotDefense2")
996       m_game->slotDefense2();
997     else if (action == "actionNextPlayer")
998       m_game->slotNextPlayer();
999   }
1000   if (action == "requestForAck")
1001   {
1002     QString ack;
1003     msg >> ack;
1004     qCDebug(KSIRK_LOG) << "acknowledging " << ack;
1005     if (p->isVirtual())
1006     {
1007       qCDebug(KSIRK_LOG) << p->name() << "is virtual; sending message";
1008       QByteArray buffer;
1009       QDataStream stream(&buffer, QIODevice::WriteOnly);
1010       stream << p->id() << ack;
1011       sendMessage(buffer,Acknowledge);
1012     }
1013     else
1014     {
1015       qCDebug(KSIRK_LOG) << p->name() << "is local; acknowledging";
1016       p->acknowledge(ack);
1017     }
1018   }
1019   return false;
1020 }
1021 
1022 // Create an IO device for the player. We could create any
1023 // device here, e.g. mouse, keyboard, computer player. In the
1024 // demo game here we have only the mouse player available.
createIO(KPlayer * player,KGameIO::IOMode io)1025 void GameAutomaton::createIO(KPlayer *player,KGameIO::IOMode io)
1026 {
1027   // Error check
1028   if (!player) return;
1029 
1030   qCDebug(KSIRK_LOG) << "createIO for " << player->name();
1031 
1032   if (io&KGameIO::MouseIO)
1033   {
1034     // Create new game mouse input
1035     KGameMouseIO *input;
1036     // We want the player to work over mouse
1037     // in our canvas view
1038     input=new KGameMouseIO(m_game->frame()->scene());
1039 
1040     // Connect mouse input to a function to process the actual input
1041     connect(
1042       input,
1043       &KGameMouseIO::signalMouseEvent,
1044       m_game->frame(),
1045       &DecoratedGameFrame::slotMouseInput);
1046 
1047     // Add the device to the player
1048     player->addGameIO(input);
1049   }
1050   else if (io&AIPLAYERIO)
1051   {
1052     if (dynamic_cast<AIPlayer*>(player) != 0)
1053     {
1054       /*AIPlayerIO* input =*/ new AIPlayerIO(dynamic_cast<AIPlayer*>(player));
1055     }
1056     else
1057     {
1058       qCCritical(KSIRK_LOG) << "Can create an AIPlayerIO only for AI players: " << io ;
1059     }
1060   }
1061   else
1062   {
1063     qCCritical(KSIRK_LOG) << "Cannot create the requested IO device " << io ;
1064   }
1065   qCDebug(KSIRK_LOG) << "Done createIO for " << player->name();
1066 }
1067 
1068 // Find out who will be the next player
1069 // Note: The default behaviour as we have it here is done automatically
1070 //        by the lib, too. So if all players player one after the other
1071 //        this functions is NOT needed at all.
nextPlayer(KPlayer *,bool)1072 KPlayer * GameAutomaton::nextPlayer(KPlayer */*last*/,bool /*exclusive*/)
1073 {
1074 //   qCDebug(KSIRK_LOG) << last->name();
1075 //   m_game->setCurrentPlayerToNext();
1076   // If a last player is given switch the player
1077 
1078   // Should be enough if the admin sets the turn (unclear)
1079   if (isAdmin())
1080   {
1081     currentPlayer()->setTurn(true,true);
1082 //     last->setTurn(true,true);
1083 //     qCDebug(KSIRK_LOG) << "nextPlayer::Setting turn to " << last->name() << ", " << last->id() << "("<<last->userId()<<")";
1084   }
1085 
1086   // Notify the world that whose turn it is. The main window uses
1087   // this to show a little message
1088 //   emit signalNextPlayer(next->userId().value(),next,this);
1089 
1090   // Return the next player
1091   return dynamic_cast<KPlayer *>(currentPlayer());
1092 }
1093 
operator >>(QDataStream & s,GameAutomaton::GameState & state)1094 QDataStream& operator>>(QDataStream& s, GameAutomaton::GameState& state)
1095 {
1096   int istate;
1097   s >> istate;
1098   state = GameAutomaton::GameState(istate);
1099   return s;
1100 }
1101 
1102 
setupPlayersNumberAndSkin(NetworkGameType netGameType)1103 bool GameAutomaton::setupPlayersNumberAndSkin(NetworkGameType netGameType)
1104 {
1105   qCDebug(KSIRK_LOG) << netGameType;
1106   m_netGameType = netGameType;
1107   m_game->newGameDialog(m_skin.value(), m_netGameType);
1108 
1109 //   m_networkPlayersNumber = ???;
1110   return false;
1111 }
1112 
finishSetupPlayersNumberAndSkin()1113 bool GameAutomaton::finishSetupPlayersNumberAndSkin()
1114 {
1115   qCDebug(KSIRK_LOG);
1116 
1117   setUseGoals(m_game->newGameSetup()->useGoals());
1118   state(GameLogic::GameAutomaton::INIT);
1119   savedState(GameLogic::GameAutomaton::INVALID);
1120   setNetworkPlayersNumber(m_game->newGameSetup()->nbNetworkPlayers());
1121   m_startingGame = true;
1122   state(INIT);
1123   setMinPlayers(m_game->newGameSetup()->nbPlayers());
1124   setMaxPlayers(m_game->newGameSetup()->nbPlayers());
1125   m_nbPlayers = m_game->newGameSetup()->nbPlayers();
1126 
1127   return true;
1128 }
1129 
setGoalFor(Player * player)1130 void GameAutomaton::setGoalFor(Player* player)
1131 {
1132   qCDebug(KSIRK_LOG) << player->name();
1133   unsigned int max = m_goals.size();
1134   unsigned int goalId = Dice::roll(max);
1135   QList< Goal* >::iterator it = m_goals.begin();
1136   for (unsigned int i = 1 ; i < goalId; it++,i++) {}
1137   Goal* goal = (*it);
1138   qCDebug(KSIRK_LOG) << "Goal for " << player->name() << " is of type " << goal->type();
1139   if (goal->type() == Goal::GoalPlayer)
1140   {
1141     Player* target = 0;
1142     while (target==0 || target->id() == player->id())
1143     {
1144       unsigned int max = playerList()->count();
1145       unsigned int playerNum = Dice::roll(max);
1146 //       qCDebug(KSIRK_LOG) << "Choice player num " << playerNum << " on " << max ;
1147       PlayersArray::iterator itp = playerList()->begin();
1148       unsigned int j = 1;
1149       for (; j < playerNum; j++,itp++) {}
1150       target = dynamic_cast< Player* >(*itp);
1151     }
1152     if (target != 0)
1153     {
1154 //       qCDebug(KSIRK_LOG) << "Target choice for " << player->name() << ": " << target->name();
1155       goal->players().push_back(target->name());
1156     }
1157     else
1158     {
1159 //       qCDebug(KSIRK_LOG) << "No target chosen for " << player->name();
1160     }
1161   }
1162   /// @note hack to avoid too easy countries goal when there is only two players
1163   else if (goal->type() == Goal::Countries
1164     && playerList()->count() == 2)
1165   {
1166     goal->nbCountries(int(goal->nbCountries()*1.5));
1167   }
1168   QByteArray buffer;
1169   QDataStream stream(&buffer, QIODevice::WriteOnly);
1170   stream << player->id();
1171   stream << (*goal);
1172   qCDebug(KSIRK_LOG) << "Sending message GoalForIs ("<<GoalForIs<<") for " << player->name();
1173   sendMessage(buffer,GoalForIs);
1174 //   delete goal;
1175   m_goals.erase(it);
1176 }
1177 
getDefCountry()1178 Country * GameAutomaton::getDefCountry ()
1179 {
1180   return this->defCountry;
1181 }
1182 
joinNetworkGame()1183 bool GameAutomaton::joinNetworkGame()
1184 {
1185   qCDebug(KSIRK_LOG);
1186    if (stateName() == "INIT"
1187      || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KStandardGuiItem::yes()) == KMessageBox::Continue))
1188    {
1189       m_game->joinNetworkGame();
1190    }
1191    return false;
1192 }
1193 
connectToServ()1194 bool GameAutomaton::connectToServ()
1195 {
1196   qCDebug(KSIRK_LOG);
1197   if (messageServer() != 0)
1198   {
1199     QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
1200                         this,&GameAutomaton::slotConnectionToClientBroken);
1201   }
1202   qCDebug(KSIRK_LOG) << "Before connectToServer";
1203   QString host = m_game->newGameSetup()->host();
1204   int port = m_game->newGameSetup()->tcpPort();
1205   bool status = connectToServer(host, port);
1206   qCDebug(KSIRK_LOG) << "After connectToServer" << status;
1207   if (messageServer())
1208     connect(messageServer(),&KMessageServer::connectionLost,
1209           this,&GameAutomaton::slotConnectionToClientBroken);
1210   return status;
1211 }
1212 
joinJabberGame(const QString & nick)1213 bool GameAutomaton::joinJabberGame(const QString& nick)
1214 {
1215   if (stateName() == "INIT" || (KMessageBox::warningContinueCancel(m_game,i18n("Do you really want to end your current game and join another?"),i18n( "New game confirmation" ),KStandardGuiItem::yes()) == KMessageBox::Continue))
1216   {
1217     // stop game
1218     setGameStatus(KGame::End);
1219     state(INIT);
1220     savedState(INVALID);
1221 
1222     if (messageServer() != 0)
1223     {
1224       QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
1225                            this,&GameAutomaton::slotConnectionToClientBroken);
1226     }
1227 
1228     qCDebug(KSIRK_LOG) << "Before connectToServer";
1229     m_game->setServerJid(nick);
1230     KMessageJabber* messageIO = new KMessageJabber(m_game->serverJid().full(), m_game->jabberClient(), this);
1231     bool status = connectToServer(messageIO);
1232     //       bool status = connectToServer(host, port);
1233     qCDebug(KSIRK_LOG) << "After connectToServer" << status;
1234     if (status)
1235     {
1236       QByteArray msg("connect");
1237       XMPP::Message message(m_game->serverJid().full());
1238       message.setType("ksirkgame");
1239       message.setId(QUuid::createUuid().toString().remove("{").remove("}").remove("-"));
1240       message.setBody(msg);
1241       m_game->jabberClient()->sendMessage(message);
1242     }
1243     //       connect(messageServer(),SIGNAL(connectionLost(KMessageIO*)),
1244                                                            //          this,SLOT(slotConnectionToClientBroken(KMessageIO*)));
1245                                                            return status;
1246   }
1247   return false;
1248 }
1249 
createPlayer(int rtti,int,bool isVirtual)1250 KPlayer * GameAutomaton::createPlayer(int rtti,
1251                                     int /*io*/,
1252                                     bool isVirtual)
1253 {
1254   qCDebug(KSIRK_LOG) << "(" << rtti << ", " << isVirtual << ")";
1255   if (rtti == 1)
1256   {
1257     Player* p = new Player(this, "", 0, 0);
1258     p->setVirtual(isVirtual);
1259     if (!isVirtual)
1260     {
1261       qCDebug(KSIRK_LOG) << "Calling player createIO";
1262       createIO(p,KGameIO::IOMode(KGameIO::MouseIO));
1263     }
1264     return (KPlayer*) p;
1265   }
1266   else if (rtti == 2)
1267   {
1268     AIPlayer* aip = new AIColsonPlayer("", 0, 0,  *playerList(), m_game->theWorld(),
1269                                    this);
1270     aip->stop();
1271     aip->setVirtual(isVirtual);
1272     if (!isVirtual)
1273     {
1274       qCDebug(KSIRK_LOG) << "Calling player createIO";
1275       createIO(aip, KGameIO::IOMode(AIPLAYERIO));
1276     }
1277     return (KPlayer*) aip;
1278   }
1279   else
1280   {
1281     qCCritical(KSIRK_LOG) << "No rtti given... creating a Player";
1282     Player* p = new Player(this, "", 0, 0);
1283     p->setVirtual(isVirtual);
1284     if (!isVirtual)
1285     {
1286       qCDebug(KSIRK_LOG) << "Calling player createIO";
1287       createIO(p,KGameIO::IOMode(KGameIO::MouseIO));
1288     }
1289     return (KPlayer*) p;
1290   }
1291 }
1292 
1293 /**
1294   * @return A pointer to the given's named player ; 0 if there is no such player
1295   */
playerNamed(const QString & playerName)1296 Player* GameAutomaton::playerNamed(const QString& playerName)
1297 {
1298   PlayersArray::iterator it = playerList()->begin();
1299   PlayersArray::iterator it_end = playerList()->end();
1300   for (; it != it_end; it++)
1301   {
1302     if ( (*it)-> name() ==  playerName)
1303     {
1304       return dynamic_cast<Player*>(*it);
1305     }
1306   }
1307   qCCritical(KSIRK_LOG) << "GameAutomaton::playerNamed: there is no player named "
1308       << playerName ;
1309   return 0;
1310 }
1311 
currentPlayer()1312 Player* GameAutomaton::currentPlayer()
1313 {
1314   if (m_game && !m_currentPlayer.isEmpty())
1315   {
1316     return playerNamed(m_currentPlayer);
1317   }
1318   else return 0;
1319 }
1320 
currentPlayer(Player * player)1321 void GameAutomaton::currentPlayer(Player* player)
1322 {
1323   qCDebug(KSIRK_LOG);
1324   if (player)
1325   {
1326     qCDebug(KSIRK_LOG) << " name = " << player->name();
1327     m_currentPlayer = player->name();
1328     m_currentPlayerPlayed = false;
1329     if (isAdmin())
1330     {
1331       QByteArray buffer;
1332       QDataStream stream(&buffer, QIODevice::WriteOnly);
1333       stream << m_currentPlayer;
1334       sendMessage(buffer,PlayerChange);
1335       player->setTurn(true,true);
1336     }
1337     QByteArray buffer;
1338     QDataStream stream(&buffer, QIODevice::WriteOnly);
1339     stream << player->name();
1340     sendMessage(buffer,SetBarFlagButton);
1341     if (!player->isVirtual())
1342     {
1343       m_game->chatWidget()->setFromPlayer(player);
1344     }
1345   }
1346   else
1347     m_currentPlayer = "";
1348 }
1349 
slotPlayerJoinedGame(KPlayer * player)1350 void GameAutomaton::slotPlayerJoinedGame(KPlayer* player)
1351 {
1352   qCDebug(KSIRK_LOG) << "currently " << playerList()->count() << " / " << maxPlayers();
1353   Player* p = dynamic_cast<Player*>(player);
1354   Q_ASSERT(p);
1355 
1356   if (isAdmin())
1357   {
1358     unsigned int nbWithNation = 0;
1359     unsigned int nbWithName = 0;
1360     PlayersArray::iterator it = playerList()->begin();
1361     PlayersArray::iterator it_end = playerList()->end();
1362     for (; it != it_end; it++)
1363     {
1364       if (p->getNation()->name() == ((Player*)(*it))->getNation()->name())
1365       {
1366         nbWithNation++;
1367       }
1368       if (p->name() == ((Player*)(*it))->name())
1369       {
1370         nbWithName++;
1371       }
1372     }
1373     if (nbWithName != 1)
1374     {
1375       QByteArray buffer;
1376       QDataStream stream(&buffer, QIODevice::WriteOnly);
1377       stream << quint32(player->id());
1378       qCDebug(KSIRK_LOG) << "Sending ChangePlayerName for player id " << player->id();
1379       sendMessage(buffer,ChangePlayerName);
1380 
1381       return;
1382     }
1383     else if (nbWithNation != 1)
1384     {
1385       QByteArray buffer;
1386       QDataStream stream(&buffer, QIODevice::WriteOnly);
1387       stream << player->id();
1388       qCDebug(KSIRK_LOG) << "Sending ChangePlayerNation for player id " << player->id();
1389       sendMessage(buffer,ChangePlayerNation);
1390 
1391       return;
1392     }
1393     KMessageParts messageParts;
1394     messageParts
1395       << I18N_NOOP("%1 (%2) joined game ; waiting for %3 players to connect")
1396       << p-> name() << p->getNation()->name()
1397       << QString::number(maxPlayers() - int(playerList()->count()));
1398     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
1399     QByteArray buffer;
1400     QDataStream stream(&buffer, QIODevice::WriteOnly);
1401     qCDebug(KSIRK_LOG) << "Sending StartGame";
1402     sendMessage(buffer,StartGame);
1403   }
1404   else
1405   {
1406     if (!player->isVirtual())
1407     {
1408       m_game->showNewGameSummary();
1409     }
1410     m_game->newGameSetup()->setNbPlayers(maxPlayers());
1411   }
1412   NewPlayerData* pd = new NewPlayerData(p->name(),p->getNation()->name(),"",p->isAI(),true);
1413   if (!m_game->newGameSetup()->addPlayer(pd))
1414   {
1415     delete pd;
1416   }
1417   m_game->updateNewGameSummary();
1418 }
1419 
startGame()1420 bool GameAutomaton::startGame()
1421 {
1422   qCDebug(KSIRK_LOG) << stateName() << "nb players = " << playerList()->count() << " / " << maxPlayers();
1423   m_aicannotrunhack = true;
1424   //   qCDebug(KSIRK_LOG) << "  state is " << GameStateNames[m_state];
1425 //   qCDebug(KSIRK_LOG) << "  saved state is " << GameStateNames[m_savedState];
1426   if (isAdmin() && int(playerList()->count()) == maxPlayers()
1427       && gameStatus()!=KGame::Run)
1428   {
1429 //     m_game->haltTimer();
1430 
1431     if (m_state == INIT && m_savedState == INVALID)
1432     {
1433       firstCountriesDistribution();
1434 
1435       if (useGoals())
1436       {
1437         PlayersArray::iterator it = playerList()->begin();
1438         PlayersArray::iterator it_end = playerList()->end();
1439         for (; it != it_end; it++)
1440         {
1441           QByteArray buffer;
1442           QDataStream stream(&buffer, QIODevice::WriteOnly);
1443           stream << (*it)->id();
1444           sendMessage(buffer,SetGoalFor);
1445         }
1446       }
1447     }
1448     else if (m_state == WAIT_PLAYERS)
1449     {
1450       sendCountries();
1451       qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << m_savedState ;
1452       state(m_savedState);
1453       currentPlayer(playerNamed(m_savedPlayer));
1454       m_game->displayButtonsForState(m_savedState);
1455       m_savedPlayer = "";
1456       m_savedState = INVALID;
1457     }
1458 
1459     qCDebug(KSIRK_LOG) << "Sending message FinalizePlayers";
1460     QByteArray buffer;
1461     QDataStream stream(&buffer, QIODevice::WriteOnly);
1462     sendMessage(buffer,FinalizePlayers);
1463 
1464     qCDebug(KSIRK_LOG) << "Setting game status to Run";
1465     setGameStatus(KGame::Run);
1466 //     m_game->initTimer();
1467 //     qCDebug(KSIRK_LOG) << "    true";
1468     return true;
1469   }
1470   else
1471   {
1472 //     qCDebug(KSIRK_LOG) << "    false";
1473     return false;
1474   }
1475 }
1476 
changePlayerName(Player * player)1477 void GameAutomaton::changePlayerName(Player* player)
1478 {
1479 //   qCDebug(KSIRK_LOG);
1480 
1481   QMap< QString, QString > nations = m_game->nationsList();
1482   PlayersArray::iterator it = playerList()->begin();
1483   PlayersArray::iterator it_end = playerList()->end();
1484   for (; it != it_end; it++)
1485   {
1486     QMap<QString,QString>::iterator nationsIt;
1487     nationsIt = nations.find(((Player*)(*it))-> getNation()->name());
1488     if (nationsIt !=  nations.end())
1489     {
1490       nations.erase(nationsIt);
1491     }
1492   }
1493 
1494 // Players names
1495   QString mes = "";
1496   QString nationName;
1497 
1498   QString nomEntre = player->name();
1499 
1500   bool found = true;
1501   KMessageBox::information(m_game, i18n("Please choose another name"), i18n("KsirK - Name already used!"));
1502   while(found)
1503   {
1504     bool emptyName = true;
1505     while (emptyName)
1506     {
1507       mes = i18n("Player number %1, what's your name?", 1);
1508       QString password;
1509       if (nomEntre.isEmpty())
1510       {
1511         mes = i18n("Error - Player %1, you have to choose a name.", 1);
1512         KMessageBox::sorry(m_game, mes, i18n("Error"));
1513         nomEntre = i18nc("@info Forged player name", "Player%1", 1);
1514       }
1515       else
1516       {
1517         emptyName = false;
1518       }
1519     }
1520     found = false;
1521     PlayersArray::iterator it = playerList()->begin();
1522     PlayersArray::iterator it_end = playerList()->end();
1523     for (; it != it_end; it++)
1524     {
1525       if ( (*it)-> name() ==  nomEntre)
1526       {
1527         found = true;
1528         it = it_end;
1529       }
1530     }
1531     if (!found)
1532     {
1533 //     qCDebug(KSIRK_LOG) << "Creating player " << nomEntre << "(computer: " << computer << "): " << nationName ;
1534       player->setName(nomEntre);
1535     }
1536   }
1537   QByteArray buffer;
1538   QDataStream stream(&buffer, QIODevice::WriteOnly);
1539   sendMessage(buffer,StartGame);
1540 }
1541 
changePlayerNation(Player * player)1542 void GameAutomaton::changePlayerNation(Player* player)
1543 {
1544 //   qCDebug(KSIRK_LOG);
1545 
1546   QMap< QString, QString > nations = m_game->nationsList();
1547   PlayersArray::iterator it = playerList()->begin();
1548   PlayersArray::iterator it_end = playerList()->end();
1549   for (; it != it_end; it++)
1550   {
1551     QMap<QString,QString>::iterator nationsIt;
1552     nationsIt = nations.find(((Player*)(*it))-> getNation()->name());
1553     if (nationsIt !=  nations.end())
1554     {
1555       nations.erase(nationsIt);
1556     }
1557   }
1558 
1559 // Players names
1560   QString mes = "";
1561   QString nationName;
1562 
1563   QString nomEntre = player->name();
1564   KMessageBox::information(m_game, i18n("Please choose another nation"), i18n("KsirK - Nation already used!"));
1565   QString password;
1566   QByteArray buffer;
1567   QDataStream stream(&buffer, QIODevice::WriteOnly);
1568   stream << player->name() << nationName;
1569   sendMessage(buffer,SetNation);
1570   QByteArray buffer2;
1571   QDataStream stream2(&buffer2, QIODevice::WriteOnly);
1572   sendMessage(buffer2,StartGame);
1573 }
1574 
idForMsg(const QString & msg)1575 quint32 GameAutomaton::idForMsg(const QString& msg)
1576 {
1577   QMap<QString,quint32>::iterator it = m_msgs2ids.find(msg);
1578   if (it != m_msgs2ids.end())
1579   {
1580     return (*it);
1581   }
1582   else
1583   {
1584     quint32 id = m_msgs2ids.size();
1585     QByteArray buffer;
1586     QDataStream stream(&buffer, QIODevice::WriteOnly);
1587     stream << msg << id;
1588     sendMessage(buffer,AddMsgIdPair);
1589     return id;
1590   }
1591 }
1592 
msgForId(quint32 id)1593 QString& GameAutomaton::msgForId(quint32 id)
1594 {
1595   return m_ids2msgs[id];
1596 }
1597 
slotPropertyChanged(KGamePropertyBase * prop,KGame *)1598 void GameAutomaton::slotPropertyChanged(KGamePropertyBase *prop,KGame *)
1599 {
1600   qCDebug(KSIRK_LOG) << prop->id() << " (skin is " << m_skinId << ")";
1601   if (prop->id() == m_skinId)
1602   {
1603     qCDebug(KSIRK_LOG) << "skin changed to: " << m_skin ;
1604     m_game->newSkin();
1605     if (m_game->theWorld()!=0)
1606     {
1607       m_game->theWorld()->reset();
1608     }
1609   }
1610   qCDebug(KSIRK_LOG) << "END GameAutomaton::slotPropertyChanged " << prop->id() << " (skin is " << m_skinId << ")";
1611 }
1612 
slotClientJoinedGame(quint32 clientid,KGame *)1613 void GameAutomaton::slotClientJoinedGame(quint32 clientid, KGame* /*me*/)
1614 {
1615   qCDebug(KSIRK_LOG) << clientid;
1616   if (isAdmin() && clientid!=gameId())
1617   {
1618     QByteArray buffernbp;
1619     QDataStream streamnbp(&buffernbp, QIODevice::WriteOnly);
1620     streamnbp << m_nbPlayers;
1621     sendMessage(buffernbp,NbPlayers,clientid);
1622 
1623     QByteArray bufferngs;
1624     QDataStream streamngs(&bufferngs, QIODevice::WriteOnly);
1625     streamngs << *m_game->newGameSetup();
1626     sendMessage(bufferngs,NewGameSetupMsg,clientid);
1627 
1628     QByteArray buffer;
1629     QDataStream stream(&buffer, QIODevice::WriteOnly);
1630     if (m_game->waitedPlayers().empty())
1631     {
1632       sendMessage(buffer,SetupOnePlayer,clientid);
1633     }
1634     else
1635     {
1636       stream << quint32(m_game->waitedPlayers().size());
1637       QList<PlayerMatrix>::iterator it, it_end;
1638       it = m_game->waitedPlayers().begin(); it_end = m_game->waitedPlayers().end();
1639       for (; it != it_end; it++)
1640       {
1641         stream << (*it);
1642       }
1643       sendMessage(buffer,SetupWaitedPlayer,clientid);
1644     }
1645   }
1646 }
1647 
slotConnectionToServerBroken()1648 void GameAutomaton::slotConnectionToServerBroken()
1649 {
1650   qCDebug(KSIRK_LOG);
1651 
1652 //   m_game->haltTimer();
1653   if (m_state != GAME_OVER)
1654   {
1655     int answer = KMessageBox::questionYesNoCancel(m_game,
1656                                                   i18n("KsirK - Lost connection to server!\nWhat do you want to do?"),
1657                                                   i18n("Starting a new game or exit."),
1658                                                   KGuiItem(i18n("New Game")),
1659                                                   KGuiItem(i18n("Exit")),
1660                                                   KGuiItem(i18n("Do nothing")));
1661     if (answer == KMessageBox::Yes)
1662     {
1663       m_game->showMainMenu();
1664     }
1665     else if (answer == KMessageBox::No)
1666     {
1667       exit(0);
1668     }
1669     else
1670     {
1671     }
1672   }
1673 }
1674 
slotConnectionToClientBroken(KMessageIO *)1675 void GameAutomaton::slotConnectionToClientBroken(KMessageIO *)
1676 {
1677   qCDebug(KSIRK_LOG);
1678 //   m_game->haltTimer();
1679   if (m_state != GAME_OVER)
1680   {
1681     KMessageBox::information(m_game,
1682                             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."),
1683                             i18n("KsirK - Lost connection to client!"));
1684     switch ( KMessageBox::warningYesNo( m_game, i18n("Do want to save your game?")) )
1685     {
1686     case KMessageBox::Yes :
1687       m_game->slotSaveGame();
1688       break;
1689     case KMessageBox::No :;
1690     default: ;
1691     }
1692     if (!m_game->actionNewGame(GameAutomaton::None))
1693       exit(1);
1694   }
1695 //   else
1696 //   {
1697 //     m_game->haltTimer();
1698 //   }
1699 }
1700 
finalizePlayers()1701 void GameAutomaton::finalizePlayers()
1702 {
1703   qCDebug(KSIRK_LOG);
1704   PlayersArray::iterator it = playerList()->begin();
1705   PlayersArray::iterator it_end = playerList()->end();
1706   for (; it != it_end; it++)
1707   {
1708     dynamic_cast<Player*>(*it)-> finalize();
1709   }
1710   QByteArray buffer;
1711   if (isAdmin())
1712   {
1713     sendMessage(buffer,DisplayGoals);
1714   }
1715   m_game->showMap();
1716   m_startingGame = false;
1717 }
1718 
1719 /** @return true if all players are played by computer ; false otherwise */
allComputerPlayers()1720 bool GameAutomaton::allComputerPlayers()
1721 {
1722   PlayersArray::iterator it = playerList()->begin();
1723   PlayersArray::iterator it_end = playerList()->end();
1724   for (; it != it_end; it++)
1725   {
1726     if ( ! dynamic_cast<Player*>(*it)-> isAI() )
1727     {
1728       return false;
1729     }
1730   }
1731   return true;
1732 }
1733 
allLocalPlayersComputer()1734 bool GameAutomaton::allLocalPlayersComputer()
1735 {
1736   PlayersArray::iterator it = playerList()->begin();
1737   PlayersArray::iterator it_end = playerList()->end();
1738   for (; it != it_end; it++)
1739   {
1740     if ( ( ! dynamic_cast<Player*>(*it)-> isVirtual() ) &&  ( ! dynamic_cast<Player*>(*it)-> isAI() ) )
1741     {
1742       return false;
1743     }
1744   }
1745   return true;
1746 }
1747 
firstCountriesDistribution()1748 void GameAutomaton::firstCountriesDistribution()
1749 {
1750   qCDebug(KSIRK_LOG);
1751 
1752   if (isAdmin())
1753   {
1754     PlayersArray::iterator it = playerList()->begin();
1755     PlayersArray::iterator it_end = playerList()->end();
1756     for (; it != it_end; it++)
1757     {
1758       ((Player*)(*it))->setNbAvailArmies((unsigned int)(m_game->theWorld()->getNbCountries() * 2.5 / nbPlayers() ), true);
1759     }
1760     m_game->setCurrentPlayerToFirst();
1761     qCDebug(KSIRK_LOG) << "Setup players: distributing countries";
1762     countriesDistribution();
1763 
1764 
1765   //    qCDebug(KSIRK_LOG) << " KGameWindow::setupPlayers: before initTimer";
1766 //     m_game->initTimer();
1767     m_game->setCurrentPlayerToFirst();
1768     if ( currentPlayer()-> isAI()  && (!currentPlayer()->isVirtual()) )
1769       if ( ! ( dynamic_cast<AIPlayer *>(currentPlayer())-> isRunning()) )
1770         dynamic_cast<AIPlayer *>(currentPlayer())-> start();
1771 
1772     QByteArray buffer;
1773     QDataStream stream(&buffer, QIODevice::WriteOnly);
1774     stream << currentPlayer()->name();
1775 //     stream << (quint32)m_game->availArmies();
1776     stream << (quint32)currentPlayer()->getNbAvailArmies();
1777     qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << (quint32)currentPlayer()->getNbAvailArmies()
1778       << " at " << __FILE__ << ", line " << __LINE__;
1779 //       qCDebug(KSIRK_LOG) << "sending DisplayRecycleDetails " << currentPlayer()->name() << m_game->availArmies()
1780 //       << " at " << __FILE__ << ", line " << __LINE__;
1781       sendMessage(buffer,DisplayRecycleDetails);
1782 
1783 
1784   //    qCDebug(KSIRK_LOG) << "OUT  KGameWindow::setupPlayers";
1785 
1786   }
1787 }
1788 
countriesDistribution()1789 void GameAutomaton::countriesDistribution()
1790 {
1791   qCDebug(KSIRK_LOG);
1792   unsigned int initialNbArmies;
1793   QList< int > vect;
1794   QMap<QString,unsigned int> distributedCountriesNumberMap;
1795   PlayersArray::iterator it = playerList()->begin();
1796   initialNbArmies = ((Player*)(*playerList()->begin()))->getNbAvailArmies();
1797   PlayersArray::iterator it_end = playerList()->end();
1798   for (; it != it_end; it++)
1799   {
1800     distributedCountriesNumberMap[(*it)-> name()] = 0;
1801   }
1802   // creates a vector containing the numbers of the countries
1803   for (unsigned int i = 0; i < m_game->theWorld()->getNbCountries()  ; i++) vect.push_back(i);
1804 
1805   // do while the vector not empty (will distribute one country each turn and
1806   // remove its number from the vector)
1807   while (vect.size())
1808   {
1809     // chooses randomly a position in the remaining countries vector
1810     int h = Dice::roll(vect.size()) - 1;
1811 
1812     // moves an iterator up to the position chosen
1813     QList< int >::iterator it = vect.begin();
1814     for (int itPos = 0; itPos < h-1; itPos++) it++;
1815 
1816     // affect the country that have the number at this position
1817     QByteArray buffer;
1818     QDataStream stream(&buffer, QIODevice::WriteOnly);
1819     stream << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name();
1820     qCDebug(KSIRK_LOG) << (m_game->theWorld()->getCountries().at(*it)->name()) << currentPlayer()-> name();
1821     distributedCountriesNumberMap[currentPlayer()-> name()] = distributedCountriesNumberMap[currentPlayer()-> name()]+1;
1822     sendMessage(buffer,CountryOwner);
1823     //m_game->theWorld()->getCountries().at(*it)-> owner(currentPlayer());
1824     m_game->setCurrentPlayerToNext(false);
1825 
1826     // removes the chosen country number from the vector, thus reducing its size
1827     vect.erase(it);
1828   }
1829   it = playerList()->begin();
1830   it_end = playerList()->end();
1831   for (; it != it_end; it++)
1832   {
1833     ((GameLogic::Player*)(*it))->setNbAvailArmies(((GameLogic::Player*)(*it))->getNbAvailArmies() - distributedCountriesNumberMap[(*it)-> name()], true);
1834 
1835     ((GameLogic::Player*)(*it))->incrNbCountries(distributedCountriesNumberMap[(*it)-> name()]);
1836   }
1837 //   qCDebug(KSIRK_LOG) << "All countries are now distributed.";
1838   m_game->setCurrentPlayerToFirst();
1839   QString nextPlayerName = currentPlayer()->name();
1840   QByteArray buffer;
1841   QDataStream stream(&buffer, QIODevice::WriteOnly);
1842   stream << (quint32)((GameLogic::Player*)(currentPlayer()))->getNbAvailArmies();
1843 //   qCDebug(KSIRK_LOG) << "  Setting status " << nextPlayerName << " / " << m_game->availArmies();
1844   QPixmap pm = playerNamed(nextPlayerName)->getFlag()->image(0);
1845   KMessageParts messageParts;
1846   messageParts
1847     << pm
1848     << I18N_NOOP("%1: %2 armies to place")
1849     << nextPlayerName
1850     <<  QString::number( initialNbArmies - distributedCountriesNumberMap[nextPlayerName]);
1851   qCDebug(KSIRK_LOG) << "Message parts size= " << messageParts.size();
1852   m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
1853   m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries."));
1854   state(INTERLUDE);
1855   m_game->setNextPlayerActionEnabled(false);
1856 }
1857 
sendCountries()1858 void GameAutomaton::sendCountries()
1859 {
1860   QByteArray buffer;
1861   QDataStream stream(&buffer, QIODevice::WriteOnly);
1862 
1863   m_game->theWorld()->sendCountries(stream);
1864   sendMessage(buffer,SetupCountries);
1865 }
1866 
movingFigthersArrived()1867 void GameAutomaton::movingFigthersArrived()
1868 {
1869   qCDebug(KSIRK_LOG);
1870   state(FIGHT_ANIMATE);
1871   QByteArray buffer;
1872   QDataStream stream(&buffer, QIODevice::WriteOnly);
1873   sendMessage(buffer,AnimCombat);
1874 }
1875 
movingArmiesArrived()1876 void GameAutomaton::movingArmiesArrived()
1877 {
1878   qCDebug(KSIRK_LOG);
1879 //   m_game->terminateAttackSequence();
1880 }
1881 
movingArmyArrived(Country * country,unsigned int number)1882 void GameAutomaton::movingArmyArrived(Country* country, unsigned int number)
1883 {
1884   qCDebug(KSIRK_LOG) << number ;
1885   country->incrNbArmies(number);
1886   country->createArmiesSprites();
1887   checkGoal(country->owner());
1888 }
1889 
firingFinished()1890 void GameAutomaton::firingFinished()
1891 {
1892   qCDebug(KSIRK_LOG);
1893   if (isAdmin())
1894   {
1895     m_game->resolveAttack();
1896     state(EXPLOSION_ANIMATE);
1897   }
1898 }
1899 
explosionFinished()1900 void GameAutomaton::explosionFinished()
1901 {
1902   qCDebug(KSIRK_LOG);
1903   if (isAdmin())
1904   {
1905     switch (gameStatus())
1906     {
1907       case KGame::Pause:
1908         m_game->setStateBeforeNewGame(FIGHT_BRINGBACK);
1909         break;
1910       case KGame::Run:;
1911       default:
1912         state(FIGHT_BRINGBACK);
1913     }
1914   }
1915 }
1916 
displayGoals()1917 void GameAutomaton::displayGoals()
1918 {
1919   qCDebug(KSIRK_LOG);
1920   PlayersArray::iterator it = playerList()->begin();
1921   PlayersArray::iterator it_end = playerList()->end();
1922   for (; it != it_end; it++)
1923   {
1924     if ( (dynamic_cast<Player*>(*it) != 0)
1925         && ( ! dynamic_cast<Player*>(*it)-> isVirtual() )
1926         && ( ! dynamic_cast<Player*>(*it)-> isAI() ) )
1927     {
1928       KMessageBox::information(
1929           game(),
1930           i18n("%1, your goal will be displayed. Please<br>"
1931                "make sure that no other player can see it!",(*it)->name()),
1932           i18n("KsirK - Displaying Goal"));
1933       dynamic_cast<Player*>(*it)->goal().show();
1934     }
1935   }
1936   m_aicannotrunhack = false;
1937 }
1938 
moveSlide()1939 void GameAutomaton::moveSlide()
1940 {
1941   qCDebug(KSIRK_LOG);
1942   if (!currentPlayer()->isVirtual())
1943     m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry(),InvasionSlider::Moving);
1944 }
1945 
1946 /**
1947   * Change the automatic attack state.
1948   * @param activated new state
1949   */
setAttackAuto(bool activated)1950 void GameAutomaton::setAttackAuto(bool activated)
1951 {
1952   QByteArray buffer;
1953   QDataStream stream(&buffer, QIODevice::WriteOnly);
1954   stream << (quint32)activated;
1955 
1956   sendMessage(buffer,AttackAuto);
1957 }
1958 
slotNetworkData(int msgid,const QByteArray & buffer,quint32 receiver,quint32 sender)1959 void GameAutomaton::slotNetworkData(int msgid, const QByteArray &buffer, quint32 receiver, quint32 sender)
1960 {
1961   qCDebug(KSIRK_LOG) << "msg " << msgid << " ; rec="<<receiver << " snd=" << sender ;
1962   if (m_game == 0)
1963   {
1964     exit(0);
1965   }
1966 
1967   if (msgid < CountryOwner || msgid>= UnusedLastMessageId)
1968   {
1969     return;
1970   }
1971   qCDebug(KSIRK_LOG) << "("<<KsirkMessagesIdsNames[msgid-(KGameMessage::IdUser+1)]<<", " << receiver << ", " << sender << ")";
1972   QDataStream stream(const_cast<QByteArray*>(&buffer), QIODevice::ReadOnly);
1973   QString countryName, playerName, nationName;
1974   QPointF point;
1975   quint32 removable;
1976   quint32 theState;
1977   quint32 nbArmies;
1978   quint32 newState;
1979   quint32 statusBarId, messagePartsNb, messagePartsCounter, logStatus;
1980   quint32 propId, prop2Id;
1981   quint32 playerId;
1982   quint32 nbVotes = 0;
1983   quint32 explosing;
1984   KMessageParts messageParts;
1985   QString messagePart;
1986   Player* player;
1987   PlayerMatrix waitedPlayerDef(this);
1988   quint32 nbWaitedPlayers;
1989   quint32 waitedPlayerId;
1990   QString waitedPlayerPassword;
1991   quint32 nbCountries;
1992   Country* country;
1993   quint32 msgId;
1994   QString ack;
1995   QString msg;
1996   Goal goal(this);
1997   QString playersNames;
1998   QPixmap pm;
1999   quint32 A1, A2, A3, D1, D2, NKA, NKD;
2000   quint32 win;
2001   quint32 attackAutoValue;
2002   quint32 availArmies;
2003   quint32 elemType;
2004   quint32 nb;
2005 
2006   if (currentPlayer() != 0 && currentPlayer()->getFlag() != 0)
2007   {
2008     pm = currentPlayer()->getFlag()->image(0);
2009   }
2010 
2011   QByteArray sendBuffer;
2012   QDataStream sendStream(&sendBuffer, QIODevice::WriteOnly);
2013   switch (msgid)
2014   {
2015   case CountryOwner:
2016     stream >> countryName >> playerName;
2017     qCDebug(KSIRK_LOG) << "CountryOwner for " << (void*)m_game->theWorld()->countryNamed(countryName) << " " << countryName << " and " << (void*)playerNamed(playerName) << playerName ;
2018     m_game->theWorld()->countryNamed(countryName)-> owner(playerNamed(playerName));
2019     break;
2020   case PlayerPutsInitialArmy:
2021     stream >> point;
2022     if (m_game->playerPutsInitialArmy(point))
2023     {
2024       if (isAdmin())
2025         gameEvent("playersLooped", point);
2026     }
2027     break;
2028   case PlayerPutsArmy:
2029     stream >> point >> removable;
2030     if (m_game->playerPutsArmy(point, removable) && isAdmin())
2031     {
2032       gameEvent("playersLooped", point);
2033     }
2034     break;
2035   case StateChange:
2036     stream >> theState;
2037     qCDebug(KSIRK_LOG) << "Got new state id: " << theState <<
2038         " ("<<GameStateNames[theState]<<")";
2039     m_state = GameState(theState);
2040     break;
2041   case PlayerChange:
2042     stream >> playerName;
2043     if (!isAdmin())
2044     {
2045       m_currentPlayer = playerName;
2046       m_currentPlayerPlayed = false;
2047     }
2048     break;
2049   case RegisterCountry:
2050     stream >> countryName >> propId >> prop2Id;
2051     m_nbArmiesIdsNamesCountriesMap.insert(int(propId),countryName);
2052     m_namesNbArmiesIdsCountriesMap.insert(countryName,int(propId));;
2053 //     m_nbAddedArmiesIdsNamesCountriesMap.insert(int(prop2Id),countryName);
2054 //     m_namesNbAddedArmiesIdsCountriesMap.insert(countryName,int(prop2Id));
2055     break;
2056   case PlayerAvailArmies:
2057     if (sender == gameId()) break;
2058     stream >> playerName >> nbArmies;
2059     if (playerNamed(playerName) != 0)
2060       playerNamed(playerName)->setNbAvailArmies((unsigned int)nbArmies, false);
2061     break;
2062 /*  case KGameWinAvailArmies:
2063     if (sender == gameId()) break;
2064     stream >> nbArmies;
2065     m_game->availArmies(nbArmies);*/
2066     break;
2067   case ChangeItem:
2068     if (sender == gameId()) break;
2069     stream >> statusBarId >> logStatus >> messagePartsNb;
2070     qCDebug(KSIRK_LOG) << "Got ChangeItem on " << statusBarId << " ; nb= " << messagePartsNb;
2071     for (messagePartsCounter = 0; messagePartsCounter < messagePartsNb; ++messagePartsCounter)
2072     {
2073       stream >> elemType;
2074       if (elemType == KMessageParts::Text)
2075       {
2076         stream >> messagePart;
2077         messageParts << messagePart;
2078         qCDebug(KSIRK_LOG) << " message part: " << messagePart;
2079       }
2080       else if (elemType == KMessageParts::StringId)
2081       {
2082         stream >> msgId;
2083         messageParts << msgForId(msgId);
2084         qCDebug(KSIRK_LOG) << " message part for id "<<msgId<<": " << msgForId(msgId);
2085       }
2086       else if (elemType == KMessageParts::Pixmap)
2087       {
2088         stream >> pm;
2089         messageParts << pm;
2090       }
2091     }
2092     m_game->changeItem(messageParts,statusBarId, logStatus);
2093     break;
2094   case DisplayRecyclingButtons:
2095     m_game->getRightDialog()->updateRecycleDetails(0,true,0);
2096     m_game->displayRecyclingButtons();
2097     break;
2098   case ClearHighlighting:
2099     m_game->clearHighlighting();
2100     break;
2101   case ActionRecycling:
2102     if (isAdmin())
2103     {
2104       m_game->actionRecycling();
2105       state(NEWARMIES);
2106     }
2107     break;
2108   case ClearGameActionsToolbar:
2109     break;
2110   case DisplayDefenseButtons:
2111     stream >> playerName;
2112     if ( (!playerNamed(playerName)->isVirtual())
2113       && (!playerNamed(playerName)->isAI()) && (!isDefenseAuto()))
2114     {
2115       defCountry = this->game()->secondCountry();
2116       m_game->displayDefenseWindow();
2117     }
2118     messageParts << I18N_NOOP("%1 chooses its defense") << playerName;
2119     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2120     break;
2121   case ActionDefense:
2122     stream >> nbArmies;
2123     if (isAdmin())
2124       m_game->defense((unsigned int)nbArmies);
2125     break;
2126   case FirstCountry:
2127     stream >> countryName;
2128     qCDebug(KSIRK_LOG) << "FirstCountry " << countryName ;
2129     m_game->firstCountry(m_game->theWorld()->countryNamed(countryName));
2130     break;
2131   case SecondCountry:
2132     stream >> countryName;
2133     qCDebug(KSIRK_LOG) << "SecondCountry " << countryName ;
2134     m_game->secondCountry(m_game->theWorld()->countryNamed(countryName));
2135     break;
2136   case InitCombatMovement:
2137     m_game->initCombatMovement();
2138     break;
2139   case AnimCombat:
2140     m_game->animCombat();
2141     break;
2142   case TerminateAttackSequence:
2143     {
2144       // update country display
2145       if (m_game->terminateAttackSequence())
2146       {
2147         // Re-display the world view
2148         m_game->showMap();
2149 
2150         setAttackAuto(false);
2151 //         setDefenseAuto(false);
2152         if(!currentPlayer()->isAI() && !currentPlayer()->isVirtual())
2153         {
2154           m_game->slideInvade(m_game->firstCountry(), m_game->secondCountry());
2155         }
2156         if (isAdmin())
2157         {
2158           state(INVADE);
2159         }
2160       }
2161       else if (isAdmin())
2162       {
2163         // if there is more than 1 army on my country and automatic
2164         // attack is activated
2165         if (m_game->firstCountry()->nbArmies() > 1 && m_attackAuto)
2166         {
2167           // continue automatically attacking by making the same attack
2168           state(WAIT1);
2169           if (m_game->firstCountry()->nbArmies() > 3)
2170           {
2171             gameEvent("actionAttack3", m_game->secondCountry()->centralPoint());
2172           }
2173           else if (m_game->firstCountry()->nbArmies() > 2)
2174           {
2175             gameEvent("actionAttack2", m_game->secondCountry()->centralPoint());
2176           }
2177           else
2178           {
2179             gameEvent("actionAttack1", m_game->secondCountry()->centralPoint());
2180           }
2181 
2182         // else wait user choice
2183         }
2184         else
2185         {
2186           // Re-display the world view
2187           m_game->showMap();
2188 
2189           setAttackAuto(false);
2190 //           setDefenseAuto(false);
2191           state(WAIT);
2192         }
2193       }
2194       m_game->firstCountry()-> createArmiesSprites();
2195       m_game->secondCountry()-> createArmiesSprites();
2196     }
2197     break;
2198   case DecrNbArmies:
2199     stream >> countryName >> nbArmies;
2200     m_game->theWorld()->countryNamed(countryName)->decrNbArmies(nbArmies);
2201     Q_FALLTHROUGH();
2202   case StartLocalCurrentAI:
2203     m_game->startLocalCurrentAI();
2204     break;
2205   case Invade:
2206     stream >> nbArmies;
2207     nb = nbArmies;
2208     while (nb >= 10)
2209     {
2210       if (m_game-> invade(10))
2211         m_game-> incrNbMovedArmies(10);
2212       nb -= 10;
2213     }
2214     while (nb >= 5)
2215     {
2216       if (m_game-> invade(5))
2217         m_game-> incrNbMovedArmies(5);
2218       nb -= 5;
2219     }
2220     while (nb > 0)
2221     {
2222       if (m_game-> invade(1))
2223         m_game-> incrNbMovedArmies(1);
2224       nb--;
2225     }
2226 
2227     break;
2228   case Retreat:
2229     stream >> nbArmies;
2230     if (m_game-> retreat(nbArmies))
2231       m_game-> decrNbMovedArmies(nbArmies);
2232     break;
2233   case  NextPlayerNormal:
2234     if (isAdmin())
2235     {
2236       stream >> playerName;
2237       stream >> newState;
2238       if (playerName == currentPlayer()->name() &&  m_game->nextPlayerNormal())
2239       {
2240         if (newState > 0)
2241         {
2242           qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ;
2243           state(GameState(newState));
2244         }
2245       }
2246     }
2247     break;
2248   case  NextPlayerRecycling:
2249     if (isAdmin())
2250     {
2251       stream >> newState;
2252       if (m_game->nextPlayerRecycling())
2253       {
2254         m_choosedToRecycleNumber = 0;
2255         if (newState > 0)
2256         {
2257           qCDebug(KSIRK_LOG) << "at " <<  __FILE__ << ", line " << __LINE__ << ", setting state to " << newState ;
2258           state(GameState(newState));
2259           m_game->slotContextualHelp();
2260         }
2261       }
2262     }
2263     break;
2264   case ShowArmiesToPlace:
2265     messageParts << pm << I18N_NOOP("%1: %2 armies to place") << (currentPlayer()-> name())
2266       << QString::number(currentPlayer()-> getNbAvailArmies());
2267     m_game->broadcastChangeItem(messageParts, ID_STATUS_MSG2);
2268     m_game->showMessage(i18n("Now, place your armies in your countries<br>by clicking in the target countries."));
2269     break;
2270   case PlayerRemovesArmy:
2271     stream >> point;
2272     m_game->playerRemovesArmy(point);
2273     break;
2274   case VoteRecyclingFinished:
2275     if (isAdmin())
2276     {
2277 //       stream >> playerName;
2278       messageParts << I18N_NOOP("%1 choose to end recycling; there are now %2 players who want so");
2279       stream >> nbVotes;
2280       stream >> playerId;
2281       playersNames = ((Player*)(findPlayer(playerId)))->name();
2282       if (!m_choosedToRecycle.contains(playerId))
2283       {
2284         m_choosedToRecycle.push_back(playerId);
2285       }
2286       else
2287       {
2288         nbVotes--;
2289       }
2290 
2291       for (quint32 i = 1 ; i < nbVotes; i++)
2292       {
2293         stream >> playerId;
2294         playersNames += QString(", ") + ((Player*)(findPlayer(playerId)))->name();
2295         if (!m_choosedToRecycle.contains(playerId))
2296         {
2297           m_choosedToRecycle.push_back(playerId);
2298         }
2299         else
2300         {
2301           nbVotes--;
2302         }
2303       }
2304       qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb before: " << m_choosedToRecycleNumber ;
2305       m_choosedToRecycleNumber+=nbVotes;
2306       qCDebug(KSIRK_LOG) << "VoteRecyclingFinished nb after : " << m_choosedToRecycleNumber ;
2307       messageParts << playersNames << QString::number(m_choosedToRecycleNumber);
2308       m_game->broadcastChangeItem(messageParts, ID_NO_STATUS_MSG);
2309       if (m_choosedToRecycleNumber == (unsigned int)(playerList()->count()))
2310       {
2311         m_game->actionRecyclingFinished();
2312         m_choosedToRecycle.clear();
2313       }
2314     }
2315     break;
2316   case CancelShiftSource:
2317     m_game-> cancelShiftSource();
2318     if (isAdmin())
2319     {
2320       state(SHIFT1);
2321     }
2322     break;
2323   case ChangePlayerNation:
2324     stream >> playerId;
2325 //     qCDebug(KSIRK_LOG) << "Got ChangePlayerNation for player id " << playerId ;
2326     player = (Player*)(findPlayer(playerId));
2327 //     qCDebug(KSIRK_LOG) << "Found player id " << player;
2328     if (player && !player->isVirtual())
2329     {
2330       changePlayerNation(player);
2331     }
2332     break;
2333   case ChangePlayerName:
2334     stream >> playerId;
2335     player = (Player*)(findPlayer(playerId));
2336     if (player && !player->isVirtual())
2337     {
2338       changePlayerName(player);
2339     }
2340     break;
2341   case StartGame:
2342     if (isAdmin())
2343       startGame();
2344     break;
2345   case SetNation:
2346     stream >> playerName >> nationName;
2347     playerNamed(playerName)->setNation(nationName);
2348     break;
2349   case SetBarFlagButton:
2350     stream >> playerName;
2351     qCDebug(KSIRK_LOG) << "Calling setBarFlagButton for player " << playerNamed(playerName) << " named " << playerName ;
2352     m_game->setBarFlagButton(playerNamed(playerName));
2353     break;
2354   case FinishMoves:
2355     m_game->finishMoves();
2356     break;
2357   case AnimExplosion:
2358     stream >> explosing;
2359     qCDebug(KSIRK_LOG) << "AnimExplosion" << explosing;
2360     if (m_game->backGnd()->bgIsArena())
2361     {
2362       m_game->animExplosionForArena();
2363     }
2364     else
2365     {
2366       if (explosing != 0 && explosing != 1 && explosing != 2)
2367       {
2368         KMessageBox::information(m_game, i18n("Problem : no one destroyed"), i18n("KsirK - Error!"));
2369       }
2370       else
2371       {
2372         m_game->animExplosion(explosing);
2373       }
2374     }
2375     break;
2376   case SetupOnePlayer:
2377     if (receiver == gameId())
2378     {
2379       m_game->setupOnePlayer();
2380     }
2381     break;
2382   case SetupWaitedPlayer:
2383     stream >> nbWaitedPlayers;
2384     for (quint32 i = 0; i < nbWaitedPlayers; i++)
2385     {
2386       stream >> waitedPlayerDef;
2387       m_game->waitedPlayers().push_back(waitedPlayerDef);
2388     }
2389     m_game->setupOneWaitedPlayer();
2390     break;
2391   case ValidateWaitedPlayerPassword:
2392     if (isAdmin())
2393     {
2394       stream >> waitedPlayerId >> waitedPlayerPassword;
2395 //       qCDebug(KSIRK_LOG) << "Validating password for waited player " << waitedPlayerId << " : " << m_game->waitedPlayers()[waitedPlayerId].password << " / " << waitedPlayerPassword ;
2396       if (m_game->waitedPlayers()[waitedPlayerId].password == waitedPlayerPassword)
2397       {
2398         sendStream << waitedPlayerId;
2399         sendMessage(sendBuffer,ValidPassword, sender);
2400       }
2401       else
2402       {
2403         sendMessage(sendBuffer,InvalidPassword, sender);
2404       }
2405     }
2406     break;
2407   case ValidPassword:
2408     if (receiver == gameId())
2409     {
2410       stream >> waitedPlayerId;
2411       m_game->createWaitedPlayer(waitedPlayerId);
2412     }
2413     break;
2414   case InvalidPassword:
2415     if (receiver == gameId())
2416     {
2417       KMessageBox::information(m_game, i18n("You entered an invalid password.\nPlease try again."), i18n("KsirK - Invalid password!"));
2418       m_game->setupOneWaitedPlayer();
2419     }
2420     break;
2421   case SetupCountries:
2422     stream >> nbCountries;
2423     for (unsigned int i = 0; i < nbCountries; i++)
2424     {
2425       stream >> countryName;
2426       country = m_game->theWorld()->countryNamed(countryName);
2427       qCDebug(KSIRK_LOG) << "Setting up country n°" << i << " on " << nbCountries << ", " << (void*)country << " named " << countryName ;
2428       if (country)
2429       {
2430         stream >> country;
2431       }
2432     }
2433     break;
2434   case AddMsgIdPair:
2435     stream >> msg >> msgId;
2436     m_msgs2ids.insert(msg,msgId);
2437     m_ids2msgs.insert(msgId,msg);
2438     break;
2439   case CheckGoal:
2440     if (isAdmin())
2441     {
2442       qCDebug(KSIRK_LOG) << "CheckGoal: ";
2443       stream >> playerId;
2444       player = dynamic_cast< Player* >(findPlayer(playerId));
2445       if (player)
2446       {
2447         if (player->checkGoal())
2448         {
2449           qCDebug(KSIRK_LOG) << "    goal reached for " << player->name();
2450           qCDebug(KSIRK_LOG) << "    setting state to " << GameStateNames[GAME_OVER];
2451 //           m_game->haltTimer();
2452           setGameStatus(KGame::End);
2453           state(GAME_OVER);
2454           sendStream << player->id();
2455           qCDebug(KSIRK_LOG) << "    sending Winner";
2456           sendMessage(sendBuffer,Winner);
2457         }
2458       }
2459     }
2460     break;
2461   case SetGoalFor:
2462     if (isAdmin())
2463     {
2464       stream >> playerId;
2465       setGoalFor(dynamic_cast<Player*>(findPlayer(playerId)));
2466     }
2467     break;
2468   case GoalForIs:
2469     qCDebug(KSIRK_LOG) << "GoalForIs: ";
2470     stream >> playerId;
2471     qCDebug(KSIRK_LOG) << "  player id: " << playerId ;
2472     stream >> goal;
2473     player = dynamic_cast<Player*>(findPlayer(playerId));
2474     if (player != 0)
2475     {
2476       player->goal(goal);
2477     }
2478     break;
2479   case FinalizePlayers:
2480       qCDebug(KSIRK_LOG) << "Got message FinalizePlayers";
2481       finalizePlayers();
2482     break;
2483   case Winner:
2484     QObject::disconnect(messageServer(),&KMessageServer::connectionLost,
2485                         this,&GameAutomaton::slotConnectionToClientBroken);
2486     stream >> playerId;
2487     m_game->winner(dynamic_cast<Player*>(findPlayer(playerId)));
2488     break;
2489   case NbPlayers:
2490     stream >> m_nbPlayers;
2491     break;
2492   case Acknowledge:
2493       stream >> playerId;
2494       stream >> ack;
2495       if (!isAdmin() && !dynamic_cast<Player*>(findPlayer(playerId))->isVirtual())
2496       {
2497         qCDebug(KSIRK_LOG) << "Got message Acknowledge" << playerId << ack;
2498         dynamic_cast<Player*>(findPlayer(playerId))->acknowledge(ack);
2499       }
2500     break;
2501   case DisplayGoals:
2502       qCDebug(KSIRK_LOG) << "Got message DisplayGoals";
2503       QTimer::singleShot(0,this,&GameAutomaton::displayGoals);
2504     break;
2505   case DisplayFightResult:
2506       qCDebug(KSIRK_LOG) << "Got message DisplayFightResult";
2507       stream >> A1 >> A2 >> A3 >> D1 >> D2 >> NKA >> NKD >> win;
2508       m_game->getRightDialog()->displayFightResult(A1,A2,A3,D1,D2,NKA,NKD,win);
2509     break;
2510   case MoveSlide:
2511       qCDebug(KSIRK_LOG) << "Got message MoveSlide";
2512       moveSlide();
2513     break;
2514   case InvasionFinished:
2515       qCDebug(KSIRK_LOG) << "Got message InvasionFinished";
2516       if (isAdmin())
2517       {
2518         gameEvent("actionInvasionFinished", point);
2519       }
2520     break;
2521   case AttackAuto:
2522       qCDebug(KSIRK_LOG) << "Got message AttackAuto";
2523       stream >> attackAutoValue;
2524       m_attackAuto = attackAutoValue;
2525     break;
2526   case DisplayRecycleDetails:
2527       stream >> playerName;
2528       stream >> availArmies;
2529       qCDebug(KSIRK_LOG) << "Got message DisplayRecycleDetails "
2530           << playerName << availArmies;
2531       m_game->getRightDialog()->displayRecycleDetails(playerNamed(playerName),availArmies);
2532 //       bool value;
2533 //       if (playerNamed(playerName)->isAI() || playerNamed(playerName)->isVirtual())
2534 //       {
2535 //         value = false;
2536 //       }
2537 //       else
2538 //       {
2539 //         value = true;
2540 //       }
2541       m_game->setNextPlayerActionEnabled(false);
2542     break;
2543   case CurrentPlayerPlayed:
2544     m_currentPlayerPlayed = true;
2545     break;
2546   case ResetPlayersDistributionData:
2547     resetPlayersDistributionData();
2548     break;
2549   case NewGameSetupMsg:
2550     qCDebug(KSIRK_LOG) << "Got message NewGameSetupMsg";
2551     stream >> *m_game->newGameSetup();
2552     break;
2553   default: ;
2554   }
2555 }
2556 
askForJabberGames()2557 void GameAutomaton::askForJabberGames()
2558 {
2559   m_game->askForJabberGames();
2560 }
2561 
rendererFor(const QString & skinName)2562 QSvgRenderer& GameAutomaton::rendererFor(const QString& skinName)
2563 {
2564   if (!m_renderers.contains(skinName))
2565   {
2566     m_renderers.insert(skinName,new QSvgRenderer(this));
2567   }
2568   return *m_renderers[skinName];
2569 }
2570 
svgDomFor(const QString & skinName)2571 KGameSvgDocument& GameAutomaton::svgDomFor(const QString& skinName)
2572 {
2573   if (!m_svgDoms.contains(skinName))
2574   {
2575     m_svgDoms.insert(skinName,KGameSvgDocument());
2576   }
2577   return m_svgDoms[skinName];
2578 }
2579 
startingGame() const2580 bool GameAutomaton::startingGame() const
2581 {
2582   qCDebug(KSIRK_LOG) << m_startingGame;
2583   return m_startingGame;
2584 }
2585 
isDefenseAuto()2586 bool GameAutomaton::isDefenseAuto()
2587 {
2588   return m_defenseAuto.isDefenseAuto(m_game->firstCountry(),m_game->secondCountry());
2589 }
2590 
setDefenseAuto(bool activated)2591 void GameAutomaton::setDefenseAuto(bool activated)
2592 {
2593   m_defenseAuto.value = activated;
2594   if (activated)
2595   {
2596     m_defenseAuto.firstCountry = m_game->firstCountry();
2597     m_defenseAuto.secondCountry= m_game->secondCountry();
2598   }
2599   else
2600   {
2601     m_defenseAuto.firstCountry = 0;
2602     m_defenseAuto.secondCountry= 0;
2603   }
2604 }
2605 
resetPlayersDistributionData()2606 void GameAutomaton::resetPlayersDistributionData()
2607 {
2608   foreach (KPlayer* p, *playerList())
2609   {
2610     if ( !p->isVirtual() )
2611     {
2612       ((GameLogic::Player*)p)->reset();
2613     }
2614   }
2615 }
2616 
actionNextPlayer()2617 void GameAutomaton::actionNextPlayer()
2618 {
2619   if ( currentPlayer()->isVirtual()
2620     || currentPlayer()->isAI()
2621     || m_currentPlayerPlayed
2622     || (KMessageBox::questionYesNo (m_game,
2623                                      i18n("%1, you have not played anything this turn.\nDo you really want to lose your turn?",m_currentPlayer),
2624                                      i18n("Really Next Player?")) == KMessageBox::Yes) )
2625   {
2626     QByteArray buffer;
2627     QDataStream stream(&buffer, QIODevice::WriteOnly);
2628     stream << currentPlayer()->name();
2629     stream << (quint32)NEWARMIES;
2630     qCDebug(KSIRK_LOG) << "(state " << stateName() << ") sending NextPlayerNormal" << currentPlayer()->name() << NEWARMIES;
2631     sendMessage(buffer,NextPlayerNormal);
2632     m_game-> cancelAction();
2633   }
2634 }
2635 
removeAllPlayers()2636 void GameAutomaton::removeAllPlayers()
2637 {
2638   qCDebug(KSIRK_LOG);
2639   m_currentPlayer = "";
2640 
2641   /* Bug 304362. KPlayer destructor removes
2642    * player from the list and makes iterators invalid.
2643    * qDeleteAll crashes in that case. */
2644   while (!playerList()->isEmpty())
2645   {
2646     delete playerList()->takeFirst();
2647   }
2648   // qDeleteAll(*playerList());
2649   // playerList()->clear();
2650 }
2651 
2652 // Bug 308527.
removeAllGoals()2653 void GameAutomaton::removeAllGoals()
2654 {
2655     qCDebug(KSIRK_LOG);
2656     while (!goals().isEmpty())
2657         delete goals().takeFirst();
2658 }
2659 
newGameNext()2660 void GameAutomaton::newGameNext()
2661 {
2662   qCDebug(KSIRK_LOG);
2663   m_startingGame = true;
2664   state(INIT);
2665 
2666   qCDebug(KSIRK_LOG) << "Changing skin";
2667   m_skin = m_game->newGameSetup()->skin();
2668   if (m_game->newGameSetup()->networkGameType() == Socket)
2669   {
2670     offerConnections(m_game->newGameSetup()->tcpPort());
2671   }
2672   m_game->finishSetupPlayers();
2673 }
2674 
checkGoal(Player * player)2675 void GameAutomaton::checkGoal(Player* player)
2676 {
2677   QByteArray buffer;
2678   QDataStream stream(&buffer, QIODevice::WriteOnly);
2679   if (player == 0)
2680     stream << currentPlayer()->id();
2681   else
2682     stream << player->id();
2683   qCDebug(KSIRK_LOG) << "sending CheckGoal";
2684   sendMessage(buffer,CheckGoal);
2685 }
2686 
2687 
2688 } // closing namespace GameLogic
2689 } // closing namespace Ksirk
2690 
2691 
2692