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