SVN_SILENT made messages (.desktop file)
[kdegames.git] / konquest / gamelogic.cc
blob23912b2c7431e4bb2200562fe10db9f07e8dcd69
1 /*
2 Copyright Russell Steffen <rsteffen@bayarea.net>
3 Copyright Stephan Zehetner <s.zehetner@nevox.org>
4 Copyright Dmitry Suzdalev <dimsuz@gmail.com>
5 Copyright Inge Wallin <inge@lysator.liu.se>
6 Copyright Pierre Ducroquet <pinaraf@gmail.com>
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include "gamelogic.h"
24 #include <klocale.h>
26 #include "gamecore.h"
27 #include "player.h"
28 #include "map.h"
30 #include "gamelogic.moc"
32 /*********************************************************************
33 Game Logic
34 *********************************************************************/
36 GameLogic::GameLogic( QObject *parent )
37 : QObject( parent )
39 m_map = new Map(16, 16);
40 m_neutralPlayer = Player::createNeutralPlayer(m_map);
42 cleanupGame();
46 GameLogic::~GameLogic()
48 delete m_map;
52 //************************************************************************
53 // To the end turn processing (resolve combat, etc.)
54 //************************************************************************
57 // FIXME: Rename into resolveTurn(), and create a new newTurn() method.
59 void
60 GameLogic::nextTurn()
62 // Resolve things from last turn.
63 resolveShipsInFlight();
65 // See if any players are left.
66 scanForSurvivors();
68 // advance to first living player
69 while( (*m_currentPlayer) && !(*m_currentPlayer)->isInPlay() ) {
70 ++m_currentPlayer;
73 // advance turn counter
74 // FIXME: Emit a newTurn() signal.
75 m_turnNumber++;
77 // update the planets
78 foreach (Planet *planet, m_planets) {
79 planet->turn();
84 //************************************************************************
85 // Determine the fate of the ships in transit
86 //************************************************************************
89 void
90 GameLogic::resolveShipsInFlight()
92 AttackFleetList arrivingShips;
94 foreach (Player *player, m_players) {
95 player->attackList() += player->newAttacks();
96 player->statFleetsLaunched( player->newAttacks().size() );
97 player->newAttacks().clear();
98 foreach (AttackFleet *fleet, player->attackList()) {
99 if( m_turnNumber == fleet->arrivalTurn ) {
100 doFleetArrival( fleet );
101 player->attackList().removeAll( fleet );
102 delete fleet;
109 Player *
110 GameLogic::findWinner()
112 Player *winner = 0;
114 foreach (Player *player, m_players) {
115 if (player->isInPlay()) {
116 // If there are more than one player alive, then there is
117 // no winner.
118 if (winner != 0)
119 return 0;
121 // Tentatively set this player as winner.
122 winner = player;
124 else if (player->attackList().count() != 0)
125 // There is still a fleet attacking, so wait for its arrival...
126 return 0;
129 return winner;
134 //************************************************************************
135 // check to see any players have been eliminated
136 //************************************************************************
139 void
140 GameLogic::scanForSurvivors()
142 QList<Player *> activePlayers;
143 QList<Player *> inactivePlayers;
145 // Insert all of the active players into a special list,
146 // then deactivate them
147 Player *player;
148 foreach (player, m_players) {
149 if( player->isInPlay() ) {
150 activePlayers.append( player );
151 player->setInPlay( false );
152 } else {
153 inactivePlayers.append( player );
158 // iterate through the list of planets and
159 // mark their owners in play
160 foreach (Planet *planet, m_planets) {
161 planet->player()->setInPlay( true );
164 foreach (player, activePlayers) {
165 if( !player->isInPlay() ) {
166 // Player has bitten the dust
167 emit gameMsg(ki18n("The once mighty empire of %1 has fallen in ruins."), player);
171 foreach (player, inactivePlayers) {
172 if( player->isInPlay() ) {
173 // Player has bitten the dust
174 emit gameMsg(ki18n("The fallen empire of %1 has staggered back to life."), player);
180 //************************************************************************
181 // handle the arrival of a fleet at a planet
182 //************************************************************************
185 void
186 GameLogic::doFleetArrival( AttackFleet *arrivingFleet )
188 // Check to see of (fleet owner) == (planet owner)
189 // if the planet and fleet owner are the same, then merge the fleets
190 // otherwise attack.
192 if( *arrivingFleet->owner == *arrivingFleet->destination->player() ) {
193 arrivingFleet->destination->fleet().absorb(arrivingFleet);
194 if ( !arrivingFleet->owner->isAiPlayer() )
195 emit gameMsg(ki18np("Reinforcements (1 ship) have arrived for planet %2.",
196 "Reinforcements (%1 ships) have arrived for planet %2.")
197 .subs(arrivingFleet->shipCount()),
198 0, arrivingFleet->destination);
199 } else {
201 // let's get ready to rumble...
203 CoreLogic cl;
204 AttackFleet &attacker = *arrivingFleet;
205 Planet &attackerPlanet = *(attacker.source);
206 Planet &defenderPlanet = *(attacker.destination);
207 DefenseFleet &defender = defenderPlanet.fleet();
209 bool haveVictor = false;
210 bool planetHolds = true;
212 while( !haveVictor ) {
213 double attackerRoll = cl.roll();
214 double defenderRoll = cl.roll();
216 if( defenderRoll < defenderPlanet.killPercentage() ) {
217 attacker.removeShips( 1 );
218 defenderPlanet.player()->statEnemyShipsDestroyed( 1 );
221 if( attacker.shipCount() <= 0 ) {
222 haveVictor = true;
223 planetHolds = true;
224 continue;
227 if( attackerRoll < attackerPlanet.killPercentage() ) {
228 defender.removeShips( 1 );
229 attacker.owner->statEnemyShipsDestroyed( 1 );
232 if( defender.shipCount() <= 0 ) {
233 haveVictor = true;
234 planetHolds = false;
238 if( planetHolds ) {
239 defenderPlanet.player()->statEnemyFleetsDestroyed(1);
240 emit gameMsg(ki18n("Planet %2 has held against an attack from %1."),
241 attacker.owner, &defenderPlanet);
242 } else {
243 Player *defender = defenderPlanet.player();
244 attacker.owner->statEnemyFleetsDestroyed( 1 );
246 defenderPlanet.conquer( &attacker );
248 emit gameMsg(ki18n("Planet %2 has fallen to %1."),
249 attacker.owner, &defenderPlanet, defender);
255 //************************************************************************
256 // Set up the game board for a new game
257 //************************************************************************
260 void
261 GameLogic::startNewGame()
263 // Setup for a new game to start playing.
264 m_currentPlayer = m_players.begin();
265 m_turnNumber = 1;
269 //************************************************************************
270 // Shut down the current game
271 //************************************************************************
273 void
274 GameLogic::cleanupGame()
276 m_map->clearMap();
278 m_planets.clear();
279 m_players.clear();
283 // The current player has done its orders, and it's the next players
284 // turn.
287 void
288 GameLogic::nextPlayer()
290 foreach (Planet *planet, m_planets) {
291 if(planet->player() == *m_currentPlayer) {
292 planet->showOldShips();
295 // End turn and advance to next player.
296 do {
297 ++m_currentPlayer;
298 } while ( m_currentPlayer != m_players.end()
299 && !(*m_currentPlayer)->isInPlay() );
301 if( m_currentPlayer == m_players.end() ) {
302 emit endTurn();
304 // end of player list, new turn
305 m_currentPlayer = m_players.begin();
307 nextTurn();
308 emit beginTurn();