initial commit, lordsawar source, slightly modified
[lordsawar] / src / army.h
diff --git a/src/army.h b/src/army.h
new file mode 100644 (file)
index 0000000..a475e03
--- /dev/null
@@ -0,0 +1,492 @@
+// Copyright (C) 2000, 2001, 2003 Michael Bartl
+// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006 Ulf Lorenz
+// Copyright (C) 2004, 2005 Andrea Paternesi
+// Copyright (C) 2007, 2008 Ben Asselstine
+// Copyright (C) 2007, 2008 Ole Laursen
+//
+//  This program is free software; you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation; either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU Library General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program; if not, write to the Free Software
+//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
+//  02110-1301, USA.
+
+#ifndef ARMY_H
+#define ARMY_H
+
+#include <gtkmm.h>
+#include <string>
+#include <sigc++/trackable.h>
+#include <sigc++/signal.h>
+
+#include "Ownable.h"
+#include "armybase.h"
+#include "UniquelyIdentified.h"
+
+class Player;
+class Temple;
+class XML_Helper;
+class ArmyProto;
+class ArmyProdBase;
+
+//! An instance of an Army unit, an Army unit type, or an Army production base.
+ /**
+  * This class is the atom of every army.  It contains values such as
+  * strength, movement points, upkeep, and so on.
+  *
+  * The purpose of the Army class is three-fold; an Army class can hold a
+  * an Army prototype, or a production base, or an Army instance.
+  *
+  * The Army instance is the most frequently used purpose of the Army class.
+  * An Army instance has a unique Id among all other game objects, has an 
+  * owner (Player), and is included in a Stack.
+  *
+  * The Army unit prototype purpose is the second-most frequently used 
+  * purpose of the Army class.  These types originate from a configuration 
+  * file; for example: army/default/default.xml.  Every Army unit type has an 
+  * type value that makes it unique among all other Army unit types in an 
+  * Armyset.
+  *
+  * The production base purpose refers to the Army units that are included
+  * in the City class as potential Army units that the City can produce.
+  * This purpose is exactly the same as the Army unit prototype purpose, 
+  * except it knows which Armyset it comes from, and it knows which Army
+  * unit type it derives from.
+  *
+  * Maybe these three purposes will be split up into three or more classes 
+  * in the future.
+  */
+class Army :public ArmyBase, public UniquelyIdentified, public Ownable, public sigc::trackable
+{
+    public:
+
+       //! The xml tag of this object in a saved-game file.
+       static std::string d_tag; 
+
+       //! Various kinds of statistics that an instance of Army unit has.
+       /**
+        * This enumeration assists in getting and setting of statistics in
+        * an instance of an Army unit.
+        */
+        enum Stat {
+         //! How strong the Army unit is in battle.
+         STRENGTH = 0,
+         //! The maximum number of hitpoints that the Army unit can have.
+         HP = 3,
+         //! The maximum number of moves the Army unit has.
+         MOVES = 4,
+         //! The various Tile::Type that the Army moves efficiently in.
+         MOVE_BONUS = 5,
+         //! The special bonus the Army has (Army::Bonus).
+         ARMY_BONUS = 6,
+         //! How far the Army unit can see on a hidden map.
+         SIGHT = 7,
+         //! If the Army unit is in a boat or not.
+         SHIP = 8,
+         //! If the Army unit is having it's movement doubled/tripled or not.
+         MOVES_MULTIPLIER = 9,
+        };
+
+       //! Copy constructor. 
+        Army(const ArmyProdBase& armyprodbase, Player* owner = 0);
+
+       //! Copy constructor. 
+        Army(const ArmyProto& armyproto, Player* owner = 0);
+
+       //! Copy constructor. 
+        Army(const Army& army, Player *owner = 0);
+
+        /** 
+        * Load an Army from an opened saved-game file or from an opened
+        * armyset configuration file.
+         *
+         * The constructor has to care for all three cases. Sometimes, an army
+         * prototype is loaded, from which other units are cloned, sometimes
+         * actual Army instances have to be loaded, and sometimes we load
+        * up a production base when loading the Army units that a City
+        * can produce.
+         *
+         * @param helper       The opened saved-game file to load from.
+         */
+       //! Loading constructor.
+        Army(XML_Helper* helper);
+        
+       /**  
+        * Creates an empty prototype Army unit.  This constructor is only
+        * used in the ArmySetWindow (the Armyset editor).
+        */
+       //! Create an empty army.
+       Army();
+
+       //! Destructor.
+        virtual ~Army();
+
+       static Army* createNonUniqueArmy(const ArmyProto& a, Player *p=NULL);
+       static Army* createNonUniqueArmy(const ArmyProdBase& a, Player *p=NULL);
+
+
+        // Set Methods
+        
+        //! Set the Id of Armyset and type that this Army belongs to.
+        void setArmyset(guint32 armyset, guint32 type);
+       
+       //! Change the armyset that the army type for this army belongs to.
+       void setArmyset(guint32 armyset_id) {d_armyset = armyset_id;};
+
+        //! Set an Army statistic.
+        void setStat(Stat stat, guint32 value);
+
+        //! Set the current number of hitpoints of this army.
+        void setHP(guint32 hp) {d_hp = hp;}
+
+        //! Sets whether or not the Army has a particular medal.
+        void setMedalBonus(guint32 index, bool value) 
+         {d_medal_bonus[index]=value;}
+        
+        //! Sets the number of battles the Army unit participated in.
+        void setBattlesNumber(guint32 value) {d_battles_number=value;}
+         
+        //! Sets the number of hits this Army unit has scored against a foe.
+        void setNumberHasHit(double value) {d_number_hashit=value;}
+
+        //! Sets the number of hits this Army unit has suffered against a foe.
+        void setNumberHasBeenHit(double value) {d_number_hasbeenhit=value;}
+
+       //! Sets whether or not this Army unit is in a boat.
+       void setInShip (bool s);
+
+       //! Sets whether or not this Army unit is in a tower.
+       void setFortified (bool f);
+
+
+        // Get Methods 
+        
+       //! Get the Id of the Armyset to which the Army's type belongs.
+        guint32 getArmyset() const {return d_armyset;}
+        
+        //! Get the type of this army.
+       /**
+        * The type of the Army is the index of it's type in the Armyset.
+        */
+        guint32 getTypeId() const {return d_type_id;}
+
+        /** 
+         * If modified is set to false, you get the raw, inherent value of
+         * the army. Set it to true to get the modified one. This is not
+         * important for generic armies, but heroes can have their stats
+         * modified by wearing items.
+        *
+        * @param stat     The statistic to get the value of.
+        * @param modified Whether or not we get the modified stat value.
+        *
+        * @return The value of the statistic.
+         */
+       //! Returns the value of the given stat for the Army.
+        virtual guint32 getStat(Stat stat, bool modified=true) const;
+
+        //! Get the current number of hitpoints that the Army has.
+        guint32 getHP() const {return d_hp;}
+
+        //! Get the current number of movement points that the Army has.
+        guint32 getMoves() const {return d_moves;}
+
+        //! Get the current number of experience points that the Army unit has.
+        double getXP() const {return d_xp;}
+
+        //! Get the current level of the Army.
+        guint32 getLevel() const {return d_level;}
+
+        //! Return which medals this Army unit has.
+        bool* getMedalBonuses() const {return (bool*)&d_medal_bonus;}
+
+        //! Return whether or not the Army has a particular medal.
+        bool getMedalBonus(guint32 index) const {return d_medal_bonus[index];}
+
+        //! Returns the number of battles the Army unit participated in.
+        guint32 getBattlesNumber() const {return d_battles_number;}
+
+        //! Returns the number of blows the Army unit has scored against a foe.
+        double getNumberHasHit() const {return d_number_hashit;}
+
+        //! Returns the number of hits this Army unit has suffered.
+        double getNumberHasBeenHit() const {return d_number_hasbeenhit;}
+
+       //! Return whether or not the Army is in a tower.
+       bool getFortified () const;
+
+       //! Is this army a hero?
+       /**
+        * isHero is overridden by the Hero class.
+        */
+       virtual bool isHero() const {return false;};
+
+       //! This army is of an army type that can be awarded as a reward.
+       bool getAwardable() const;
+
+       //! This army is of an army type that can be the keeper in a ruin.
+       bool getDefendsRuins() const;
+
+       //! This army is of an army type that has this name.
+       virtual std::string getName() const;
+
+       //Methods that operate on class data and modify the class data
+        /** 
+        * Regenerate an amount of the Army unit's hitpoints but not 
+        * exceeding the maximum number of hitpoints.
+        *
+         * @param hp       The amount of hitpoints to heal.  Set to zero for 
+        *                 "natural" healing -- but this feature is not 
+        *                 currently used because wounded army units are always 
+        *                 fully healed after battle.
+         */
+       //! Heal the Army unit.
+        void heal(guint32 hp = 0);
+
+        /** 
+        * Decrease the number of hitpoints that this Army has.
+         * 
+         * @param damageDone       The amount of damage that the Army suffers.
+        *
+         * @return True if the Army unit has died, otherwise false.
+         */
+       //! Damage the Army.
+        bool damage(guint32 damageDone);
+
+        /** 
+        * Reduce the number of moves that the Army unit has.
+        * @note This method doesn't reduce the maximum number of movement 
+        * points; it reduces the current number of movement points, which 
+        * get restored at the start of the next turn.
+         * 
+         * @param moves      The number of movement points to consume.
+         */
+       //! Consume some movement points.
+        void decrementMoves(guint32 moves);
+
+        //! Restores the number of movement points to the maximum level.
+        void resetMoves();
+
+       /**
+        * Add 1 to the strength of the Army unit if it has not already
+        * visited the Temple at which it's parent stack is currently
+        * sitting on.
+        *
+        * @param temple   The temple that the army is being blessed at.
+        *
+        * @return True if the Army unit was blessed, otherwise false.
+        */
+       //! Bless the Army unit if it hasn't already visited this Temple.
+        bool bless(Temple *temple);
+
+        //! Increases the experience points of the Army by the given amount.
+        void gainXp(double n);
+
+       //! Make this army look and behave like another one.
+       void morph(const ArmyProto *armyproto);
+
+       //Methods that operate on class data and do not modify the class data
+
+       //! Returns whether or not the army was blessed at the given temple.
+        bool blessedAtTemple(guint32 temple_id) const;
+
+        void printAllDebugInfo() const;
+
+        //! Saves the Army to an opened saved-game file.
+        virtual bool save(XML_Helper* helper) const;
+
+       //signals
+        
+       /**
+        * @note This signal is static because sometimes the army doesn't 
+        * exist yet when the signal is connected.
+        *
+        * @param army  The army that has died.
+        */
+       //! Emitted when an Army has died.
+        static sigc::signal<void, Army*> sdying;
+
+    protected:
+
+        //! Generic method for saving Army data.  Useful to the Hero class.
+        bool saveData(XML_Helper* helper) const;
+
+       //! The index of the Army unit's type in it's Armyset.
+        guint32 d_type_id;
+
+       //! The Id of the Armyset that the Army prototype belongs to.
+        guint32 d_armyset;
+
+       /**
+        * The maximum number of hitpoints is the secondmost important
+        * factor when calculating the outgoing of a Fight.
+        *
+        * This value should always be 2.
+        *
+        * This value does not change during gameplay.
+        */
+       //! The maximum number of hitpoints this Army unit has.
+        guint32 d_max_hp;
+
+       //! Movement point multiplier of the Army unit.
+       /**
+        * If an Army unit is being affected by a Hero unit's Item that
+        * confers the Item::DOUBLEMOVESTACK Item::Bonus, the effect is
+        * stored in d_max_moves_multiplier.
+        *
+        * This value must be 1 or more.
+        *
+        * This value typically changes from 1 to 2, and back to 1 during
+        * gameplay.
+        */
+       guint32 d_max_moves_multiplier;
+
+       //! Movement point bonus due to resting.
+       /**
+        * When an army unit doesn't use all of it's movement points in a
+        * turn, some of those points get held-over until the following turn.
+        * If a unit has 3 movement points remaining, the bonus is 2.  If the
+        * unit has 2 movement points remaining, the bonus is 2.  If the unit
+        * has 1 movement point remaining, the bonus is 1.
+        *
+        * This value is a number between 0 and 2.
+        */
+       guint32 d_max_moves_rest_bonus;
+
+       /**
+        * Being in a ship affects the Army's strength in battle.
+        * Every army has a strength of 4 when fighting on a boat.
+        * It also affects the number of moves that the Army has.
+        * See MAX_BOAT_MOVES.
+        *
+        * This value gets set and unset as Army unit's stack goes in
+        * and out of the water.
+        */
+       //! Whether or not this Army unit is afloat in a boat.
+       bool d_ship;
+
+       //! The current number of hitpoints that the Army unit has.
+       /**
+        * When this value is 0 it means the Army unit is dead.
+        * 
+        * During a Fight this value gets decremented as the Army unit
+        * suffers attacks by enemy Army units.
+        *
+        * After a Fight, this value gets restored to d_max_hp.
+        *
+        * d_hp does not exceed d_max_hp.
+        */
+        guint32 d_hp;
+
+       //! The current number of movement points that the Army unit has.
+       /**
+        * As the Army unit moves around in a Stack on the GameMap, it travels
+        * over certain terrain tiles.  As the Army unit moves over a
+        * particular terrain Tile, d_moves dwindles in value.
+        *
+        * At the end of a round, this value gets restored to d_max_moves.
+        *
+        * d_moves does not exceed d_moves_hp.
+        */
+        guint32 d_moves;
+
+       //! The current level of experience points the Army unit has.
+       /**
+        * This value increases as the Army unit assists in killing enemy
+        * Army units.  This value does not decrease during gameplay.
+        *
+        * This value affects what d_level the Army unit is.
+        */
+        double d_xp;
+
+       //! The experience level the Army unit has attained.
+       /**
+        * This value increases as the Army unit increases it's experience
+        * points.  d_level increases when a multiple of Army::xp_per_level 
+        * is surpassed.  d_level does not decrease during gameplay.
+        *
+        * d_level is not factored into any calculations that affect the
+        * outcome of the game.  It's just for show.
+        *
+        * @note Only Hero units advance in levels.
+        */
+        guint32 d_level;
+
+       /**
+        * There are three different medals that an Army unit can win.
+        *
+        * Merciless Medal: medal for being extremely merciless.  A unit 
+        *                  gets this medal if in a combat it scores more 
+        *                  than 90% of hits.
+        * Defender Medal: medal for being very good in defense.  A unit 
+        *                 gets this medal if in a combat is never hit.
+        * Veteran Medal: medal for being very good in combat.  A unit gets 
+        *                this medal if it survives 10 battles.
+        *
+        * Medals do not affect the game outcome and are just for show.
+        */
+       //! The medals that the Army unit has been given.
+        bool d_medal_bonus[3];
+
+        //! The total number of battles that this Army unit has fought in.
+       /**
+        * d_battles_number is a counter that is used to know when to
+        * award the Veteran's medal to this Army unit.
+        *
+        * This value does not decrease during gameplay.
+        */
+        guint32 d_battles_number;
+
+        //! The weighted number of hits per battle for this Army unit.
+       /**
+        * d_number_hashit is a counter that is used to know when to award
+        * the Merciless medal to this Army unit.
+        *
+        * This value does not decrease during gameplay.
+        */
+        double d_number_hashit;
+
+        //! The weighted number of times the Army unit has been hit in a battle.
+       /**
+        * d_number_hasbeenhit is a counter that is used to know when to award
+        * the Defender medal to this Army unit.
+        *
+        * This value does not decrease during gameplay.
+        */
+        double d_number_hasbeenhit;
+
+       //! A list of the Ids of Temples the Army unit has visited.
+       /**
+        * As the Army unit gets blessed at various Temple objects, this
+        * list grows with unique Temple Ids.
+        * The purpose of the list is to prevent the Army unit from being
+        * blessed at the same Temple more than once.
+        *
+        * The length of the list does not decrease during gameplay.
+        */
+        std::list<guint32> d_visitedTemples;
+
+       //! The number of experience points per experience level.
+       /**
+        * When an Army unit's d_xp surpasses a multiple of xp_per_level,
+        * it increases it's d_level by 1.
+        */
+        static const int xp_per_level = 10;
+
+    private:
+
+       //! Create an army with a non-unique id from an army prototype.
+       Army(const ArmyProto& a, guint32 id, Player *player = NULL);
+       //! Create an army with a non-unique id from an army production base.
+       Army(const ArmyProdBase& a, guint32 id, Player *player = NULL);
+
+};
+
+#endif // ARMY_H