initial commit, lordsawar source, slightly modified
[lordsawar] / src / stack.h
1 // Copyright (C) 2000, 2001, 2003 Michael Bartl
2 // Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 Ulf Lorenz
3 // Copyright (C) 2004, 2005, 2006 Andrea Paternesi
4 // Copyright (C) 2007, 2008, 2009 Ben Asselstine
5 // Copyright (C) 2007, 2008 Ole Laursen
6 //
7 //  This program is free software; you can redistribute it and/or modify
8 //  it under the terms of the GNU General Public License as published by
9 //  the Free Software Foundation; either version 3 of the License, or
10 //  (at your option) any later version.
11 //
12 //  This program is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 //  GNU Library General Public License for more details.
16 //
17 //  You should have received a copy of the GNU General Public License
18 //  along with this program; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
20 //  02110-1301, USA.
21
22 #ifndef STACK_H
23 #define STACK_H
24
25 #include <list>
26 #include <vector>
27 #include "vector.h"
28 #include <sigc++/trackable.h>
29 #include <sigc++/signal.h>
30 #include <sstream>
31
32 #include "UniquelyIdentified.h"
33 #include "Ownable.h"
34 #include "Movable.h"
35
36 class Player;
37 class Path;
38 class Army;
39 class ArmyProdBase;
40 class XML_Helper;
41 class Temple;
42 class Hero;
43
44 //! A set of up to eight Army units that move as a single entity on the map.
45 /** 
46  * While Army units are the actual troops you command, they always belong to a
47  * stack. The stack holds these armies together in one object. The player
48  * usually doesn't command the armies but the stack, so all functionality and
49  * data which affects player's controls is bundled in the stack class. Among
50  * this is the location of the units, the intended movement path, and more.
51  */
52
53 class Stack : public ::UniquelyIdentified, public Movable, public Ownable, public std::list<Army*>, public sigc::trackable
54 {
55     public:
56         //! The xml tag of this object in a saved-game file.
57         static std::string d_tag; 
58
59         /** 
60          * Make a new stack.
61          * 
62          * @param player       A pointer to the owning player.
63          * @param pos          The position on the map where the stack is to 
64          *                     be created.
65          */
66         //! Default constructor.
67         Stack(Player* player, Vector<int> pos);
68
69         /**
70          * Copy the whole stack into a new stack.  This method performs a 
71          * deep copy of the stack's Army units.
72          */
73         //! Copy constructor.
74         Stack(const Stack& s);
75
76         //! Loading constructor.
77         Stack(XML_Helper* helper);
78
79         //! Destructor.
80         ~Stack();
81
82         // Get Methods
83
84         //! Returns the minimum number of movement points of all Army units.
85         guint32 getMoves() const;
86
87         //! Returns the maximum MP the stack would have if it were on land
88         guint32 getMaxLandMoves() const;
89
90         //! Returns the max MP the stack would have if it were in the water
91         guint32 getMaxBoatMoves() const;
92
93         //! Returns the Path object of the stack.
94         Path* getPath() const {return d_path;}
95
96         //! Return true if any of the Army units in the stack are fortified.
97         bool getFortified() const;
98         
99         //! Calculate the number of gold pieces this stack costs this turn.
100         guint32 getUpkeep() const;
101
102         //! How many army units can be put into this stack?
103         guint32 getMaxArmiesToJoin() const;
104
105         guint32 countAllies() const;
106
107         // Set Methods
108
109         //! Change the loyalty of the stack.
110         void setPlayer(Player* p);
111
112         /** 
113          * Sets the defending value.  Defending entails that this stack is 
114          * ignored when a user cycles through the list of stacks with 
115          * Stacklist::getNextMovable().  If a stack stays defending to the
116          * next round, it gets a fortify bonus in battle.
117          */
118         //! Set the defending status of the stack.
119         void setDefending(bool defending){d_defending = defending;}
120
121         /** 
122          * Sets the parked value. Parking entails that this stack is ignored
123          * when a player cycles through his list of stacks with 
124          * Stacklist::getNextMovable().  This value behaves just like 
125          * defending, but there's no bonus conferred if a stack remains in 
126          * this state.
127          */
128         //! Set the parked status of the stack.
129         void setParked(bool parked){d_parked = parked;}
130
131         //! Sets the path object for this stack.
132         void setPath(const Path p);
133
134         //! Set all Army units in the stack to have this fortified state.
135         void setFortified(bool fortified);
136
137
138
139         // Methods that operate on class data and modify the class
140         
141         /**
142          * When the end of a turn occurs, this callback is used to calculate
143          * stack bonuses, moves, paths, and it also charges the player the
144          * upkeep fee for every Army unit in the Stack.
145          */
146         //! Callback when the end of a turn happens.
147         void nextTurn();
148
149         //! Reduces movement points of the Army units in the Stack.
150         void decrementMoves(guint32 moves);
151
152         //! Sets the stack's position to the next point in it's Path.
153         void moveOneStep(bool skipping = false);
154
155         void moveToDest(Vector<int> dest, bool skipping = false);
156
157         /**
158          * Adds one to the strength of each Army unit in the stack.
159          * If the Army unit has already visited the temple co-located with
160          * the stack's position, no strength bonus will be added.
161          *
162          * @return The number of Army units blessed.
163          */
164         //! Bless the Army units in the stack.
165         int bless();
166
167         //! Uncovers some of the hidden map around this stack.
168         void deFog();
169
170         //! Erase the stack, deleting the Army units too.
171         void flClear();
172
173         /** 
174          * Erase an Army unit from the Stack, and free the contents of 
175          * the Army unit too (e.g. Items a Hero might be carrying).
176          *
177          * @param it   The place in the Stack to erase.
178          *
179          * @return The place in the stack that was erased.
180          */
181         //! Erase an Army unit from the list.
182         iterator flErase(iterator object);
183
184         /**
185          * Alter the order of the Army units in the stack according to each
186          * unit's groupedness, and fight order.
187          *
188          * The purpose of this sorting is to show the units in the stack
189          * info window.
190          *
191          * @param reverse     Invert the sort.
192          */
193         //! Sort the Army units in the stack.
194         void sortForViewing(bool reverse);
195
196         void sortByStrength(bool reverse);
197
198         //! Have the stack collect it's upkeep from a given player (owner).
199         void payUpkeep(Player *p);
200
201         //! Merge the given stack with this stack.
202         void join(Stack *join);
203
204         //! Return a new stack that holds the given armies from this stack.
205         Stack *splitArmies(std::list<Army*> armies);
206
207         //! Return a new stack that holds the given armies from this stack.
208         Stack *splitArmies(std::list<guint32> armies);
209
210         // Return a new stack holds the given army from this stack.
211         Stack *splitArmy(Army *army);
212
213         //! Return a new stack that holds armies that have some mp.
214         Stack *splitArmiesWithMovement(guint32 mp = 1);
215
216         //! Add an army to this stack.
217         /**
218          * This method should be used instead of push_back.
219          */
220         void add(Army *army);
221
222         //! Remove this stack's path.  Return true if anything was cleared.
223         bool clearPath();
224
225         // Methods that operate on class and do not modify the class
226
227         //! Returns true if the stack has any points in it's path.
228         bool hasPath() const;
229
230         //! Is there at least one hero in this stack who has a quest?
231         bool hasQuest() const;
232
233         //! Does the stack contain this kind of army?
234         bool hasArmyType(guint32 army_type) const;
235
236         //! Save the stack to an opened saved-game file.
237         bool save(XML_Helper* helper) const;
238
239         /**
240          * @return True if the stack has enough moves to traverse to
241          * the next step in it's Path.  Otherwise, false.
242          */
243         //! Returns whether or not the stack can move.
244         bool enoughMoves() const;
245
246         /**
247          * @return Whether or not the stack has enough moves to travel to
248          *         an adjacent tile.  The adjacent tile does not have to be
249          *         in the stack's Path.
250          */
251         //! Returns whether the stack can move in any direction.
252         bool canMove() const;
253         
254         /**
255          * Scan all adjacent tiles relative to the stack's position and 
256          * see how much a move would cost in terms of movement points.
257          * Determine the minimum amount of movement points to make a move.
258          * 
259          * @return The minimum number of movement points to travel to the
260          *         cheapest adjacent tile that the stack can afford to
261          *         move to.  If the stack cannot afford to move there, this
262          *         method returns -1.
263          */
264         int getMinTileMoves() const;
265
266         //! Return the Army unit in the Stack that has the best strength value.
267         Army* getStrongestArmy() const;
268
269         //! Return the Hero unit in the Stack that has the best strength value.
270         Army* getStrongestHero() const;
271
272         //! Go find the army with this identifier in the stack and return it.
273         Army* getArmyById(guint32 id) const;
274         
275         //! True if the stack contains a Hero unit.  Otherwise, false.
276         bool hasHero() const;
277
278         //! Return the first Hero unit in the stack, or NULL if no Hero found.
279         Army* getFirstHero() const;
280
281         //! Return the first hero unit in the stack that is on a quest.
282         Hero *getFirstHeroWithAQuest() const;
283
284         //! Return the first hero unit in the stack that isn't questing.
285         Hero *getFirstHeroWithoutAQuest() const;
286
287         //! Returns the ids of all (living) heroes in the stack in the dst reference
288         /**
289          * Scan the Army units in the Stack for heroes that have more than
290          * zero hitpoints.
291          *
292          * @param dst       Passed in as an empty or non-empty list, and
293          *                  filled up with the Ids belonging to Hero army 
294          *                  units in the stack.
295          */
296         // Return the Ids of all of the Hero units in the Stack.
297         void getHeroes(std::vector<guint32>& dst) const;
298
299         //! Return the defending status of the stack.
300         bool getDefending() const {return d_defending;}
301
302         //! Return the parked status of the stack.
303         bool getParked() const {return d_parked;}
304
305         //! Returns whether the stack is being deleted.
306         bool getDeleting() const {return d_deleting;}
307
308         //! Return the maximum sight of the stack.
309         guint32 getMaxSight() const;
310
311        /** 
312         * Determine which terrain kinds (Tile::Type) the Stack can travel 
313         * efficiently on.  When one Army unit is good at traveling through 
314         * the forest, and another in the same stack is good at traveling 
315         * through the hills, the movement capabilities of each individual 
316         * army is given to the other Army units in the Stack.  This means 
317         * the whole stack can move well through hills and forest.
318         * Traveling efficently on a tile means it takes 2 movement points
319         * to traverse.
320         *
321         * The calculation also takes into account a movement-changing Item
322         * that the Hero may be carrying (e.g. `Wings of Flying', or 
323         * `Swamp Boots').
324         *
325         * This calculation also lets Hero units `ride' flying Army units;
326         * meaning that the Hero doesn't have the ability to fly, but it
327         * has the special ability to ride on the back of another flying
328         * Army unit.
329         *
330         * @return A bitwise OR-ing of the values in Tile::Type.
331         */
332         //! Calculate the move bonus for the Stack.
333         guint32 calculateMoveBonus() const;
334
335         //! Calculate if the Stack has the gift of flight.
336         bool isFlying () const;
337
338         //! Calculate if the Stack is in a boat.
339         bool hasShip () const;
340
341         /**
342          * Calculate the number of movement points it costs for the Stack
343          * to move to an adjacent tile.
344          *
345          * @note This is not a distance calculation.
346          *
347          * @param pos    The adjacent tile to calculate the movement points for.
348          *
349          * @return The number of movement points, or -1 if moving to the
350          *         adjacent tile is impossible.
351          */
352         //! Return the movement points it costs to travel to an adjacent tile.
353         guint32 calculateTileMovementCost(Vector<int> pos) const;
354
355         //! Returns true if this stack can join the given stack.
356         /**
357          * @note This is not a distance calculation.  It checks to see if
358          * the stack sizes are such that the amalgamated stack would be less
359          * than 8.
360          */
361         bool canJoin(const Stack *stack) const;
362
363         //! Return a list of army Ids in the stack that can reach the given 
364         //! destination.
365         std::list<guint32> determineReachableArmies(Vector<int> dest) const;
366
367         //! Return a list of army ids whose strength totals strength.
368         std::list<guint32> determineWeakArmies(float strength) const;
369         std::list<guint32> determineStrongArmies(float strength) const;
370
371         //! Returns how many armies in the stack have visited the given temple.
372         guint32 countArmiesBlessedAtTemple(guint32 temple_id) const;
373
374         //!If this stack were at the given pos, would it move in/out of a ship?
375         /**
376          * The on_ship paramater holds whether or not the stack is in a ship
377          * at the given position.  This is an out-parameter so that we can
378          * subsequently call this method for a series of points on a path.
379          */
380         bool isMovingToOrFromAShip(Vector<int> dest, bool &on_ship) const;
381
382         //! Get the starting point in the stack's intended path.
383         /**
384          * Returns a position of -1,-1 if there isn't a path.
385          */
386         Vector<int> getFirstPointInPath() const;
387
388         //! Get the final point in the stack's intended path.
389         /**
390          * Returns a position of -1,-1 if there isn't a path.
391          */
392         Vector<int> getLastPointInPath() const;
393
394         //! Gets the final point in the stack's path that we have mp to reach.
395         /**
396          *
397          * This method checks how many movement points the stack currently 
398          * has, and calculates how far along it's intended path it can go.
399          *
400          * Returns the final reachable spot in the path, or returns a 
401          * position of -1,-1 if there isn't a path, or none are reachable.
402          */
403         Vector<int> getLastReachablePointInPath() const;
404
405         //! Does everything in this stack look okay?
406         bool validate() const;
407
408         //! Does this stack have 8 units in it?
409         bool isFull() const;
410
411         // Signals
412
413         //! Emitted when this stack dies.
414         sigc::signal<void, Stack*> sdying;
415
416         //! Emitted when this stack is about to move one step
417         sigc::signal<void, Stack*> smoving;
418
419         //! Emitted when this stack has finished moving that one step
420         sigc::signal<void, Stack*> smoved;
421
422         //! Emitted when this stack is grouped or ungrouped
423         sigc::signal<void, Stack*, bool> sgrouped;
424
425
426         // Static Methods
427         
428         /**
429          * This comparator function compares the fight order of two Army units.
430          *
431          * @param left    An army that we want to sort by fight order.
432          * @param right   An army that we want to sort by fight order.
433          *
434          * @return True if the fight order of the left army is more than
435          *         the fight order of the right army.
436          */
437         //! Comparator function to assist in sorting the armies in the stack.
438         static bool armyCompareFightOrder (const Army *left, const Army *right);
439         static bool armyCompareStrength (const Army *left, const Army *right);
440
441         //! Create a stack with an id that isn't unique.
442         static Stack* createNonUniqueStack(Player *player, Vector<int> pos);
443
444         bool isOnCity() const;
445     private:    
446
447         std::list<guint32> determineArmiesByStrength(bool strongest, float strength) const;
448
449         //! Private constructor.
450         Stack(guint32 id, Player* player, Vector<int> pos);
451
452         //! Callback for loading the object from an opened saved-game file.
453         bool load(std::string tag, XML_Helper* helper);
454     
455         //! Helper method for returning strongest army.
456         Army* getStrongestArmy(bool hero) const;
457
458         // DATA
459
460         //! The stack's intended path.
461         Path* d_path;
462
463         //! Whether or not the stack is defending.
464         bool d_defending;
465
466         //! Whether or not the stack is parked.
467         bool d_parked;
468         
469         /**
470          * True if the stack is currently being deleted. This is neccessary as
471          * some things may happen in the destructor of the contained armies and
472          * we don't want bigmap to draw the stack when it is being removed.
473          */
474         //! Whether or not this stack is in the midst of being deleted.
475         bool d_deleting;
476 };
477
478 #endif // STACK_H
479
480 // End of file