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