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, 2011, 2014, 2015 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 #pragma once
23 #ifndef STACK_H
24 #define STACK_H
25 
26 #include <list>
27 #include <vector>
28 #include "vector.h"
29 #include <sigc++/trackable.h>
30 #include <sigc++/signal.h>
31 #include <sstream>
32 
33 #include "UniquelyIdentified.h"
34 #include "Ownable.h"
35 #include "Movable.h"
36 
37 class Player;
38 class Path;
39 class Army;
40 class XML_Helper;
41 class Hero;
42 class Item;
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 Glib::ustring 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, bool unique = false);
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 maximum number of movements points for this stack.
94         guint32 getMaxMoves() const;
95 
96         //! Returns the Path object of the stack.
getPath()97         Path* getPath() const {return d_path;}
98 
99 	//! Return true if any of the Army units in the stack are fortified.
100 	bool getFortified() const;
101 
102 	//! Calculate the number of gold pieces this stack costs this turn.
103 	guint32 getUpkeep() const;
104 
105         //! How many army units can be put into this stack?
106         guint32 getMaxArmiesToJoin() const;
107 
108         bool hasDeadArmies() const;
109 
110 	// Set Methods
111 
112         //! Change the loyalty of the stack.
113         void setPlayer(Player* p);
114 
115         /**
116 	 * Sets the defending value.  Defending entails that this stack is
117 	 * ignored when a user cycles through the list of stacks with
118 	 * Stacklist::getNextMovable().  If a stack stays defending to the
119 	 * next round, it gets a fortify bonus in battle.
120 	 */
121 	//! Set the defending status of the stack.
setDefending(bool defending)122         void setDefending(bool defending){d_defending = defending;}
123 
124         /**
125 	 * Sets the parked value. Parking entails that this stack is ignored
126          * when a player cycles through his list of stacks with
127 	 * Stacklist::getNextMovable().  This value behaves just like
128 	 * defending, but there's no bonus conferred if a stack remains in
129 	 * this state.
130          */
131 	//! Set the parked status of the stack.
setParked(bool parked)132         void setParked(bool parked){d_parked = parked;}
133 
134 	//! Sets the path object for this stack.
135 	void setPath(const Path p);
136 
137 	//! Set all Army units in the stack to have this fortified state.
138 	void setFortified(bool fortified);
139 
140 
141 
142 	// Methods that operate on class data and modify the class
143 
144 	/**
145 	 * This method is used to calculate stack bonuses, moves, paths, and
146          * hp for every army in the stack.
147 	 */
148         //!Recharge all of the armies in this stack with movement points and hp.
149         void reset(bool recalculate_path = true);
150 
151         //! Reduces movement points of the Army units in the Stack.
152         void decrementMoves(guint32 moves);
153 
154         //! Increases movement points of the Army units in the Stack.
155         void incrementMoves(guint32 moves);
156 
157         //! Removes all movement from all Army units in the stack.
158         void drainMovement();
159 
160         //! Sets the stack's position to the next point in it's Path.
161         void moveOneStep(bool skipping = false);
162 
163         void moveToDest(Vector<int> dest, bool skipping = false);
164 
165 	/**
166 	 * Adds one to the strength of each Army unit in the stack.
167 	 * If the Army unit has already visited the temple co-located with
168 	 * the stack's position, no strength bonus will be added.
169 	 *
170 	 * @return The number of Army units blessed.
171 	 */
172 	//! Bless the Army units in the stack.
173         int bless();
174 
175 	//! Uncovers some of the hidden map around this stack.
176 	void deFog();
177 
178         //! Erase the stack, deleting the Army units too.
179         void flClear();
180 
181         /**
182 	 * Erase an Army unit from the Stack, and free the contents of
183 	 * the Army unit too (e.g. Items a Hero might be carrying).
184 	 *
185 	 * @param it   The place in the Stack to erase.
186 	 *
187 	 * @return The place in the stack that was erased.
188          */
189 	//! Erase an Army unit from the list.
190         iterator flErase(iterator object);
191 
192 	/**
193 	 * Alter the order of the Army units in the stack according to each
194 	 * unit's groupedness, and fight order.
195 	 *
196 	 * The purpose of this sorting is to show the units in the stack
197 	 * info window.
198 	 *
199 	 * @param reverse     Invert the sort.
200 	 */
201 	//! Sort the Army units in the stack.
202 	void sortForViewing(bool reverse);
203 
204         void sortByStrength(bool reverse);
205 
206 	//! Have the stack collect it's upkeep from a given player (owner).
207 	void payUpkeep(Player *p);
208 
209 	//! Merge the given stack with this stack.
210 	void join(Stack *join);
211 
212 	//! Return a new stack that holds the given armies from this stack.
213 	Stack *splitArmies(std::list<Army*> armies);
214 
215 	//! Return a new stack that holds the given armies from this stack.
216 	Stack *splitArmies(std::list<guint32> armies);
217 
218 	// Return a new stack holds the given army from this stack.
219 	Stack *splitArmy(Army *army);
220 
221 	//! Return a new stack that holds armies that have some mp.
222 	Stack *splitArmiesWithMovement(guint32 mp = 1);
223 
224         //! Drown the non-flying units over water.  sets hitpoints to zero.
225         bool killArmyUnitsInBoats();
226 
227         //! Kill the armies of a given type.  sets hitpoints to zero.
228         bool killArmies(guint32 army_type);
229 
230         //! Sets the hitpoints of all army units in the stack to zero.
231         void kill();
232 
233 
234 	//! Add an army to this stack.
235 	/**
236 	 * This method should be used instead of push_back.
237 	 */
238 	void add(Army *army);
239 
240 	//! Remove this stack's path.  Return true if anything was cleared.
241 	bool clearPath();
242 
243         //! Sort the armies in this stack in the order shown by ids.
244         void sortByIds(std::list<guint32> ids);
245 
246         //! Puts the stack into or out of a ship, depending on the tile at dest.
247         /*
248          * If the destination tile is water tile, and it doesn't have a bridge
249          * on it, then put the army units of this stack in a ship.
250          * Otherwise they're on land.
251          * This method must not be called on stacks that are flying.
252          */
253         void updateShipStatus(Vector<int> dest);
254 
255         bool removeArmiesWithoutArmyType(guint32 armyset_id);
256 
257 	// Methods that operate on class and do not modify the class
258 
259         //! Returns true if the stack has any points in it's path.
260         bool hasPath() const;
261 
262         //! Is there at least one hero in this stack who has a quest?
263         bool hasQuest() const;
264 
265         //! Does the stack contain this kind of army?
266         bool hasArmyType(guint32 army_type) const;
267 
268         //! Save the stack to an opened saved-game file.
269         bool save(XML_Helper* helper) const;
270 
271 	/**
272          * @return True if the stack has enough moves to traverse to
273 	 * the next step in it's Path.  Otherwise, false.
274 	 */
275 	//! Returns whether or not the stack can move.
276         bool enoughMoves() const;
277 
278 	/**
279 	 * @return Whether or not the stack has enough moves to travel to
280 	 *         an adjacent tile.  The adjacent tile does not have to be
281 	 *         in the stack's Path.
282 	 */
283 	//! Returns whether the stack can move in any direction.
284 	bool canMove() const;
285 
286 	/**
287 	 * Scan all adjacent tiles relative to the stack's position and
288 	 * see how much a move would cost in terms of movement points.
289 	 * Determine the minimum amount of movement points to make a move.
290 	 *
291 	 * @return The minimum number of movement points to travel to the
292 	 *         cheapest adjacent tile that the stack can afford to
293 	 *         move to.  If the stack cannot afford to move there, this
294 	 *         method returns -1.
295 	 */
296         int getMinTileMoves() const;
297 
298         //! Return the Army unit in the Stack that has the best strength value.
299         Army* getStrongestArmy() const;
300 
301         //! Return the Hero unit in the Stack that has the best strength value.
302         Army* getStrongestHero() const;
303 
304 	//! Go find the army with this identifier in the stack and return it.
305         Army* getArmyById(guint32 id) const;
306 
307         //! True if the stack contains a Hero unit.  Otherwise, false.
308         bool hasHero() const;
309 
310         //! Return the first Hero unit in the stack, or NULL if no Hero found.
311         Army* getFirstHero() const;
312 
313         //! Return the first hero unit in the stack that is on a quest.
314         Hero *getFirstHeroWithAQuest() const;
315 
316         //! Return the first hero unit in the stack that isn't questing.
317         Hero *getFirstHeroWithoutAQuest() const;
318 
319         //! Returns the ids of all (living) heroes in the stack in the dst reference
320 	/**
321 	 * Scan the Army units in the Stack for heroes that have more than
322 	 * zero hitpoints.
323 	 *
324 	 * @param dst       Passed in as an empty or non-empty list, and
325 	 *                  filled up with the Ids belonging to Hero army
326 	 *                  units in the stack.
327 	 */
328 	// Return the Ids of all of the Hero units in the Stack.
329         void getHeroes(std::vector<guint32>& dst) const;
330 
331         //! Return the defending status of the stack.
getDefending()332         bool getDefending() const {return d_defending;}
333 
334         //! Return the parked status of the stack.
getParked()335         bool getParked() const {return d_parked;}
336 
337         //! Returns whether the stack is being deleted.
getDeleting()338         bool getDeleting() const {return d_deleting;}
339 
340         //! Return the maximum sight of the stack.
341         guint32 getMaxSight() const;
342 
343        /**
344 	* Determine which terrain kinds (Tile::Type) the Stack can travel
345 	* efficiently on.  When one Army unit is good at traveling through
346 	* the forest, and another in the same stack is good at traveling
347 	* through the hills, the movement capabilities of each individual
348 	* army is given to the other Army units in the Stack.  This means
349 	* the whole stack can move well through hills and forest.
350 	* Traveling efficently on a tile means it takes 2 movement points
351 	* to traverse.
352 	*
353 	* The calculation also takes into account a movement-changing Item
354 	* that the Hero may be carrying (e.g. `Wings of Flying', or
355 	* `Swamp Boots').
356 	*
357 	* This calculation also lets Hero units `ride' flying Army units;
358 	* meaning that the Hero doesn't have the ability to fly, but it
359 	* has the special ability to ride on the back of another flying
360 	* Army unit.
361 	*
362 	* @return A bitwise OR-ing of the values in Tile::Type.
363         */
364 	//! Calculate the move bonus for the Stack.
365         guint32 calculateMoveBonus() const;
366 
367 	//! Calculate if the Stack has the gift of flight.
368         bool isFlying () const;
369 
370         //! Check if splitting a stack would strand army units.
371         bool fliesWithItemAndNonFlyersOverWaterOrMountains() const;
372 
373 	//! Calculate if the Stack is in a boat.
374         bool hasShip () const;
375 
376         //! Check to see if the stack has any items that can be used.
377         bool hasUsableItem() const;
378 
379         void getUsableItems(std::list<Item*> &items) const;
380 	/**
381 	 * Calculate the number of movement points it costs for the Stack
382 	 * to move to an adjacent tile.
383 	 *
384 	 * @note This is not a distance calculation.
385 	 *
386 	 * @param pos    The adjacent tile to calculate the movement points for.
387 	 *
388 	 * @return The number of movement points, or -1 if moving to the
389 	 *         adjacent tile is impossible.
390 	 */
391 	//! Return the movement points it costs to travel to an adjacent tile.
392 	guint32 calculateTileMovementCost(Vector<int> pos) const;
393 
394 	//! Returns true if this stack can join the given stack.
395 	/**
396 	 * @note This is not a distance calculation.  It checks to see if
397 	 * the stack sizes are such that the amalgamated stack would be less
398 	 * than 8.
399 	 */
400 	bool canJoin(const Stack *stack) const;
401 
402 	//! Return a list of army Ids in the stack that can reach the given
403 	//! destination.
404 	std::list<guint32> determineReachableArmies(Vector<int> dest) const;
405 
406         //! Return a list of army ids whose strength totals strength.
407         std::list<guint32> determineWeakArmies(float strength) const;
408         std::list<guint32> determineStrongArmies(float strength) const;
409 
410 	//! Returns how many armies in the stack have visited the given temple.
411 	guint32 countArmiesBlessedAtTemple(guint32 temple_id) const;
412 
413         //! Returns how many items this stack has.
414         guint32 countItems() const;
415 
416 	//!If this stack were at the given pos, would it move in/out of a ship?
417 	/**
418 	 * The on_ship paramater holds whether or not the stack is in a ship
419 	 * at the given position.  This is an out-parameter so that we can
420 	 * subsequently call this method for a series of points on a path.
421 	 */
422 	bool isMovingToOrFromAShip(Vector<int> dest, bool &on_ship) const;
423 
424 	//! Get the starting point in the stack's intended path.
425 	/**
426 	 * Returns a position of -1,-1 if there isn't a path.
427 	 */
428 	Vector<int> getFirstPointInPath() const;
429 
430 	//! Get the final point in the stack's intended path.
431 	/**
432 	 * Returns a position of -1,-1 if there isn't a path.
433 	 */
434 	Vector<int> getLastPointInPath() const;
435 
436 	//! Gets the final point in the stack's path that we have mp to reach.
437 	/**
438 	 *
439 	 * This method checks how many movement points the stack currently
440 	 * has, and calculates how far along it's intended path it can go.
441 	 *
442 	 * Returns the final reachable spot in the path, or returns a
443 	 * position of -1,-1 if there isn't a path, or none are reachable.
444 	 */
445 	Vector<int> getLastReachablePointInPath() const;
446 
447 	//! Does everything in this stack look okay?
448 	bool validate() const;
449 
450 	//! Does this stack have 8 units in it?
451 	bool isFull() const;
452 
453         //! Return the hero that owns this given item.
454         Hero* getHeroWithItem(Item *item) const;
455 
456 	// Signals
457 
458 	//! Emitted when this stack dies.
459         sigc::signal<void, Stack*> sdying;
460 
461 	//! Emitted when this stack is about to move one step
462 	sigc::signal<void, Stack*> smoving;
463 
464 	//! Emitted when this stack has finished moving that one step
465 	sigc::signal<void, Stack*> smoved;
466 
467 	//! Emitted when this stack is grouped or ungrouped
468 	sigc::signal<void, Stack*, bool> sgrouped;
469 
470 
471 	// Static Methods
472 
473 	/**
474 	 * This comparator function compares the fight order of two Army units.
475 	 *
476 	 * @param left    An army that we want to sort by fight order.
477 	 * @param right   An army that we want to sort by fight order.
478 	 *
479 	 * @return True if the fight order of the left army is more than
480 	 *         the fight order of the right army.
481 	 */
482 	//! Comparator function to assist in sorting the armies in the stack.
483 	static bool armyCompareFightOrder (const Army *left, const Army *right);
484 	static bool armyCompareStrength (const Army *left, const Army *right);
485 
486 	//! Create a stack with an id that isn't unique.
487 	static Stack* createNonUniqueStack(Player *player, Vector<int> pos);
488 
489         bool isOnCity() const;
490     private:
491 
492         std::list<guint32> determineArmiesByStrength(float strength) const;
493 
494 static bool compareIds(const Army *lhs, const Army *rhs);
495 	//! Private constructor.
496 	Stack(guint32 id, Player* player, Vector<int> pos);
497 
498         //! Callback for loading the object from an opened saved-game file.
499         bool load(Glib::ustring tag, XML_Helper* helper);
500 
501 	//! Helper method for returning strongest army.
502 	Army* getStrongestArmy(bool hero) const;
503 
504         // DATA
505 
506 	//! The stack's intended path.
507         Path* d_path;
508 
509 	//! Whether or not the stack is defending.
510         bool d_defending;
511 
512 	//! Whether or not the stack is parked.
513         bool d_parked;
514 
515 	/**
516 	 * True if the stack is currently being deleted. This is neccessary as
517 	 * some things may happen in the destructor of the contained armies and
518 	 * we don't want bigmap to draw the stack when it is being removed.
519 	 */
520 	//! Whether or not this stack is in the midst of being deleted.
521         bool d_deleting;
522 };
523 
524 guint32 getFightOrder(std::list<guint32> values, guint32 value);
525 
526 #endif // STACK_H
527 
528 // End of file
529