1 // Copyright (C) 2003, 2004, 2005 Ulf Lorenz
2 // Copyright (C) 2007, 2008 Ben Asselstine
3 // Copyright (C) 2007, 2008 Ole Laursen
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Library General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include "NextTurnNetworked.h"
22 #include "playerlist.h"
25 #include "stacklist.h"
26 #include "armysetlist.h"
28 #include "vectoredunitlist.h"
31 #include "QuestsManager.h"
32 #include "network_player.h"
33 #include "game-server.h"
34 #include "game-client.h"
35 #include "GameScenarioOptions.h"
40 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<flush<<endl;}
43 NextTurnNetworked::NextTurnNetworked(bool turnmode, bool random_turns)
44 :NextTurn(turnmode, random_turns)
46 Playerlist* plist = Playerlist::getInstance();
47 for (Playerlist::iterator i = plist->begin(); i != plist->end(); ++i) {
49 p->ending_turn.connect(sigc::mem_fun(this, &NextTurn::endTurn));
53 NextTurnNetworked::~NextTurnNetworked()
57 void NextTurnNetworked::start()
59 //We need the playerlist a lot, so maintain a copy of it.
60 Playerlist* plist = Playerlist::getInstance();
62 //set first player as active if no active player exists
63 if (!plist->getActiveplayer())
66 if (plist->getActiveplayer()->isDead())
69 if (plist->getActiveplayer()->isDead())
72 if (plist->getActiveplayer()->getType() != Player::NETWORKED)
80 // inform everyone about the next turn
81 snextTurn.emit(plist->getActiveplayer());
83 if (plist->getNoOfPlayers() <= 2)
85 if (plist->checkPlayers()) //end of game detected
89 splayerStart.emit(plist->getActiveplayer());
91 // let the player do his or her duties...
92 bool continue_loop = plist->getActiveplayer()->startTurn();
96 //Now do some cleanup at the end of the turn.
99 //...and initiate the next one.
103 //if it is the first player's turn now, a new round has started
104 if (Playerlist::getInstance()->getActiveplayer() ==
105 Playerlist::getInstance()->getFirstLiving())
107 //if (GameServer::getInstance()->isListening() == true)
109 if (plist->checkPlayers() == true)
111 if (plist->getNoOfPlayers() <= 1)
113 if (plist->getActiveplayer()->isDead())
118 if (GameServer::getInstance()->isListening() == false)
119 GameClient::getInstance()->sendRoundOver();
121 //both client and server exit this loop at the end of the round
124 if (Playerlist::getInstance()->getActiveplayer()->getType() == Player::NETWORKED)
130 Player *active = Playerlist::getInstance()->getActiveplayer();
131 if (active->getType() == Player::NETWORKED &&
132 Playerlist::getInstance()->getNeutral() != active)
134 NetworkPlayer *player = dynamic_cast<NetworkPlayer*>(active);
135 if (player->isConnected() == false)
136 snextPlayerUnavailable.emit(active);
141 void NextTurnNetworked::endTurn()
143 // Finish off the player and transfers the control to the start function
148 if (Playerlist::getActiveplayer() == Playerlist::getInstance()->getFirstLiving())
150 //if (GameServer::getInstance()->isListening() == true)
154 if (GameServer::getInstance()->isListening() == false)
155 GameClient::getInstance()->sendRoundOver();
163 void NextTurnNetworked::startTurn()
165 //this function is called before a player starts his turn. Some
166 //items you could imagine to be placed here: healing/building
167 //units, check for joining heroes...
170 Player* p = Playerlist::getActiveplayer();
172 //here we check to see if the player is about to start a new turn
173 //we do this check to see if we're re-sitting down again in the game lobby
174 //we want to prevent offering the player another hero, etc.
175 if (p->hasAlreadyInitializedTurn() && p->hasAlreadyEndedTurn() == false)
179 //calculate upkeep and income
180 p->calculateUpkeep();
181 p->calculateIncome();
183 //if turnmode is set, create/heal armies at player's turn
187 //if (p->getType() != Player::NETWORKED)
190 Citylist::getInstance()->collectTaxes(p);
192 guint32 num_cities = Citylist::getInstance()->countCities(p);
193 p->getStacklist()->collectTaxes(p, num_cities);
195 //vector armies (needs to preceed city's next turn)
196 VectoredUnitlist::getInstance()->nextTurn(p);
198 //pay upkeep for existing stacks
199 p->getStacklist()->payUpkeep(p);
201 //reset moves, and heal stacks
202 p->getStacklist()->nextTurn();
205 Citylist::getInstance()->nextTurn(p);
208 p->calculateUpkeep();
210 QuestsManager::getInstance()->nextTurn(p);
213 void NextTurnNetworked::finishTurn()
215 //Put everything that has to be done before the next player starts
216 //his turn here. E.g. one could clear some caches.
217 Player *p = Playerlist::getActiveplayer();
218 p->getFogMap()->smooth();
222 void NextTurnNetworked::finishRound()
224 Playerlist *plist = Playerlist::getInstance();
225 //Put everything that has to be done when a new round starts in here.
226 //E.g. increase the round number in GameScenario. (this is done with
227 //the snextRound signal, but useful for an example).
231 //do this for all players at once
233 for (Playerlist::iterator it = plist->begin(); it != plist->end(); it++)
238 //collect monies from cities
239 Citylist::getInstance()->collectTaxes(*it);
241 guint32 num_cities = Citylist::getInstance()->countCities(*it);
242 (*it)->getStacklist()->collectTaxes((*it), num_cities);
244 //vector armies (needs to preceed city's next turn)
245 VectoredUnitlist::getInstance()->nextTurn(*it);
247 //pay for existing armies
248 (*it)->getStacklist()->payUpkeep(*it);
250 //reset, and heal armies
251 (*it)->getStacklist()->nextTurn();
254 Citylist::getInstance()->nextTurn(*it);
259 // heal the stacks in the ruins
260 Ruinlist* rl = Ruinlist::getInstance();
261 for (Ruinlist::iterator it = rl->begin(); it != rl->end(); it++)
263 Stack* keeper = (*it)->getOccupant();
270 plist->randomizeOrder();