initial commit, lordsawar source, slightly modified
[lordsawar] / src / playerlist.h
1 // Copyright (C) 2000, 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
4 // Copyright (C) 2007 Ole Laursen
5 //
6 //  This program is free software; you can redistribute it and/or modify
7 //  it under the terms of the GNU General Public License as published by
8 //  the Free Software Foundation; either version 3 of the License, or
9 //  (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU Library General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
19 //  02110-1301, USA.
20
21 #ifndef PLAYERLIST_H
22 #define PLAYERLIST_H
23
24 #include <list>
25 #include <map>
26 #include <string>
27 #include <vector>
28 #include <sigc++/trackable.h>
29 #include <sigc++/signal.h>
30 #include "game-parameters.h"
31
32 class History;
33
34 #include "player.h"
35
36 //! A list of all of the Player objects in a scenario.
37 /** 
38  * The Playerlist is implemented as a singleton class. The currently
39  * active player is designated, you can access players by name or id and the
40  * playerlist can check if there are more than one player remaining alive.
41  * This class also holds methods that affect all players.
42  */
43
44 class Playerlist : public std::list<Player*>, public sigc::trackable
45 {
46     public:
47
48         //! The xml tag of this object in a saved-game file.
49         static std::string d_tag; 
50
51         // Set Methods
52
53         //! Set the winning human player.
54         void setWinningPlayer(Player *winner);
55
56         //! Set the player who's turn it is.  should only be used by the editor.
57         void setActiveplayer(Player *p) {d_activeplayer = p;};
58
59         //! set the player who is looking at the bigmap and smallmap.
60         void setViewingplayer(Player *p) {viewingplayer = p;};
61
62         //! Get Methods
63
64         //! Returns the neutral player.
65         Player* getNeutral() const {return d_neutral;}
66
67         //! Return the player with the highest score.
68         Player *getWinningPlayer() const;
69
70
71         // Methods that operate on the class data and modify the class.
72
73         //! Sets the active player to the next player in the order.
74         void nextPlayer();
75
76         /** 
77          * Checks if a player is alive and has no cities left. If not then 
78          * this method marks the player as killed.
79          *
80          * @param Returns whether or not any players were marked as dead.
81          */
82         //! Kill any players that don't have cities left.
83         bool checkPlayers();
84
85         /** 
86          * Though the neutral player is located in the list of existing 
87          * players, it is handled in a special way in many different cases.
88          *
89          * There can only be one neutral player per Playerlist.
90          *
91          * @param neutral          The new neutral player.
92          */
93         //! Set the neutral player.
94         void setNeutral(Player* neutral) {d_neutral = neutral;}
95
96         /** 
97          * Swap out a player from the list and replace it with a new one.
98          * Specical care is taken to remove all references to the original
99          * player and replace it with a reference to the new player.
100          *
101          * The purpose of this method is to change a human player into a
102          * computer player and vice-versa.
103          *
104          * @param old_player   A pointer to the player to replace.
105          * @param new_player   A pointer to the new player to replace the 
106          *                     original player.
107          */
108         //! Replace a Player in the list with a new Player.
109         void swap(Player *old_player, Player *new_player);
110         
111         /** 
112          * Erase a Player from the list, and free the contents of the Player.
113          *
114          * @param it   The place in the Playerlist to erase.
115          *
116          * @return The place in the list that was erased.
117          */
118         //! Erase a player from the list.
119         iterator flErase(iterator it);
120
121         /**
122          * This method is called when a round starts.
123          * The purpose of this method is to calculate who is winning, and 
124          * it to negotiate diplomacy between players.  This method also 
125          * implements the computer players collectively surrendering to a 
126          * final human player.
127          *
128          * @param diplomacy     Whether or not we should negotiate diplomacy
129          *                      between players.
130          * @param surrender_already_offered Tells the method if surrender
131          *                      has already been offered by the computer
132          *                      players.  This needs to be kept track of
133          *                      because the computer players only offer
134          *                      surrender once.  The method will change this
135          *                      value from false to true if it decided that 
136          *                      the computer players collectively offer 
137          *                      surrender.
138          */
139         //! Callback method to process all players at the start of a round.
140         void nextRound(bool diplomacy, bool *surrender_already_offered);
141
142         /**
143          * The purpose of randomzing the Playerlist is to implement
144          * random turns.
145          * Note: This method does not set the active player.
146          */
147         //! Randomize the order of the players in the list.
148         void randomizeOrder();
149
150         /**
151          * This method takes care of giving a player it's diplomatic
152          * ranking among all other players.  The rank is determined by 
153          * adding up all of the diplomatic scores, and then sorting them.
154          * Each rank has a title.  There is always a Player who has the 
155          * title of `Statesman', and there is always a Player who has the 
156          * title of `Running Dog'.  The other titles disappear as the other 
157          * players die off.
158          */
159         //! Figure out who's winning diplomatically.
160         void calculateDiplomaticRankings();
161
162         //! Sync the playerlist.
163         /**
164          * Sync the playerlist with the list of players given.
165          */
166         void syncPlayers(std::vector<GameParameters::Player> players);
167
168         //! Sync the given player with the playerlist
169         void syncPlayer(GameParameters::Player player);
170
171         //! Converts all of the human players into network players.
172         void turnHumansIntoNetworkPlayers();
173
174         //! Converts a given number of the human players into a type of player.
175         void turnHumansInto(Player::Type type, int num_players = -1);
176
177         //! Reorder the list according to the given order.
178         void reorder(std::list<guint32> order);
179
180         //! Perform the surrender of all computer players.
181         void surrender();
182
183         //! Add a player to the list.  Use this instead of push_back.
184         void add(Player *player);
185
186
187         // Methods that operate on the class data but do not modify it.
188
189         /**
190          * Scan the list of players for a Player with a given name.
191          *
192          * @param name      The name of the Player to lookup.
193          *
194          * @return A pointer to the Player if it is found, or NULL if it isn't.
195          */
196         //! Lookup a Player by it's name.
197         Player* getPlayer(std::string name) const;
198
199         /**
200          * Scan the list of players for a Player with a given Id.
201          *
202          * @param id        The id of the Player to lookup.
203          *
204          * @return A pointer to the Player if it is found, or NULL if it isn't.
205          */
206         //! Lookup a Player by it's Id.
207         Player* getPlayer(guint32 id) const;
208
209         //! Returns the number of living players (neutral player excluded.)
210         guint32 getNoOfPlayers() const;
211
212         /** 
213          * Scan the list of players for the first Player that is alive.
214          * This method is used to determine the beginning of a round.
215          *
216          * @return A pointer to the first living Player.
217          */
218         //! Return the first living Player in the list.
219         Player* getFirstLiving() const;
220
221         //! Saves the playerlist to an opened saved-game file.
222         bool save(XML_Helper* helper) const;
223
224         //! Return the number of human players left alive in the list.
225         guint32 countHumanPlayersAlive() const;
226
227         //! Return the number of players left alive, not including neutral.
228         guint32 countPlayersAlive() const;
229
230
231         //! Return the list of activities that the given hero has accomplished.
232         std::list<History *>getHistoryForHeroId(guint32 id) const;
233
234         /** 
235           \brief Check to see if this is the end of the round or not.
236           */
237         bool isEndOfRound() const;
238
239
240         // Signals
241
242         /**
243          * @param player  The player who has died.
244          */
245         //! Emitted when a player has died.
246         sigc::signal<void, Player*> splayerDead;
247     
248         /**
249          * Emitted when the computer players collectively offer surrender to 
250          * a single remaining human player.
251          *
252          * @param player  The human player who is being surrendered to.
253          */
254         //! Emitted when a surrender is offered.
255         sigc::signal<void, Player*> ssurrender;
256     
257
258         // Static Methods
259
260         //! Gets the singleton instance or creates a new one.
261         static Playerlist* getInstance();
262
263         /**
264          * Load all Players in the Playerlist from a saved-game file.
265          *
266          * @param helper     The opened saved-game file to read from.
267          *
268          * @return The loaded Playerlist.
269          */
270         //! Loads the playerlist from a saved-game file.
271         static Playerlist* getInstance(XML_Helper* helper);
272
273         //! Explicitly deletes the singleton instance.
274         static void deleteInstance();
275
276         //! Returns the active player (the Player whose turn it is).
277         static Player* getActiveplayer() {return d_activeplayer;}
278
279         //! Returns the viewing player (the Player who is looking at maps).
280         static Player *getViewingplayer() {return viewingplayer;}
281
282
283         int countFightsThisTurn() const;
284         int countMovesThisTurn() const;
285     protected:
286
287         //! Default constructor.
288         Playerlist();
289
290         //! Loading constructor.
291         Playerlist(XML_Helper* helper);
292
293         //! Destructor.
294         ~Playerlist();
295         
296     private:
297         //! Callback for loading the playerlist from an opened saved-game file.
298         bool load(std::string, XML_Helper* helper);
299
300         //! Comparison function to assist in sorting the list of players.
301         static bool randomly(const Player *lhs, const Player *rhs);
302
303         //! Comparison function to assist in sorting the list of players.
304         static bool inGivenOrder(const Player *lhs, const Player *rhs);
305
306         //! Comparison function to assist in sorting the list of players.
307         static bool inOrderOfId(const Player *lhs, const Player *rhs);
308
309         //! Calculate new scores for all players.
310         void calculateWinners();
311
312         //! Calculate new diplomatic states for all players.
313         void negotiateDiplomacy();
314
315         // DATA
316
317         //! The pointer to the player whose turn it is in the list.
318         static Player* d_activeplayer;
319
320         //! The player that the smallmap and bigmap are being viewed as.
321         static Player *viewingplayer;
322
323         //! The pointer to the neutral player in the list.
324         Player* d_neutral;
325
326         typedef std::map<guint32, Player*> IdMap;
327         IdMap d_id;
328
329         //! A static pointer for the singleton instance.
330         static Playerlist* s_instance;
331         
332 };
333
334 #endif // PLAYERLIST_H