1 /**
2  * @file
3  * @brief Spell casting functions.
4 **/
5 
6 #pragma once
7 
8 #include <vector>
9 #include <memory>
10 #include <functional>
11 
12 #include "enum.h"
13 #include "item-def.h"
14 #include "skill-type.h"
15 #include "spell-type.h"
16 
17 using std::vector;
18 
19 struct monster_info;
20 class dist;
21 
22 enum class spflag
23 {
24     none               = 0x00000000,
25     dir_or_target      = 0x00000001,      // use DIR_NONE targeting
26     target             = 0x00000002,      // use DIR_TARGET targeting
27                      //  0x00000004,
28                      //  0x00000008,
29                                           // used to test for targeting
30     targeting_mask     = spflag::dir_or_target | spflag::target,
31     obj                = 0x00000010,      // TARG_MOVABLE_OBJECT used
32     helpful            = 0x00000020,      // TARG_FRIEND used
33     neutral            = 0x00000040,      // TARG_ANY used
34     not_self           = 0x00000080,      // aborts on isMe
35     unholy             = 0x00000100,      // counts as "unholy"
36     unclean            = 0x00000200,      // counts as "unclean"
37     chaotic            = 0x00000400,      // counts as "chaotic"
38     hasty              = 0x00000800,      // counts as "hasty"
39                      //  0x00001000,
40     escape             = 0x00002000,      // useful for running away
41     recovery           = 0x00004000,      // healing or recovery spell
42     area               = 0x00008000,      // area affect
43                      //  0x00010000,      // was SPFLAG_BATTLE
44     selfench           = 0x00020000,      // monsters use as selfench
45     monster            = 0x00040000,      // monster-only spell
46     needs_tracer       = 0x00080000,      // monster casting needs tracer
47     noisy              = 0x00100000,      // makes noise, even if innate
48     testing            = 0x00200000,      // a testing/debugging spell
49                      //  0x00400000,      // was spflag::corpse_violating
50                      //  0x00800000,      // was SPFLAG_ALLOW_SELF
51     utility            = 0x01000000,      // usable no matter what foe is
52     no_ghost           = 0x02000000,      // ghosts can't get this spell
53     cloud              = 0x04000000,      // makes a cloud
54     WL_check           = 0x08000000,      // spell that checks monster WL
55     mons_abjure        = 0x10000000,      // monsters can cast abjuration
56                                           // instead of this spell
57     not_evil           = 0x20000000,      // not considered evil by the
58                                           // good gods
59     holy               = 0x40000000,      // considered holy (can't be
60                                           // used by Yred enslaved souls)
61 };
62 DEF_BITFIELD(spell_flags, spflag);
63 
64 enum class spret
65 {
66     abort = 0,            // should be left as 0
67     fail,
68     success,
69     none,                 // spell was not handled
70 };
71 
72 #define IOOD_X "iood_x"
73 #define IOOD_Y "iood_y"
74 #define IOOD_VX "iood_vx"
75 #define IOOD_VY "iood_vy"
76 #define IOOD_KC "iood_kc"
77 #define IOOD_POW "iood_pow"
78 #define IOOD_CASTER "iood_caster"
79 #define IOOD_REFLECTOR "iood_reflector"
80 #define IOOD_DIST "iood_distance"
81 #define IOOD_MID "iood_mid"
82 #define IOOD_FLAWED "iood_flawed"
83 #define IOOD_TPOS "iood_tpos"
84 
85 #define INNATE_SPELLS_KEY "innate_spells"
86 
87 #define fail_check() if (fail) return spret::fail
88 
89 void surge_power(const int enhanced);
90 void surge_power_wand(const int mp_cost);
91 
92 typedef bool (*spell_selector)(spell_type spell);
93 
94 int list_spells(bool toggle_with_I = true, bool viewing = false,
95                 bool allow_preselect = true,
96                 const string &title = "Your Spells",
97                 spell_selector selector = nullptr);
98 int raw_spell_fail(spell_type spell);
99 int stepdown_spellpower(int power, int scale = 1);
100 int calc_spell_power(spell_type spell, bool apply_intel,
101                      bool fail_rate_chk = false, bool cap_power = true,
102                      int scale = 1);
103 int calc_spell_range(spell_type spell, int power = 0, bool allow_bonus = true,
104                      bool ignore_shadows = false);
105 
106 bool cast_a_spell(bool check_range, spell_type spell = SPELL_NO_SPELL, dist *_target = nullptr);
107 
108 int apply_enhancement(const int initial_power, const int enhancer_levels);
109 
110 void inspect_spells();
111 bool can_cast_spells(bool quiet = false, bool exegesis = false);
112 void do_cast_spell_cmd(bool force);
113 
114 int hex_success_chance(const int mr, int powc, int scale,
115                        bool round_up = false);
116 class targeter;
117 unique_ptr<targeter> find_spell_targeter(spell_type spell, int pow, int range);
118 bool spell_has_targeter(spell_type spell);
119 vector<string> desc_wl_success_chance(const monster_info& mi, int pow,
120                                       targeter* hitfunc);
121 
122 typedef function<vector<string> (const monster_info& mi)> (desc_filter);
123 desc_filter targeter_addl_desc(spell_type spell, int powc, spell_flags flags,
124                                        targeter *hitfunc);
125 spret your_spells(spell_type spell, int powc = 0, bool allow_fail = true,
126                   const item_def* const evoked_item = nullptr,
127                   dist *_target = nullptr);
128 
129 extern const char *fail_severity_adjs[];
130 
131 int max_miscast_damage(spell_type spell);
132 int fail_severity(spell_type spell);
133 int failure_rate_colour(spell_type spell);
134 int failure_rate_to_int(int fail);
135 string failure_rate_to_string(int fail);
136 
137 int power_to_barcount(int power);
138 
139 int spell_power_percent(spell_type spell);
140 string spell_power_string(spell_type spell);
141 string spell_damage_string(spell_type spell, bool evoked = false);
142 int spell_acc(spell_type spell);
143 string spell_range_string(spell_type spell);
144 string range_string(int range, int maxrange, char32_t caster_char);
145 string spell_schools_string(spell_type spell);
146 string spell_failure_rate_string(spell_type spell);
147 string spell_noise_string(spell_type spell, int chop_wiz_display_width = 0);
148 
149 void spell_skills(spell_type spell, set<skill_type> &skills);
150 void do_demonic_magic(int pow, int rank);
151