1 #pragma once 2 #ifndef CATA_SRC_MAGIC_ENCHANTMENT_H 3 #define CATA_SRC_MAGIC_ENCHANTMENT_H 4 5 #include <iosfwd> 6 #include <map> 7 #include <new> 8 #include <set> 9 #include <utility> 10 #include <vector> 11 12 #include "calendar.h" 13 #include "magic.h" 14 #include "optional.h" 15 #include "type_id.h" 16 #include "units_fwd.h" 17 18 class Character; 19 class Creature; 20 class JsonObject; 21 class JsonOut; 22 class item; 23 24 namespace enchant_vals 25 { 26 // the different types of values that can be modified by enchantments 27 // either the item directly or the Character, whichever is more appropriate 28 enum class mod : int { 29 // effects for the Character 30 STRENGTH, 31 DEXTERITY, 32 PERCEPTION, 33 INTELLIGENCE, 34 SPEED, 35 ATTACK_COST, 36 ATTACK_SPEED, // affects attack speed of item even if it's not the one you're wielding 37 MOVE_COST, 38 METABOLISM, 39 MAX_MANA, 40 REGEN_MANA, 41 BIONIC_POWER, 42 MAX_STAMINA, 43 REGEN_STAMINA, 44 MAX_HP, // for all limbs! use with caution 45 REGEN_HP, 46 THIRST, // thirst rate 47 FATIGUE, // fatigue rate 48 PAIN, // cost or regen over time 49 BONUS_DODGE, 50 BONUS_BLOCK, 51 BONUS_DAMAGE, 52 ATTACK_NOISE, 53 SHOUT_NOISE, 54 FOOTSTEP_NOISE, 55 SIGHT_RANGE, 56 CARRY_WEIGHT, 57 SOCIAL_LIE, 58 SOCIAL_PERSUADE, 59 SOCIAL_INTIMIDATE, 60 ARMOR_BASH, 61 ARMOR_CUT, 62 ARMOR_STAB, 63 ARMOR_BULLET, 64 ARMOR_HEAT, 65 ARMOR_COLD, 66 ARMOR_ELEC, 67 ARMOR_ACID, 68 ARMOR_BIO, 69 // effects for the item that has the enchantment 70 ITEM_DAMAGE_PURE, 71 ITEM_DAMAGE_BASH, 72 ITEM_DAMAGE_CUT, 73 ITEM_DAMAGE_STAB, 74 ITEM_DAMAGE_BULLET, 75 ITEM_DAMAGE_HEAT, 76 ITEM_DAMAGE_COLD, 77 ITEM_DAMAGE_ELEC, 78 ITEM_DAMAGE_ACID, 79 ITEM_DAMAGE_BIO, 80 ITEM_DAMAGE_AP, // armor piercing 81 ITEM_ARMOR_BASH, 82 ITEM_ARMOR_CUT, 83 ITEM_ARMOR_STAB, 84 ITEM_ARMOR_BULLET, 85 ITEM_ARMOR_HEAT, 86 ITEM_ARMOR_COLD, 87 ITEM_ARMOR_ELEC, 88 ITEM_ARMOR_ACID, 89 ITEM_ARMOR_BIO, 90 ITEM_WEIGHT, 91 ITEM_ENCUMBRANCE, 92 ITEM_VOLUME, 93 ITEM_COVERAGE, 94 ITEM_ATTACK_SPEED, 95 ITEM_WET_PROTECTION, 96 NUM_MOD 97 }; 98 } // namespace enchant_vals 99 100 // an "enchantment" is what passive artifact effects used to be: 101 // under certain conditions, the effect persists upon the appropriate Character 102 class enchantment 103 { 104 public: 105 // if a Character "has" an enchantment, it is viable to check for the condition 106 enum has { 107 WIELD, 108 WORN, 109 HELD, 110 NUM_HAS 111 }; 112 // the condition at which the enchantment is giving passive effects 113 enum condition { 114 ALWAYS, 115 UNDERGROUND, 116 UNDERWATER, 117 ACTIVE, // the item, mutation, etc. is active 118 NUM_CONDITION 119 }; 120 121 static void load_enchantment( const JsonObject &jo, const std::string &src ); 122 void load( const JsonObject &jo, const std::string &src = "" ); 123 124 // attempts to add two like enchantments together. 125 // if their conditions don't match, return false. else true. 126 bool add( const enchantment &rhs ); 127 128 // adds two enchantments together and ignores their conditions 129 void force_add( const enchantment &rhs ); 130 131 void set_has( has value ); 132 133 void add_value_add( enchant_vals::mod value, int add_value ); 134 void add_value_mult( enchant_vals::mod value, float mult_value ); 135 136 void add_hit_me( const fake_spell &sp ); 137 void add_hit_you( const fake_spell &sp ); 138 139 int get_value_add( enchant_vals::mod value ) const; 140 double get_value_multiply( enchant_vals::mod value ) const; 141 // the standard way of modifying a value, adds then multiplies. 142 double modify_value( enchant_vals::mod mod_val, double value ) const; 143 units::energy modify_value( enchant_vals::mod mod_val, units::energy value ) const; 144 units::mass modify_value( enchant_vals::mod mod_val, units::mass value ) const; 145 146 // this enchantment has a valid condition and is in the right location 147 bool is_active( const Character &guy, const item &parent ) const; 148 149 // this enchantment has a valid item independent conditions 150 // @active means the container for the enchantment is active, for comparison to active flag. 151 bool is_active( const Character &guy, bool active ) const; 152 153 // this enchantment is active when wielded. 154 // shows total conditional values, so only use this when Character is not available 155 bool active_wield() const; 156 157 // modifies character stats, or does other passive effects 158 void activate_passive( Character &guy ) const; 159 160 enchantment_id id; 161 162 bool was_loaded = false; 163 164 void serialize( JsonOut &jsout ) const; 165 166 // casts all the hit_you_effects on the target 167 void cast_hit_you( Character &caster, const Creature &target ) const; 168 // casts all the hit_me_effects on self or a target depending on the enchantment definition 169 void cast_hit_me( Character &caster, const Creature *target ) const; 170 get_mutations()171 const std::set<trait_id> &get_mutations() const { 172 return mutations; 173 } 174 175 bool operator==( const enchantment &rhs ) const; 176 private: 177 std::set<trait_id> mutations; 178 cata::optional<emit_id> emitter; 179 std::map<efftype_id, int> ench_effects; 180 // values that add to the base value 181 std::map<enchant_vals::mod, int> values_add; 182 // values that get multiplied to the base value 183 // multipliers add to each other instead of multiply against themselves 184 std::map<enchant_vals::mod, double> values_multiply; 185 186 std::vector<fake_spell> hit_me_effect; 187 std::vector<fake_spell> hit_you_effect; 188 189 std::map<time_duration, std::vector<fake_spell>> intermittent_activation; 190 191 std::pair<has, condition> active_conditions; 192 193 void add_activation( const time_duration &dur, const fake_spell &fake ); 194 195 // checks if the enchantments have the same active_conditions 196 bool stacks_with( const enchantment &rhs ) const; 197 198 int mult_bonus( enchant_vals::mod value_type, int base_value ) const; 199 200 // performs cooldown and distance checks before casting enchantment spells 201 void cast_enchantment_spell( Character &caster, const Creature *target, 202 const fake_spell &sp ) const; 203 }; 204 205 template <typename E> struct enum_traits; 206 207 template<> 208 struct enum_traits<enchantment::has> { 209 static constexpr enchantment::has last = enchantment::has::NUM_HAS; 210 }; 211 212 template<> 213 struct enum_traits<enchantment::condition> { 214 static constexpr enchantment::condition last = enchantment::condition::NUM_CONDITION; 215 }; 216 217 template<> 218 struct enum_traits<enchant_vals::mod> { 219 static constexpr enchant_vals::mod last = enchant_vals::mod::NUM_MOD; 220 }; 221 222 #endif // CATA_SRC_MAGIC_ENCHANTMENT_H 223