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, 2014, 2015, 2017, 2020 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 #pragma once
22 #ifndef PLAYERLIST_H
23 #define PLAYERLIST_H
24 
25 #include <list>
26 #include <map>
27 #include <vector>
28 #include <sigc++/trackable.h>
29 #include <sigc++/signal.h>
30 #include "game-parameters.h"
31 
32 class History;
33 class Shieldset;
34 class Stack;
35 
36 #include "player.h"
37 
38 //! A list of all of the Player objects in a scenario.
39 /**
40  * The Playerlist is implemented as a singleton class. The currently
41  * active player is designated, you can access players by name or id and the
42  * playerlist can check if there are more than one player remaining alive.
43  * This class also holds methods that affect all players.
44  */
45 
46 class Playerlist : public std::list<Player*>, public sigc::trackable
47 {
48     public:
49 
50 	//! The xml tag of this object in a saved-game file.
51 	static Glib::ustring d_tag;
52 
53 	// Set Methods
54 
55 	//! Set the winning human player.
56 	void setWinningPlayer(Player *winner);
57 
58 	//! Set the player who's turn it is.  should only be used by the editor.
setActiveplayer(Player * p)59 	void setActiveplayer(Player *p) {d_activeplayer = p;};
60 
61 	//! set the player who is looking at the bigmap and smallmap.
62 	//void setViewingplayer(Player *p) {viewingplayer = p;};
63 
64 	//! Get Methods
65 
66         //! Returns the neutral player.
getNeutral()67         Player* getNeutral() const {return d_neutral;}
68 
69         //! The game is over and this is the winner.
70         Player *getWinningPlayer() const;
71 
72 
73 	// Methods that operate on the class data and modify the class.
74 
75         //! Sets the active player to the next player in the order.
76         void nextPlayer();
77 
78         /**
79 	 * Checks if a player is alive and has no cities left. If not then
80 	 * this method marks the player as killed.
81 	 *
82 	 * @param Returns whether or not any players were marked as dead.
83          */
84 	//! Kill any players that don't have cities left.
85         bool checkPlayers();
86 
87         /**
88 	 * Though the neutral player is located in the list of existing
89 	 * players, it is handled in a special way in many different cases.
90 	 *
91 	 * There can only be one neutral player per Playerlist.
92          *
93          * @param neutral          The new neutral player.
94          */
95 	//! Set the neutral player.
setNeutral(Player * neutral)96         void setNeutral(Player* neutral) {d_neutral = neutral;}
97 
98 	/**
99 	 * Swap out a player from the list and replace it with a new one.
100 	 * Specical care is taken to remove all references to the original
101 	 * player and replace it with a reference to the new player.
102 	 *
103 	 * The purpose of this method is to change a human player into a
104 	 * computer player and vice-versa.
105 	 *
106 	 * @param old_player   A pointer to the player to replace.
107 	 * @param new_player   A pointer to the new player to replace the
108 	 *                     original player.
109 	 */
110 	//! Replace a Player in the list with a new Player.
111 	void swap(Player *old_player, Player *new_player);
112 
113         /**
114 	 * Erase a Player from the list, and free the contents of the Player.
115 	 *
116 	 * @param it   The place in the Playerlist to erase.
117 	 *
118 	 * @return The place in the list that was erased.
119          */
120 	//! Erase a player from the list.
121         iterator flErase(iterator it);
122 
123 	/**
124 	 * This method is called when a round starts.
125 	 * The purpose of this method is to calculate who is winning, and
126 	 * it to negotiate diplomacy between players.  This method also
127 	 * implements the computer players collectively surrendering to a
128 	 * final human player.
129 	 *
130 	 * @param diplomacy     Whether or not we should negotiate diplomacy
131 	 *                      between players.
132 	 * @param surrender_already_offered Tells the method if surrender
133 	 *                      has already been offered by the computer
134 	 *                      players.  This needs to be kept track of
135 	 *                      because the computer players only offer
136 	 *                      surrender once.  The method will change this
137 	 *                      value from false to true if it decided that
138 	 *                      the computer players collectively offer
139 	 *                      surrender.
140 	 */
141 	//! Callback method to process all players at the start of a round.
142 	void nextRound(bool diplomacy, bool *surrender_already_offered);
143 
144 	/**
145 	 * The purpose of randomzing the Playerlist is to implement
146 	 * random turns.
147 	 * Note: This method does not set the active player.
148 	 */
149 	//! Randomize the order of the players in the list.
150 	void randomizeOrder();
151 
152 	/**
153 	 * This method takes care of giving a player it's diplomatic
154 	 * ranking among all other players.  The rank is determined by
155 	 * adding up all of the diplomatic scores, and then sorting them.
156 	 * Each rank has a title.  There is always a Player who has the
157 	 * title of `Statesman', and there is always a Player who has the
158 	 * title of `Running Dog'.  The other titles disappear as the other
159 	 * players die off.
160 	 */
161 	//! Figure out who's winning diplomatically.
162         void calculateDiplomaticRankings();
163 
164 	//! Sync the playerlist.
165 	/**
166 	 * Sync the playerlist with the list of players given.
167 	 */
168 	void syncPlayers(std::vector<GameParameters::Player> players);
169 
170 	//! Sync the given player with the playerlist
171 	void syncPlayer(GameParameters::Player player);
172 
173         //! Switch the neutral player to AI_DUMMY if it has any other type.
174         void syncNeutral();
175 
176 	//! Converts all of the human players into network players.
177 	guint32 turnHumansIntoNetworkPlayers();
178 
179 	//! Converts a given number of the human players into a type of player.
180 	guint32 turnHumansInto(Player::Type type, int num_players = -1);
181 
182 	//! Reorder the list according to the given order.
183 	void reorder(std::list<guint32> order);
184 
185 	//! Perform the surrender of all computer players.
186 	void surrender();
187 
188 	//! Add a player to the list.  Use this instead of push_back.
189 	void add(Player *player);
190 
191         //! Reassign player colours.
192         void setNewColours(Shieldset *shieldset);
193 
194         //! Remove all actions from every player's action list.
195         void clearAllActions();
196 
197 	// Methods that operate on the class data but do not modify it.
198 
199 	/**
200 	 * Scan the list of players for a Player with a given name.
201 	 *
202 	 * @param name      The name 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 name.
207         Player* getPlayer(Glib::ustring name) const;
208 
209 	/**
210 	 * Scan the list of players for a Player with a given Id.
211 	 *
212 	 * @param id        The id of the Player to lookup.
213 	 *
214 	 * @return A pointer to the Player if it is found, or NULL if it isn't.
215 	 */
216         //! Lookup a Player by it's Id.
217         Player* getPlayer(guint32 id) const;
218 
219         //! Returns the number of living players (neutral player excluded.)
220         guint32 getNoOfPlayers() const;
221 
222         /**
223 	 * Scan the list of players for the first Player that is alive.
224 	 * This method is used to determine the beginning of a round.
225 	 *
226 	 * @return A pointer to the first living Player.
227          */
228 	//! Return the first living Player in the list.
229         Player* getFirstLiving() const;
230 
231         //! Saves the playerlist to an opened saved-game file.
232         bool save(XML_Helper* helper) const;
233 
234 	//! Return the number of human players left alive in the list.
235 	guint32 countHumanPlayersAlive() const;
236 
237 	//! Return the number of players left alive, not including neutral.
238 	guint32 countPlayersAlive() const;
239 
240         //! Return the total number of stacks on the map.
241         guint32 countAllStacks () const;
242 
243         //! Return true if one non-neutral player doesn't have a capital city.
244         bool playerHasNoCapitalCity () const;
245 
246 	//! Return the list of activities that the given hero has accomplished.
247 	std::list<History *>getHistoryForHeroId(guint32 id) const;
248 
249         //! Return a stack belonging to any player with the given id.
250         Stack *getStackById(guint32 id) const;
251 
252 	/**
253 	  \brief Check to see if this is the end of the round or not.
254 	  */
255 	bool isEndOfRound() const;
256 
257         //! Return true if any of the players use the given armyset.
258         bool hasArmyset(guint32 id) const;
259 
260         //! Get which numeric sequence the player is in this round
261         guint32 getTurnOrderNumber(const Player *p);
262 	// Signals
263 
264 	/**
265 	 * @param player  The player who has died.
266 	 */
267         //! Emitted when a player has died.
268         sigc::signal<void, Player*> splayerDead;
269 
270 	/**
271 	 * Emitted when the computer players collectively offer surrender to
272 	 * a single remaining human player.
273 	 *
274 	 * @param player  The human player who is being surrendered to.
275 	 */
276         //! Emitted when a surrender is offered.
277         sigc::signal<void, Player*> ssurrender;
278 
279 
280 	// Static Methods
281 
282         //! Gets the singleton instance or creates a new one.
283         static Playerlist* getInstance();
284 
285 	/**
286 	 * Load all Players in the Playerlist from a saved-game file.
287 	 *
288 	 * @param helper     The opened saved-game file to read from.
289 	 *
290 	 * @return The loaded Playerlist.
291 	 */
292         //! Loads the playerlist from a saved-game file.
293         static Playerlist* getInstance(XML_Helper* helper);
294 
295         //! Explicitly deletes the singleton instance.
296         static void deleteInstance();
297 
298         //! Returns the active player (the Player whose turn it is).
getActiveplayer()299         static Player* getActiveplayer() {return d_activeplayer;}
300 
301         //! Returns the viewing player (the Player who is looking at maps).
getViewingplayer()302 	static Player *getViewingplayer() {return viewingplayer;}
303 
304     protected:
305 
306 	//! Default constructor.
307         Playerlist();
308 
309 	//! Loading constructor.
310         Playerlist(XML_Helper* helper);
311 
312 	//! Destructor.
313         ~Playerlist();
314 
315     private:
316         //! Callback for loading the playerlist from an opened saved-game file.
317         bool load(Glib::ustring, XML_Helper* helper);
318 
319 	//! Comparison function to assist in sorting the list of players.
320 	static bool randomly(const Player *lhs, const Player *rhs);
321 
322 	//! Comparison function to assist in sorting the list of players.
323 	static bool inGivenOrder(const Player *lhs, const Player *rhs);
324 
325 	//! Comparison function to assist in sorting the list of players.
326 	static bool inOrderOfId(const Player *lhs, const Player *rhs);
327 
328 	//! Calculate new scores for all players.
329         void calculateWinners();
330 
331 	//! Calculate new diplomatic states for all players.
332 	void negotiateDiplomacy();
333 
334         void updateViewingPlayer ();
335 
336         Glib::ustring get_title(int rank);
337         // DATA
338 
339 	//! The pointer to the player whose turn it is in the list.
340         static Player* d_activeplayer;
341 
342 	//! The player that the smallmap and bigmap are being viewed as.
343 	static Player *viewingplayer;
344 
345 	//! The pointer to the neutral player in the list.
346         Player* d_neutral;
347 
348 	typedef std::map<guint32, Player*> IdMap;
349 	IdMap d_id;
350 
351         //! A static pointer for the singleton instance.
352         static Playerlist* s_instance;
353 
354 };
355 
356 //! A helper struct in Playerlist to help with sorting Player objects by score.
357 struct rankable_t
358 {
359   guint32 score;
360   Player *player;
361 };
362 
363 bool compareDiplomaticScores (const struct rankable_t lhs, const struct rankable_t rhs);
364 #endif // PLAYERLIST_H
365