1 /**
2  * @file
3  * @brief data handlers for player spell list
4 **/
5 
6 #pragma once
7 
8 #include <functional>
9 #include <vector>
10 
11 #include "enum.h"
12 #include "mon-info.h"
13 
14 using std::vector;
15 
16 enum class spschool
17 {
18   none           = 0,
19   conjuration    = 1<<0,
20   hexes          = 1<<1,
21   fire           = 1<<2,
22   ice            = 1<<3,
23   transmutation  = 1<<4,
24   necromancy     = 1<<5,
25   summoning      = 1<<6,
26   translocation  = 1<<7,
27   poison         = 1<<8,
28   earth          = 1<<9,
29   air            = 1<<10,
30   LAST_SCHOOL    = spschool::air,
31   random         = spschool::LAST_SCHOOL << 1,
32 };
33 DEF_BITFIELD(spschools_type, spschool, 10);
34 const int SPSCHOOL_LAST_EXPONENT = spschools_type::last_exponent;
35 COMPILE_CHECK(spschools_type::exponent(SPSCHOOL_LAST_EXPONENT)
36               == spschool::LAST_SCHOOL);
37 // Moved from mapdef.cc:5318, needed to ensure randbook spschools are short ints
38 COMPILE_CHECK(static_cast<int>(spschool::LAST_SCHOOL) < SHRT_MAX);
39 
40 struct bolt;
41 class dist;
42 struct direction_chooser_args;
43 
44 enum spell_highlight_colours
45 {
46     COL_UNKNOWN      = LIGHTGRAY,   // spells for which no known brand applies.
47     COL_UNMEMORIZED  = LIGHTBLUE,   // spell hasn't been memorised (used reading spellbooks)
48     COL_MEMORIZED    = LIGHTGRAY,   // spell has been memorised
49     COL_USELESS      = DARKGRAY,    // ability would have no useful effect
50     COL_INAPPLICABLE = COL_USELESS, // ability cannot be meaningfully applied (e.g., no targets)
51     COL_FORBIDDEN    = LIGHTRED,    // The player's god hates this ability
52     COL_DANGEROUS    = LIGHTRED,    // ability/spell use could be dangerous
53 };
54 
55 bool is_valid_spell(spell_type spell);
56 void init_spell_descs();
57 void init_spell_name_cache();
58 bool spell_data_initialized();
59 spell_type spell_by_name(string name, bool partial_match = false);
60 
61 spschool school_by_name(string name);
62 
63 int get_spell_slot_by_letter(char letter);
64 int get_spell_letter(spell_type spell);
65 spell_type get_spell_by_letter(char letter);
66 
67 bool add_spell_to_memory(spell_type spell);
68 bool del_spell_from_memory_by_slot(int slot);
69 bool del_spell_from_memory(spell_type spell);
70 
71 int spell_mana(spell_type which_spell, bool real_spell = true);
72 int spell_difficulty(spell_type which_spell);
73 int spell_power_cap(spell_type spell);
74 int spell_range(spell_type spell, int pow, bool allow_bonus = true,
75                 bool ignore_shadows = false);
76 int spell_noise(spell_type spell);
77 int spell_effect_noise(spell_type spell);
78 
79 const char *get_spell_target_prompt(spell_type which_spell);
80 tileidx_t get_spell_tile(spell_type which_spell);
81 
82 bool spell_is_direct_explosion(spell_type spell);
83 bool spell_harms_target(spell_type spell);
84 bool spell_harms_area(spell_type spell);
85 bool spell_is_direct_attack(spell_type spell);
86 int spell_levels_required(spell_type which_spell);
87 
88 spell_flags get_spell_flags(spell_type which_spell);
89 
90 bool spell_typematch(spell_type which_spell, spschool which_disc);
91 spschools_type get_spell_disciplines(spell_type which_spell);
92 int count_bits(uint64_t bits);
93 
94 template <class E, int Exp>
count_bits(enum_bitfield<E,Exp> bits)95 int count_bits(enum_bitfield<E, Exp> bits)
96 {
97     return count_bits(bits.flags);
98 }
99 
100 const char *spell_title(spell_type which_spell);
101 const char* spelltype_short_name(spschool which_spelltype);
102 const char* spelltype_long_name(spschool which_spelltype);
103 
104 typedef function<int (coord_def where)> cell_func;
105 typedef function<int (coord_def where, int pow, int spreadrate,
106                        cloud_type type, const actor* agent, int excl_rad)>
107         cloud_func;
108 
109 int apply_area_visible(cell_func cf, const coord_def& where);
110 
111 int apply_random_around_square(cell_func cf, const coord_def& where,
112                                bool hole_in_middle, int max_targs);
113 
114 void apply_area_cloud(cloud_func func, const coord_def& where,
115                       int pow, int number, cloud_type ctype,
116                       const actor *agent, int spread_rate = -1,
117                       int excl_rad = -1);
118 
119 bool spell_direction(dist &spelld, bolt &pbolt,
120                      direction_chooser_args *args = nullptr);
121 
122 skill_type spell_type2skill(spschool spelltype);
123 spschool skill2spell_type(skill_type spell_skill);
124 
125 skill_type arcane_mutation_to_skill(mutation_type mutation);
126 bool cannot_use_schools(spschools_type schools);
127 
128 bool spell_is_form(spell_type spell) PURE;
129 
130 bool casting_is_useless(spell_type spell, bool temp);
131 string casting_uselessness_reason(spell_type spell, bool temp);
132 bool spell_is_useless(spell_type spell, bool temp = true,
133                       bool prevent = false, bool fake_spell = false) PURE;
134 string spell_uselessness_reason(spell_type spell, bool temp = true,
135                                 bool prevent = false,
136                                 bool fake_spell = false) PURE;
137 
138 int spell_highlight_by_utility(spell_type spell,
139                                 int default_colour = COL_UNKNOWN,
140                                 bool transient = false,
141                                 bool memcheck = false);
142 bool spell_no_hostile_in_range(spell_type spell);
143 
144 bool spell_is_soh_breath(spell_type spell);
145 const vector<spell_type> *soh_breath_spells(spell_type spell);
146 
147 bool spell_removed(spell_type spell);
148 
149 void end_wait_spells(bool quiet = false);
150