1 /**
2  * @file
3  * @brief data handlers for player-available spell list
4 **/
5 
6 #include "AppHdr.h"
7 
8 #include "spl-util.h"
9 
10 #include <algorithm>
11 #include <cctype>
12 #include <climits>
13 #include <cstdio>
14 #include <cstdlib>
15 #include <cstring>
16 
17 #include "areas.h"
18 #include "art-enum.h"
19 #include "coordit.h"
20 #include "directn.h"
21 #include "env.h"
22 #include "god-passive.h"
23 #include "god-abil.h"
24 #include "item-prop.h"
25 #include "level-state-type.h"
26 #include "libutil.h"
27 #include "message.h"
28 #include "notes.h"
29 #include "options.h"
30 #include "orb.h"
31 #include "output.h"
32 #include "prompt.h"
33 #include "religion.h"
34 #include "skills.h"
35 #include "spl-book.h"
36 #include "spl-clouds.h"
37 #include "spl-damage.h"
38 #include "spl-other.h"
39 #include "spl-summoning.h"
40 #include "spl-transloc.h"
41 #include "spl-util.h"
42 #include "spl-zap.h"
43 #include "stringutil.h"
44 #include "target.h"
45 #include "terrain.h"
46 #include "rltiles/tiledef-gui.h"    // spell tiles
47 #include "tag-version.h"
48 #include "tiles-build-specific.h"
49 #include "transform.h"
50 
51 struct spell_desc
52 {
53     spell_type id;
54     const char  *title;
55     spschools_type disciplines;
56     spell_flags flags;       // bitfield
57     unsigned int level;
58 
59     // Usually in the range 0..200 (0 means uncapped).
60     // Note that some spells are also capped through zap_type.
61     // See spell_power_cap below.
62     int power_cap;
63 
64     // At power 0, you get min_range. At power power_cap, you get max_range.
65     int min_range;
66     int max_range;
67 
68     // Noise made directly by casting this spell.
69     // Noise used to be based directly on spell level:
70     //  * for conjurations: spell level
71     //  * for non-conj pois/air: spell level / 2 (rounded up)
72     //  * for others: spell level * 3/4 (rounded up)
73     // These are probably good guidelines for new spells.
74     int noise;
75 
76     // Some spells have a noise at their place of effect, in addition
77     // to at the place of casting. effect_noise handles that, and is also
78     // used even if the spell is not casted directly (by Xom, for instance).
79     int effect_noise;
80 
81     /// Icon for the spell in e.g. spellbooks, casting menus, etc.
82     tileidx_t tile;
83 };
84 
85 // TODO: apply https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2
86 // to spelldata
87 #include "spl-data.h"
88 
89 // spell_list is a static vector mapping spell_type enum values into positions
90 // in spelldata. It is not initialized until game startup, so can't be relied
91 // on in static constructors. (E.g., all spells register as invalid until
92 // `init_spell_descs` has been run.)
_get_spell_list()93 static vector<int> &_get_spell_list()
94 {
95     // https://isocpp.org/wiki/faq/ctors#construct-on-first-use-v2
96     static vector<int> spell_list(NUM_SPELLS, -1);
97     return spell_list;
98 }
99 
100 #define SPELLDATASIZE ARRAYSZ(spelldata)
101 
102 static const struct spell_desc *_seekspell(spell_type spellid);
103 
104 //
105 //             BEGIN PUBLIC FUNCTIONS
106 //
107 
108 // All this does is merely refresh the internal spell list {dlb}:
init_spell_descs()109 void init_spell_descs()
110 {
111     vector<int> &spell_list = _get_spell_list();
112 
113     for (unsigned int i = 0; i < SPELLDATASIZE; i++)
114     {
115         const spell_desc &data = spelldata[i];
116 
117         ASSERTM(data.id >= SPELL_NO_SPELL && data.id < NUM_SPELLS,
118                 "spell #%d has invalid id %d", i, data.id);
119 
120         ASSERTM(data.title != nullptr && *data.title,
121                 "spell #%d, id %d has no name", i, data.id);
122 
123         ASSERTM(data.level >= 1 && data.level <= 9,
124                 "spell '%s' has invalid level %d", data.title, data.level);
125 
126         ASSERTM(data.min_range <= data.max_range,
127                 "spell '%s' has min_range larger than max_range", data.title);
128 
129         ASSERTM(!(data.flags & spflag::targeting_mask)
130                 || (data.min_range >= 0 && data.max_range > 0),
131                 "targeted/directed spell '%s' has invalid range", data.title);
132 
133         if (!spell_removed(data.id)
134             && data.id != SPELL_NO_SPELL
135             && data.id != SPELL_DEBUGGING_RAY)
136         {
137             ASSERTM(!(data.flags & spflag::monster && is_player_spell(data.id)),
138                 "spell '%s' is declared as a monster spell but is a player spell", data.title);
139 
140             ASSERTM(!(!(data.flags & spflag::monster) && !is_player_spell(data.id)),
141                 "spell '%s' is not declared as a monster spell but is not a player spell", data.title);
142         }
143 
144         spell_list[data.id] = i;
145     }
146 }
147 
148 typedef map<string, spell_type> spell_name_map;
149 
_get_spell_name_cache()150 static spell_name_map &_get_spell_name_cache()
151 {
152     static spell_name_map spell_name_cache;
153     return spell_name_cache;
154 }
155 
init_spell_name_cache()156 void init_spell_name_cache()
157 {
158     spell_name_map &cache = _get_spell_name_cache();
159     for (int i = 0; i < NUM_SPELLS; i++)
160     {
161         spell_type type = static_cast<spell_type>(i);
162 
163         if (!is_valid_spell(type))
164             continue;
165 
166         const char *sptitle = spell_title(type);
167         ASSERT(sptitle);
168         const string spell_name = lowercase_string(sptitle);
169         cache[spell_name] = type;
170     }
171 }
172 
spell_data_initialized()173 bool spell_data_initialized()
174 {
175     return _get_spell_name_cache().size() > 0;
176 }
177 
spell_by_name(string name,bool partial_match)178 spell_type spell_by_name(string name, bool partial_match)
179 {
180     if (name.empty())
181         return SPELL_NO_SPELL;
182 
183     lowercase(name);
184 
185     if (!partial_match)
186         return lookup(_get_spell_name_cache(), name, SPELL_NO_SPELL);
187 
188     const spell_type sp = find_earliest_match(name, SPELL_NO_SPELL, NUM_SPELLS,
189                                               is_valid_spell, spell_title);
190     return sp == NUM_SPELLS ? SPELL_NO_SPELL : sp;
191 }
192 
school_by_name(string name)193 spschool school_by_name(string name)
194 {
195     spschool short_match, long_match;
196     int                short_matches, long_matches;
197 
198     short_match   = long_match   = spschool::none;
199     short_matches = long_matches = 0;
200 
201     lowercase(name);
202 
203     for (int i = 0; i <= (int)spschool::random; i++)
204     {
205         const auto type = spschools_type::exponent(i);
206 
207         string short_name = spelltype_short_name(type);
208         string long_name  = spelltype_long_name(type);
209 
210         lowercase(short_name);
211         lowercase(long_name);
212 
213         if (name == short_name)
214             return type;
215         if (name == long_name)
216             return type;
217 
218         if (short_name.find(name) != string::npos)
219         {
220             short_match = type;
221             short_matches++;
222         }
223         if (long_name.find(name) != string::npos)
224         {
225             long_match = type;
226             long_matches++;
227         }
228     }
229 
230     if (short_matches != 1 && long_matches != 1)
231         return spschool::none;
232 
233     if (short_matches == 1 && long_matches != 1)
234         return short_match;
235     if (short_matches != 1 && long_matches == 1)
236         return long_match;
237 
238     if (short_match == long_match)
239         return short_match;
240 
241     return spschool::none;
242 }
243 
get_spell_slot_by_letter(char letter)244 int get_spell_slot_by_letter(char letter)
245 {
246     ASSERT(isaalpha(letter));
247 
248     const int index = letter_to_index(letter);
249 
250     if (you.spell_letter_table[ index ] == -1)
251         return -1;
252 
253     return you.spell_letter_table[index];
254 }
255 
_get_spell_slot(spell_type spell)256 static int _get_spell_slot(spell_type spell)
257 {
258     // you.spells is a FixedVector of spells in some arbitrary order. It
259     // doesn't corespond to letters.
260     auto i = find(begin(you.spells), end(you.spells), spell);
261     return i == end(you.spells) ? -1 : i - begin(you.spells);
262 }
263 
_get_spell_letter_from_slot(int slot)264 static int _get_spell_letter_from_slot(int slot)
265 {
266     // you.spell_letter_table is a FixedVector that is basically a mapping
267     // from alpha char indices to spell slots (e.g. indices in you.spells).
268     auto letter = find(begin(you.spell_letter_table), end(you.spell_letter_table), slot);
269     return letter == end(you.spell_letter_table) ? -1 : letter - begin(you.spell_letter_table);
270 }
271 
get_spell_letter(spell_type spell)272 int get_spell_letter(spell_type spell)
273 {
274     int i = _get_spell_letter_from_slot(_get_spell_slot(spell));
275     return (i == -1) ? -1 : index_to_letter(i);
276 }
277 
get_spell_by_letter(char letter)278 spell_type get_spell_by_letter(char letter)
279 {
280     ASSERT(isaalpha(letter));
281 
282     const int slot = get_spell_slot_by_letter(letter);
283 
284     return (slot == -1) ? SPELL_NO_SPELL : you.spells[slot];
285 }
286 
add_spell_to_memory(spell_type spell)287 bool add_spell_to_memory(spell_type spell)
288 {
289     if (vehumet_is_offering(spell))
290         library_add_spells({ spell });
291 
292     int slot_i;
293     int letter_j = -1;
294     string sname = spell_title(spell);
295     lowercase(sname);
296     // first we find a slot in our head:
297     for (slot_i = 0; slot_i < MAX_KNOWN_SPELLS; slot_i++)
298     {
299         if (you.spells[slot_i] == SPELL_NO_SPELL)
300             break;
301     }
302 
303     you.spells[slot_i] = spell;
304 
305     // now we find an available label:
306     // first check to see whether we've chosen an automatic label:
307     bool overwrite = false;
308     for (const auto &entry : Options.auto_spell_letters)
309     {
310         if (!entry.first.matches(sname))
311             continue;
312         for (char ch : entry.second)
313         {
314             if (ch == '+')
315                 overwrite = true;
316             else if (ch == '-')
317                 overwrite = false;
318             else if (isaalpha(ch))
319             {
320                 const int new_letter = letter_to_index(ch);
321                 const int existing_slot = you.spell_letter_table[new_letter];
322                 if (existing_slot == -1)
323                 {
324                     letter_j = new_letter;
325                     break;
326                 }
327                 else if (overwrite)
328                 {
329                     const string ename = lowercase_string(
330                             spell_title(get_spell_by_letter(ch)));
331                     // Don't overwrite a spell matched by the same rule.
332                     if (!entry.first.matches(ename))
333                     {
334                         letter_j = new_letter;
335                         break;
336                     }
337                 }
338                 // Otherwise continue on to the next letter in this rule.
339             }
340         }
341         if (letter_j != -1)
342             break;
343     }
344     // If we didn't find a label above, choose the first available one.
345     if (letter_j == -1)
346         for (letter_j = 0; letter_j < 52; letter_j++)
347         {
348             if (you.spell_letter_table[letter_j] == -1)
349                 break;
350         }
351 
352     if (you.num_turns)
353         mprf("Spell assigned to '%c'.", index_to_letter(letter_j));
354 
355     // Swapping with an existing spell.
356     if (you.spell_letter_table[letter_j] != -1)
357     {
358         // Find a spot for the spell being moved. Assumes there will be one.
359         for (int free_letter = 0; free_letter < 52; free_letter++)
360             if (you.spell_letter_table[free_letter] == -1)
361             {
362                 you.spell_letter_table[free_letter] = you.spell_letter_table[letter_j];
363                 break;
364             }
365     }
366 
367     you.spell_letter_table[letter_j] = slot_i;
368 
369     you.spell_no++;
370 
371     take_note(Note(NOTE_LEARN_SPELL, spell));
372 
373     spell_skills(spell, you.skills_to_show);
374 
375 #ifdef USE_TILE_LOCAL
376     tiles.layout_statcol();
377     redraw_screen();
378     update_screen();
379 #endif
380 
381     return true;
382 }
383 
del_spell_from_memory_by_slot(int slot)384 bool del_spell_from_memory_by_slot(int slot)
385 {
386     ASSERT_RANGE(slot, 0, MAX_KNOWN_SPELLS);
387 
388     if (you.last_cast_spell == you.spells[slot])
389         you.last_cast_spell = SPELL_NO_SPELL;
390 
391     spell_skills(you.spells[slot], you.skills_to_hide);
392 
393     mprf("Your memory of %s unravels.", spell_title(you.spells[slot]));
394 
395     you.spells[slot] = SPELL_NO_SPELL;
396 
397     for (int j = 0; j < 52; j++)
398         if (you.spell_letter_table[j] == slot)
399             you.spell_letter_table[j] = -1;
400 
401     you.spell_no--;
402 
403 #ifdef USE_TILE_LOCAL
404     tiles.layout_statcol();
405     redraw_screen();
406     update_screen();
407 #endif
408 
409     return true;
410 }
411 
del_spell_from_memory(spell_type spell)412 bool del_spell_from_memory(spell_type spell)
413 {
414     int i = _get_spell_slot(spell);
415     if (i == -1)
416         return false;
417     else
418         return del_spell_from_memory_by_slot(i);
419 }
420 
421 // Checks if the spell is an explosion that can be placed anywhere even without
422 // an unobstructed beam path, such as fire storm.
spell_is_direct_explosion(spell_type spell)423 bool spell_is_direct_explosion(spell_type spell)
424 {
425     return spell == SPELL_FIRE_STORM || spell == SPELL_CALL_DOWN_DAMNATION
426            || spell == SPELL_GHOSTLY_SACRIFICE || spell == SPELL_UPHEAVAL
427            || spell == SPELL_ERUPTION;
428 }
429 
spell_harms_target(spell_type spell)430 bool spell_harms_target(spell_type spell)
431 {
432     const spell_flags flags = _seekspell(spell)->flags;
433 
434     if (flags & (spflag::helpful | spflag::neutral))
435         return false;
436 
437     if (flags & spflag::targeting_mask)
438         return true;
439 
440     // n.b. this excludes various untargeted attack spells like hailstorm, abs 0
441 
442     return false;
443 }
444 
spell_harms_area(spell_type spell)445 bool spell_harms_area(spell_type spell)
446 {
447     const spell_flags flags = _seekspell(spell)->flags;
448 
449     if (flags & (spflag::helpful | spflag::neutral))
450         return false;
451 
452     if (flags & spflag::area)
453         return true;
454 
455     return false;
456 }
457 
458 /**
459  * Does the spell cause damage directly on a successful, non-resisted, cast?
460  * This is much narrower than "harm", and excludes e.g. hexes that harm in a
461  * broader sense.
462  */
spell_is_direct_attack(spell_type spell)463 bool spell_is_direct_attack(spell_type spell)
464 {
465     if (spell_harms_target(spell))
466     {
467         // spell school exceptions
468         if (   spell == SPELL_VIOLENT_UNRAVELLING  // hex
469             || spell == SPELL_FORCE_LANCE // transloc
470             || spell == SPELL_GRAVITAS
471             || spell == SPELL_BLINKBOLT
472             || spell == SPELL_BANISHMENT)
473         {
474             return true;
475         }
476 
477         // spell schools that generally "harm" but not damage
478         if (get_spell_disciplines(spell) & (spschool::hexes | spschool::translocation | spschool::summoning))
479             return false;
480 
481         // harms target exceptions outside of those schools
482         if (spell == SPELL_PETRIFY
483             || spell == SPELL_STICKY_FLAME // maybe ok?
484             || spell == SPELL_FREEZING_CLOUD // some targeted cloud spells that do indirect damage via the clouds
485             || spell == SPELL_MEPHITIC_CLOUD
486             || spell == SPELL_POISONOUS_CLOUD)
487         {
488             return false;
489         }
490 
491         return true;
492     }
493 
494     // The area harm check has too many false positives to bother with here
495     if (   spell == SPELL_ISKENDERUNS_MYSTIC_BLAST
496         || spell == SPELL_OZOCUBUS_REFRIGERATION
497         || spell == SPELL_SYMBOL_OF_TORMENT
498         || spell == SPELL_SHATTER
499         || spell == SPELL_DISCHARGE
500         || spell == SPELL_CHAIN_LIGHTNING
501         || spell == SPELL_DRAIN_LIFE
502         || spell == SPELL_CHAIN_OF_CHAOS
503         || spell == SPELL_IRRADIATE
504         || spell == SPELL_IGNITION
505         || spell == SPELL_STARBURST
506         || spell == SPELL_HAILSTORM
507         || spell == SPELL_MANIFOLD_ASSAULT
508         || spell == SPELL_MAXWELLS_COUPLING) // n.b. not an area spell
509     {
510         return true;
511     }
512     return false;
513 }
514 
515 // How much MP does it cost for the player to cast this spell?
516 //
517 // @param real_spell  True iff the player is casting the spell normally,
518 // not via an evocable or other odd source.
spell_mana(spell_type which_spell,bool real_spell)519 int spell_mana(spell_type which_spell, bool real_spell)
520 {
521     const int level = _seekspell(which_spell)->level;
522     if (real_spell && (you.duration[DUR_BRILLIANCE]
523                        || player_equip_unrand(UNRAND_FOLLY)))
524     {
525         return level/2 + level%2; // round up
526     }
527     return level;
528 }
529 
530 // applied in naughties (more difficult = higher level knowledge = worse)
531 // and triggers for Sif acting (same reasoning as above, just good) {dlb}
spell_difficulty(spell_type which_spell)532 int spell_difficulty(spell_type which_spell)
533 {
534     return _seekspell(which_spell)->level;
535 }
536 
spell_levels_required(spell_type which_spell)537 int spell_levels_required(spell_type which_spell)
538 {
539     return spell_difficulty(which_spell);
540 }
541 
get_spell_flags(spell_type which_spell)542 spell_flags get_spell_flags(spell_type which_spell)
543 {
544     return _seekspell(which_spell)->flags;
545 }
546 
get_spell_target_prompt(spell_type which_spell)547 const char *get_spell_target_prompt(spell_type which_spell)
548 {
549     switch (which_spell)
550     {
551     case SPELL_APPORTATION:
552         return "Apport";
553     case SPELL_SMITING:
554         return "Smite";
555     case SPELL_LRD:
556         return "Fragment what (e.g. wall or brittle monster)?";
557     default:
558         return nullptr;
559     }
560 }
561 
562 /// What's the icon for the given spell?
get_spell_tile(spell_type which_spell)563 tileidx_t get_spell_tile(spell_type which_spell)
564 {
565     return _seekspell(which_spell)->tile;
566 }
567 
spell_typematch(spell_type which_spell,spschool which_disc)568 bool spell_typematch(spell_type which_spell, spschool which_disc)
569 {
570     return bool(get_spell_disciplines(which_spell) & which_disc);
571 }
572 
573 //jmf: next two for simple bit handling
get_spell_disciplines(spell_type spell)574 spschools_type get_spell_disciplines(spell_type spell)
575 {
576     return _seekspell(spell)->disciplines;
577 }
578 
count_bits(uint64_t bits)579 int count_bits(uint64_t bits)
580 {
581     uint64_t n;
582     int c = 0;
583 
584     for (n = 1; n; n <<= 1)
585         if (n & bits)
586             c++;
587 
588     return c;
589 }
590 
spell_title(spell_type spell)591 const char *spell_title(spell_type spell)
592 {
593     return _seekspell(spell)->title;
594 }
595 
596 // FUNCTION APPLICATORS: Idea from Juho Snellman <jsnell@lyseo.edu.ouka.fi>
597 //                       on the Roguelike News pages, Development section.
598 //                       <URL:http://www.skoardy.demon.co.uk/rlnews/>
599 // Here are some function applicators: sort of like brain-dead,
600 // home-grown iterators for the container "dungeon".
601 
602 // Apply a function-pointer to all visible squares
603 // Returns summation of return values from passed in function.
apply_area_visible(cell_func cf,const coord_def & where)604 int apply_area_visible(cell_func cf, const coord_def &where)
605 {
606     int rv = 0;
607 
608     for (radius_iterator ri(where, LOS_NO_TRANS); ri; ++ri)
609         rv += cf(*ri);
610 
611     return rv;
612 }
613 
614 // Applies the effect to all nine squares around/including the target.
615 // Returns summation of return values from passed in function.
_apply_area_square(cell_func cf,const coord_def & where)616 static int _apply_area_square(cell_func cf, const coord_def& where)
617 {
618     int rv = 0;
619 
620     for (adjacent_iterator ai(where, false); ai; ++ai)
621         rv += cf(*ai);
622 
623     return rv;
624 }
625 
626 // Applies the effect to the eight squares beside the target.
627 // Returns summation of return values from passed in function.
_apply_area_around_square(cell_func cf,const coord_def & where)628 static int _apply_area_around_square(cell_func cf, const coord_def& where)
629 {
630     int rv = 0;
631 
632     for (adjacent_iterator ai(where, true); ai; ++ai)
633         rv += cf(*ai);
634 
635     return rv;
636 }
637 
638 // Affect up to max_targs monsters around a point, chosen randomly.
639 // Return varies with the function called; return values will be added up.
apply_random_around_square(cell_func cf,const coord_def & where,bool exclude_center,int max_targs)640 int apply_random_around_square(cell_func cf, const coord_def& where,
641                                bool exclude_center, int max_targs)
642 {
643     int rv = 0;
644 
645     if (max_targs <= 0)
646         return 0;
647 
648     if (max_targs >= 9 && !exclude_center)
649         return _apply_area_square(cf, where);
650 
651     if (max_targs >= 8 && exclude_center)
652         return _apply_area_around_square(cf, where);
653 
654     coord_def targs[8];
655 
656     int count = 0;
657 
658     for (adjacent_iterator ai(where, exclude_center); ai; ++ai)
659     {
660         if (monster_at(*ai) == nullptr && *ai != you.pos())
661             continue;
662 
663         // Found target
664         count++;
665 
666         // Slight difference here over the basic algorithm...
667         //
668         // For cases where the number of choices <= max_targs it's
669         // obvious (all available choices will be selected).
670         //
671         // For choices > max_targs, here's a brief proof:
672         //
673         // Let m = max_targs, k = choices - max_targs, k > 0.
674         //
675         // Proof, by induction (over k):
676         //
677         // 1) Show n = m + 1 (k = 1) gives uniform distribution,
678         //    P(new one not chosen) = 1 / (m + 1).
679         //                                         m     1     1
680         //    P(specific previous one replaced) = --- * --- = ---
681         //                                        m+1    m    m+1
682         //
683         //    So the probablity is uniform (ie. any element has
684         //    a 1/(m+1) chance of being in the unchosen slot).
685         //
686         // 2) Assume the distribution is uniform at n = m+k.
687         //    (ie. the probablity that any of the found elements
688         //     was chosen = m / (m+k) (the slots are symmetric,
689         //     so it's the sum of the probabilities of being in
690         //     any of them)).
691         //
692         // 3) Show n = m + k + 1 gives a uniform distribution.
693         //    P(new one chosen) = m / (m + k + 1)
694         //    P(any specific previous choice remaining chosen)
695         //    = [1 - P(swapped into m+k+1 position)] * P(prev. chosen)
696         //              m      1       m
697         //    = [ 1 - ----- * --- ] * ---
698         //            m+k+1    m      m+k
699         //
700         //       m+k     m       m
701         //    = ----- * ---  = -----
702         //      m+k+1   m+k    m+k+1
703         //
704         // Therefore, it's uniform for n = m + k + 1. QED
705         //
706         // The important thing to note in calculating the last
707         // probability is that the chosen elements have already
708         // passed tests which verify that they *don't* belong
709         // in slots m+1...m+k, so the only positions an already
710         // chosen element can end up in are its original
711         // position (in one of the chosen slots), or in the
712         // new slot.
713         //
714         // The new item can, of course, be placed in any slot,
715         // swapping the value there into the new slot... we
716         // just don't care about the non-chosen slots enough
717         // to store them, so it might look like the item
718         // automatically takes the new slot when not chosen
719         // (although, by symmetry all the non-chosen slots are
720         // the same... and similarly, by symmetry, all chosen
721         // slots are the same).
722         //
723         // Yes, that's a long comment for a short piece of
724         // code, but I want people to have an understanding
725         // of why this works (or at least make them wary about
726         // changing it without proof and breaking this code). -- bwr
727 
728         // Accept the first max_targs choices, then when
729         // new choices come up, replace one of the choices
730         // at random, max_targs/count of the time (the rest
731         // of the time it replaces an element in an unchosen
732         // slot -- but we don't care about them).
733         if (count <= max_targs)
734             targs[count - 1] = *ai;
735         else if (x_chance_in_y(max_targs, count))
736         {
737             const int pick = random2(max_targs);
738             targs[ pick ] = *ai;
739         }
740     }
741 
742     const int targs_found = min(count, max_targs);
743 
744     if (targs_found)
745     {
746         // Used to divide the power up among the targets here, but
747         // it's probably better to allow the full power through and
748         // balance the called function. -- bwr
749         for (int i = 0; i < targs_found; i++)
750         {
751             ASSERT(!targs[i].origin());
752             rv += cf(targs[i]);
753         }
754     }
755 
756     return rv;
757 }
758 
759 /*
760  * Place clouds over an area with a function.
761  *
762  * @param func        A function called to place each cloud.
763  * @param where       The starting location of the cloud. A targeter_cloud
764  *                    with aim set to this location is used to determine the
765  *                    affected locations.
766  * @param pow         The spellpower of the spell placing the clouds, which
767  *                    determines how long the cloud will last.
768  * @param number      How many clouds to place in total. Only this number will
769  *                    be placed regardless
770  * @param ctype       The type of cloud to place.
771  * @param agent       Any agent that may have caused the cloud. If this is the
772  *                    player, god conducts are applied.
773  * @param spread_rate How quickly the cloud spreads.
774  * @param excl_rad    How large of an exclusion radius to make around the
775  *                    cloud.
776 */
apply_area_cloud(cloud_func func,const coord_def & where,int pow,int number,cloud_type ctype,const actor * agent,int spread_rate,int excl_rad)777 void apply_area_cloud(cloud_func func, const coord_def& where,
778                        int pow, int number, cloud_type ctype,
779                        const actor *agent, int spread_rate, int excl_rad)
780 {
781     if (number <= 0)
782         return;
783 
784     targeter_cloud place(agent, GDM, number, number);
785     if (!place.set_aim(where))
786         return;
787     unsigned int dist = 0;
788     while (number > 0)
789     {
790         while (place.queue[dist].empty())
791             if (++dist >= place.queue.size())
792                 return;
793         vector<coord_def> &q = place.queue[dist];
794         int el = random2(q.size());
795         coord_def c = q[el];
796         q[el] = q[q.size() - 1];
797         q.pop_back();
798 
799         if (place.seen[c] <= 0 || cell_is_solid(c))
800             continue;
801         func(c, pow, spread_rate, ctype, agent, excl_rad);
802         number--;
803     }
804 }
805 
806 /**
807  * Select a spell target and fill dist and pbolt appropriately.
808  *
809  * @param[out] spelld    the output of the direction() call.
810  * @param[in, out] pbolt a beam; its range is used if none is set in args, and
811  *                       its source and target are set if the direction() call
812  *                       succeeds.
813  * @param[in] args       The arguments for the direction() call. May be null,
814  *                       which case a default is used.
815  * @return false if the user cancelled, true otherwise.
816  */
spell_direction(dist & spelld,bolt & pbolt,direction_chooser_args * args)817 bool spell_direction(dist &spelld, bolt &pbolt, direction_chooser_args *args)
818 {
819     direction_chooser_args newargs;
820     // This should be before the overwrite, so callers can specify a different
821     // mode if they want.
822     newargs.mode = TARG_HOSTILE;
823     if (args)
824         newargs = *args;
825     if (newargs.range < 1)
826         newargs.range = (pbolt.range < 1) ? you.current_vision : pbolt.range;
827 
828     direction(spelld, newargs);
829 
830     if (!spelld.isValid)
831     {
832         // Check for user cancel in interactive direction choosing.
833         if (spelld.isCancel && spelld.interactive && !spelld.fire_context)
834             canned_msg(MSG_OK);
835         return false;
836     }
837 
838     pbolt.set_target(spelld);
839     pbolt.source = you.pos();
840 
841     return true;
842 }
843 
spelltype_short_name(spschool which_spelltype)844 const char* spelltype_short_name(spschool which_spelltype)
845 {
846     switch (which_spelltype)
847     {
848     case spschool::conjuration:
849         return "Conj";
850     case spschool::hexes:
851         return "Hex";
852     case spschool::fire:
853         return "Fire";
854     case spschool::ice:
855         return "Ice";
856     case spschool::transmutation:
857         return "Tmut";
858     case spschool::necromancy:
859         return "Necr";
860     case spschool::summoning:
861         return "Summ";
862     case spschool::translocation:
863         return "Tloc";
864     case spschool::poison:
865         return "Pois";
866     case spschool::earth:
867         return "Erth";
868     case spschool::air:
869         return "Air";
870     case spschool::random:
871         return "Rndm";
872     default:
873         return "Bug";
874     }
875 }
876 
spelltype_long_name(spschool which_spelltype)877 const char* spelltype_long_name(spschool which_spelltype)
878 {
879     switch (which_spelltype)
880     {
881     case spschool::conjuration:
882         return "Conjuration";
883     case spschool::hexes:
884         return "Hexes";
885     case spschool::fire:
886         return "Fire";
887     case spschool::ice:
888         return "Ice";
889     case spschool::transmutation:
890         return "Transmutation";
891     case spschool::necromancy:
892         return "Necromancy";
893     case spschool::summoning:
894         return "Summoning";
895     case spschool::translocation:
896         return "Translocation";
897     case spschool::poison:
898         return "Poison";
899     case spschool::earth:
900         return "Earth";
901     case spschool::air:
902         return "Air";
903     case spschool::random:
904         return "Random";
905     default:
906         return "Bug";
907     }
908 }
909 
spell_type2skill(spschool spelltype)910 skill_type spell_type2skill(spschool spelltype)
911 {
912     switch (spelltype)
913     {
914     case spschool::conjuration:    return SK_CONJURATIONS;
915     case spschool::hexes:          return SK_HEXES;
916     case spschool::fire:           return SK_FIRE_MAGIC;
917     case spschool::ice:            return SK_ICE_MAGIC;
918     case spschool::transmutation:  return SK_TRANSMUTATIONS;
919     case spschool::necromancy:     return SK_NECROMANCY;
920     case spschool::summoning:      return SK_SUMMONINGS;
921     case spschool::translocation:  return SK_TRANSLOCATIONS;
922     case spschool::poison:         return SK_POISON_MAGIC;
923     case spschool::earth:          return SK_EARTH_MAGIC;
924     case spschool::air:            return SK_AIR_MAGIC;
925 
926     default:
927         dprf("spell_type2skill: called with unmapped spell school %u"
928              " (name '%s')", static_cast<unsigned int>(spelltype),
929              spelltype_long_name(spelltype));
930         return SK_NONE;
931     }
932 }
933 
skill2spell_type(skill_type spell_skill)934 spschool skill2spell_type(skill_type spell_skill)
935 {
936     switch (spell_skill)
937     {
938     case SK_CONJURATIONS:    return spschool::conjuration;
939     case SK_HEXES:           return spschool::hexes;
940     case SK_FIRE_MAGIC:      return spschool::fire;
941     case SK_ICE_MAGIC:       return spschool::ice;
942     case SK_TRANSMUTATIONS:  return spschool::transmutation;
943     case SK_NECROMANCY:      return spschool::necromancy;
944     case SK_SUMMONINGS:      return spschool::summoning;
945     case SK_TRANSLOCATIONS:  return spschool::translocation;
946     case SK_POISON_MAGIC:    return spschool::poison;
947     case SK_EARTH_MAGIC:     return spschool::earth;
948     case SK_AIR_MAGIC:       return spschool::air;
949 
950     default:
951         return spschool::none;
952     }
953 }
954 
955 /*
956  **************************************************
957  *                                                *
958  *              END PUBLIC FUNCTIONS              *
959  *                                                *
960  **************************************************
961  */
962 
963 //jmf: Simplified; moved init code to top function, init_spell_descs().
_seekspell(spell_type spell)964 static const spell_desc *_seekspell(spell_type spell)
965 {
966     ASSERT_RANGE(spell, 0, NUM_SPELLS);
967     const int index = _get_spell_list()[spell];
968     ASSERT(index != -1);
969 
970     return &spelldata[index];
971 }
972 
is_valid_spell(spell_type spell)973 bool is_valid_spell(spell_type spell)
974 {
975     return spell > SPELL_NO_SPELL && spell < NUM_SPELLS
976            && _get_spell_list()[spell] != -1;
977 }
978 
_spell_range_varies(spell_type spell)979 static bool _spell_range_varies(spell_type spell)
980 {
981     int minrange = _seekspell(spell)->min_range;
982     int maxrange = _seekspell(spell)->max_range;
983 
984     return minrange < maxrange;
985 }
986 
spell_power_cap(spell_type spell)987 int spell_power_cap(spell_type spell)
988 {
989     const int scap = _seekspell(spell)->power_cap;
990     const int zcap = spell_zap_power_cap(spell);
991 
992     if (scap == 0)
993         return zcap;
994     else if (zcap == 0)
995         return scap;
996     else
997     {
998         // Two separate power caps; pre-zapping spell power
999         // goes into range.
1000         if (scap <= zcap || _spell_range_varies(spell))
1001             return scap;
1002         else
1003             return zcap;
1004     }
1005 }
1006 
spell_range(spell_type spell,int pow,bool allow_bonus,bool ignore_shadows)1007 int spell_range(spell_type spell, int pow,
1008                 bool allow_bonus, bool ignore_shadows)
1009 {
1010     int minrange = _seekspell(spell)->min_range;
1011     int maxrange = _seekspell(spell)->max_range;
1012 
1013     const int range_cap = ignore_shadows ? you.normal_vision
1014                                          : you.current_vision;
1015 
1016     ASSERT(maxrange >= minrange);
1017 
1018     // spells with no range have maxrange == minrange == -1
1019     if (maxrange < 0)
1020         return maxrange;
1021 
1022     if (allow_bonus
1023         && vehumet_supports_spell(spell)
1024         && have_passive(passive_t::spells_range)
1025         && maxrange > 1
1026         && spell != SPELL_HAILSTORM // uses a special system
1027         && spell != SPELL_THUNDERBOLT) // lightning rod only
1028     {
1029         maxrange++;
1030         minrange++;
1031     }
1032 
1033     if (minrange == maxrange)
1034         return min(minrange, range_cap);
1035 
1036     const int powercap = spell_power_cap(spell);
1037 
1038     if (powercap <= pow)
1039         return min(maxrange, range_cap);
1040 
1041     // Round appropriately.
1042     return min(range_cap,
1043            (pow * (maxrange - minrange) + powercap / 2) / powercap + minrange);
1044 }
1045 
1046 /**
1047  * Spell casting noise.
1048  *
1049  * @param spell  The spell being casted.
1050  * @return       The amount of noise generated on cast.
1051  */
spell_noise(spell_type spell)1052 int spell_noise(spell_type spell)
1053 {
1054     return _seekspell(spell)->noise;
1055 }
1056 
1057 /**
1058  * Miscellaneous spell casting noise.
1059  *
1060  * This returns the usual spell noise for the effects of this spell.
1061  * Used for various noisy() calls, as well as the I screen; see effect_noise
1062  * comment above for more information.
1063  * @param spell  The spell being casted.
1064  * @return       The amount of noise generated by the effects of the spell.
1065  */
spell_effect_noise(spell_type spell)1066 int spell_effect_noise(spell_type spell)
1067 {
1068     const int noise = _seekspell(spell)->effect_noise;
1069 
1070     int expl_size;
1071     switch (spell)
1072     {
1073     case SPELL_MEPHITIC_CLOUD:
1074     case SPELL_FIREBALL:
1075     case SPELL_VIOLENT_UNRAVELLING:
1076     case SPELL_IGNITION:
1077         expl_size = 1;
1078         break;
1079 
1080     case SPELL_LRD:
1081         expl_size = 2; // Can reach 3 only with crystal walls, which are rare
1082         break;
1083 
1084     // worst case scenario for these
1085     case SPELL_FIRE_STORM:
1086     case SPELL_CONJURE_BALL_LIGHTNING:
1087         expl_size = 3;
1088         break;
1089 
1090     default:
1091         expl_size = 0;
1092     }
1093 
1094     if (expl_size)
1095         return explosion_noise(expl_size);
1096 
1097     return noise;
1098 }
1099 
1100 /**
1101  * Does the given spell map to a player transformation?
1102  *
1103  * @param spell     The spell in question.
1104  * @return          Whether the spell, when cast, puts the player in a form.
1105  */
spell_is_form(spell_type spell)1106 bool spell_is_form(spell_type spell)
1107 {
1108     switch (spell)
1109     {
1110         case SPELL_BEASTLY_APPENDAGE:
1111         case SPELL_BLADE_HANDS:
1112         case SPELL_DRAGON_FORM:
1113         case SPELL_ICE_FORM:
1114         case SPELL_SPIDER_FORM:
1115         case SPELL_STATUE_FORM:
1116         case SPELL_NECROMUTATION:
1117             return true;
1118         default:
1119             return false;
1120     }
1121 }
1122 
1123 /**
1124  * Casting-specific checks that are involved when casting any spell. Includes
1125  * MP (which does use the spell level if provided), confusion state, banned
1126  * schools.
1127  *
1128  * @param spell      The spell in question.
1129  * @param temp       Include checks for volatile or temporary states
1130  *                   (status effects, mana)
1131  * @return           Whether casting is useless
1132  */
casting_is_useless(spell_type spell,bool temp)1133 bool casting_is_useless(spell_type spell, bool temp)
1134 {
1135     return !casting_uselessness_reason(spell, temp).empty();
1136 }
1137 
1138 /**
1139  * Casting-specific checks that are involved when casting any spell or larger
1140  * groups of spells (e.g. entire schools). Includes MP (which does use the
1141  * spell level if provided), confusion state, banned schools.
1142  *
1143  * @param spell      The spell in question.
1144  * @param temp       Include checks for volatile or temporary states
1145  *                   (status effects, mana)
1146  # @return           A reason why casting is useless, or "" if it isn't.
1147  */
casting_uselessness_reason(spell_type spell,bool temp)1148 string casting_uselessness_reason(spell_type spell, bool temp)
1149 {
1150     if (temp)
1151     {
1152         if (you.duration[DUR_CONF] > 0)
1153             return "you're too confused to cast spells.";
1154 
1155         if (spell_difficulty(spell) > you.experience_level)
1156             return "you aren't experienced enough to cast this spell.";
1157 
1158         if (you.has_mutation(MUT_HP_CASTING))
1159         {
1160             // TODO: deduplicate with enough_hp()
1161             if (you.duration[DUR_DEATHS_DOOR])
1162                 return "you cannot pay life while functionally dead.";
1163             if (!enough_hp(spell_mana(spell), true, false))
1164                 return "you don't have enough health to cast this spell.";
1165         }
1166         else if (!enough_mp(spell_mana(spell), true, false))
1167             return "you don't have enough magic to cast this spell.";
1168 
1169         if (spell == SPELL_SUBLIMATION_OF_BLOOD
1170             && you.magic_points == you.max_magic_points)
1171         {
1172             if (you.has_mutation(MUT_HP_CASTING))
1173                 return "your magic and health are inextricable.";
1174             return "your reserves of magic are already full.";
1175         }
1176     }
1177 
1178     // Check for banned schools (Currently just Ru sacrifices)
1179     if (cannot_use_schools(get_spell_disciplines(spell)))
1180         return "you cannot use spells of this school.";
1181 
1182     // TODO: these checks were in separate places, but is this already covered
1183     // by cannot_use_schools?
1184     if (get_spell_disciplines(spell) & spschool::summoning
1185         && you.get_mutation_level(MUT_NO_LOVE))
1186     {
1187         return "you cannot coerce anything to answer your summons.";
1188     }
1189 
1190     // other Ru spells not affected by the school checks
1191     switch (spell)
1192     {
1193     case SPELL_ANIMATE_DEAD:
1194     case SPELL_ANIMATE_SKELETON:
1195     case SPELL_DEATH_CHANNEL:
1196     case SPELL_SIMULACRUM:
1197     case SPELL_INFESTATION:
1198     case SPELL_TUKIMAS_DANCE:
1199         if (you.get_mutation_level(MUT_NO_LOVE))
1200             return "you cannot coerce anything to obey you.";
1201         break;
1202     default:
1203         break;
1204     }
1205 
1206 
1207     return "";
1208 }
1209 
1210 /**
1211  * This function attempts to determine if a given spell is useless to the
1212  * player.
1213  *
1214  * @param spell      The spell in question.
1215  * @param temp       Include checks for volatile or temporary states
1216  *                   (status effects, mana, gods, items, etc.)
1217  * @param prevent    Whether to only check for effects which prevent casting,
1218  *                   rather than just ones that make it unproductive.
1219  * @param skip_casting_checks true if the spell is evoked or from an innate or
1220  *                   divine ability, or if casting checks are carried out
1221  *                   already.
1222  *                   false if it is a spell being cast normally.
1223  * @return           Whether the given spell has no chance of being useful.
1224  */
spell_is_useless(spell_type spell,bool temp,bool prevent,bool skip_casting_checks)1225 bool spell_is_useless(spell_type spell, bool temp, bool prevent,
1226                       bool skip_casting_checks)
1227 {
1228     return !spell_uselessness_reason(spell, temp, prevent, skip_casting_checks).empty();
1229 }
1230 
1231 /**
1232  * This function gives the reason that a spell is currently useless to the
1233  * player, if it is.
1234  *
1235  * @param spell      The spell in question.
1236  * @param temp       Include checks for volatile or temporary states
1237  *                   (status effects, mana, gods, items, etc.)
1238  * @param prevent    Whether to only check for effects which prevent casting,
1239  *                   rather than just ones that make it unproductive.
1240  * @param skip_casting_checks true if the spell is evoked or from an innate or
1241  *                   divine ability, or if casting checks are carried out
1242  *                   already.
1243  *                   false if it is a spell being cast normally.
1244  * @return           The reason a spell is useless to the player, if it is;
1245  *                   "" otherwise. The string should be a full clause, but
1246  *                   begin with a lowercase letter so callers can put it in
1247  *                   the middle of a sentence.
1248  */
spell_uselessness_reason(spell_type spell,bool temp,bool prevent,bool skip_casting_checks)1249 string spell_uselessness_reason(spell_type spell, bool temp, bool prevent,
1250                                 bool skip_casting_checks)
1251 {
1252     // prevent all of this logic during excursions / levelgen. This function
1253     // does get called during character creation, so allow it to run for !temp.
1254     if (temp && (!in_bounds(you.pos()) || !you.on_current_level))
1255         return "you can't cast spells right now.";
1256 
1257     if (!skip_casting_checks)
1258     {
1259         string c_check = casting_uselessness_reason(spell, temp);
1260         if (!c_check.empty())
1261             return c_check;
1262     }
1263 
1264     if (!prevent && temp && spell_no_hostile_in_range(spell))
1265         return "you can't see any hostile targets that would be affected.";
1266 
1267     switch (spell)
1268     {
1269     case SPELL_BLINK:
1270         // XXX: this is a little redundant with you_no_tele_reason()
1271         // but trying to sort out temp and so on is a mess
1272         if (you.stasis())
1273             return "your stasis prevents you from teleporting.";
1274 
1275         if (temp && you.no_tele(false, false, true))
1276             return lowercase_first(you.no_tele_reason(false, true));
1277         break;
1278 
1279     case SPELL_SWIFTNESS:
1280         if (you.stasis())
1281             return "your stasis precludes magical swiftness.";
1282 
1283         if (temp)
1284         {
1285             if (you.duration[DUR_SWIFTNESS])
1286                 return "this spell is already in effect.";
1287             if (player_movement_speed() <= FASTEST_PLAYER_MOVE_SPEED)
1288                 return "you're already traveling as fast as you can.";
1289             if (you.is_stationary())
1290                 return "you can't move.";
1291         }
1292         break;
1293 
1294     case SPELL_INVISIBILITY:
1295         if (!prevent && temp && you.backlit())
1296             return "invisibility won't help you when you glow in the dark.";
1297         break;
1298 
1299     case SPELL_STATUE_FORM:
1300         if (SP_GARGOYLE == you.species)
1301             return "you're already a statue.";
1302         // fallthrough to other forms
1303 
1304     case SPELL_BEASTLY_APPENDAGE:
1305     case SPELL_BLADE_HANDS:
1306     case SPELL_DRAGON_FORM:
1307     case SPELL_ICE_FORM:
1308     case SPELL_STORM_FORM:
1309     case SPELL_SPIDER_FORM:
1310         if (you.undead_state(temp) == US_UNDEAD)
1311             return "your undead flesh cannot be transformed.";
1312         if (you.is_lifeless_undead(temp))
1313             return "your current blood level is not sufficient.";
1314         break;
1315 
1316     case SPELL_EXCRUCIATING_WOUNDS:
1317         if (is_useless_skill(SK_NECROMANCY))
1318             return "you lack the necromantic skill to inflict true pain.";
1319         if (temp
1320             && (!you.weapon()
1321                 || you.weapon()->base_type != OBJ_WEAPONS
1322                 || !is_brandable_weapon(*you.weapon(), true)))
1323         {
1324             return "you aren't wielding a brandable weapon.";
1325         }
1326         // intentional fallthrough to portal projectile
1327     case SPELL_PORTAL_PROJECTILE:
1328         if (you.has_mutation(MUT_NO_GRASPING))
1329             return "this spell is useless without hands.";
1330         break;
1331     case SPELL_LEDAS_LIQUEFACTION:
1332         if (temp && you.duration[DUR_LIQUEFYING])
1333             return "you need to wait for the ground to become solid again.";
1334         break;
1335 
1336     case SPELL_BORGNJORS_REVIVIFICATION:
1337         if (temp && you.hp == you.hp_max)
1338             return "you cannot be healed further.";
1339         if (temp && you.hp_max < 21)
1340             return "you lack the resilience to cast this spell.";
1341         // Prohibited to all undead.
1342         if (you.undead_state(temp))
1343             return "you're too dead.";
1344         break;
1345     case SPELL_DEATHS_DOOR:
1346         if (temp && you.duration[DUR_DEATHS_DOOR])
1347             return "you are already standing in death's doorway.";
1348         if (temp && you.duration[DUR_DEATHS_DOOR_COOLDOWN])
1349             return "you are still too close to death's doorway.";
1350         // Prohibited to all undead.
1351         if (you.undead_state(temp))
1352             return "you're too dead.";
1353         break;
1354     case SPELL_NECROMUTATION:
1355         // only prohibited to actual undead, not lichformed players
1356         if (you.undead_state(false))
1357             return "you're too dead.";
1358         break;
1359 
1360     case SPELL_OZOCUBUS_ARMOUR:
1361         if (temp && you.form == transformation::statue)
1362             return "the film of ice won't work on stone.";
1363         if (temp && player_equip_unrand(UNRAND_SALAMANDER))
1364             return "your ring of flames would instantly melt the ice.";
1365         break;
1366 
1367     case SPELL_SUBLIMATION_OF_BLOOD:
1368         if (!you.can_bleed(temp))
1369             return "you have no blood to sublime.";
1370         break;
1371 
1372     case SPELL_POLAR_VORTEX:
1373         if (temp && (you.duration[DUR_VORTEX]
1374                      || you.duration[DUR_VORTEX_COOLDOWN]))
1375         {
1376             return "you need to wait for the winds to calm down.";
1377         }
1378         break;
1379 
1380     case SPELL_MALIGN_GATEWAY:
1381         if (temp && !can_cast_malign_gateway())
1382         {
1383             return "the dungeon can only cope with one malign gateway"
1384                     " at a time.";
1385         }
1386         break;
1387 
1388     case SPELL_SUMMON_FOREST:
1389         if (temp && you.duration[DUR_FORESTED])
1390             return "you can only summon one forest at a time.";
1391         if (temp && cast_summon_forest(&you, 0, GOD_NO_GOD, false, true) == spret::abort)
1392             return "you need more open space to fit a forest.";
1393         break;
1394 
1395     case SPELL_PASSWALL:
1396         // the full check would need a real spellpower here, so we just check
1397         // a drastically simplified version of it
1398         if (temp && you.is_stationary())
1399             return "you can't move.";
1400         if (temp && !passwall_simplified_check(you))
1401             return "you aren't next to any passable walls.";
1402         break;
1403 
1404     case SPELL_ANIMATE_DEAD:
1405         if (temp && !animate_dead(&you, 1, BEH_FRIENDLY, MHITYOU, &you, "", GOD_NO_GOD, false))
1406             return "there is nothing nearby to animate!";
1407         break;
1408 
1409     case SPELL_ANIMATE_SKELETON:
1410         if (temp && !in_bounds(find_animatable_skeleton(you.pos())))
1411             return "there is nothing nearby to animate!";
1412         break;
1413     case SPELL_SIMULACRUM:
1414         if (temp && find_simulacrable_corpse(you.pos()) < 0)
1415             return "there is nothing here to animate!";
1416         break;
1417 
1418     case SPELL_CORPSE_ROT:
1419         if (temp && corpse_rot(&you, false) == spret::abort)
1420             return "there is nothing fresh enough to decay nearby.";
1421         // fallthrough
1422     case SPELL_POISONOUS_VAPOURS:
1423     case SPELL_CONJURE_FLAME:
1424     case SPELL_POISONOUS_CLOUD:
1425     case SPELL_FREEZING_CLOUD:
1426     case SPELL_MEPHITIC_CLOUD:
1427         if (temp && env.level_state & LSTATE_STILL_WINDS)
1428             return "the air is too still for clouds to form.";
1429         break;
1430 
1431     case SPELL_GOLUBRIAS_PASSAGE:
1432         if (temp && player_in_branch(BRANCH_GAUNTLET))
1433         {
1434             return "a magic seal in the Gauntlet prevents this spell "
1435                    "from working.";
1436         }
1437         break;
1438 
1439     case  SPELL_DRAGON_CALL:
1440         if (temp && (you.duration[DUR_DRAGON_CALL]
1441                      || you.duration[DUR_DRAGON_CALL_COOLDOWN]))
1442         {
1443             return "you cannot issue another dragon's call so soon.";
1444         }
1445         break;
1446 
1447     case SPELL_FROZEN_RAMPARTS:
1448         if (temp && you.duration[DUR_FROZEN_RAMPARTS])
1449             return "you cannot sustain more frozen ramparts right now.";
1450         break;
1451 
1452     case SPELL_WEREBLOOD:
1453         if (you.undead_state(temp) == US_UNDEAD
1454             || you.is_lifeless_undead(temp))
1455         {
1456             return "you lack blood to transform.";
1457         }
1458         break;
1459 
1460     case SPELL_SANDBLAST:
1461         if (temp && sandblast_find_ammo().first == 0)
1462             return "you don't have any stones to cast with.";
1463         break;
1464 
1465     case SPELL_NOXIOUS_BOG:
1466         if (temp && you.duration[DUR_NOXIOUS_BOG])
1467             return "you cannot sustain more bogs right now.";
1468         break;
1469 
1470     case SPELL_ANIMATE_ARMOUR:
1471         if (you_can_wear(EQ_BODY_ARMOUR, temp) == MB_FALSE)
1472             return "you cannot wear body armour.";
1473         if (temp && !you.slot_item(EQ_BODY_ARMOUR))
1474             return "you have no body armour to summon the spirit of.";
1475         break;
1476 
1477     case SPELL_MANIFOLD_ASSAULT:
1478     {
1479         if (temp)
1480         {
1481             const string unproj_reason = weapon_unprojectability_reason();
1482             if (unproj_reason != "")
1483                 return unproj_reason;
1484         }
1485     }
1486         break;
1487 
1488     default:
1489         break;
1490     }
1491 
1492     return "";
1493 }
1494 
1495 /**
1496  * Determines what colour a spell should be highlighted with.
1497  *
1498  * @param spell           The type of spell to be coloured.
1499  * @param default_colour   Colour to be used if the spell is unremarkable.
1500  * @param transient       If true, check if spell is temporarily useless.
1501  * @param memcheck        If true, check if spell can be memorised
1502  * @return                The colour to highlight the spell.
1503  */
spell_highlight_by_utility(spell_type spell,int default_colour,bool transient,bool memcheck)1504 int spell_highlight_by_utility(spell_type spell, int default_colour,
1505                                bool transient, bool memcheck)
1506 {
1507     // If your god hates the spell, that overrides all other concerns.
1508     if (god_hates_spell(spell, you.religion)
1509         || is_good_god(you.religion) && you.spellcasting_unholy())
1510     {
1511         return COL_FORBIDDEN;
1512     }
1513     // Grey out spells for which you lack experience or spell levels.
1514     if (memcheck && (spell_difficulty(spell) > you.experience_level
1515         || player_spell_levels() < spell_levels_required(spell)))
1516     {
1517         return COL_INAPPLICABLE;
1518     }
1519     // Check if the spell is considered useless based on your current status
1520     if (spell_is_useless(spell, transient))
1521         return COL_USELESS;
1522 
1523     return default_colour;
1524 }
1525 
spell_no_hostile_in_range(spell_type spell)1526 bool spell_no_hostile_in_range(spell_type spell)
1527 {
1528     // sanity check: various things below will be prone to crash in these cases.
1529     if (!in_bounds(you.pos()) || !you.on_current_level)
1530         return true;
1531 
1532     const int range = calc_spell_range(spell, 0);
1533     const int minRange = get_dist_to_nearest_monster();
1534     const int pow = calc_spell_power(spell, true, false, true);
1535 
1536     switch (spell)
1537     {
1538     // These don't target monsters or can target features.
1539     case SPELL_APPORTATION:
1540     case SPELL_CONJURE_FLAME:
1541     case SPELL_PASSWALL:
1542     case SPELL_GOLUBRIAS_PASSAGE:
1543     // case SPELL_LRD: // TODO: LRD logic here is a bit confusing, it should error
1544     //                 // now that it doesn't destroy walls
1545     case SPELL_FULMINANT_PRISM:
1546     case SPELL_SUMMON_LIGHTNING_SPIRE:
1547     case SPELL_NOXIOUS_BOG:
1548     // This can always potentially hit out-of-LOS, although this is conditional
1549     // on spell-power.
1550     case SPELL_FIRE_STORM:
1551         return false;
1552 
1553     case SPELL_OLGREBS_TOXIC_RADIANCE:
1554     case SPELL_IGNITION:
1555     case SPELL_FROZEN_RAMPARTS:
1556         return minRange > you.current_vision;
1557 
1558     case SPELL_POISONOUS_VAPOURS:
1559     {
1560         // can this just be turned into a zap at this point?
1561         dist test_targ;
1562         for (radius_iterator ri(you.pos(), range, C_SQUARE, LOS_NO_TRANS);
1563              ri; ++ri)
1564         {
1565             test_targ.target = *ri;
1566             const monster* mons = monster_at(*ri);
1567             if (mons && cast_poisonous_vapours(0, test_targ, true, true)
1568                                                             == spret::success)
1569             {
1570                 return false;
1571             }
1572         }
1573         return true;
1574     }
1575 
1576     // Special handling for cloud spells.
1577     case SPELL_FREEZING_CLOUD:
1578     case SPELL_POISONOUS_CLOUD:
1579     case SPELL_HOLY_BREATH:
1580     {
1581         targeter_cloud tgt(&you, range);
1582         // Accept monsters that are in clouds for the hostiles-in-range check
1583         // (not for actual targeting).
1584         tgt.avoid_clouds = false;
1585         for (radius_iterator ri(you.pos(), range, C_SQUARE, LOS_NO_TRANS);
1586              ri; ++ri)
1587         {
1588             if (!tgt.valid_aim(*ri))
1589                 continue;
1590             tgt.set_aim(*ri);
1591             for (const auto &entry : tgt.seen)
1592             {
1593                 if (entry.second == AFF_NO || entry.second == AFF_TRACER)
1594                     continue;
1595 
1596                 // Checks here are from get_dist_to_nearest_monster().
1597                 const monster* mons = monster_at(entry.first);
1598                 if (mons && !mons->wont_attack() && mons_is_threatening(*mons))
1599                     return false;
1600             }
1601         }
1602 
1603         return true;
1604     }
1605 
1606     case SPELL_IGNITE_POISON:
1607         return cast_ignite_poison(&you, -1, false, true) == spret::abort;
1608 
1609     case SPELL_STARBURST:
1610         return cast_starburst(-1, false, true) == spret::abort;
1611 
1612     case SPELL_HAILSTORM:
1613         return cast_hailstorm(-1, false, true) == spret::abort;
1614 
1615     case SPELL_DAZZLING_FLASH:
1616         return cast_dazzling_flash(pow, false, true) == spret::abort;
1617 
1618      case SPELL_MAXWELLS_COUPLING:
1619          return cast_maxwells_coupling(pow, false, true) == spret::abort;
1620 
1621      case SPELL_INTOXICATE:
1622          return cast_intoxicate(-1, false, true) == spret::abort;
1623 
1624     case SPELL_MANIFOLD_ASSAULT:
1625          return cast_manifold_assault(-1, false, false) == spret::abort;
1626 
1627     case SPELL_OZOCUBUS_REFRIGERATION:
1628          return trace_los_attack_spell(SPELL_OZOCUBUS_REFRIGERATION, pow, &you)
1629              == spret::abort;
1630 
1631     case SPELL_CHAIN_LIGHTNING:
1632         for (coord_def t : chain_lightning_targets())
1633         {
1634             const monster *mon = monster_at(t);
1635             if (mon != nullptr && !mon->wont_attack())
1636                 return false;
1637         }
1638         return true;
1639 
1640     default:
1641         break;
1642     }
1643 
1644     if (minRange < 0 || range < 0)
1645         return false;
1646 
1647     const spell_flags flags = get_spell_flags(spell);
1648 
1649     // The healing spells.
1650     if (testbits(flags, spflag::helpful))
1651         return false;
1652 
1653     const bool neutral = testbits(flags, spflag::neutral);
1654 
1655     bolt beam;
1656     beam.flavour = BEAM_VISUAL;
1657     beam.origin_spell = spell;
1658 
1659     zap_type zap = spell_to_zap(spell);
1660     if (zap != NUM_ZAPS)
1661     {
1662         beam.thrower = KILL_YOU_MISSILE;
1663         zappy(zap, calc_spell_power(spell, true, false, true), false,
1664               beam);
1665         if (spell == SPELL_MEPHITIC_CLOUD)
1666             beam.damage = dice_def(1, 1); // so that foe_info is populated
1667     }
1668 
1669     if (beam.flavour != BEAM_VISUAL)
1670     {
1671         bolt tempbeam;
1672         bool found = false;
1673         beam.source_id = MID_PLAYER;
1674         beam.range = range;
1675         beam.is_tracer = true;
1676         beam.is_targeting = true;
1677         beam.source  = you.pos();
1678         beam.dont_stop_player = true;
1679         beam.friend_info.dont_stop = true;
1680         beam.foe_info.dont_stop = true;
1681         beam.attitude = ATT_FRIENDLY;
1682 #ifdef DEBUG_DIAGNOSTICS
1683         beam.quiet_debug = true;
1684 #endif
1685 
1686         const bool smite = testbits(flags, spflag::target);
1687 
1688         for (radius_iterator ri(you.pos(), range, C_SQUARE, LOS_DEFAULT);
1689              ri; ++ri)
1690         {
1691             tempbeam = beam;
1692             tempbeam.target = *ri;
1693 
1694             // For smite-targeted spells that aren't LOS-range.
1695             if (smite)
1696             {
1697                 // XXX These are basic checks that might be applicable to
1698                 // non-smiting spells as well. For those, the loop currently
1699                 // relies mostly on results from the temp beam firing, but it
1700                 // may be valid to exclude solid and non-reachable targets for
1701                 // all spells. -gammafunk
1702                 if (cell_is_solid(*ri) || !you.see_cell_no_trans(*ri))
1703                     continue;
1704 
1705                 // XXX Currently Vile Clutch is the only smite-targeted area
1706                 // spell that isn't LOS-range. Spell explosion radii are not
1707                 // stored anywhere, defaulting to 1 for non-smite-targeting
1708                 // spells through bolt::refine_for_explosions() or being set in
1709                 // setup functions for the smite targeted explosions. It would
1710                 // be good to move basic explosion radius info into spell_desc
1711                 // or possibly zap_data. -gammafunk
1712                 tempbeam.ex_size = tempbeam.is_explosion ? 1 : 0;
1713                 tempbeam.explode();
1714             }
1715             else
1716                 tempbeam.fire();
1717 
1718             if (tempbeam.foe_info.count > 0
1719                 || neutral && tempbeam.friend_info.count > 0)
1720             {
1721                 found = true;
1722                 break;
1723             }
1724         }
1725         return !found;
1726     }
1727 
1728     if (range < minRange)
1729         return true;
1730 
1731     return false;
1732 }
1733 
1734 
1735 // a map of schools to the corresponding sacrifice 'mutations'.
1736 static const mutation_type arcana_sacrifice_map[] = {
1737     MUT_NO_CONJURATION_MAGIC,
1738     MUT_NO_HEXES_MAGIC,
1739     MUT_NO_FIRE_MAGIC,
1740     MUT_NO_ICE_MAGIC,
1741     MUT_NO_TRANSMUTATION_MAGIC,
1742     MUT_NO_NECROMANCY_MAGIC,
1743     MUT_NO_SUMMONING_MAGIC,
1744     MUT_NO_TRANSLOCATION_MAGIC,
1745     MUT_NO_POISON_MAGIC,
1746     MUT_NO_EARTH_MAGIC,
1747     MUT_NO_AIR_MAGIC
1748 };
1749 
1750 /**
1751  * Are some subset of the given schools unusable by the player?
1752  * (Due to Sacrifice Arcana)
1753  *
1754  * @param schools   A bitfield containing a union of spschools.
1755  * @return          Whether the player is unable use any of the given schools.
1756  */
cannot_use_schools(spschools_type schools)1757 bool cannot_use_schools(spschools_type schools)
1758 {
1759     COMPILE_CHECK(ARRAYSZ(arcana_sacrifice_map) == SPSCHOOL_LAST_EXPONENT + 1);
1760 
1761     // iter over every school
1762     for (int i = 0; i <= SPSCHOOL_LAST_EXPONENT; i++)
1763     {
1764         // skip schools not in the provided set
1765         const auto school = spschools_type::exponent(i);
1766         if (!(schools & school))
1767             continue;
1768 
1769         // check if the player has this school locked out
1770         const mutation_type lockout_mut = arcana_sacrifice_map[i];
1771         if (you.has_mutation(lockout_mut))
1772             return true;
1773     }
1774 
1775     return false;
1776 }
1777 
1778 
1779 /**
1780  * What's the spell school corresponding to the given Ru mutation?
1781  *
1782  * @param mutation  The variety of MUT_NO_*_MAGIC in question.
1783  * @return          The skill of the appropriate school (SK_AIR_MAGIC, etc).
1784  *                  If no school corresponds, returns SK_NONE.
1785  */
arcane_mutation_to_skill(mutation_type mutation)1786 skill_type arcane_mutation_to_skill(mutation_type mutation)
1787 {
1788     for (int exp = 0; exp <= SPSCHOOL_LAST_EXPONENT; exp++)
1789         if (arcana_sacrifice_map[exp] == mutation)
1790             return spell_type2skill(spschools_type::exponent(exp));
1791     return SK_NONE;
1792 }
1793 
spell_is_soh_breath(spell_type spell)1794 bool spell_is_soh_breath(spell_type spell)
1795 {
1796     return spell == SPELL_SERPENT_OF_HELL_GEH_BREATH
1797         || spell == SPELL_SERPENT_OF_HELL_COC_BREATH
1798         || spell == SPELL_SERPENT_OF_HELL_DIS_BREATH
1799         || spell == SPELL_SERPENT_OF_HELL_TAR_BREATH;
1800 }
1801 
soh_breath_spells(spell_type spell)1802 const vector<spell_type> *soh_breath_spells(spell_type spell)
1803 {
1804     static const map<spell_type, vector<spell_type>> soh_breaths = {
1805         { SPELL_SERPENT_OF_HELL_GEH_BREATH,
1806             { SPELL_FIRE_BREATH,
1807               SPELL_FLAMING_CLOUD,
1808               SPELL_FIREBALL } },
1809         { SPELL_SERPENT_OF_HELL_COC_BREATH,
1810             { SPELL_COLD_BREATH,
1811               SPELL_FREEZING_CLOUD,
1812               SPELL_FLASH_FREEZE } },
1813         { SPELL_SERPENT_OF_HELL_DIS_BREATH,
1814             { SPELL_METAL_SPLINTERS,
1815               SPELL_QUICKSILVER_BOLT,
1816               SPELL_LEHUDIBS_CRYSTAL_SPEAR } },
1817         { SPELL_SERPENT_OF_HELL_TAR_BREATH,
1818             { SPELL_BOLT_OF_DRAINING,
1819               SPELL_MIASMA_BREATH,
1820               SPELL_CORROSIVE_BOLT } },
1821     };
1822 
1823     return map_find(soh_breaths, spell);
1824 }
1825 
1826 /* How to regenerate this:
1827    comm -2 -3 \
1828     <(clang -P -E -nostdinc -nobuiltininc spell-type.h -DTAG_MAJOR_VERSION=34 | sort) \
1829     <(clang -P -E -nostdinc -nobuiltininc spell-type.h -DTAG_MAJOR_VERSION=35 | sort) \
1830     | grep SPELL
1831 */
1832 const set<spell_type> removed_spells =
1833 {
1834 #if TAG_MAJOR_VERSION == 34
1835     SPELL_AURA_OF_ABJURATION,
1836     SPELL_BOLT_OF_INACCURACY,
1837     SPELL_CHANT_FIRE_STORM,
1838     SPELL_CIGOTUVIS_DEGENERATION,
1839     SPELL_CIGOTUVIS_EMBRACE,
1840     SPELL_CONDENSATION_SHIELD,
1841     SPELL_CONTROLLED_BLINK,
1842     SPELL_CONTROL_TELEPORT,
1843     SPELL_CONTROL_UNDEAD,
1844     SPELL_CONTROL_WINDS,
1845     SPELL_CORRUPT_BODY,
1846     SPELL_CURE_POISON,
1847     SPELL_DEFLECT_MISSILES,
1848     SPELL_DELAYED_FIREBALL,
1849     SPELL_DEMONIC_HORDE,
1850     SPELL_DRACONIAN_BREATH,
1851     SPELL_EPHEMERAL_INFUSION,
1852     SPELL_EVAPORATE,
1853     SPELL_EXPLOSIVE_BOLT,
1854     SPELL_FAKE_RAKSHASA_SUMMON,
1855     SPELL_FIRE_BRAND,
1856     SPELL_FIRE_CLOUD,
1857     SPELL_FLY,
1858     SPELL_FORCEFUL_DISMISSAL,
1859     SPELL_FREEZING_AURA,
1860     SPELL_FRENZY,
1861     SPELL_FULSOME_DISTILLATION,
1862     SPELL_GRAND_AVATAR,
1863     SPELL_HASTE_PLANTS,
1864     SPELL_HOLY_LIGHT,
1865     SPELL_HOLY_WORD,
1866     SPELL_HOMUNCULUS,
1867     SPELL_HUNTING_CRY,
1868     SPELL_IGNITE_POISON_SINGLE,
1869     SPELL_INFUSION,
1870     SPELL_INSULATION,
1871     SPELL_IRON_ELEMENTALS,
1872     SPELL_LETHAL_INFUSION,
1873     SPELL_MELEE,
1874     SPELL_MIASMA_CLOUD,
1875     SPELL_MISLEAD,
1876     SPELL_PHASE_SHIFT,
1877     SPELL_POISON_CLOUD,
1878     SPELL_POISON_WEAPON,
1879     SPELL_RANDOM_BOLT,
1880     SPELL_REARRANGE_PIECES,
1881     SPELL_RECALL,
1882     SPELL_REGENERATION,
1883     SPELL_RESURRECT,
1884     SPELL_RING_OF_FLAMES,
1885     SPELL_SACRIFICE,
1886     SPELL_SCATTERSHOT,
1887     SPELL_SEE_INVISIBLE,
1888     SPELL_SERPENT_OF_HELL_BREATH_REMOVED,
1889     SPELL_SHAFT_SELF,
1890     SPELL_SHROUD_OF_GOLUBRIA,
1891     SPELL_SILVER_BLAST,
1892     SPELL_SINGULARITY,
1893     SPELL_SONG_OF_SHIELDING,
1894     SPELL_SPECTRAL_WEAPON,
1895     SPELL_STEAM_CLOUD,
1896     SPELL_STICKS_TO_SNAKES,
1897     SPELL_STONESKIN,
1898     SPELL_STRIKING,
1899     SPELL_SUMMON_BUTTERFLIES,
1900     SPELL_SUMMON_ELEMENTAL,
1901     SPELL_SUMMON_RAKSHASA,
1902     SPELL_SUMMON_SCORPIONS,
1903     SPELL_SUMMON_SWARM,
1904     SPELL_SUMMON_TWISTER,
1905     SPELL_SUNRAY,
1906     SPELL_SURE_BLADE,
1907     SPELL_THROW,
1908     SPELL_VAMPIRE_SUMMON,
1909     SPELL_WARP_BRAND,
1910     SPELL_WEAVE_SHADOWS,
1911     SPELL_DARKNESS,
1912     SPELL_CLOUD_CONE,
1913     SPELL_RING_OF_THUNDER,
1914     SPELL_TWISTED_RESURRECTION,
1915     SPELL_RANDOM_EFFECTS,
1916     SPELL_HYDRA_FORM,
1917     SPELL_VORTEX,
1918 #endif
1919 };
1920 
spell_removed(spell_type spell)1921 bool spell_removed(spell_type spell)
1922 {
1923     return removed_spells.count(spell) != 0;
1924 }
1925 
end_wait_spells(bool quiet)1926 void end_wait_spells(bool quiet)
1927 {
1928     end_searing_ray();
1929     end_maxwells_coupling(quiet);
1930 }
1931