1 #pragma once
2 #ifndef CATA_SRC_MUTATION_H
3 #define CATA_SRC_MUTATION_H
4 
5 #include <climits>
6 #include <iosfwd>
7 #include <map>
8 #include <new>
9 #include <set>
10 #include <string>
11 #include <unordered_map>
12 #include <utility>
13 #include <vector>
14 
15 #include "calendar.h"
16 #include "character.h"
17 #include "damage.h"
18 #include "hash_utils.h"
19 #include "memory_fast.h"
20 #include "optional.h"
21 #include "point.h"
22 #include "translations.h"
23 #include "type_id.h"
24 #include "value_ptr.h"
25 
26 class JsonArray;
27 class JsonIn;
28 class JsonObject;
29 class Trait_group;
30 class item;
31 class nc_color;
32 struct dream;
33 
34 enum game_message_type : int;
35 
36 template <typename E> struct enum_traits;
37 
38 extern std::vector<dream> dreams;
39 extern std::map<mutation_category_id, std::vector<trait_id> > mutations_category;
40 
41 struct dream {
42     private:
43         std::vector<translation> raw_messages; // The messages that the dream will give
44 
45     public:
46         std::vector<std::string> messages() const;
47 
48         mutation_category_id category; // The category that will trigger the dream
49         int strength; // The category strength required for the dream
50 
dreamdream51         dream() {
52             strength = 0;
53         }
54 
55         static void load( const JsonObject &jsobj );
56 };
57 
58 struct mut_attack {
59     /** Text printed when the attack is proced by you */
60     translation attack_text_u;
61     /** As above, but for npc */
62     translation attack_text_npc;
63     /** Need all of those to qualify for this attack */
64     std::set<trait_id> required_mutations;
65     /** Need none of those to qualify for this attack */
66     std::set<trait_id> blocker_mutations;
67 
68     /** If not empty, this body part needs to be uncovered for the attack to proc */
69     bodypart_str_id bp;
70 
71     /** Chance to proc is one_in( chance - dex - unarmed ) */
72     int chance = 0;
73 
74     damage_instance base_damage;
75     /** Multiplied by strength and added to the above */
76     damage_instance strength_damage;
77 
78     /** Should be true when and only when this attack needs hardcoded handling */
79     bool hardcoded_effect = false;
80 };
81 
82 struct mut_transform {
83 
84     trait_id target;
85 
86     /** displayed if player sees transformation with %s replaced by mutation name */
87     translation msg_transform;
88     /** used to set the active property of the transformed @ref target */
89     bool active = false;
90     /** subtracted from @ref Creature::moves when transformation is successful */
91     int moves = 0;
92     mut_transform();
93     bool load( const JsonObject &jsobj, const std::string &member );
94 };
95 
96 enum trigger_type {
97     PAIN,
98     HUNGER,
99     THRIST,
100     MOOD,
101     STAMINA,
102     MOON,
103     TIME,
104     num_trigger
105 };
106 template<>
107 struct enum_traits<trigger_type> {
108     static constexpr trigger_type last = trigger_type::num_trigger;
109 };
110 
111 struct reflex_activation_data {
112 
113     /**What variable controls the activation*/
114     trigger_type trigger = trigger_type::TIME;
115 
116     /**Activates above that threshold and deactivates below it*/
117     int threshold_low = INT_MIN;
118     /**Activates below that threshold and deactivates above it*/
119     int threshold_high = INT_MAX;
120 
121     std::pair<translation, game_message_type> msg_on;
122     std::pair<translation, game_message_type> msg_off;
123 
124     bool is_trigger_true( const Character &guy ) const;
125 
126     bool was_loaded = false;
127     void load( const JsonObject &jsobj );
128     void deserialize( JsonIn &jsin );
129 };
130 
131 struct mutation_branch {
132         trait_id id;
133         bool was_loaded = false;
134         // True if this is a valid mutation (False for "unavailable from generic mutagen").
135         bool valid = false;
136         // True if Purifier can remove it (False for *Special* mutations).
137         bool purifiable = false;
138         // True if it's a threshold itself, and shouldn't be obtained *easily* (False by default).
139         bool threshold = false;
140         // True if this is a trait associated with professional training/experience, so profession/quest ONLY.
141         bool profession = false;
142         // True if the mutation is obtained through the debug menu
143         bool debug = false;
144         // True if the mutation should be displayed in the `@` menu
145         bool player_display = true;
146         // Whether it has positive as well as negative effects.
147         bool mixed_effect  = false;
148         bool startingtrait = false;
149         bool activated     = false;
150         // Should it activate as soon as it is gained?
151         bool starts_active = false;
152         // Should it destroy gear on restricted body parts? (otherwise just pushes it off)
153         bool destroys_gear = false;
154         // Allow soft (fabric) gear on restricted body parts
155         bool allow_soft_gear  = false;
156         // IF any of the three are true, it drains that as the "cost"
157         bool fatigue       = false;
158         bool hunger        = false;
159         bool thirst        = false;
160         // How many points it costs in character creation
161         int points     = 0;
162         int visibility = 0;
163         int ugliness   = 0;
164         int cost       = 0;
165         // costs are consumed every cooldown turns,
166         int cooldown   = 0;
167         // bodytemp elements:
168         int bodytemp_min = 0;
169         int bodytemp_max = 0;
170         int bodytemp_sleep = 0;
171         // Healing per turn
172         cata::optional<float> healing_awake = cata::nullopt;
173         cata::optional<float> healing_resting = cata::nullopt;
174         // Limb mending bonus
175         cata::optional<float> mending_modifier = cata::nullopt;
176         // Bonus HP multiplier. That is, 1.0 doubles hp, -0.5 halves it.
177         cata::optional<float> hp_modifier = cata::nullopt;
178         // Second HP modifier that stacks with first but is otherwise identical.
179         cata::optional<float> hp_modifier_secondary = cata::nullopt;
180         // Flat bonus/penalty to hp.
181         cata::optional<float> hp_adjustment = cata::nullopt;
182         // Modify strength stat without changing HP
183         cata::optional<float> str_modifier = cata::nullopt;
184         //melee bonuses
185         int cut_dmg_bonus = 0;
186         float pierce_dmg_bonus = 0.0f;
187         std::pair<int, int> rand_cut_bonus;
188         int bash_dmg_bonus = 0;
189         std::pair<int, int> rand_bash_bonus;
190         // Additional bonuses
191         cata::optional<float> dodge_modifier = cata::nullopt;
192         cata::optional<float> speed_modifier = cata::nullopt;
193         cata::optional<float> movecost_modifier = cata::nullopt;
194         cata::optional<float> movecost_flatground_modifier = cata::nullopt;
195         cata::optional<float> movecost_obstacle_modifier = cata::nullopt;
196         cata::optional<float> attackcost_modifier = cata::nullopt;
197         cata::optional<float> max_stamina_modifier = cata::nullopt;
198         cata::optional<float> weight_capacity_modifier = cata::nullopt;
199         cata::optional<float> hearing_modifier = cata::nullopt;
200         cata::optional<float> movecost_swim_modifier = cata::nullopt;
201         cata::optional<float> noise_modifier = cata::nullopt;
202         float scent_modifier = 1.0f;
203         cata::optional<int> scent_intensity;
204         cata::optional<int> scent_mask;
205         int bleed_resist = 0;
206 
207         int butchering_quality = 0;
208 
209         cata::value_ptr<mut_transform> transform;
210 
211         std::vector<std::vector<reflex_activation_data>> trigger_list;
212 
213         /**Map of crafting skills modifiers, can be negative*/
214         std::map<skill_id, int> craft_skill_bonus;
215 
216         /**What do you smell like*/
217         cata::optional<scenttype_id> scent_typeid;
218 
219         /**Map of glowing body parts and their glow intensity*/
220         std::map<bodypart_str_id, float> lumination;
221 
222         /**Rate at which bmi above character_weight_category::normal increases the character max_hp*/
223         float fat_to_max_hp = 0.0f;
224         /**How fast does healthy tends toward healthy_mod*/
225         float healthy_rate = 1.0f;
226 
227         /**maximum damage dealt by water every minute when wet. Can be negative and regen hit points.*/
228         int weakness_to_water = 0;
229 
230         cata::optional<float> crafting_speed_multiplier = cata::nullopt;
231 
232         // Subtracted from the range at which monsters see player, corresponding to percentage of change. Clamped to +/- 60 for effectiveness
233         cata::optional<float> stealth_modifier = cata::nullopt;
234 
235         // Speed lowers--or raises--for every X F (X C) degrees below or above 65 F (18.3 C)
236         cata::optional<float> temperature_speed_modifier = cata::nullopt;
237         // Extra metabolism rate multiplier. 1.0 doubles usage, -0.5 halves.
238         cata::optional<float> metabolism_modifier = cata::nullopt;
239         // As above but for thirst.
240         cata::optional<float> thirst_modifier = cata::nullopt;
241         // As above but for fatigue.
242         cata::optional<float> fatigue_modifier = cata::nullopt;
243         // Modifier for the rate at which fatigue and sleep deprivation drops when resting.
244         cata::optional<float> fatigue_regen_modifier = cata::nullopt;
245         // Modifier for the rate at which stamina regenerates.
246         cata::optional<float> stamina_regen_modifier = cata::nullopt;
247         // the modifier for obtaining an item from a container as a handling penalty
248         cata::optional<float> obtain_cost_multiplier = cata::nullopt;
249         // the modifier for the stomach size
250         cata::optional<float> stomach_size_multiplier = cata::nullopt;
251         // the modifier for the vomit chance
252         cata::optional<float> vomit_multiplier = cata::nullopt;
253 
254         // Adjusts sight range on the overmap. Positives make it farther, negatives make it closer.
255         cata::optional<float> overmap_sight = cata::nullopt;
256 
257         // Multiplier for sight range, defaulting to 1.
258         cata::optional<float> overmap_multiplier = cata::nullopt;
259 
260         // Multiplier for map memory capacity, defaulting to 1.
261         cata::optional<float> map_memory_capacity_multiplier = cata::nullopt;
262 
263         // Multiplier for reading speed, defaulting to 1.
264         cata::optional<float> reading_speed_multiplier = cata::nullopt;
265 
266         // Multiplier for skill rust delay, defaulting to 1.
267         cata::optional<float> skill_rust_multiplier = cata::nullopt;
268 
269         // Multiplier for consume time, defaulting to 1.
270         cata::optional<float> consume_time_modifier = cata::nullopt;
271 
272         // Bonus or penalty to social checks (additive).  50 adds 50% to success, -25 subtracts 25%
273         social_modifiers social_mods;
274 
275         /** The item, if any, spawned by the mutation */
276         itype_id spawn_item;
277 
278         /**Species ignoring character with the mutation*/
279         std::vector<species_id> ignored_by;
280 
281         /**Map of angered species and there intensity*/
282         std::map<species_id, int> anger_relations;
283 
284         /**List of material required for food to be be edible*/
285         std::set<material_id> can_only_eat;
286 
287         /**List of healing items allowed*/
288         std::set<itype_id> can_only_heal_with;
289         std::set<itype_id> can_heal_with;
290 
291         /**List of allowed mutation category*/
292         std::set<mutation_category_id> allowed_category;
293 
294         /**List of body parts locked out of bionics*/
295         std::set<bodypart_str_id> no_cbm_on_bp;
296 
297         // amount of mana added or subtracted from max
298         cata::optional<float> mana_modifier = cata::nullopt;
299         cata::optional<float> mana_multiplier = cata::nullopt;
300         cata::optional<float> mana_regen_multiplier = cata::nullopt;
301         // for every point of bionic power, reduces max mana pool by 1 * bionic_mana_penalty
302         cata::optional<float> bionic_mana_penalty = cata::nullopt;
303         cata::optional<float> casting_time_multiplier = cata::nullopt;
304         // spells learned and their associated level when gaining the mutation
305         std::map<spell_id, int> spells_learned;
306         /** mutation enchantments */
307         std::vector<enchantment_id> enchantments;
308     private:
309         translation raw_spawn_item_message;
310     public:
311         std::string spawn_item_message() const;
312 
313         /** The fake gun, if any, spawned and fired by the ranged mutation */
314         itype_id ranged_mutation;
315     private:
316         translation raw_ranged_mutation_message;
317     public:
318         std::string ranged_mutation_message() const;
319 
320         /** Attacks granted by this mutation */
321         std::vector<mut_attack> attacks_granted;
322 
323         /** Mutations may adjust one or more of the default vitamin usage rates */
324         std::map<vitamin_id, time_duration> vitamin_rates;
325 
326         // Mutations may affect absorption rates of vitamins based on material (or "all")
327         std::map<material_id, std::map<vitamin_id, double>> vitamin_absorb_multi;
328 
329         std::vector<trait_id> prereqs; // Prerequisites; Only one is required
330         std::vector<trait_id> prereqs2; // Prerequisites; need one from here too
331         std::vector<trait_id> threshreq; // Prerequisites; dedicated slot to needing thresholds
332         std::set<std::string> types; // Mutation types, you can't have two mutations that share a type
333         std::vector<trait_id> cancels; // Mutations that conflict with this one
334         std::vector<trait_id> replacements; // Mutations that replace this one
335         std::vector<trait_id> additions; // Mutations that add to this one
336         std::vector<mutation_category_id> category; // Mutation Categories
337         std::set<json_character_flag> flags; // Mutation flags
338         std::set<json_character_flag> active_flags; // Mutation flags only when active
339         std::set<json_character_flag> inactive_flags; // Mutation flags only when inactive
340         std::map<bodypart_str_id, tripoint> protection; // Mutation wet effects
341         std::map<bodypart_str_id, int> encumbrance_always; // Mutation encumbrance that always applies
342         // Mutation encumbrance that applies when covered with unfitting item
343         std::map<bodypart_str_id, int> encumbrance_covered;
344         // a multiplier to encumbrance that is already modified by mutations
345         std::map<bodypart_str_id, float> encumbrance_multiplier_always;
346         // Body parts that now need OVERSIZE gear
347         std::set<bodypart_str_id> restricts_gear;
348         // item flags that allow wearing gear even if its body part is restricted
349         std::set<flag_id> allowed_items;
350         // Mutation stat mods
351         /** Key pair is <active: bool, mod type: "STR"> */
352         std::unordered_map<std::pair<bool, std::string>, int, cata::tuple_hash> mods;
353         std::map<bodypart_str_id, resistances> armor;
354         std::vector<matype_id>
355         initial_ma_styles; // Martial art styles that can be chosen upon character generation
356     private:
357         std::map<bodypart_str_id, int> bionic_slot_bonuses;
358         translation raw_name;
359         translation raw_desc;
360     public:
361         std::string name() const;
362         std::string desc() const;
363 
364         /**
365          * Returns the color to display the mutation name with.
366          */
367         nc_color get_display_color() const;
368         /**
369          * Returns true if a character with this mutation shouldn't be able to wear given item.
370          */
371         bool conflicts_with_item( const item &it ) const;
372         /**
373          * Returns damage resistance on a given body part granted by this mutation.
374          */
375         const resistances &damage_resistance( const bodypart_id &bp ) const;
376         /**
377          * Returns bionic slot bonus on a given body part granted by this mutation
378          */
379         int bionic_slot_bonus( const bodypart_str_id &part ) const;
380         /**
381          * Shortcut for getting the name of a (translated) mutation, same as
382          * @code get( mutation_id ).name @endcode
383          */
384         static std::string get_name( const trait_id &mutation_id );
385         /**
386          * All known mutations. Key is the mutation id, value is the mutation_branch that you would
387          * also get by calling @ref get.
388          */
389         static const std::vector<mutation_branch> &get_all();
390         // For init.cpp: reset (clear) the mutation data
391         static void reset_all();
392         // For init.cpp: load mutation data from json
393         void load( const JsonObject &jo, const std::string &src );
394         static void load_trait( const JsonObject &jo, const std::string &src );
395         // For init.cpp: check internal consistency (valid ids etc.) of all mutations
396         static void check_consistency();
397 
398         /**
399          * Load a trait blacklist specified by the given JSON object.
400          */
401         static void load_trait_blacklist( const JsonObject &jsobj );
402 
403         /**
404          * Check if the trait with the given ID is blacklisted.
405          */
406         static bool trait_is_blacklisted( const trait_id &tid );
407 
408         /** called after all JSON has been read and performs any necessary cleanup tasks */
409         static void finalize();
410         static void finalize_trait_blacklist();
411 
412         /**
413          * @name Trait groups
414          *
415          * Trait groups are used to generate a randomized set of traits.
416          * You usually only need the @ref Trait_group::traits_from function to
417          * create traits from a group.
418          */
419         /*@{*/
420         /**
421          * Callback for the init system (@ref DynamicDataLoader), loads a trait
422          * group definitions.
423          * @param jsobj The json object to load from.
424          * @throw JsonError if the json object contains invalid data.
425          */
426         static void load_trait_group( const JsonObject &jsobj );
427 
428         /**
429          * Load a trait group from json. It differs from the other load_trait_group function as it
430          * uses the group ID and subtype given as parameters, and does not look them up in
431          * the json data (i.e. the given json object does not need to have them).
432          *
433          * This is intended for inline definitions of trait groups, e.g. in NPC class definitions:
434          * the trait group there is embedded into the class type definition.
435          *
436          * @param jsobj The json object to load from.
437          * @param gid The ID of the group that is to be loaded.
438          * @param subtype The type of the trait group, either "collection", "distribution" or "old"
439          * (i.e. the old list-based format, `[ ["TRAIT", 100] ]`).
440          * @throw JsonError if the json object contains invalid data.
441          */
442         static void load_trait_group( const JsonObject &jsobj, const trait_group::Trait_group_tag &gid,
443                                       const std::string &subtype );
444 
445         /**
446          * Like the above function, except this function assumes that the given
447          * array is the "entries" member of the trait group.
448          *
449          * For each element in the array, @ref mutation_branch::add_entry is called.
450          *
451          * Assuming the input array looks like `[ x, y, z ]`, this function loads it like the
452          * above would load this object:
453          * \code
454          * {
455          *      "subtype": "depends on is_collection parameter",
456          *      "id": "identifier",
457          *      "entries": [ x, y, z ]
458          * }
459          * \endcode
460          * Note that each entry in the array has to be a JSON object. The other function above
461          * can also load data from arrays of strings, where the strings are item or group ids.
462          */
463         static void load_trait_group( const JsonArray &entries, const trait_group::Trait_group_tag &gid,
464                                       bool is_collection );
465 
466         /**
467          * Create a new trait group as specified by the given JSON object and register
468          * it as part of the given trait group.
469          */
470         static void add_entry( Trait_group &tg, const JsonObject &obj );
471 
472         /**
473          * Get the trait group object specified by the given ID, or null if no
474          * such group exists.
475          */
476         static shared_ptr_fast<Trait_group> get_group( const trait_group::Trait_group_tag &gid );
477 
478         /**
479          * Return the idents of all trait groups that are known.
480          */
481         static std::vector<trait_group::Trait_group_tag> get_all_group_names();
482 };
483 
484 struct mutation_category_trait {
485     private:
486         translation raw_name;
487         // Message when you consume mutagen
488         translation raw_mutagen_message;
489         // Message when you inject an iv
490         translation raw_iv_message;
491         translation raw_iv_sound_message = no_translation( "NULL" );
492         std::string raw_iv_sound_id = "shout";
493         std::string raw_iv_sound_variant = "default";
494         translation raw_iv_sleep_message = no_translation( "NULL" );
495         translation raw_junkie_message;
496         // Memorial message when you cross a threshold
497         std::string raw_memorial_message;
498 
499     public:
500         std::string name() const;
501         std::string mutagen_message() const;
502         std::string iv_message() const;
503         std::string iv_sound_message() const;
504         std::string iv_sound_id() const;
505         std::string iv_sound_variant() const;
506         std::string iv_sleep_message() const;
507         std::string junkie_message() const;
508         std::string memorial_message_male() const;
509         std::string memorial_message_female() const;
510 
511         // Mutation category i.e "BIRD", "CHIMERA"
512         mutation_category_id id;
513         // The trait that you gain when you break the threshold for this category
514         trait_id threshold_mut;
515 
516         // These are defaults
517         int mutagen_hunger  = 10;
518         int mutagen_thirst  = 10;
519         int mutagen_pain    = 2;
520         int mutagen_fatigue = 5;
521         int mutagen_morale  = 0;
522         // The minimum mutations an injection provides
523         int iv_min_mutations    = 1;
524         int iv_additional_mutations = 2;
525         // Chance of additional mutations
526         int iv_additional_mutations_chance = 3;
527         int iv_hunger   = 10;
528         int iv_thirst   = 10;
529         int iv_pain     = 2;
530         int iv_fatigue  = 5;
531         int iv_morale   = 0;
532         int iv_morale_max = 0;
533         // Meta-label indicating that the category isn't finished yet.
534         bool wip = false;
535         // Determines if you make a sound when you inject mutagen
536         bool iv_sound = false;
537         // The amount of noise produced by the sound
538         int iv_noise = 0;
539         // Whether the iv has a chance of knocking you out.
540         bool iv_sleep = false;
541         int iv_sleep_dur = 0;
542 
543         static const std::map<mutation_category_id, mutation_category_trait> &get_all();
544         static const mutation_category_trait &get_category(
545             const mutation_category_id &category_id );
546         static void reset();
547         static void check_consistency();
548 
549         static void load( const JsonObject &jsobj );
550 };
551 
552 void load_mutation_type( const JsonObject &jsobj );
553 bool mutation_category_is_valid( const mutation_category_id &cat );
554 bool mutation_type_exists( const std::string &id );
555 std::vector<trait_id> get_mutations_in_types( const std::set<std::string> &ids );
556 std::vector<trait_id> get_mutations_in_type( const std::string &id );
557 bool trait_display_sort( const trait_id &a, const trait_id &b ) noexcept;
558 bool trait_display_nocolor_sort( const trait_id &a, const trait_id &b ) noexcept;
559 
560 bool are_conflicting_traits( const trait_id &trait_a, const trait_id &trait_b );
561 bool b_is_lower_trait_of_a( const trait_id &trait_a, const trait_id &trait_b );
562 bool b_is_higher_trait_of_a( const trait_id &trait_a, const trait_id &trait_b );
563 bool are_opposite_traits( const trait_id &trait_a, const trait_id &trait_b );
564 bool are_same_type_traits( const trait_id &trait_a, const trait_id &trait_b );
565 bool contains_trait( std::vector<string_id<mutation_branch>> traits, const trait_id &trait );
566 
567 enum class mutagen_technique : int {
568     consumed_mutagen,
569     injected_mutagen,
570     consumed_purifier,
571     injected_purifier,
572     injected_smart_purifier,
573     num_mutagen_techniques // last
574 };
575 
576 template<>
577 struct enum_traits<mutagen_technique> {
578     static constexpr mutagen_technique last = mutagen_technique::num_mutagen_techniques;
579 };
580 
581 enum class mutagen_rejection : int {
582     accepted,
583     rejected,
584     destroyed
585 };
586 
587 struct mutagen_attempt {
588     mutagen_attempt( bool a, int c ) : allowed( a ), charges_used( c ) {}
589     bool allowed;
590     int charges_used;
591 };
592 
593 mutagen_attempt mutagen_common_checks( Character &guy, const item &it, bool strong,
594                                        mutagen_technique technique );
595 
596 void test_crossing_threshold( Character &guy, const mutation_category_trait &m_category );
597 
598 #endif // CATA_SRC_MUTATION_H
599