initial commit, lordsawar source, slightly modified
[lordsawar] / src / stacklist.h
1 // Copyright (C) 2000, 2001, 2002, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004, 2005 Andrea Paternesi
4 // Copyright (C) 2004 Andrea Paternesi
5 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
6 // Copyright (C) 2008 Ole Laursen
7 //
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 3 of the License, or
11 //  (at your option) any later version.
12 //
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 Library General Public License for more details.
17 //
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 
21 //  02110-1301, USA.
22
23 #ifndef STACKLIST_H
24 #define STACKLIST_H
25
26 #include <list>
27 #include <map>
28 #include <vector>
29 #include <string>
30 #include <sigc++/trackable.h>
31 #include <gtkmm.h>
32 #include "vector.h"
33 #include <sstream>
34 #include <sigc++/signal.h>
35
36 class City;
37 class Stack;
38 class XML_Helper;
39 class Player;
40 class Hero;
41
42 //! A list of Stack objects for a single player.
43 /** 
44  * All stacks owned by a Player are contained in a Stacklist.  This class
45  * covers the loading and saving of stack lists, and also some methods for
46  * getting and managing groups of stacks.
47  */
48
49 class Stacklist : public std::list<Stack*>, public sigc::trackable
50 {
51     public:
52
53         //! The xml tag of this object in a saved-game file.
54         static std::string d_tag; 
55
56         //! Default constructor.
57         Stacklist();
58
59         //! Copy constructor.
60         Stacklist(Stacklist *stacklist);
61
62         //! Loading constructor.
63         Stacklist(XML_Helper* helper);
64
65         //! Destructor.
66         ~Stacklist();
67
68         // Set Methods
69
70         //!Set the stack the player is currently working with.
71         /** 
72          * Sets the currently selected stack. The purpose of this method is 
73          * to designate a stack to be the one the player is currently touching.
74          * It is important to use this method because several functions
75          * expect that there is an active stack.
76          *
77          * @param activestack      The stack currently selected by the player.
78          */
79         void setActivestack(Stack* activestack);
80
81
82         // Get Methods
83
84         //! Returns the currently selected stack.
85         Stack* getActivestack() const {return d_activestack;}
86
87
88         // Methods that operate on class data and do not modify the class.
89
90         /** 
91          * This method finds stacks which occupy the same tile.
92          * For internal and logical reasons, we always assume that a tile is
93          * occupied by at most one stack as strange bugs may happen when this
94          * is violated. However, in some cases, it does happen that stacks
95          * temporarily occupy the same tile. Reasons may be that, on its
96          * route, a stack crosses another stacks tile and can't move further.
97          *
98          * We only expect one ambiguity at a time with stacks of the same 
99          * player. This never happens except when a stack comes to halt on 
100          * another stack during long movements.
101          *
102          * @param stack        The stack which we search an ambiguity for.
103          *
104          * @return The other stack on the same tile occupied by stack.
105          */
106         //! Get the other stack on a tile that has more than one stack on it.
107         static Stack* getAmbiguity(Stack* stack);
108
109         //! Returns the total number of armies in the list.
110         unsigned int countArmies() const;
111
112         //! Returns the total number of armies in the list that are awardable.
113         unsigned int countAllies() const;
114
115         /**
116          * Scan through the list of stacks to find one that is not defending, 
117          * and not parked, and can move to another tile.
118          *
119          * @return A pointer to the next moveable stack or NULL if no more
120          *         stacks can move.
121          */
122         //! Return the next moveable stack in the list.
123         Stack* getNextMovable() const;
124
125         /**
126          * @return True if any stacks in the list have enough moves for 
127          * it's next step along it's Path.  Otherwise, false.
128          */
129         //! Returns whether or not any stacks can move.
130         bool enoughMoves() const;
131
132         //! Save the data to an opened saved-game file.
133         bool save(XML_Helper* helper) const;
134
135         //! Find a stack in this stacklist given this id.
136         Stack *getStackById(guint32 id) const;
137
138         //! Find the stack in this stacklist that contains an army with this id.
139         Stack *getArmyStackById(guint32 army) const;
140
141         //! Collect gold pieces from army units in the list that give money.
142         /**
143          * Heroes in a stacklist can provide gold pieces by carrying items.
144          * These items are +3 gold per city, etc so the number of cities
145          * must be passed into this method.
146          *
147          * This method increases the given player's treasury.
148          */
149         void collectTaxes(Player *p, guint32 num_cities) const;
150
151         //! Return a list of the heroes in the stacklist.
152         std::list<Hero*> getHeroes() const;
153
154         //! Return a hero from this stacklist that is closest to the given pos.
155         /**
156          * The hero must be within a given distance, provided by the dist
157          * parameter.  The distance is measured in tiles (not movement points).
158          */
159         Hero *getNearestHero(Vector<int> pos, int dist) const;
160         
161
162         // Methods that operate on class data and modify the class.
163
164         //! remove all movement points from every army in every stack.
165         void drainAllMovement();
166
167         //! Callback method executed at the end of every turn.
168         void nextTurn();
169
170         //! Have everyone in this stacklist collect their upkeep from a player.
171         /**
172          * This method decreases the given player's treasury.
173          */
174         void payUpkeep(Player *p);
175
176         //! Erase all stacks from the list, and their contents too.
177         void flClear();
178
179         //! Add a stack to the list.
180         void add(Stack *stack);
181
182         /** 
183          * Erase a Stack from the list, and free the contents of the Stack.
184          *
185          * @param it   The place in the Stacklist to erase.
186          *
187          * @return The place in the list that was erased.
188          */
189         //! Erase a stack from the list.
190         iterator flErase(iterator object);
191
192         /** 
193          * Scan the list of stacks for a particular stack.  If it is found,
194          * remove it from the list of stacks and free it's contents.
195          *
196          * @param stack  The stack in the Stacklist to remove.
197          *
198          * @return Whether or not the stack was found and deleted.
199          */
200         //! Erase a stack from the list.
201         bool flRemove(Stack* stack);
202
203         //! Erase a stack from the list, given the stack id.
204         bool flRemove(guint32 id);
205
206
207         // Signals
208
209         //! The stack in the stacklist has been grouped or ungrouped.
210         sigc::signal<void, Stack*, bool> sgrouped;
211
212         //! The stack in the stacklist is arriving on a new tile.
213         sigc::signal<void, Stack*, Vector<int> > snewpos;
214
215         //! The stack in the stacklist is leaving an old tile.
216         sigc::signal<void, Stack*, Vector<int> > soldpos;
217
218
219         // Static Methods
220
221         //! Searches through the all players Stacklists and deletes the stack.
222         static bool deleteStack(Stack* stack);
223
224         //! Searches for the stack id in all lists, and deletes it.
225         static bool deleteStack(guint32 id);
226
227         /** 
228          * Scan each tile occupied by the given city and return a list of
229          * stacks who are in the city.
230          *
231          * When a city is attacked, all stacks which occupy a city tile are
232          * regarded as defenders.  The purpose of this function is to 
233          * enumerate the defending stacks when a stack has attacked a city.
234          *
235          * @param city        The city to search for stacks in.
236          *
237          * @return A list of all stacks defending the city.
238          */
239         //! Return a list of stacks defending a city.
240         static std::vector<Stack*> getDefendersInCity(const City* city);
241
242         //! Returns the total number of stacks owned by all players.
243         static unsigned int getNoOfStacks();
244
245         //! Returns the total number of armies owned by all players.
246         static unsigned int getNoOfArmies();
247
248         /**
249          * This method removes the given stack from it's owner's stacklist and
250          * places it in the new owner's stacklist.
251          */
252         //! Change allegience of the given stack to a new owner.
253         static void changeOwnership(Stack *stack, Player *new_owner);
254
255         //! Can this stack reach a point where it is not blocked by friendlies?
256         /**
257          * The idea here is that the stack is blocked by a friendly stack on
258          * it's path.  This method checks to see if the stack has enough 
259          * movement points to proceed through the friendly stacks (that are
260          * too big to join with), and land on a point in it's path beyond it.
261          */
262         static bool canJumpOverTooLargeStack(Stack *s);
263
264         //! Return position of an Army with the given id in this stacklist.
265         /**
266          * Scan through all stacks in the list, and then through each Army 
267          * unit of every Stack for an Army unit with a particular Id.
268          *
269          * @param id     The Id of the Army unit that we're looking for.
270          *
271          * @return The position of the Army unit.  If no Army unit could be
272          *         found with the given Id, the position of (-1,-1) is
273          *         returned.
274          */
275         static Vector<int> getPosition(guint32 id);
276
277
278         std::list<Vector<int> > getPositions() const;
279     private:
280
281         //! Callback for loading this object from an opened saved-game file.
282         bool load(std::string tag, XML_Helper* helper);
283
284         //! Callback for when a stack initiates movement after being stopped.
285         void on_stack_starts_moving (Stack *s);
286
287         //! Callback for when a stack halts.
288         void on_stack_stops_moving (Stack *s);
289
290         //! Callback for when a stack has been killed, or disbanded.
291         void on_stack_died (Stack *stack);
292
293         //! Callback for when a stack has been grouped or ungrouped.
294         void on_stack_grouped (Stack *stack, bool grouped);
295
296         void getHeroes(std::vector<guint32>& dst) const;
297
298         //! Notify the game map that a stack is leaving it's tile.
299         bool deletePositionFromMap(Stack *stack);
300
301         //! Notify the game map that a stack is arriving on a tile.
302         bool addPositionToMap(Stack *s);
303
304         // DATA
305
306         //! A pointer to the currently selected Stack.
307         Stack* d_activestack;
308
309         typedef std::map<Stack *, std::list<sigc::connection> > ConnectionMap;
310         // A set of signal connections for each stack in our list.
311         /**
312          * We can use this map to lookup the outstanding signals connections
313          * that a given stack has.  This is so that we can destroy them
314          * when the stack is deleted.
315          */
316         ConnectionMap d_connections;
317         
318         typedef std::map<guint32, Stack*> IdMap;
319         //! A map to quickly lookup the stack by it's unique id.
320         IdMap d_id;
321
322 };
323
324 #endif // STACKLIST_H
325
326 // End of file