1 // Copyright (C) 2000, 2001, 2003 Michael Bartl
2 // Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
3 // Copyright (C) 2004, 2005 Andrea Paternesi
4 // Copyright (C) 2007, 2008 Ben Asselstine
5 // Copyright (C) 2007, 2008 Ole Laursen
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.
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.
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
27 #include <sigc++/trackable.h>
28 #include <sigc++/signal.h>
32 #include "UniquelyIdentified.h"
40 //! An instance of an Army unit, an Army unit type, or an Army production base.
42 * This class is the atom of every army. It contains values such as
43 * strength, movement points, upkeep, and so on.
45 * The purpose of the Army class is three-fold; an Army class can hold a
46 * an Army prototype, or a production base, or an Army instance.
48 * The Army instance is the most frequently used purpose of the Army class.
49 * An Army instance has a unique Id among all other game objects, has an
50 * owner (Player), and is included in a Stack.
52 * The Army unit prototype purpose is the second-most frequently used
53 * purpose of the Army class. These types originate from a configuration
54 * file; for example: army/default/default.xml. Every Army unit type has an
55 * type value that makes it unique among all other Army unit types in an
58 * The production base purpose refers to the Army units that are included
59 * in the City class as potential Army units that the City can produce.
60 * This purpose is exactly the same as the Army unit prototype purpose,
61 * except it knows which Armyset it comes from, and it knows which Army
62 * unit type it derives from.
64 * Maybe these three purposes will be split up into three or more classes
67 class Army :public ArmyBase, public UniquelyIdentified, public Ownable, public sigc::trackable
71 //! The xml tag of this object in a saved-game file.
72 static std::string d_tag;
74 //! Various kinds of statistics that an instance of Army unit has.
76 * This enumeration assists in getting and setting of statistics in
77 * an instance of an Army unit.
80 //! How strong the Army unit is in battle.
82 //! The maximum number of hitpoints that the Army unit can have.
84 //! The maximum number of moves the Army unit has.
86 //! The various Tile::Type that the Army moves efficiently in.
88 //! The special bonus the Army has (Army::Bonus).
90 //! How far the Army unit can see on a hidden map.
92 //! If the Army unit is in a boat or not.
94 //! If the Army unit is having it's movement doubled/tripled or not.
99 Army(const ArmyProdBase& armyprodbase, Player* owner = 0);
101 //! Copy constructor.
102 Army(const ArmyProto& armyproto, Player* owner = 0);
104 //! Copy constructor.
105 Army(const Army& army, Player *owner = 0);
108 * Load an Army from an opened saved-game file or from an opened
109 * armyset configuration file.
111 * The constructor has to care for all three cases. Sometimes, an army
112 * prototype is loaded, from which other units are cloned, sometimes
113 * actual Army instances have to be loaded, and sometimes we load
114 * up a production base when loading the Army units that a City
117 * @param helper The opened saved-game file to load from.
119 //! Loading constructor.
120 Army(XML_Helper* helper);
123 * Creates an empty prototype Army unit. This constructor is only
124 * used in the ArmySetWindow (the Armyset editor).
126 //! Create an empty army.
132 static Army* createNonUniqueArmy(const ArmyProto& a, Player *p=NULL);
133 static Army* createNonUniqueArmy(const ArmyProdBase& a, Player *p=NULL);
138 //! Set the Id of Armyset and type that this Army belongs to.
139 void setArmyset(guint32 armyset, guint32 type);
141 //! Change the armyset that the army type for this army belongs to.
142 void setArmyset(guint32 armyset_id) {d_armyset = armyset_id;};
144 //! Set an Army statistic.
145 void setStat(Stat stat, guint32 value);
147 //! Set the current number of hitpoints of this army.
148 void setHP(guint32 hp) {d_hp = hp;}
150 //! Sets whether or not the Army has a particular medal.
151 void setMedalBonus(guint32 index, bool value)
152 {d_medal_bonus[index]=value;}
154 //! Sets the number of battles the Army unit participated in.
155 void setBattlesNumber(guint32 value) {d_battles_number=value;}
157 //! Sets the number of hits this Army unit has scored against a foe.
158 void setNumberHasHit(double value) {d_number_hashit=value;}
160 //! Sets the number of hits this Army unit has suffered against a foe.
161 void setNumberHasBeenHit(double value) {d_number_hasbeenhit=value;}
163 //! Sets whether or not this Army unit is in a boat.
164 void setInShip (bool s);
166 //! Sets whether or not this Army unit is in a tower.
167 void setFortified (bool f);
172 //! Get the Id of the Armyset to which the Army's type belongs.
173 guint32 getArmyset() const {return d_armyset;}
175 //! Get the type of this army.
177 * The type of the Army is the index of it's type in the Armyset.
179 guint32 getTypeId() const {return d_type_id;}
182 * If modified is set to false, you get the raw, inherent value of
183 * the army. Set it to true to get the modified one. This is not
184 * important for generic armies, but heroes can have their stats
185 * modified by wearing items.
187 * @param stat The statistic to get the value of.
188 * @param modified Whether or not we get the modified stat value.
190 * @return The value of the statistic.
192 //! Returns the value of the given stat for the Army.
193 virtual guint32 getStat(Stat stat, bool modified=true) const;
195 //! Get the current number of hitpoints that the Army has.
196 guint32 getHP() const {return d_hp;}
198 //! Get the current number of movement points that the Army has.
199 guint32 getMoves() const {return d_moves;}
201 //! Get the current number of experience points that the Army unit has.
202 double getXP() const {return d_xp;}
204 //! Get the current level of the Army.
205 guint32 getLevel() const {return d_level;}
207 //! Return which medals this Army unit has.
208 bool* getMedalBonuses() const {return (bool*)&d_medal_bonus;}
210 //! Return whether or not the Army has a particular medal.
211 bool getMedalBonus(guint32 index) const {return d_medal_bonus[index];}
213 //! Returns the number of battles the Army unit participated in.
214 guint32 getBattlesNumber() const {return d_battles_number;}
216 //! Returns the number of blows the Army unit has scored against a foe.
217 double getNumberHasHit() const {return d_number_hashit;}
219 //! Returns the number of hits this Army unit has suffered.
220 double getNumberHasBeenHit() const {return d_number_hasbeenhit;}
222 //! Return whether or not the Army is in a tower.
223 bool getFortified () const;
225 //! Is this army a hero?
227 * isHero is overridden by the Hero class.
229 virtual bool isHero() const {return false;};
231 //! This army is of an army type that can be awarded as a reward.
232 bool getAwardable() const;
234 //! This army is of an army type that can be the keeper in a ruin.
235 bool getDefendsRuins() const;
237 //! This army is of an army type that has this name.
238 virtual std::string getName() const;
240 //Methods that operate on class data and modify the class data
242 * Regenerate an amount of the Army unit's hitpoints but not
243 * exceeding the maximum number of hitpoints.
245 * @param hp The amount of hitpoints to heal. Set to zero for
246 * "natural" healing -- but this feature is not
247 * currently used because wounded army units are always
248 * fully healed after battle.
250 //! Heal the Army unit.
251 void heal(guint32 hp = 0);
254 * Decrease the number of hitpoints that this Army has.
256 * @param damageDone The amount of damage that the Army suffers.
258 * @return True if the Army unit has died, otherwise false.
261 bool damage(guint32 damageDone);
264 * Reduce the number of moves that the Army unit has.
265 * @note This method doesn't reduce the maximum number of movement
266 * points; it reduces the current number of movement points, which
267 * get restored at the start of the next turn.
269 * @param moves The number of movement points to consume.
271 //! Consume some movement points.
272 void decrementMoves(guint32 moves);
274 //! Restores the number of movement points to the maximum level.
278 * Add 1 to the strength of the Army unit if it has not already
279 * visited the Temple at which it's parent stack is currently
282 * @param temple The temple that the army is being blessed at.
284 * @return True if the Army unit was blessed, otherwise false.
286 //! Bless the Army unit if it hasn't already visited this Temple.
287 bool bless(Temple *temple);
289 //! Increases the experience points of the Army by the given amount.
290 void gainXp(double n);
292 //! Make this army look and behave like another one.
293 void morph(const ArmyProto *armyproto);
295 //Methods that operate on class data and do not modify the class data
297 //! Returns whether or not the army was blessed at the given temple.
298 bool blessedAtTemple(guint32 temple_id) const;
300 void printAllDebugInfo() const;
302 //! Saves the Army to an opened saved-game file.
303 virtual bool save(XML_Helper* helper) const;
308 * @note This signal is static because sometimes the army doesn't
309 * exist yet when the signal is connected.
311 * @param army The army that has died.
313 //! Emitted when an Army has died.
314 static sigc::signal<void, Army*> sdying;
318 //! Generic method for saving Army data. Useful to the Hero class.
319 bool saveData(XML_Helper* helper) const;
321 //! The index of the Army unit's type in it's Armyset.
324 //! The Id of the Armyset that the Army prototype belongs to.
328 * The maximum number of hitpoints is the secondmost important
329 * factor when calculating the outgoing of a Fight.
331 * This value should always be 2.
333 * This value does not change during gameplay.
335 //! The maximum number of hitpoints this Army unit has.
338 //! Movement point multiplier of the Army unit.
340 * If an Army unit is being affected by a Hero unit's Item that
341 * confers the Item::DOUBLEMOVESTACK Item::Bonus, the effect is
342 * stored in d_max_moves_multiplier.
344 * This value must be 1 or more.
346 * This value typically changes from 1 to 2, and back to 1 during
349 guint32 d_max_moves_multiplier;
351 //! Movement point bonus due to resting.
353 * When an army unit doesn't use all of it's movement points in a
354 * turn, some of those points get held-over until the following turn.
355 * If a unit has 3 movement points remaining, the bonus is 2. If the
356 * unit has 2 movement points remaining, the bonus is 2. If the unit
357 * has 1 movement point remaining, the bonus is 1.
359 * This value is a number between 0 and 2.
361 guint32 d_max_moves_rest_bonus;
364 * Being in a ship affects the Army's strength in battle.
365 * Every army has a strength of 4 when fighting on a boat.
366 * It also affects the number of moves that the Army has.
367 * See MAX_BOAT_MOVES.
369 * This value gets set and unset as Army unit's stack goes in
370 * and out of the water.
372 //! Whether or not this Army unit is afloat in a boat.
375 //! The current number of hitpoints that the Army unit has.
377 * When this value is 0 it means the Army unit is dead.
379 * During a Fight this value gets decremented as the Army unit
380 * suffers attacks by enemy Army units.
382 * After a Fight, this value gets restored to d_max_hp.
384 * d_hp does not exceed d_max_hp.
388 //! The current number of movement points that the Army unit has.
390 * As the Army unit moves around in a Stack on the GameMap, it travels
391 * over certain terrain tiles. As the Army unit moves over a
392 * particular terrain Tile, d_moves dwindles in value.
394 * At the end of a round, this value gets restored to d_max_moves.
396 * d_moves does not exceed d_moves_hp.
400 //! The current level of experience points the Army unit has.
402 * This value increases as the Army unit assists in killing enemy
403 * Army units. This value does not decrease during gameplay.
405 * This value affects what d_level the Army unit is.
409 //! The experience level the Army unit has attained.
411 * This value increases as the Army unit increases it's experience
412 * points. d_level increases when a multiple of Army::xp_per_level
413 * is surpassed. d_level does not decrease during gameplay.
415 * d_level is not factored into any calculations that affect the
416 * outcome of the game. It's just for show.
418 * @note Only Hero units advance in levels.
423 * There are three different medals that an Army unit can win.
425 * Merciless Medal: medal for being extremely merciless. A unit
426 * gets this medal if in a combat it scores more
428 * Defender Medal: medal for being very good in defense. A unit
429 * gets this medal if in a combat is never hit.
430 * Veteran Medal: medal for being very good in combat. A unit gets
431 * this medal if it survives 10 battles.
433 * Medals do not affect the game outcome and are just for show.
435 //! The medals that the Army unit has been given.
436 bool d_medal_bonus[3];
438 //! The total number of battles that this Army unit has fought in.
440 * d_battles_number is a counter that is used to know when to
441 * award the Veteran's medal to this Army unit.
443 * This value does not decrease during gameplay.
445 guint32 d_battles_number;
447 //! The weighted number of hits per battle for this Army unit.
449 * d_number_hashit is a counter that is used to know when to award
450 * the Merciless medal to this Army unit.
452 * This value does not decrease during gameplay.
454 double d_number_hashit;
456 //! The weighted number of times the Army unit has been hit in a battle.
458 * d_number_hasbeenhit is a counter that is used to know when to award
459 * the Defender medal to this Army unit.
461 * This value does not decrease during gameplay.
463 double d_number_hasbeenhit;
465 //! A list of the Ids of Temples the Army unit has visited.
467 * As the Army unit gets blessed at various Temple objects, this
468 * list grows with unique Temple Ids.
469 * The purpose of the list is to prevent the Army unit from being
470 * blessed at the same Temple more than once.
472 * The length of the list does not decrease during gameplay.
474 std::list<guint32> d_visitedTemples;
476 //! The number of experience points per experience level.
478 * When an Army unit's d_xp surpasses a multiple of xp_per_level,
479 * it increases it's d_level by 1.
481 static const int xp_per_level = 10;
485 //! Create an army with a non-unique id from an army prototype.
486 Army(const ArmyProto& a, guint32 id, Player *player = NULL);
487 //! Create an army with a non-unique id from an army production base.
488 Army(const ArmyProdBase& a, guint32 id, Player *player = NULL);