1 // Copyright (C) 2008, 2009, 2010, 2011, 2014, 2015, 2020 Ben Asselstine
2 //
3 //  This program is free software; you can redistribute it and/or modify
4 //  it under the terms of the GNU General Public License as published by
5 //  the Free Software Foundation; either version 3 of the License, or
6 //  (at your option) any later version.
7 //
8 //  This program is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 //  GNU Library General Public License for more details.
12 //
13 //  You should have received a copy of the GNU General Public License
14 //  along with this program; if not, write to the Free Software
15 //  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16 //  02110-1301, USA.
17 
18 #pragma once
19 #ifndef ITEM_PROTO_H
20 #define ITEM_PROTO_H
21 
22 #include <gtkmm.h>
23 
24 #include "Renamable.h"
25 class XML_Helper;
26 
27 //! A carryable type of thing that confers special properties on it's holder.
28 /**
29  * This class describes an item prototype.  Items are carried by heroes in a
30  * backpack, and each item has a "kind".  The item prototype is this kind.
31  * When Items are carried they give special abilities to that hero, and
32  * perhaps the stack it is included in.
33  * Items can be dropped onto the ground, and picked up from the ground.
34  * When a hero dies, all of that hero's items get dropped onto the ground.
35  *
36  */
37 
38 class ItemProto: public Renamable
39 {
40     public:
41 
42 	//! The xml tag of this object in an itemlist configuration file.
43 	/**
44 	 * @note This tag appears in the item configuration file, and in
45 	 * saved-game files.
46 	 */
47 	static Glib::ustring d_tag;
48 
49 	// The item can confer these special properties.
50         enum Bonus {
51 
52 	  //! Add 1 to the strength of the wearer.
53 	  ADD1STR         = 0x00000001,
54 	  //! Add 2 to the strength of the wearer.
55 	  ADD2STR         = 0x00000002,
56 	  //! Add 3 to the strength of the wearer.
57 	  ADD3STR         = 0x00000004,
58 	  //! Add 1 to the strength of the Stack.
59 	  ADD1STACK       = 0x00000008,
60 	  //! Add 2 to the strength of the Stack.
61 	  ADD2STACK       = 0x00000010,
62 	  //! Add 3 to the strength of the Stack.
63 	  ADD3STACK       = 0x00000020,
64 	  //! Provides the gift of flight to the Stack.
65 	  FLYSTACK        = 0x00000040,
66 	  //! Makes the stack go two times as far.
67 	  DOUBLEMOVESTACK = 0x00000080,
68 	  //! Add 2 gold to the Player's treasury per City it holds.
69 	  ADD2GOLDPERCITY = 0x00000100,
70 	  //! Add 3 gold to the Player's treasury per City it holds.
71 	  ADD3GOLDPERCITY = 0x00000200,
72 	  //! Add 4 gold to the Player's treasury per City it holds.
73 	  ADD4GOLDPERCITY = 0x00000400,
74 	  //! Add 5 gold to the Player's treasury per City it holds.
75 	  ADD5GOLDPERCITY = 0x00000800,
76           //! Steal half of a player's gold.
77           STEAL_GOLD      = 0x00001000,
78           //! Sink all of a player's boats.
79           SINK_SHIPS      = 0x00002000,
80           //! Pick up any bags of items that are on the ground.
81           PICK_UP_BAGS    = 0x00004000,
82           //! Provide 2 movement points to the stack.
83           ADD_2MP_STACK   = 0x00008000,
84           //! Kill all of the giant worms
85           BANISH_WORMS    = 0x00010000,
86           //! Burn Bridge
87           BURN_BRIDGE     = 0x00020000,
88           //! Persuade a monster from a ruin into joining the stack.
89           CAPTURE_KEEPER  = 0x00040000,
90           //! Summon a monster.
91           SUMMON_MONSTER  = 0x00080000,
92           //! Target a city and kill a percentage of army units there.
93           DISEASE_CITY    = 0x00100000,
94           //! Make some defenders show up in a friendly city.
95           RAISE_DEFENDERS = 0x00200000,
96           //! Coerce a neutral city into flying your flag.
97           PERSUADE_NEUTRALS = 0x00400000,
98           //! Take the stack to a tile outside of a given city.
99           TELEPORT_TO_CITY  = 0x00800000
100         };
101 
102         enum UsableItems {
103           USABLE = STEAL_GOLD | SINK_SHIPS | PICK_UP_BAGS | ADD_2MP_STACK
104             | BANISH_WORMS | BURN_BRIDGE | CAPTURE_KEEPER | SUMMON_MONSTER
105             | DISEASE_CITY | RAISE_DEFENDERS | PERSUADE_NEUTRALS |
106             TELEPORT_TO_CITY
107         };
108 
109 
110 	static guint32 bonusFlagsFromString(const Glib::ustring str);
111 	static Glib::ustring bonusFlagsToString(const guint32 bonus);
112 
113 	//! Loading constructor.
114         ItemProto(XML_Helper* helper);
115 
116 	//! Copy constructor.
117         ItemProto(const ItemProto& orig);
118 
119 	//! Creates a new Item Prototype from scratch.
120         ItemProto(Glib::ustring name);
121 
122         //! Destructor.
~ItemProto()123         virtual ~ItemProto() {};
124 
125         //! Save the item to the opened saved-game file.
126         bool save(XML_Helper* helper) const;
127         //! Save the item, but not the enclosing d_tag.
128         bool saveContents(XML_Helper* helper) const;
129 
130         //! Returns whether or not the Item has a particular special bonus.
getBonus()131         guint32 getBonus() const {return d_bonus;};
132 
133         //! Returns whether or not the Item has a particular special bonus.
134         bool getBonus(ItemProto::Bonus bonus) const;
135 
136 	//! Add a bonus to the Item.
137 	void addBonus(ItemProto::Bonus bonus);
138 
139 	//! Remove a bonus from the Item.
140 	void removeBonus(ItemProto::Bonus bonus);
141 
142 	//! Return some text describing the item's special abilities.
143         Glib::ustring getBonusDescription() const;
144 
145         //! Return if the item is usable or not.
isUsable()146         bool isUsable() const {return d_bonus & USABLE;}
147 
getNumberOfUsesLeft()148         guint32 getNumberOfUsesLeft() const {return d_uses_left;}
149 
150         //! Set the number of uses left.
setNumberOfUsesLeft(guint32 uses_left)151         void setNumberOfUsesLeft(guint32 uses_left) {d_uses_left = uses_left;}
152 
usableOnVictimPlayer()153         bool usableOnVictimPlayer() const { if (d_bonus & SINK_SHIPS || d_bonus & STEAL_GOLD) return true; else return false;}
154 
usableOnEnemyCity()155         bool usableOnEnemyCity() const { if (d_bonus & DISEASE_CITY) return true; else return false;}
usableOnFriendlyCity()156         bool usableOnFriendlyCity() const { if (d_bonus & RAISE_DEFENDERS) return true; else return false;}
usableOnNeutralCity()157         bool usableOnNeutralCity() const { if (d_bonus & PERSUADE_NEUTRALS) return true; else return false;}
usableOnAnyCity()158         bool usableOnAnyCity() const { if (d_bonus & TELEPORT_TO_CITY) return true; else return false;}
159 
hasArmyTypeToKill()160         bool hasArmyTypeToKill () const {return d_has_army_type_to_kill;}
clearArmyTypeToKill()161         void clearArmyTypeToKill ()
162           {d_has_army_type_to_kill = false; d_army_type_to_kill = 0;}
getArmyTypeToKill()163         guint32 getArmyTypeToKill() const {return d_army_type_to_kill;}
setArmyTypeToKill(guint32 type)164         void setArmyTypeToKill(guint32 type)
165           {d_army_type_to_kill = type; d_has_army_type_to_kill = true;}
166 
getPercentGoldToSteal()167         double getPercentGoldToSteal() const {return d_steal_gold_percent;}
setPercentGoldToSteal(double p)168         void setPercentGoldToSteal(double p) {d_steal_gold_percent = p;}
169 
hasArmyTypeToSummon()170         bool hasArmyTypeToSummon() const {return d_has_army_type_to_summon;}
clearArmyTypeToSummon()171         void clearArmyTypeToSummon ()
172           {d_has_army_type_to_summon = false; d_army_type_to_summon = 0;}
getArmyTypeToSummon()173         guint32 getArmyTypeToSummon() const {return d_army_type_to_summon;}
setArmyTypeToSummon(guint32 type)174         void setArmyTypeToSummon(guint32 type)
175           {d_army_type_to_summon = type; d_has_army_type_to_summon = true;}
176 
getBuildingTypeToSummonOn()177         guint32 getBuildingTypeToSummonOn() const {return d_building_type_to_summon_on;}
setBuildingTypeToSummonOn(guint32 type)178         void setBuildingTypeToSummonOn(guint32 type) {d_building_type_to_summon_on = type;}
179 
180         bool isCurrentlyUsable(guint32 building, bool bags_on_map, bool victims_left, bool ruin_has_occupant, bool friendly_cities_present, bool enemy_cities_present, bool neutral_cities_present);
getPercentArmiesToKill()181         double getPercentArmiesToKill() const {return d_percent_armies_to_kill;};
setPercentArmiesToKill(double p)182         void setPercentArmiesToKill(double p) {d_percent_armies_to_kill = p;}
183 
getMovementPointsToAdd()184         guint32 getMovementPointsToAdd() const {return d_mp_to_add;}
setMovementPointsToAdd(guint32 mp)185         void setMovementPointsToAdd(guint32 mp) {d_mp_to_add = mp;}
186 
hasArmyTypeToRaise()187         bool hasArmyTypeToRaise () const {return d_has_army_type_to_raise;}
clearArmyTypeToRaise()188         void clearArmyTypeToRaise ()
189           {d_has_army_type_to_raise = false; d_army_type_to_raise = 0;}
getArmyTypeToRaise()190         guint32 getArmyTypeToRaise() const {return d_army_type_to_raise;}
setArmyTypeToRaise(guint32 type)191         void setArmyTypeToRaise(guint32 type)
192           {d_army_type_to_raise = type; d_has_army_type_to_raise = true;}
193 
getNumberOfArmiesToRaise()194         guint32 getNumberOfArmiesToRaise() const {return d_num_armies_to_raise;}
setNumberOfArmiesToRaise(guint32 num)195         void setNumberOfArmiesToRaise(guint32 num) {d_num_armies_to_raise = num;}
196 
197     protected:
198 	//! The item's bonus.
199 	/**
200 	 * This value is a bitwise OR-ing of the values in ItemProto::Bonus.
201 	 */
202         guint32 d_bonus;
203 
204         //! The number of uses this item has before it is spent.
205         guint32 d_uses_left;
206 
207         //! Which army type to kill if d_bonus includes BANISH_WORMS.
208         guint32 d_army_type_to_kill;
209 
210         //! How much gold to steal if d_bonus includes STEAL_GOLD.
211         double d_steal_gold_percent;
212 
213         //! Which army type to summon when d_bonus includes SUMMON_MONSTER.
214         guint32 d_army_type_to_summon;
215 
216         //! The building type to allow summoning in SUMMON_MONSTER.
217         /**
218          * When this value is 0 (Building::NONE), it means the monster can
219          * be summoned on any tile.
220          */
221         guint32 d_building_type_to_summon_on;
222 
223         //! The percentage of army units to kill in DISEASE_CITY.
224         double d_percent_armies_to_kill;
225 
226         //! How many movement points to add in ADD_2MP_STACK.
227         guint32 d_mp_to_add;
228 
229         //! Which army type to create when RAISE_DEFENDERS is used.
230         guint32 d_army_type_to_raise;
231 
232         //! How many armies to create when RAISE_DEFENDERS is used.
233         guint32 d_num_armies_to_raise;
234 
235         //! Whether or not d_army_type_to_kill has a value
236         bool d_has_army_type_to_kill;
237 
238         //! Whether or not d_army_type_to_summon has a value
239         bool d_has_army_type_to_summon;
240 
241         //! Whether or not d_army_type_to_raise has a value
242         bool d_has_army_type_to_raise;
243     private:
244 
245 	static Glib::ustring bonusFlagToString(ItemProto::Bonus type);
246 	static guint32 bonusFlagFromString(Glib::ustring str);
247 
248 
249 };
250 
251 #endif //ITEM_PROTOTYPE_H
252