1 /**
2  * @file
3  * @brief Misc religion related functions.
4 **/
5 
6 #pragma once
7 
8 #include <vector>
9 
10 #include "enum.h"
11 #include "mgen-data.h"
12 #include "player.h"
13 #include "religion-enum.h"
14 
15 using std::vector;
16 
17 #define MAX_PIETY      200
18 #define HALF_MAX_PIETY (MAX_PIETY / 2)
19 
20 #define MAX_PENANCE    200
21 
22 #define NUM_VEHUMET_GIFTS 13
23 
24 #define NUM_PIETY_STARS 6
25 
26 enum class lifesaving_chance
27 {
28     never,
29     sometimes,
30     always,
31 };
32 
33 bool is_evil_god(god_type god);
34 bool is_good_god(god_type god);
35 bool is_chaotic_god(god_type god);
36 bool is_unknown_god(god_type god);
37 bool god_has_name(god_type god);
38 
39 // Returns true if the god is not present in the current game. This is
40 // orthogonal to whether the player can worship the god in question.
41 bool is_unavailable_god(god_type god);
42 
43 god_type random_god();
44 
45 int piety_breakpoint(int i);
46 string god_name(god_type which_god, bool long_name = false);
47 string god_name_jiyva(bool second_name = false);
48 string wu_jian_random_sifu_name();
49 god_type str_to_god(const string &name, bool exact = true);
50 
51 int initial_wrath_penance_for(god_type god);
52 bool active_penance(god_type god);
53 bool xp_penance(god_type god);
54 void dec_penance(int val);
55 void dec_penance(god_type god, int val);
56 
57 void excommunication(bool voluntary = false, god_type new_god = GOD_NO_GOD);
58 int excom_xp_docked();
59 
60 bool gain_piety(int pgn, int denominator = 1, bool should_scale_piety = true);
61 void dock_piety(int pietyloss, int penance);
62 void god_speaks(god_type god, const char *mesg);
63 void lose_piety(int pgn);
64 void set_piety(int piety);
65 void handle_god_time(int /*time_delta*/);
66 int god_colour(god_type god);
67 colour_t god_message_altar_colour(god_type god);
68 int gozag_service_fee();
69 bool player_can_join_god(god_type which_god, bool temp = true);
70 void join_trog_skills(void);
71 void join_religion(god_type which_god);
72 void god_pitch(god_type which_god);
73 god_type choose_god(god_type def_god = NUM_GODS);
74 
you_worship(god_type god)75 static inline bool you_worship(god_type god)
76 {
77     return you.religion == god;
78 }
79 
80 static inline int player_under_penance(god_type god = you.religion)
81 {
82     return you.penance[god];
83 }
84 
85 /** Is the player in good (enough) standing with a particular god?
86  *
87  * @param god    The religion being asked about.
88  * @param pbreak The minimum piety breakpoint (number of stars minus one) to
89  *               consider "enough"; a negative number (the default) checks
90  *               only for worship and not for piety.
91  * @return true if the player worships the given god, is not under penance,
92  *         and has at least (pbreak + 1) stars of piety.
93  */
94 static inline bool in_good_standing(god_type god, int pbreak = -1)
95 {
96     return you_worship(god) && !player_under_penance(god)
97            && (pbreak < 0 || you.piety >= piety_breakpoint(pbreak));
98 }
99 
100 int had_gods();
101 int piety_rank(int piety = you.piety);
102 int piety_scale(int piety_change);
103 bool god_likes_your_god(god_type god, god_type your_god = you.religion);
104 bool god_hates_your_god(god_type god, god_type your_god = you.religion);
105 bool god_hates_killing(god_type god, const monster& mon);
106 bool god_hates_eating(god_type god, monster_type mc);
107 
108 bool god_likes_spell(spell_type spell, god_type god);
109 bool god_hates_spellcasting(god_type god);
110 bool god_hates_spell(spell_type spell, god_type god, bool fake_spell = false);
111 bool god_loathes_spell(spell_type spell, god_type god);
112 string god_spell_warn_string(spell_type spell, god_type god);
113 bool god_hates_ability(ability_type ability, god_type god);
114 
115 void initialize_ashenzari_props();
116 lifesaving_chance elyvilon_lifesaving();
117 bool god_protects_from_harm();
118 bool jiyva_is_dead();
119 void set_penance_xp_timeout();
120 bool fedhas_protects(const monster* target);
121 bool god_protects(const actor *agent, const monster *target, bool quiet=true);
122 bool god_protects(const monster *target, bool quiet=true);
123 bool fedhas_neutralises(const monster& target);
124 void nemelex_death_message();
125 
126 void mons_make_god_gift(monster& mon, god_type god = you.religion);
127 bool mons_is_god_gift(const monster& mon, god_type god = you.religion);
128 
129 int yred_random_servants(unsigned int threshold, bool force_hostile = false);
130 bool is_yred_undead_slave(const monster& mon);
131 bool is_orcish_follower(const monster& mon);
132 bool is_fellow_slime(const monster& mon);
133 bool is_follower(const monster& mon);
134 
135 // Vehumet gift interface.
136 bool vehumet_is_offering(spell_type spell);
137 void vehumet_accept_gift(spell_type spell);
138 
139 mgen_data hepliaklqana_ancestor_gen_data();
140 string hepliaklqana_ally_name();
141 int hepliaklqana_ally_hp();
142 
143 void upgrade_hepliaklqana_ancestor(bool quiet_force = false);
144 void upgrade_hepliaklqana_weapon(monster_type mtyp, item_def &item);
145 void upgrade_hepliaklqana_shield(const monster& ancestor, item_def &item);
146 
147 bool god_hates_attacking_friend(god_type god, const monster& fr);
148 
149 void religion_turn_start();
150 void religion_turn_end();
151 
152 int get_tension(god_type god = you.religion);
153 int get_monster_tension(const monster& mons, god_type god = you.religion);
154 int get_fuzzied_monster_difficulty(const monster& mons);
155 
156 typedef void (*delayed_callback)(const mgen_data &mg, monster *&mon, int placed);
157 
158 void delayed_monster(const mgen_data &mg, delayed_callback callback = nullptr);
159 void delayed_monster_done(string success,
160                           delayed_callback callback = nullptr);
161 
162 bool do_god_gift(bool forced = false);
163 
164 vector<god_type> temple_god_list();
165 vector<god_type> nontemple_god_list();
166 
167 class god_iterator
168 {
169 public:
170     god_iterator();
171 
172     operator bool() const;
173     god_type operator*() const;
174     god_type operator->() const;
175     god_iterator& operator++();
176     god_iterator operator++(int);
177 
178 protected:
179     int i;
180 };
181 
182 struct god_power
183 {
184     // 1-6 means it unlocks at that many stars of piety;
185     // 0 means it is always available when worshipping the god;
186     // -1 means it is available even under penance;
187     // 7 means it is a capstone.
188     int rank;
189     ability_type abil;
190 
191     // These strings can be one of two types:
192     //   - a full sentence, starting with a capital letter and ending with a
193     //     a period, that will be used for the relevant description; or
194     //   - part of a sentence, starting with a lowercase letter, to which the
195     //     following strings will be prepended, depending on which variable is
196     //     being used, and "." will be appended, before it is used for a
197     //     description:
198     //         "You can now "       for `gain`
199     //         "You can no longer " for `loss`
200     //         "You can "           for `general`.
201 
202     // Printed to message log when the piety threshold for the power is reached
203     const char* gain;
204     // Printed to message log when piety falls below the threshold for the power
205     const char* loss;
206     // Shown on the god powers (^) screen
207     const char* general;
208 
209     god_power(int rank_, ability_type abil_, const char* gain_,
210               const char* loss_ = "", const char* general_ = "") :
211               rank{rank_}, abil{abil_}, gain{gain_},
212               loss{*loss_ ? loss_ : gain_},
213               general{*general_ ? general_ : gain_}
214     { }
215 
216     god_power(int rank_, const char* gain_, const char* loss_ = "",
217               const char* general_ = "") :
god_powergod_power218               god_power(rank_, ABIL_NON_ABILITY, gain_, loss_, general_)
219     { }
220 
221     void display(bool gaining, const char* fmt) const;
222 };
223 
224 void set_god_ability_slots();
225 vector<god_power> get_god_powers(god_type god);
226 const god_power* god_power_from_ability(ability_type abil);
227 bool god_power_usable(const god_power& power, bool ignore_piety=false, bool ignore_penance=false);
228