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