Move sacrifice special cases into data
[crawl.git] / crawl-ref / source / godabil.cc
1 /**
2  * @file
3  * @brief God-granted abilities.
4 **/
5
6 #include "AppHdr.h"
7
8 #include "godabil.h"
9
10 #include <queue>
11 #include <sstream>
12
13 #include "act-iter.h"
14 #include "areas.h"
15 #include "attitude-change.h"
16 #include "branch.h"
17 #include "butcher.h"
18 #include "cloud.h"
19 #include "colour.h"
20 #include "coordit.h"
21 #include "dactions.h"
22 #include "database.h"
23 #include "dgn-overview.h"
24 #include "directn.h"
25 #include "dungeon.h"
26 #include "effects.h"
27 #include "english.h"
28 #include "fight.h"
29 #include "files.h"
30 #include "food.h"
31 #include "godblessing.h"
32 #include "godcompanions.h"
33 #include "goditem.h"
34 #include "hiscores.h"
35 #include "invent.h"
36 #include "itemprop.h"
37 #include "items.h"
38 #include "item_use.h"
39 #include "libutil.h"
40 #include "losglobal.h"
41 #include "macro.h"
42 #include "mapmark.h"
43 #include "maps.h"
44 #include "message.h"
45 #include "misc.h"
46 #include "mon-act.h"
47 #include "mon-behv.h"
48 #include "mon-book.h"
49 #include "mon-cast.h"
50 #include "mon-death.h"
51 #include "mon-place.h"
52 #include "mon-poly.h"
53 #include "mutation.h"
54 #include "notes.h"
55 #include "ouch.h"
56 #include "output.h"
57 #include "place.h"
58 #include "player-equip.h"
59 #include "player-stats.h"
60 #include "potion.h"
61 #include "prompt.h"
62 #include "religion.h"
63 #include "shout.h"
64 #include "skill_menu.h"
65 #include "spl-book.h"
66 #include "spl-monench.h"
67 #include "spl-summoning.h"
68 #include "spl-transloc.h"
69 #include "spl-util.h"
70 #include "sprint.h"
71 #include "state.h"
72 #include "stringutil.h"
73 #include "target.h"
74 #include "terrain.h"
75 #include "throw.h"
76 #ifdef USE_TILE
77  #include "tiledef-main.h"
78 #endif
79 #include "traps.h"
80 #include "viewchar.h"
81 #include "view.h"
82
83 static bool _player_sacrificed_arcana();
84
85 // Load the sacrifice_def definition and the sac_data array.
86 #include "sacrifice-data.h"
87
88 static void _zin_saltify(monster* mon);
89
90 string zin_recite_text(const int seed, const int prayertype, int step)
91 {
92     // 'prayertype':
93     // This is in enum.h; there are currently four prayers.
94
95     // 'step':
96     // -1: We're either starting or stopping, so we just want the passage name.
97     // 2/1/0: That many rounds are left. So, if step = 2, we want to show the passage #1/3.
98
99     // That's too confusing, so:
100
101     if (step > -1)
102     {
103         step = abs(step-3);
104         if (step > 3)
105             step = 0;
106     }
107
108     // We change it to turn 1, turn 2, turn 3.
109
110     // 'trits':
111     // To have deterministic passages we need to store a random seed.
112     // Ours consists of an array of trinary bits.
113
114     // Yes, really.
115
116     const int trits[7] = { seed % 3, (seed / 3) % 3, (seed / 9) % 3,
117                            (seed / 27) % 3, (seed / 81) % 3, (seed / 243) % 3,
118                            (seed / 729) % 3};
119     const int chapter = 1 + trits[0] + trits[1] * 3 + trits[2] * 9;
120     const int verse = 1 + trits[3] + trits[4] * 3 + trits[5] * 9 + trits[6] * 27;
121
122     string sinner_text[12] =
123     {
124         "hordes of the Abyss",
125         "bastard children of Xom",
126         "amorphous wretches",
127         "fetid masses",
128         "agents of filth",
129         "squalid dregs",
130         "unbelievers",
131         "heretics",
132         "guilty",
133         "legions of the damned",
134         "servants of Hell",
135         "forces of darkness",
136     };
137
138     string sin_text[12] =
139     {
140         "chaotic",
141         "discordant",
142         "anarchic",
143         "unclean",
144         "impure",
145         "contaminated",
146         "unfaithful",
147         "disloyal",
148         "doubting",
149         "profane",
150         "blasphemous",
151         "sacrilegious",
152     };
153
154     string long_sin_text[12] =
155     {
156         "chaos",
157         "discord",
158         "anarchy",
159         "uncleanliness",
160         "impurity",
161         "contamination",
162         "unfaithfulness",
163         "disloyalty",
164         "doubt",
165         "profanity",
166         "blasphemy",
167         "sacrilege",
168     };
169
170     string virtue_text[12] =
171     {
172         "ordered",
173         "harmonic",
174         "lawful",
175         "clean",
176         "pure",
177         "hygienic",
178         "faithful",
179         "loyal",
180         "believing",
181         "reverent",
182         "pious",
183         "obedient",
184     };
185
186     string long_virtue_text[12] =
187     {
188         "order",
189         "harmony",
190         "lawfulness",
191         "cleanliness",
192         "purity",
193         "hygiene",
194         "faithfulness",
195         "loyalty",
196         "belief",
197         "reverence",
198         "piety",
199         "obedience",
200     };
201
202     string smite_text[9] =
203     {
204         "purify",
205         "censure",
206         "condemn",
207         "strike down",
208         "expel",
209         "oust",
210         "smite",
211         "castigate",
212         "rebuke",
213     };
214
215     string smitten_text[9] =
216     {
217         "purified",
218         "censured",
219         "condemned",
220         "struck down",
221         "expelled",
222         "ousted",
223         "smitten",
224         "castigated",
225         "rebuked",
226     };
227
228     string sinner = sinner_text[trits[3] + prayertype * 3];
229     string sin[2] = {sin_text[trits[6] + prayertype * 3],
230                      long_sin_text[trits[6] + prayertype * 3]};
231     string virtue[2] = {virtue_text[trits[6] + prayertype * 3],
232                         long_virtue_text[trits[6] + prayertype * 3]};
233     string smite[2] = {smite_text[(trits[4] + trits[5] * 3)],
234                        smitten_text[(trits[4] + trits[5] * 3)]};
235
236     string turn[4] = {"This is only here because arrays start from 0.",
237                       "Zin is a buggy god.", "Please report this.",
238                       "This isn't right at all."};
239
240     switch (chapter)
241     {
242         case 1:
243             turn[1] = make_stringf("It was the word of Zin that there would not be %s...",
244                                    sin[1].c_str());
245             turn[2] = make_stringf("...and did the people not suffer until they had %s...",
246                                    smite[1].c_str());
247             turn[3] = make_stringf("...the %s, after which all was well?", sinner.c_str());
248             break;
249         case 2:
250             turn[1] = make_stringf("The voice of Zin, pure and clear, did say that the %s...",
251                                    sinner.c_str());
252             turn[2] = make_stringf("...were not %s! And hearing this, the people rose up...",
253                                    virtue[0].c_str());
254             turn[3] = make_stringf("...and embraced %s, for they feared Zin's wrath.",
255                                    virtue[1].c_str());
256             break;
257         case 3:
258             turn[1] = make_stringf("Zin spoke of the doctrine of %s, and...",
259                                    virtue[1].c_str());
260             turn[2] = make_stringf("...saw the %s filled with fear, for they were...",
261                                    sinner.c_str());
262             turn[3] = make_stringf("...%s and knew Zin's wrath would come for them.",
263                                    sin[0].c_str());
264             break;
265         case 4:
266             turn[1] = make_stringf("And so Zin bade the %s to come before...",
267                                    sinner.c_str());
268             turn[2] = make_stringf("...the altar, that judgement might be passed...");
269             turn[3] = make_stringf("...upon those who were not %s.", virtue[0].c_str());
270             break;
271         case 5:
272             turn[1] = make_stringf("To the devout, Zin provideth. From the rest...");
273             turn[2] = make_stringf("...ye %s, ye guilty...", sinner.c_str());
274             turn[3] = make_stringf("...of %s, Zin taketh.", sin[1].c_str());
275             break;
276         case 6:
277             turn[1] = make_stringf("Zin saw the %s of the %s, and...",
278                                    sin[1].c_str(), sinner.c_str());
279             turn[2] = make_stringf("...was displeased, for did the law not say that...");
280             turn[3] = make_stringf("...those who did not become %s would be %s?",
281                                    virtue[0].c_str(), smite[1].c_str());
282             break;
283         case 7:
284             turn[1] = make_stringf("Zin said that %s shall be the law of the land, and...",
285                                    virtue[1].c_str());
286             turn[2] = make_stringf("...those who turn to %s will be %s. This was fair...",
287                                    sin[1].c_str(), smite[1].c_str());
288             turn[3] = make_stringf("...and just, and not a voice dissented.");
289             break;
290         case 8:
291             turn[1] = make_stringf("Damned, damned be the %s and...", sinner.c_str());
292             turn[2] = make_stringf("...all else who abandon %s! Let them...",
293                                    virtue[1].c_str());
294             turn[3] = make_stringf("...be %s by the jurisprudence of Zin!",
295                                    smite[1].c_str());
296             break;
297         case 9:
298             turn[1] = make_stringf("And Zin said to all in attendance, 'Which of ye...");
299             turn[2] = make_stringf("...number among the %s? Come before me, that...",
300                                    sinner.c_str());
301             turn[3] = make_stringf("...I may %s you now for your %s!'",
302                                    smite[0].c_str(), sin[1].c_str());
303             break;
304         case 10:
305             turn[1] = make_stringf("Yea, I say unto thee, bring forth...");
306             turn[2] = make_stringf("...the %s that they may know...", sinner.c_str());
307             turn[3] = make_stringf("...the wrath of Zin, and thus be %s!",
308                                    smite[1].c_str());
309             break;
310         case 11:
311             turn[1] = make_stringf("In a great set of silver scales are weighed the...");
312             turn[2] = make_stringf("...souls of the %s, and with their %s...",
313                                    sinner.c_str(), sin[0].c_str());
314             turn[3] = make_stringf("...ways, the balance hath tipped against them!");
315             break;
316         case 12:
317             turn[1] = make_stringf("It is just that the %s shall be %s...",
318                                    sinner.c_str(), smite[1].c_str());
319             turn[2] = make_stringf("...in due time, for %s is what Zin has declared...",
320                                    virtue[1].c_str());
321             turn[3] = make_stringf("...the law of the land, and Zin's word is law!");
322             break;
323         case 13:
324             turn[1] = make_stringf("Thus the people made the covenant of %s with...",
325                                    virtue[1].c_str());
326             turn[2] = make_stringf("...Zin, and all was good, for they knew that the...");
327             turn[3] = make_stringf("...%s would trouble them no longer.", sinner.c_str());
328             break;
329         case 14:
330             turn[1] = make_stringf("What of the %s? %s for their...",
331                                    sinner.c_str(), uppercase_first(smite[1]).c_str());
332             turn[2] = make_stringf("...%s they shall be! Zin will %s them again...",
333                                    sin[1].c_str(), smite[0].c_str());
334             turn[3] = make_stringf("...and again, and again!");
335             break;
336         case 15:
337             turn[1] = make_stringf("And lo, the wrath of Zin did find...");
338             turn[2] = make_stringf("...them wherever they hid, and the %s...",
339                                    sinner.c_str());
340             turn[3] = make_stringf("...were %s for their %s!",
341                                    smite[1].c_str(), sin[1].c_str());
342             break;
343         case 16:
344             turn[1] = make_stringf("Zin looked out upon the remains of the %s...",
345                                    sinner.c_str());
346             turn[2] = make_stringf("...and declared it good that they had been...");
347             turn[3] = make_stringf("...%s. And thus justice was done.", smite[1].c_str());
348             break;
349         case 17:
350             turn[1] = make_stringf("The law of Zin demands thee...");
351             turn[2] = make_stringf("...be %s, and that the punishment for %s...",
352                                    virtue[0].c_str(), sin[1].c_str());
353             turn[3] = make_stringf("...shall be swift and harsh!");
354             break;
355         case 18:
356             turn[1] = make_stringf("It was then that Zin bade them...");
357             turn[2] = make_stringf("...not to stray from %s, lest...", virtue[1].c_str());
358             turn[3] = make_stringf("...they become as damned as the %s.", sinner.c_str());
359             break;
360         case 19:
361             turn[1] = make_stringf("Only the %s shall be judged worthy, and...",
362                                    virtue[0].c_str());
363             turn[2] = make_stringf("...all the %s will be found wanting. Such is...",
364                                    sinner.c_str());
365             turn[3] = make_stringf("...the word of Zin, and such is the law!");
366             break;
367         case 20:
368             turn[1] = make_stringf("To those who would swear an oath of %s on my altar...",
369                                    virtue[1].c_str());
370             turn[2] = make_stringf("...I bring ye salvation. To the rest, ye %s...",
371                                    sinner.c_str());
372             turn[3] = make_stringf("...and the %s, the name of Zin shall be thy damnation.",
373                                    sin[0].c_str());
374             break;
375         case 21:
376             turn[1] = make_stringf("And Zin decreed that the people would be...");
377             turn[2] = make_stringf("...protected from %s in all its forms, and...",
378                                    sin[1].c_str());
379             turn[3] = make_stringf("...preserved in their %s for all the days to come.",
380                                    virtue[1].c_str());
381             break;
382         case 22:
383             turn[1] = make_stringf("For those who would enter Zin's holy bosom...");
384             turn[2] = make_stringf("...and live in %s, Zin provideth. Such is...",
385                                    virtue[1].c_str());
386             turn[3] = make_stringf("...the covenant, and such is the way of things.");
387             break;
388         case 23:
389             turn[1] = make_stringf("Zin hath not damned the %s, but it is they...",
390                                    sinner.c_str());
391             turn[2] = make_stringf("...that have damned themselves for their %s, for...",
392                                    sin[1].c_str());
393             turn[3] = make_stringf("...did Zin not decree that to be %s was wrong?",
394                                    sin[0].c_str());
395             break;
396         case 24:
397             turn[1] = make_stringf("And Zin, furious at their %s, held...", sin[1].c_str());
398             turn[2] = make_stringf("...aloft a silver sceptre! The %s...", sinner.c_str());
399             turn[3] = make_stringf("...were %s, and thus the way of things was maintained.",
400                                    smite[1].c_str());
401             break;
402         case 25:
403             turn[1] = make_stringf("When the law of the land faltered, Zin rose...");
404             turn[2] = make_stringf("...from the silver throne, and the %s were...",
405                                    sinner.c_str());
406             turn[3] = make_stringf("...%s. And it was thus that the law was made good.",
407                                    smite[1].c_str());
408             break;
409         case 26:
410             turn[1] = make_stringf("Zin descended from on high in a silver chariot...");
411             turn[2] = make_stringf("...to %s the %s for their...",
412                                    smite[0].c_str(), sinner.c_str());
413             turn[3] = make_stringf("...%s, and thus judgement was rendered.",
414                                    sin[1].c_str());
415             break;
416         case 27:
417             turn[1] = make_stringf("The %s stood before Zin, and in that instant...",
418                                    sinner.c_str());
419             turn[2] = make_stringf("...they knew they would be found guilty of %s...",
420                                    sin[1].c_str());
421             turn[3] = make_stringf("...for that is the word of Zin, and Zin's word is law.");
422             break;
423     }
424
425     string recite = "Hail Satan.";
426
427     if (step == -1)
428     {
429         string bookname = (prayertype == RECITE_CHAOTIC)  ?  "Abominations"  :
430                           (prayertype == RECITE_IMPURE)   ?  "Ablutions"     :
431                           (prayertype == RECITE_HERETIC)  ?  "Apostates"     :
432                           (prayertype == RECITE_UNHOLY)   ?  "Anathema"      :
433                                                              "Bugginess";
434         ostringstream numbers;
435         numbers << chapter;
436         numbers << ":";
437         numbers << verse;
438         recite = bookname + " " + numbers.str();
439     }
440     else
441         recite = turn[step];
442
443     return recite;
444 }
445
446 /** How vulnerable to RECITE_HERETIC is this monster?
447  *
448  * @param[in] mon The monster to check.
449  * @returns the susceptibility.
450  */
451 static int _heretic_recite_weakness(const monster *mon)
452 {
453     int degree = 0;
454
455     // Sleeping or paralyzed monsters will wake up or still perceive their
456     // surroundings, respectively.  So, you can still recite to them.
457     if (mons_intel(mon) >= I_NORMAL
458         && !(mon->has_ench(ENCH_DUMB) || mons_is_confused(mon)))
459     {
460         // In the eyes of Zin, everyone is a sinner until proven otherwise!
461             degree++;
462
463         // Any priest is a heretic...
464         if (mon->is_priest())
465             degree++;
466
467         // Or those who believe in themselves...
468         if (mon->type == MONS_DEMIGOD)
469             degree++;
470
471         // ...but evil gods are worse.
472         if (is_evil_god(mon->god) || is_unknown_god(mon->god))
473             degree++;
474
475         // (The above mean that worshipers will be treated as
476         // priests for reciting, even if they aren't actually.)
477
478
479         // Sanity check: monsters that won't attack you, and aren't
480         // priests/evil, don't get recited against.
481         if (mon->wont_attack() && degree <= 1)
482             degree = 0;
483
484         // Sanity check: monsters that are holy, know holy spells, or worship
485         // holy gods aren't heretics.
486         if (mon->is_holy() || is_good_god(mon->god))
487             degree = 0;
488     }
489
490     return degree;
491 }
492
493 typedef FixedVector<int, NUM_RECITE_TYPES> recite_counts;
494 /** Check whether this monster might be influenced by Recite.
495  *
496  * @param[in] mon The monster to check.
497  * @param[out] eligibility A vector, indexed by recite_type, that indicates
498  *             which recitation types the monster is affected by, if any:
499  *             eligibility[RECITE_FOO] is nonzero if the monster is affected
500  *             by RECITE_FOO. Only modified if the function returns 0 or 1.
501  * @param quiet[in]     Whether to suppress messenging.
502  * @return  -1 if the monster is already affected. The eligibility vector
503  *          is unchanged.
504  * @return  0 if the monster is otherwise ineligible for recite. The
505  *          eligibility vector is filled with zeros.
506  * @return  1 if the monster is eligible for recite. The eligibility vector
507  *          indicates which types of recitation it is vulnerable to.
508  */
509 static int _zin_check_recite_to_single_monster(const monster *mon,
510                                                recite_counts &eligibility,
511                                                bool quiet = false)
512 {
513     ASSERT(mon);
514
515     // Can't recite if they were recently recited to.
516     if (mon->has_ench(ENCH_RECITE_TIMER))
517         return -1;
518
519     const mon_holy_type holiness = mon->holiness();
520
521     eligibility.init(0);
522
523     // Too high HD to ever be affected.
524     if (mon->get_hit_dice() >= zin_recite_power())
525         return 0;
526
527     // Anti-chaos prayer: Hits things vulnerable to silver, or with chaotic spells/gods.
528     eligibility[RECITE_CHAOTIC] = mon->how_chaotic(true);
529
530     // Anti-impure prayer: Hits things that Zin hates in general.
531     // Don't look at the monster's god; that's what RECITE_HERETIC is for.
532     eligibility[RECITE_IMPURE] = mon->how_unclean(false);
533     // Sanity check: if a monster is 'really' natural, don't consider it impure.
534     if (mons_intel(mon) < I_NORMAL
535         && (holiness == MH_NATURAL || holiness == MH_PLANT)
536         && mon->type != MONS_UGLY_THING
537         && mon->type != MONS_VERY_UGLY_THING
538         && mon->type != MONS_DEATH_DRAKE)
539     {
540         eligibility[RECITE_IMPURE] = 0;
541     }
542
543     // Anti-unholy prayer: Hits demons and incorporeal undead.
544     if (holiness == MH_UNDEAD && mon->is_insubstantial()
545         || holiness == MH_DEMONIC)
546     {
547         eligibility[RECITE_UNHOLY]++;
548     }
549
550     // Anti-heretic prayer: Hits intelligent monsters, especially priests.
551     eligibility[RECITE_HERETIC] = _heretic_recite_weakness(mon);
552
553 #ifdef DEBUG_DIAGNOSTICS
554     if (!quiet)
555     {
556         string elig;
557         for (int i = 0; i < NUM_RECITE_TYPES; i++)
558             elig += '0' + eligibility[i];
559         dprf("Eligibility: %s", elig.c_str());
560     }
561 #endif
562
563     // Checking to see whether they were eligible for anything at all.
564     for (int i = 0; i < NUM_RECITE_TYPES; i++)
565         if (eligibility[i] > 0)
566             return 1;
567
568     return 0;
569 }
570
571 int zin_recite_power()
572 {
573     // Resistance is now based on HD.
574     // You can affect up to (30+30)/2 = 30 'power' (HD).
575     const int power_mult = 10;
576     const int invo_power = you.skill_rdiv(SK_INVOCATIONS, power_mult)
577                            + 3 * power_mult;
578     const int piety_power = you.piety * 3 / 2;
579     return (invo_power + piety_power) / 2 / power_mult;
580 }
581
582 bool zin_check_able_to_recite(bool quiet)
583 {
584     if (you.duration[DUR_RECITE])
585     {
586         if (!quiet)
587             mpr("Finish your current sermon first, please.");
588         return false;
589     }
590
591     if (you.duration[DUR_BREATH_WEAPON])
592     {
593         if (!quiet)
594             mpr("You're too short of breath to recite.");
595         return false;
596     }
597
598     if (you.duration[DUR_WATER_HOLD] && !you.res_water_drowning())
599     {
600         if (!quiet)
601             mpr("You cannot recite while unable to breathe!");
602         return false;
603     }
604
605     return true;
606 }
607
608 /**
609  * Check whether there are monsters who might be influenced by Recite.
610  * If prayertype is null, we're just checking whether we can.
611  * Otherwise we're actually reciting, and may need to present a menu.
612  *
613  * @param quiet     Whether to suppress messages.
614  * @return  0 if no monsters were found, or if all the found monsters returned
615  *          zero from _zin_check_recite_to_single_monster().
616  * @return  1 if an eligible audience was found.
617  * @return  -1 if only an ineligible audience was found: no eligibile
618  *          monsters, and at least one returned -1 from
619  *          _zin_check_recite_to_single_monster().
620  */
621 int zin_check_recite_to_monsters(bool quiet)
622 {
623     bool found_ineligible = false;
624     bool found_eligible = false;
625
626     for (radius_iterator ri(you.pos(), LOS_DEFAULT); ri; ++ri)
627     {
628         const monster *mon = monster_at(*ri);
629         if (!mon || !you.can_see(mon))
630             continue;
631
632         recite_counts retval;
633         switch (_zin_check_recite_to_single_monster(mon, retval, quiet))
634         {
635         case -1:
636             found_ineligible = true;
637         // Intentional fallthrough
638         case 0:
639             continue;
640         }
641
642         for (int i = 0; i < NUM_RECITE_TYPES; i++)
643             if (retval[i] > 0)
644                 found_eligible = true;
645     }
646
647     if (!found_eligible && !found_ineligible)
648     {
649         if (!quiet)
650             dprf("No audience found!");
651         return 0;
652     }
653     else if (!found_eligible && found_ineligible)
654     {
655         if (!quiet)
656             dprf("No sensible audience found!");
657         return -1;
658     }
659     else
660         return 1; // We just recite against everything.
661 }
662
663 enum zin_eff
664 {
665     ZIN_NOTHING,
666     ZIN_DAZE,
667     ZIN_CONFUSE,
668     ZIN_PARALYSE,
669     ZIN_BLEED,
670     ZIN_SMITE,
671     ZIN_BLIND,
672     ZIN_SILVER_CORONA,
673     ZIN_ANTIMAGIC,
674     ZIN_MUTE,
675     ZIN_MAD,
676     ZIN_DUMB,
677     ZIN_IGNITE_CHAOS,
678     ZIN_SALTIFY,
679     ZIN_ROT,
680     ZIN_HOLY_WORD,
681 };
682
683 bool zin_recite_to_single_monster(const coord_def& where)
684 {
685     // That's a pretty good sanity check, I guess.
686     ASSERT(you_worship(GOD_ZIN));
687
688     monster* mon = monster_at(where);
689
690     // Once you're already reciting, invis is ok.
691     if (!mon || !cell_see_cell(where, you.pos(), LOS_DEFAULT))
692         return false;
693
694     recite_counts eligibility;
695     bool affected = false;
696
697     if (_zin_check_recite_to_single_monster(mon, eligibility) < 1)
698         return false;
699
700     recite_type prayertype = RECITE_HERETIC;
701     for (int i = NUM_RECITE_TYPES - 1; i >= RECITE_HERETIC; i--)
702     {
703         if (eligibility[i] > 0)
704         {
705             prayertype = static_cast <recite_type>(i);
706             break;
707         }
708     }
709
710     // Second check: because this affects the whole screen over several turns,
711     // its effects are staggered. There's a 50% chance per monster, per turn,
712     // that nothing will happen - so the cumulative odds of nothing happening
713     // are one in eight, since you recite three times.
714     if (coinflip())
715         return false;
716
717     const int power = zin_recite_power();
718     // Old recite was mostly deterministic, which is bad.
719     const int resist = mon->get_hit_dice() + random2(6);
720     const int check = power - resist;
721
722     // We abort if we didn't *beat* their HD - but first we might get a cute message.
723     if (mon->can_speak() && one_chance_in(5))
724     {
725         if (check < -10)
726             simple_monster_message(mon, " guffaws at your puny god.");
727         else if (check < -5)
728             simple_monster_message(mon, " sneers at your recitation.");
729     }
730
731     if (check <= 0)
732         return false;
733
734     // To what degree are they eligible for this prayertype?
735     const int degree = eligibility[prayertype];
736     const bool minor = degree <= (prayertype == RECITE_HERETIC ? 2 : 1);
737     const int spellpower = power * 2 + degree * 20;
738     zin_eff effect = ZIN_NOTHING;
739
740     switch (prayertype)
741     {
742     case RECITE_HERETIC:
743         if (degree == 1)
744         {
745             if (mon->asleep())
746                 break;
747             // This is the path for 'conversion' effects.
748             // Their degree is only 1 if they weren't a priest,
749             // a worshiper of an evil or chaotic god, etc.
750
751             // Right now, it only has the 'failed conversion' effects, though.
752             // This branch can't hit sleeping monsters - until they wake up.
753
754             if (check < 5)
755                 effect = ZIN_DAZE;
756             else if (check < 10)
757             {
758                 if (coinflip())
759                     effect = ZIN_CONFUSE;
760                 else
761                     effect = ZIN_DAZE;
762             }
763             else if (check < 15)
764                 effect = ZIN_CONFUSE;
765             else
766             {
767                 if (one_chance_in(3))
768                     effect = ZIN_PARALYSE;
769                 else
770                     effect = ZIN_CONFUSE;
771             }
772         }
773         else
774         {
775             // This is the path for 'smiting' effects.
776             // Their degree is only greater than 1 if
777             // they're unable to be redeemed.
778             if (check < 5)
779             {
780                 if (coinflip())
781                     effect = ZIN_BLEED;
782                 else
783                     effect = ZIN_SMITE;
784             }
785             else if (check < 10)
786             {
787                 if (one_chance_in(3))
788                     effect = ZIN_BLIND;
789                 else if (mon->antimagic_susceptible())
790                     effect = ZIN_ANTIMAGIC;
791                 else
792                     effect = ZIN_SILVER_CORONA;
793             }
794             else if (check < 15)
795             {
796                 if (one_chance_in(3))
797                     effect = ZIN_BLIND;
798                 else if (coinflip())
799                     effect = ZIN_PARALYSE;
800                 else
801                     effect = ZIN_MUTE;
802             }
803             else
804             {
805                 if (coinflip())
806                     effect = ZIN_MAD;
807                 else
808                     effect = ZIN_DUMB;
809             }
810         }
811         break;
812
813     case RECITE_CHAOTIC:
814         if (check < 5)
815         {
816             // nastier -- fallthrough if immune
817             if (coinflip() && mon->can_bleed())
818                 effect = ZIN_BLEED;
819             else
820                 effect = ZIN_SMITE;
821         }
822         else if (check < 10)
823         {
824             if (coinflip())
825                 effect = ZIN_SILVER_CORONA;
826             else
827                 effect = ZIN_SMITE;
828         }
829         else if (check < 15)
830         {
831             if (coinflip())
832                 effect = ZIN_IGNITE_CHAOS;
833             else
834                 effect = ZIN_SILVER_CORONA;
835         }
836         else
837             effect = ZIN_SALTIFY;
838         break;
839
840     case RECITE_IMPURE:
841         // Many creatures normally resistant to rotting are still affected,
842         // because this is divine punishment.  Those with no real flesh are
843         // immune, of course.
844         if (check < 5)
845         {
846             if (coinflip() && mon->can_bleed())
847                 effect = ZIN_BLEED;
848             else
849                 effect = ZIN_SMITE;
850         }
851         else if (check < 10)
852         {
853             if (coinflip() && mon->res_rotting() <= 1)
854                 effect = ZIN_ROT;
855             else
856                 effect = ZIN_SILVER_CORONA;
857         }
858         else if (check < 15)
859         {
860             if (mon->undead_or_demonic() && coinflip())
861                 effect = ZIN_HOLY_WORD;
862             else
863                 effect = ZIN_SILVER_CORONA;
864         }
865         else
866             effect = ZIN_SALTIFY;
867         break;
868
869     case RECITE_UNHOLY:
870         if (check < 5)
871         {
872             if (mons_intel(mon) > I_INSECT && coinflip())
873                 effect = ZIN_DAZE;
874             else
875                 effect = ZIN_CONFUSE;
876         }
877         else if (check < 10)
878         {
879             if (coinflip())
880                 effect = ZIN_CONFUSE;
881             else
882                 effect = ZIN_SILVER_CORONA;
883         }
884         // Half of the time, the anti-unholy prayer will be capped at this
885         // level of effect.
886         else if (check < 15 || coinflip())
887         {
888             if (coinflip())
889                 effect = ZIN_HOLY_WORD;
890             else
891                 effect = ZIN_SILVER_CORONA;
892         }
893         else
894             effect = ZIN_SALTIFY;
895         break;
896
897     case NUM_RECITE_TYPES:
898         die("invalid recite type");
899     }
900
901     // And the actual effects...
902     switch (effect)
903     {
904     case ZIN_NOTHING:
905         break;
906
907     case ZIN_DAZE:
908         if (mon->add_ench(mon_enchant(ENCH_DAZED, degree, &you,
909                           (degree + random2(spellpower)) * BASELINE_DELAY)))
910         {
911             simple_monster_message(mon, " is dazed by your recitation.");
912             affected = true;
913         }
914         break;
915
916     case ZIN_CONFUSE:
917         if (mons_class_is_confusable(mon->type)
918             && !mon->check_clarity(false)
919             && mon->add_ench(mon_enchant(ENCH_CONFUSION, degree, &you,
920                              (degree + random2(spellpower)) * BASELINE_DELAY)))
921         {
922             if (prayertype == RECITE_HERETIC)
923                 simple_monster_message(mon, " is confused by your recitation.");
924             else
925                 simple_monster_message(mon, " stumbles about in disarray.");
926             affected = true;
927         }
928         break;
929
930     case ZIN_PARALYSE:
931         if (mon->add_ench(mon_enchant(ENCH_PARALYSIS, 0, &you,
932                           (degree + random2(spellpower)) * BASELINE_DELAY)))
933         {
934             simple_monster_message(mon,
935                 minor ? " is awed by your recitation."
936                       : " is aghast at the heresy of your recitation.");
937             affected = true;
938         }
939         break;
940
941     case ZIN_BLEED:
942         if (mon->can_bleed()
943             && mon->add_ench(mon_enchant(ENCH_BLEED, degree, &you,
944                              (degree + random2(spellpower)) * BASELINE_DELAY)))
945         {
946             mon->add_ench(mon_enchant(ENCH_SICK, degree, &you,
947                           (degree + random2(spellpower)) * BASELINE_DELAY));
948             switch (prayertype)
949             {
950             case RECITE_HERETIC:
951                 if (minor)
952                     simple_monster_message(mon, "'s eyes and ears begin to bleed.");
953                 else
954                 {
955                     mprf("%s bleeds profusely from %s eyes and ears.",
956                          mon->name(DESC_THE).c_str(),
957                          mon->pronoun(PRONOUN_POSSESSIVE).c_str());
958                 }
959                 break;
960             case RECITE_CHAOTIC:
961                 simple_monster_message(mon,
962                     minor ? "'s chaotic flesh is covered in bleeding sores."
963                           : "'s chaotic flesh erupts into weeping sores!");
964                 break;
965             case RECITE_IMPURE:
966                 simple_monster_message(mon,
967                     minor ? "'s impure flesh is covered in bleeding sores."
968                           : "'s impure flesh erupts into weeping sores!");
969                 break;
970             default:
971                 die("bad recite bleed");
972             }
973             affected = true;
974         }
975         break;
976
977     case ZIN_SMITE:
978         if (minor)
979             simple_monster_message(mon, " is smitten by the wrath of Zin.");
980         else
981             simple_monster_message(mon, " is blasted by the fury of Zin!");
982         // XXX: This duplicates code in cast_smiting().
983         mon->hurt(&you, 7 + (random2(spellpower) * 33 / 191));
984         if (mon->alive())
985             print_wounds(mon);
986         affected = true;
987         break;
988
989     case ZIN_BLIND:
990         if (mon->add_ench(mon_enchant(ENCH_BLIND, degree, &you, INFINITE_DURATION)))
991         {
992             simple_monster_message(mon, " is struck blind by the wrath of Zin!");
993             affected = true;
994         }
995         break;
996
997     case ZIN_SILVER_CORONA:
998         if (mon->add_ench(mon_enchant(ENCH_SILVER_CORONA, degree, &you,
999                           (degree + random2(spellpower)) * BASELINE_DELAY)))
1000         {
1001             simple_monster_message(mon, " is limned with silver light.");
1002             affected = true;
1003         }
1004         break;
1005
1006     case ZIN_ANTIMAGIC:
1007         ASSERT(prayertype == RECITE_HERETIC);
1008         if (mon->add_ench(mon_enchant(ENCH_ANTIMAGIC, degree, &you,
1009                           (degree + random2(spellpower)) * BASELINE_DELAY)))
1010         {
1011             simple_monster_message(mon,
1012                 minor ? " quails at your recitation."
1013                       : " looks feeble and powerless before your recitation.");
1014             affected = true;
1015         }
1016         break;
1017
1018     case ZIN_MUTE:
1019         if (mon->add_ench(mon_enchant(ENCH_MUTE, degree, &you, INFINITE_DURATION)))
1020         {
1021             simple_monster_message(mon, " is struck mute by the wrath of Zin!");
1022             affected = true;
1023         }
1024         break;
1025
1026     case ZIN_MAD:
1027         if (mon->add_ench(mon_enchant(ENCH_MAD, degree, &you, INFINITE_DURATION)))
1028         {
1029             simple_monster_message(mon, " is driven mad by the wrath of Zin!");
1030             affected = true;
1031         }
1032         break;
1033
1034     case ZIN_DUMB:
1035         if (mon->add_ench(mon_enchant(ENCH_DUMB, degree, &you, INFINITE_DURATION)))
1036         {
1037             simple_monster_message(mon, " is left stupefied by the wrath of Zin!");
1038             affected = true;
1039         }
1040         break;
1041
1042     case ZIN_IGNITE_CHAOS:
1043         ASSERT(prayertype == RECITE_CHAOTIC);
1044         {
1045             bolt beam;
1046             dice_def dam_dice(0, 5 + spellpower/7);  // Dice added below if applicable.
1047             dam_dice.num = degree;
1048
1049             int damage = dam_dice.roll();
1050             if (damage > 0)
1051             {
1052                 mon->hurt(&you, damage, BEAM_MISSILE, KILLED_BY_BEAM,
1053                           "", "", false);
1054
1055                 if (mon->alive())
1056                 {
1057                     simple_monster_message(mon,
1058                       (damage < 25) ? "'s chaotic flesh sizzles and spatters!" :
1059                       (damage < 50) ? "'s chaotic flesh bubbles and boils."
1060                                     : "'s chaotic flesh runs like molten wax.");
1061
1062                     print_wounds(mon);
1063                     behaviour_event(mon, ME_WHACK, &you);
1064                     affected = true;
1065                 }
1066                 else
1067                 {
1068                     simple_monster_message(mon,
1069                         " melts away into a sizzling puddle of chaotic flesh.");
1070                     monster_die(mon, KILL_YOU, NON_MONSTER);
1071                 }
1072             }
1073         }
1074         break;
1075
1076     case ZIN_SALTIFY:
1077         _zin_saltify(mon);
1078         break;
1079
1080     case ZIN_ROT:
1081         ASSERT(prayertype == RECITE_IMPURE);
1082         if (mon->res_rotting() <= 1
1083             && mon->add_ench(mon_enchant(ENCH_ROT, degree, &you,
1084                              (degree + random2(spellpower)) * BASELINE_DELAY)))
1085         {
1086             mon->add_ench(mon_enchant(ENCH_SICK, degree, &you,
1087                           (degree + random2(spellpower)) * BASELINE_DELAY));
1088             simple_monster_message(mon,
1089                 minor ? "'s impure flesh begins to rot away."
1090                       : "'s impure flesh sloughs off!");
1091             affected = true;
1092         }
1093         break;
1094
1095     case ZIN_HOLY_WORD:
1096         holy_word_monsters(where, spellpower, HOLY_WORD_ZIN, &you);
1097         affected = true;
1098         break;
1099     }
1100
1101     // Recite time, to prevent monsters from being recited against
1102     // more than once in a given recite instance.
1103     if (affected)
1104         mon->add_ench(mon_enchant(ENCH_RECITE_TIMER, degree, &you, 40));
1105
1106     // Monsters that have been affected may shout.
1107     if (affected
1108         && one_chance_in(3)
1109         && mon->alive()
1110         && !mon->asleep()
1111         && !mon->cannot_move()
1112         && mons_shouts(mon->type, false) != S_SILENT)
1113     {
1114         handle_monster_shouts(mon, true);
1115     }
1116
1117     return true;
1118 }
1119
1120 static void _zin_saltify(monster* mon)
1121 {
1122     const coord_def where = mon->pos();
1123     const monster_type pillar_type =
1124         mons_is_zombified(mon) ? mons_zombie_base(mon)
1125                                : mons_species(mon->type);
1126     const int hd = mon->get_hit_dice();
1127
1128     simple_monster_message(mon, " is turned into a pillar of salt by the wrath of Zin!");
1129
1130     // If the monster leaves a corpse when it dies, destroy the corpse.
1131     int corpse = monster_die(mon, KILL_YOU, NON_MONSTER);
1132     if (corpse != -1)
1133         destroy_item(corpse);
1134
1135     if (monster *pillar = create_monster(
1136                         mgen_data(MONS_PILLAR_OF_SALT,
1137                                   BEH_HOSTILE,
1138                                   0,
1139                                   0,
1140                                   0,
1141                                   where,
1142                                   MHITNOT,
1143                                   MG_FORCE_PLACE,
1144                                   GOD_NO_GOD,
1145                                   pillar_type),
1146                                   false))
1147     {
1148         // Enemies with more HD leave longer-lasting pillars of salt.
1149         int time_left = (random2(8) + hd) * BASELINE_DELAY;
1150         mon_enchant temp_en(ENCH_SLOWLY_DYING, 1, 0, time_left);
1151         pillar->update_ench(temp_en);
1152     }
1153 }
1154
1155 void zin_recite_interrupt()
1156 {
1157     if (!you.duration[DUR_RECITE])
1158         return;
1159     mprf(MSGCH_DURATION, "Your recitation is interrupted.");
1160     mpr("You feel short of breath.");
1161     you.duration[DUR_RECITE] = 0;
1162
1163     you.increase_duration(DUR_BREATH_WEAPON, random2(10) + random2(30));
1164 }
1165
1166 bool zin_vitalisation()
1167 {
1168     simple_god_message(" grants you divine stamina.");
1169
1170     // Feed the player slightly.
1171     if (you.hunger_state < HS_FULL)
1172         lessen_hunger(250, false);
1173
1174     // Add divine stamina.
1175     const int stamina_amt = max(1, you.skill_rdiv(SK_INVOCATIONS, 1, 3));
1176     you.attribute[ATTR_DIVINE_STAMINA] = stamina_amt;
1177     you.set_duration(DUR_DIVINE_STAMINA, 60 + roll_dice(2, 10));
1178
1179     notify_stat_change(STAT_STR, stamina_amt, true);
1180     notify_stat_change(STAT_INT, stamina_amt, true);
1181     notify_stat_change(STAT_DEX, stamina_amt, true);
1182
1183     return true;
1184 }
1185
1186 void zin_remove_divine_stamina()
1187 {
1188     mprf(MSGCH_DURATION, "Your divine stamina fades away.");
1189     notify_stat_change(STAT_STR, -you.attribute[ATTR_DIVINE_STAMINA], true);
1190     notify_stat_change(STAT_INT, -you.attribute[ATTR_DIVINE_STAMINA], true);
1191     notify_stat_change(STAT_DEX, -you.attribute[ATTR_DIVINE_STAMINA], true);
1192     you.duration[DUR_DIVINE_STAMINA] = 0;
1193     you.attribute[ATTR_DIVINE_STAMINA] = 0;
1194 }
1195
1196 bool zin_remove_all_mutations()
1197 {
1198     if (!how_mutated())
1199     {
1200         mpr("You have no mutations to be cured!");
1201         return false;
1202     }
1203
1204     you.one_time_ability_used.set(GOD_ZIN);
1205     take_note(Note(NOTE_GOD_GIFT, you.religion));
1206
1207     simple_god_message(" draws all chaos from your body!");
1208     delete_all_mutations("Zin's power");
1209
1210     return true;
1211 }
1212
1213 bool zin_sanctuary()
1214 {
1215     // Casting is disallowed while previous sanctuary in effect.
1216     // (Checked in ability.cc.)
1217     if (env.sanctuary_time)
1218         return false;
1219
1220     // Yes, shamelessly stolen from NetHack...
1221     if (!silenced(you.pos())) // How did you manage that?
1222         mprf(MSGCH_SOUND, "You hear a choir sing!");
1223     else
1224         mpr("You are suddenly bathed in radiance!");
1225
1226     flash_view(UA_PLAYER, WHITE);
1227
1228     holy_word(100, HOLY_WORD_ZIN, you.pos(), true, &you);
1229
1230 #ifndef USE_TILE_LOCAL
1231     // Allow extra time for the flash to linger.
1232     scaled_delay(1000);
1233 #endif
1234
1235     // Pets stop attacking and converge on you.
1236     you.pet_target = MHITYOU;
1237
1238     create_sanctuary(you.pos(), 7 + you.skill_rdiv(SK_INVOCATIONS) / 2);
1239
1240     return true;
1241 }
1242
1243 // shield bonus = attribute for duration turns, then decreasing by 1
1244 //                every two out of three turns
1245 // overall shield duration = duration + attribute
1246 // recasting simply resets those two values (to better values, presumably)
1247 void tso_divine_shield()
1248 {
1249     if (!you.duration[DUR_DIVINE_SHIELD])
1250     {
1251         if (you.shield()
1252             || you.duration[DUR_CONDENSATION_SHIELD])
1253         {
1254             mprf("Your shield is strengthened by %s divine power.",
1255                  apostrophise(god_name(GOD_SHINING_ONE)).c_str());
1256         }
1257         else
1258             mpr("A divine shield forms around you!");
1259     }
1260     else
1261         mpr("Your divine shield is renewed.");
1262
1263     you.redraw_armour_class = true;
1264
1265     // duration of complete shield bonus from 35 to 80 turns
1266     you.set_duration(DUR_DIVINE_SHIELD,
1267                      35 + you.skill_rdiv(SK_INVOCATIONS, 4, 3));
1268
1269     // affects size of SH bonus, decreases near end of duration
1270     you.attribute[ATTR_DIVINE_SHIELD] = 3 + you.skill_rdiv(SK_INVOCATIONS, 1, 5);
1271
1272     you.redraw_armour_class = true;
1273 }
1274
1275 void tso_remove_divine_shield()
1276 {
1277     mprf(MSGCH_DURATION, "Your divine shield disappears!");
1278     you.duration[DUR_DIVINE_SHIELD] = 0;
1279     you.attribute[ATTR_DIVINE_SHIELD] = 0;
1280     you.redraw_armour_class = true;
1281 }
1282
1283 void elyvilon_purification()
1284 {
1285     mpr("You feel purified!");
1286
1287     you.disease = 0;
1288     you.rotting = 0;
1289     you.duration[DUR_POISONING] = 0;
1290     you.duration[DUR_CONF] = 0;
1291     you.duration[DUR_SLOW] = 0;
1292     you.duration[DUR_PETRIFYING] = 0;
1293     you.duration[DUR_WEAK] = 0;
1294     restore_stat(STAT_ALL, 0, false);
1295     unrot_hp(9999);
1296     you.redraw_evasion = true;
1297 }
1298
1299 bool elyvilon_divine_vigour()
1300 {
1301     bool success = false;
1302
1303     if (!you.duration[DUR_DIVINE_VIGOUR])
1304     {
1305         mprf("%s grants you divine vigour.",
1306              god_name(GOD_ELYVILON).c_str());
1307
1308         const int vigour_amt = 1 + you.skill_rdiv(SK_INVOCATIONS, 1, 3);
1309         const int old_hp_max = you.hp_max;
1310         const int old_mp_max = you.max_magic_points;
1311         you.attribute[ATTR_DIVINE_VIGOUR] = vigour_amt;
1312         you.set_duration(DUR_DIVINE_VIGOUR,
1313                          40 + you.skill_rdiv(SK_INVOCATIONS, 5, 2));
1314
1315         calc_hp();
1316         inc_hp((you.hp_max * you.hp + old_hp_max - 1)/old_hp_max - you.hp);
1317         calc_mp();
1318         if (old_mp_max > 0)
1319         {
1320             inc_mp((you.max_magic_points * you.magic_points + old_mp_max - 1)
1321                      / old_mp_max
1322                    - you.magic_points);
1323         }
1324
1325         success = true;
1326     }
1327     else
1328         canned_msg(MSG_NOTHING_HAPPENS);
1329
1330     return success;
1331 }
1332
1333 void elyvilon_remove_divine_vigour()
1334 {
1335     mprf(MSGCH_DURATION, "Your divine vigour fades away.");
1336     you.duration[DUR_DIVINE_VIGOUR] = 0;
1337     you.attribute[ATTR_DIVINE_VIGOUR] = 0;
1338     calc_hp();
1339     calc_mp();
1340 }
1341
1342 bool vehumet_supports_spell(spell_type spell)
1343 {
1344     if (spell_typematch(spell, SPTYP_CONJURATION))
1345         return true;
1346
1347     // Conjurations work by conjuring up a chunk of short-lived matter and
1348     // propelling it towards the victim.  This is the most popular way, but
1349     // by no means it has a monopoly for being destructive.
1350     // Vehumet loves all direct physical destruction.
1351     if (spell == SPELL_SHATTER
1352         || spell == SPELL_LRD
1353         || spell == SPELL_SANDBLAST
1354         || spell == SPELL_AIRSTRIKE
1355         || spell == SPELL_TORNADO
1356         || spell == SPELL_FREEZE
1357         || spell == SPELL_IGNITE_POISON
1358         || spell == SPELL_OZOCUBUS_REFRIGERATION
1359         || spell == SPELL_OLGREBS_TOXIC_RADIANCE
1360         || spell == SPELL_INNER_FLAME)
1361     {
1362         return true;
1363     }
1364
1365     return false;
1366 }
1367
1368 // Returns false if the invocation fails (no spellbooks in sight, etc.).
1369 bool trog_burn_spellbooks()
1370 {
1371     if (!you_worship(GOD_TROG))
1372         return false;
1373
1374     god_acting gdact;
1375
1376     // XXX: maybe this should be allowed with less than immunity.
1377     if (player_res_fire(false) <= 3)
1378     {
1379         for (stack_iterator si(you.pos()); si; ++si)
1380         {
1381             if (item_is_spellbook(*si))
1382             {
1383                 mprf("Burning your own %s might not be such a smart idea!",
1384                         you.foot_name(true).c_str());
1385                 return false;
1386             }
1387         }
1388     }
1389
1390     int totalpiety = 0;
1391     int totalblocked = 0;
1392     vector<coord_def> mimics;
1393
1394     for (radius_iterator ri(you.pos(), LOS_DEFAULT); ri; ++ri)
1395     {
1396         const unsigned short cloud = env.cgrid(*ri);
1397         int count = 0;
1398         int rarity = 0;
1399         for (stack_iterator si(*ri); si; ++si)
1400         {
1401             if (!item_is_spellbook(*si))
1402                 continue;
1403
1404             // If a grid is blocked, books lying there will be ignored.
1405             // Allow bombing of monsters.
1406             if (cell_is_solid(*ri)
1407                 || cloud != EMPTY_CLOUD && env.cloud[cloud].type != CLOUD_FIRE)
1408             {
1409                 totalblocked++;
1410                 continue;
1411             }
1412
1413             if (si->flags & ISFLAG_MIMIC)
1414             {
1415                 totalblocked++;
1416                 mimics.push_back(*ri);
1417                 continue;
1418             }
1419
1420             // Ignore {!D} inscribed books.
1421             if (!check_warning_inscriptions(*si, OPER_DESTROY))
1422             {
1423                 mpr("Won't ignite {!D} inscribed spellbook.");
1424                 continue;
1425             }
1426
1427             totalpiety += 2;
1428
1429             // Rarity influences the duration of the pyre.
1430             rarity += book_rarity(si->sub_type);
1431
1432             dprf("Burned spellbook rarity: %d", rarity);
1433             destroy_spellbook(*si);
1434             item_was_destroyed(*si);
1435             destroy_item(si.link());
1436             count++;
1437         }
1438
1439         if (count)
1440         {
1441             if (cloud != EMPTY_CLOUD)
1442             {
1443                 // Reinforce the cloud.
1444                 mpr("The fire roars with new energy!");
1445                 const int extra_dur = count + random2(rarity / 2);
1446                 env.cloud[cloud].decay += extra_dur * 5;
1447                 env.cloud[cloud].set_whose(KC_YOU);
1448                 continue;
1449             }
1450
1451             const int duration = min(4 + count + random2(rarity/2), 23);
1452             place_cloud(CLOUD_FIRE, *ri, duration, &you);
1453
1454             mprf(MSGCH_GOD, "The spellbook%s burst%s into flames.",
1455                  count == 1 ? ""  : "s",
1456                  count == 1 ? "s" : "");
1457         }
1458     }
1459
1460     if (totalpiety)
1461     {
1462         simple_god_message(" is delighted!", GOD_TROG);
1463         gain_piety(totalpiety);
1464     }
1465     else if (totalblocked)
1466     {
1467         mprf("The spellbook%s fail%s to ignite!",
1468              totalblocked == 1 ? ""  : "s",
1469              totalblocked == 1 ? "s" : "");
1470         for (auto c : mimics)
1471             discover_mimic(c);
1472         return false;
1473     }
1474     else
1475     {
1476         mpr("You cannot see a spellbook to ignite!");
1477         return false;
1478     }
1479
1480     return true;
1481 }
1482
1483 void trog_do_trogs_hand(int pow)
1484 {
1485     you.increase_duration(DUR_TROGS_HAND,
1486                           5 + roll_dice(2, pow / 3 + 1), 100,
1487                           "Your skin crawls.");
1488     mprf(MSGCH_DURATION, "You feel resistant to hostile enchantments.");
1489 }
1490
1491 void trog_remove_trogs_hand()
1492 {
1493     if (you.duration[DUR_REGENERATION] == 0)
1494         mprf(MSGCH_DURATION, "Your skin stops crawling.");
1495     mprf(MSGCH_DURATION, "You feel less resistant to hostile enchantments.");
1496     you.duration[DUR_TROGS_HAND] = 0;
1497 }
1498
1499 bool beogh_water_walk()
1500 {
1501     return in_good_standing(GOD_BEOGH, 4);
1502 }
1503
1504 /**
1505  * Has the monster been given a Beogh gift?
1506  *
1507  * @param mon the orc in question.
1508  * @returns whether you have given the monster a Beogh gift before now.
1509  */
1510 static bool _given_gift(const monster* mon)
1511 {
1512     return mon->props.exists(BEOGH_WPN_GIFT_KEY)
1513             || mon->props.exists(BEOGH_ARM_GIFT_KEY)
1514             || mon->props.exists(BEOGH_SH_GIFT_KEY);
1515 }
1516
1517 /**
1518  * Checks whether the target monster is a valid target for beogh item-gifts.
1519  *
1520  * @param mons[in]  The monster to consider giving an item to.
1521  * @param quiet     Whether to print messages if the target is invalid.
1522  * @return          Whether the player can give an item to the monster.
1523  */
1524 bool beogh_can_gift_items_to(const monster* mons, bool quiet)
1525 {
1526     if (!mons || !mons->visible_to(&you))
1527     {
1528         if (!quiet)
1529             canned_msg(MSG_NOTHING_THERE);
1530         return false;
1531     }
1532
1533     if (!is_orcish_follower(mons))
1534     {
1535         if (!quiet)
1536             mpr("That's not an orcish ally!");
1537         return false;
1538     }
1539
1540     if (!mons->is_named())
1541     {
1542         if (!quiet)
1543             mpr("That orc has not proved itself worthy of your gift.");
1544         return false;
1545     }
1546
1547     if (_given_gift(mons))
1548     {
1549         if (!quiet)
1550         {
1551             mprf("%s has already been given a gift.",
1552                  mons->name(DESC_THE, false).c_str());
1553         }
1554         return false;
1555     }
1556
1557     return true;
1558 }
1559
1560 /**
1561  * Checks whether there are any valid targets for beogh gifts in LOS.
1562  */
1563 static bool _valid_beogh_gift_targets_in_sight()
1564 {
1565     for (monster_near_iterator rad(you.pos(), LOS_NO_TRANS); rad; ++rad)
1566         if (beogh_can_gift_items_to(*rad))
1567             return true;
1568     return false;
1569 }
1570
1571 /**
1572  * Allow the player to give an item to a named orcish ally that hasn't
1573  * been given a gift before
1574  *
1575  * @returns whether an item was given.
1576  */
1577 bool beogh_gift_item()
1578 {
1579     if (!_valid_beogh_gift_targets_in_sight())
1580     {
1581         mpr("No worthy followers in sight.");
1582         return false;
1583     }
1584
1585     dist spd;
1586
1587     direction_chooser_args args;
1588     args.restricts = DIR_TARGET;
1589     args.mode = TARG_BEOGH_GIFTABLE;
1590     args.range = LOS_RADIUS;
1591     args.needs_path = false;
1592     args.may_target_monster = true;
1593     args.cancel_at_self = true;
1594     args.show_floor_desc = true;
1595     args.top_prompt = "Select a follower to give a gift to.";
1596
1597     direction(spd, args);
1598
1599     if (!spd.isValid)
1600         return false;
1601
1602     monster* mons = monster_at(spd.target);
1603     if (!beogh_can_gift_items_to(mons, false))
1604         return false;
1605
1606     int item_slot = prompt_invent_item("Give which item?",
1607                                        MT_INVLIST, OSEL_ANY, true);
1608
1609     if (item_slot == PROMPT_ABORT || item_slot == PROMPT_NOTHING)
1610     {
1611         canned_msg(MSG_OK);
1612         return false;
1613     }
1614
1615     item_def& gift = you.inv[item_slot];
1616
1617     const bool shield = is_shield(gift);
1618     const bool body_armour = gift.base_type == OBJ_ARMOUR
1619                              && get_armour_slot(gift) == EQ_BODY_ARMOUR;
1620     const bool weapon = gift.base_type == OBJ_WEAPONS;
1621     const bool range_weapon = weapon && is_range_weapon(gift);
1622     const item_def* mons_weapon = mons->weapon();
1623
1624     if (!(weapon && mons->could_wield(gift)
1625           || body_armour && check_armour_size(gift, mons->body_size())
1626           || shield
1627              && (!mons_weapon
1628                  || mons->hands_reqd(*mons_weapon) != HANDS_TWO)))
1629     {
1630         mprf("%s can't use that.", mons->name(DESC_THE, false).c_str());
1631
1632         return false;
1633     }
1634
1635     // if we're giving a ranged weapon to an orc holding a melee weapon in
1636     // their hands, or vice versa, put it in their carried slot instead.
1637     // this will of course drop anything that's there.
1638     const bool use_alt_slot = weapon && mons_weapon
1639                               && is_range_weapon(gift) !=
1640                                  is_range_weapon(*mons_weapon);
1641
1642     mons->take_item(item_slot, body_armour ? MSLOT_ARMOUR :
1643                                     shield ? MSLOT_SHIELD :
1644                               use_alt_slot ? MSLOT_ALT_WEAPON :
1645                                              MSLOT_WEAPON);
1646     if (use_alt_slot)
1647         mons->swap_weapons(true);
1648
1649     dprf("is_ranged weap: %d", range_weapon);
1650     if (range_weapon)
1651         gift_ammo_to_orc(mons, true); // give a small initial ammo freebie
1652
1653
1654     if (shield)
1655         mons->props[BEOGH_SH_GIFT_KEY] = true;
1656     else if (body_armour)
1657         mons->props[BEOGH_ARM_GIFT_KEY] = true;
1658     else
1659         mons->props[BEOGH_WPN_GIFT_KEY] = true;
1660
1661     return true;
1662 }
1663
1664 void jiyva_paralyse_jellies()
1665 {
1666     mprf("You call upon nearby slimes to pray to %s.",
1667          god_name(you.religion).c_str());
1668
1669     int jelly_count = 0;
1670     for (radius_iterator ri(you.pos(), LOS_DEFAULT); ri; ++ri)
1671     {
1672         monster* mon = monster_at(*ri);
1673         const int dur = 16 + random2(9);
1674         if (mon != nullptr && mons_is_slime(mon) && !mon->is_shapeshifter())
1675         {
1676             mon->add_ench(mon_enchant(ENCH_PARALYSIS, 0,
1677                                       &you, dur * BASELINE_DELAY));
1678             jelly_count++;
1679         }
1680     }
1681
1682     if (jelly_count > 0)
1683     {
1684         if (jelly_count > 1)
1685             mpr("The nearby slimes join the prayer.");
1686         else
1687             mpr("A nearby slime joins the prayer.");
1688
1689         lose_piety(max(5, min(jelly_count, 20)));
1690     }
1691 }
1692
1693 bool jiyva_remove_bad_mutation()
1694 {
1695     if (!how_mutated())
1696     {
1697         mpr("You have no bad mutations to be cured!");
1698         return false;
1699     }
1700
1701     // Ensure that only bad mutations are removed.
1702     if (!delete_mutation(RANDOM_BAD_MUTATION, "Jiyva's power", true, false, true, true))
1703     {
1704         canned_msg(MSG_NOTHING_HAPPENS);
1705         return false;
1706     }
1707
1708     mpr("You feel cleansed.");
1709     return true;
1710 }
1711
1712 bool yred_injury_mirror()
1713 {
1714     return in_good_standing(GOD_YREDELEMNUL, 1)
1715            && you.duration[DUR_MIRROR_DAMAGE]
1716            && crawl_state.which_god_acting() != GOD_YREDELEMNUL;
1717 }
1718
1719 bool yred_can_animate_dead()
1720 {
1721     return in_good_standing(GOD_YREDELEMNUL, 2);
1722 }
1723
1724 /**
1725  * Animates corpses/skeletons where you are or in LOS, depending on piety.
1726  *
1727  * @returns false if it did nothing and you could have known so.
1728  */
1729 bool yred_animate_remains_or_dead()
1730 {
1731     if (yred_can_animate_dead())
1732     {
1733         canned_msg(MSG_CALL_DEAD);
1734
1735         animate_dead(&you, you.skill_rdiv(SK_INVOCATIONS) + 1, BEH_FRIENDLY,
1736                      MHITYOU, &you, "", GOD_YREDELEMNUL);
1737     }
1738     else
1739     {
1740         canned_msg(MSG_ANIMATE_REMAINS);
1741
1742         if (animate_remains(you.pos(), CORPSE_BODY, BEH_FRIENDLY,
1743                             MHITYOU, &you, "", GOD_YREDELEMNUL) < 0)
1744         {
1745             mpr("There are no remains here to animate!");
1746             return false;
1747         }
1748     }
1749     return true;
1750 }
1751
1752 void yred_make_enslaved_soul(monster* mon, bool force_hostile)
1753 {
1754     ASSERT(mons_enslaved_body_and_soul(mon));
1755
1756     add_daction(DACT_OLD_ENSLAVED_SOULS_POOF);
1757     remove_enslaved_soul_companion();
1758
1759     const string whose = you.can_see(mon) ? apostrophise(mon->name(DESC_THE))
1760                                           : mon->pronoun(PRONOUN_POSSESSIVE);
1761
1762     // Remove the monster's soul-enslaving enchantment, as it's no
1763     // longer needed.
1764     mon->del_ench(ENCH_SOUL_RIPE, false, false);
1765
1766     // Remove the monster's invisibility enchantment. If we don't do
1767     // this, it'll stay invisible after being remade as a spectral thing
1768     // below.
1769     mon->del_ench(ENCH_INVIS, false, false);
1770
1771     // If the monster's held in a net, get it out.
1772     mons_clear_trapping_net(mon);
1773
1774     // Drop the monster's holy equipment, and keep wielding the rest.  Also
1775     // remove any of its active avatars.
1776     monster_drop_things(mon, false, is_holy_item);
1777     mon->remove_avatars();
1778
1779     const monster orig = *mon;
1780
1781     // Use the original monster type as the zombified type here, to get
1782     // the proper stats from it.
1783     define_zombie(mon, mon->type, MONS_SPECTRAL_THING);
1784
1785     // If the original monster has been levelled up, its HD might be different
1786     // from its class HD, in which case its HP should be rerolled to match.
1787     if (mon->get_experience_level() != orig.get_experience_level())
1788     {
1789         mon->set_hit_dice(max(orig.get_experience_level(), 1));
1790         roll_zombie_hp(mon);
1791     }
1792
1793     mon->colour = ETC_UNHOLY;
1794
1795     mon->flags |= MF_NO_REWARD;
1796     mon->flags |= MF_ENSLAVED_SOUL;
1797
1798     // If the original monster type has melee abilities, make sure
1799     // its spectral thing has them as well.
1800     mon->flags |= orig.flags & MF_MELEE_MASK;
1801     mon->spells = orig.spells;
1802
1803     name_zombie(mon, &orig);
1804
1805     mons_make_god_gift(mon, GOD_YREDELEMNUL);
1806     add_companion(mon);
1807
1808     mon->attitude = !force_hostile ? ATT_FRIENDLY : ATT_HOSTILE;
1809     behaviour_event(mon, ME_ALERT, force_hostile ? &you : 0);
1810
1811     mon->stop_constricting_all(false);
1812     mon->stop_being_constricted();
1813
1814     mprf("%s soul %s.", whose.c_str(),
1815          !force_hostile ? "is now yours" : "fights you");
1816 }
1817
1818 bool kiku_receive_corpses(int pow)
1819 {
1820     // pow = necromancy * 4, ranges from 0 to 108
1821     dprf("kiku_receive_corpses() power: %d", pow);
1822
1823     // Kiku gives branch-appropriate corpses (like shadow creatures).
1824     // 1d2 at 0 Nec, up to 8 at 27 Nec.
1825     int expected_extra_corpses = 1 + random2(2) + random2(pow / 18);
1826     int corpse_delivery_radius = 1;
1827
1828     // We should get the same number of corpses
1829     // in a hallway as in an open room.
1830     int spaces_for_corpses = 0;
1831     for (radius_iterator ri(you.pos(), corpse_delivery_radius, C_ROUND,
1832                             LOS_NO_TRANS, true); ri; ++ri)
1833     {
1834         if (mons_class_can_pass(MONS_HUMAN, grd(*ri)))
1835             spaces_for_corpses++;
1836     }
1837     // floating over lava, heavy tomb abuse, etc
1838     if (!spaces_for_corpses)
1839         spaces_for_corpses++;
1840
1841     int percent_chance_a_square_receives_extra_corpse = // can be > 100
1842         int(float(expected_extra_corpses) / float(spaces_for_corpses) * 100.0);
1843
1844     int corpses_created = 0;
1845
1846     for (radius_iterator ri(you.pos(), corpse_delivery_radius, C_ROUND,
1847                             LOS_NO_TRANS); ri; ++ri)
1848     {
1849         bool square_is_walkable = mons_class_can_pass(MONS_HUMAN, grd(*ri));
1850         bool square_is_player_square = (*ri == you.pos());
1851         bool square_gets_corpse =
1852             random2(100) < percent_chance_a_square_receives_extra_corpse
1853             || square_is_player_square && random2(100) < 97;
1854
1855         if (!square_is_walkable || !square_gets_corpse)
1856             continue;
1857
1858         corpses_created++;
1859
1860         // Find an appropriate monster corpse for level and power.
1861         const int adjusted_power = min(pow / 4, random2(random2(pow)));
1862         // Pick a place based on the power.  This may be below the branch's
1863         // start, that's ok.
1864         const level_id lev(you.where_are_you, adjusted_power
1865                            - absdungeon_depth(you.where_are_you, 0));
1866         const monster_type mon_type = pick_local_corpsey_monster(lev);
1867         ASSERT(mons_class_can_be_zombified(mons_species(mon_type)));
1868
1869         // Create corpse object.
1870         monster dummy;
1871         dummy.type = mon_type;
1872         define_monster(&dummy);
1873         int index_of_corpse_created = get_mitm_slot();
1874
1875         if (index_of_corpse_created == NON_ITEM)
1876             break;
1877
1878         int valid_corpse = fill_out_corpse(&dummy,
1879                                            dummy.type,
1880                                            mitm[index_of_corpse_created],
1881                                            false);
1882         if (valid_corpse == -1)
1883         {
1884             mitm[index_of_corpse_created].clear();
1885             continue;
1886         }
1887
1888         // no scumming for hides
1889         if (mons_class_leaves_hide(mon_type))
1890             mitm[index_of_corpse_created].props[MANGLED_CORPSE_KEY] = true;
1891
1892         ASSERT(valid_corpse >= 0);
1893
1894         // Higher piety means fresher corpses.
1895         int rottedness = 200 -
1896             (!one_chance_in(10) ? random2(200 - you.piety)
1897                                 : random2(100 + random2(75)));
1898         mitm[index_of_corpse_created].special = rottedness;
1899
1900         // Place the corpse.
1901         move_item_to_grid(&index_of_corpse_created, *ri);
1902     }
1903
1904     if (corpses_created)
1905     {
1906         if (you_worship(GOD_KIKUBAAQUDGHA))
1907         {
1908             simple_god_message(corpses_created > 1 ? " delivers you corpses!"
1909                                                    : " delivers you a corpse!");
1910         }
1911         maybe_update_stashes();
1912         return true;
1913     }
1914     else
1915     {
1916         if (you_worship(GOD_KIKUBAAQUDGHA))
1917             simple_god_message(" can find no cadavers for you!");
1918         return false;
1919     }
1920 }
1921
1922 /**
1923  * Destroy a corpse at the player's location
1924  *
1925  * @return  True if a corpse was destroyed, false otherwise.
1926 */
1927 bool kiku_take_corpse()
1928 {
1929     for (int i = you.visible_igrd(you.pos()); i != NON_ITEM; i = mitm[i].link)
1930     {
1931         item_def &item(mitm[i]);
1932
1933         if (item.base_type != OBJ_CORPSES || item.sub_type != CORPSE_BODY)
1934             continue;
1935         item_was_destroyed(item);
1936         destroy_item(i);
1937         return true;
1938     }
1939
1940     return false;
1941 }
1942
1943 bool fedhas_passthrough_class(const monster_type mc)
1944 {
1945     return you_worship(GOD_FEDHAS)
1946            && mons_class_is_plant(mc)
1947            && mons_class_is_stationary(mc)
1948            && mc != MONS_SNAPLASHER_VINE
1949            && mc != MONS_SNAPLASHER_VINE_SEGMENT;
1950 }
1951
1952 // Fedhas allows worshipers to walk on top of stationary plants and
1953 // fungi.
1954 bool fedhas_passthrough(const monster* target)
1955 {
1956     return target
1957            && fedhas_passthrough_class(target->type)
1958            && (mons_species(target->type) != MONS_OKLOB_PLANT
1959                || target->attitude != ATT_HOSTILE);
1960 }
1961
1962 bool fedhas_passthrough(const monster_info* target)
1963 {
1964     return target
1965            && fedhas_passthrough_class(target->type)
1966            && (mons_species(target->type) != MONS_OKLOB_PLANT
1967                || target->attitude != ATT_HOSTILE);
1968 }
1969
1970 // Fedhas worshipers can shoot through non-hostile plants, can a
1971 // particular beam go through a particular monster?
1972 bool fedhas_shoot_through(const bolt& beam, const monster* victim)
1973 {
1974     actor *originator = beam.agent();
1975     if (!victim || !originator)
1976         return false;
1977
1978     bool origin_worships_fedhas;
1979     mon_attitude_type origin_attitude;
1980     if (originator->is_player())
1981     {
1982         origin_worships_fedhas = you_worship(GOD_FEDHAS);
1983         origin_attitude = ATT_FRIENDLY;
1984     }
1985     else
1986     {
1987         monster* temp = originator->as_monster();
1988         if (!temp)
1989             return false;
1990         origin_worships_fedhas = temp->god == GOD_FEDHAS;
1991         origin_attitude = temp->attitude;
1992     }
1993
1994     return origin_worships_fedhas
1995            && fedhas_protects(victim)
1996            && !beam.is_enchantment()
1997            && !(beam.is_explosion && beam.in_explosion_phase)
1998            && beam.name != "lightning arc"
1999            && (mons_atts_aligned(victim->attitude, origin_attitude)
2000                || victim->neutral());
2001 }
2002
2003 // Turns corpses in LOS into skeletons and grows toadstools on them.
2004 // Can also turn zombies into skeletons and destroy ghoul-type monsters.
2005 // Returns the number of corpses consumed.
2006 int fedhas_fungal_bloom()
2007 {
2008     int seen_mushrooms = 0;
2009     int seen_corpses = 0;
2010     int processed_count = 0;
2011     bool kills = false;
2012
2013     for (radius_iterator i(you.pos(), LOS_NO_TRANS); i; ++i)
2014     {
2015         monster* target = monster_at(*i);
2016         if (!can_spawn_mushrooms(*i))
2017             continue;
2018
2019         if (target && target->type != MONS_TOADSTOOL)
2020         {
2021             bool piety = !target->is_summoned();
2022             switch (mons_genus(target->mons_species()))
2023             {
2024             case MONS_ZOMBIE:
2025                 // Maybe turn a zombie into a skeleton.
2026                 if (mons_skeleton(mons_zombie_base(target)))
2027                 {
2028                     simple_monster_message(target, "'s flesh rots away.");
2029
2030                     downgrade_zombie_to_skeleton(target);
2031
2032                     behaviour_event(target, ME_ALERT, &you);
2033
2034                     if (piety)
2035                         processed_count++;
2036
2037                     continue;
2038                 }
2039                 // Else fall through and destroy the zombie.
2040                 // Ghoul-type monsters are always destroyed.
2041             case MONS_GHOUL:
2042             {
2043                 simple_monster_message(target, " rots away and dies.");
2044
2045                 kills = true;
2046
2047                 const coord_def pos = target->pos();
2048                 const int colour = target->colour;
2049                 const int corpse = monster_die(target, KILL_MISC, NON_MONSTER,
2050                                                true);
2051
2052                 // If a corpse didn't drop, create a toadstool.
2053                 // If one did drop, we will create toadstools from it as usual
2054                 // later on.
2055                 // Give neither piety nor toadstools for summoned creatures.
2056                 // Assumes that summoned creatures do not drop corpses (hence
2057                 // will not give piety in the next loop).
2058                 if (corpse < 0 && piety)
2059                 {
2060                     if (create_monster(
2061                                 mgen_data(MONS_TOADSTOOL,
2062                                           BEH_GOOD_NEUTRAL,
2063                                           &you,
2064                                           0,
2065                                           0,
2066                                           pos,
2067                                           MHITNOT,
2068                                           MG_FORCE_PLACE,
2069                                           GOD_NO_GOD,
2070                                           MONS_NO_MONSTER,
2071                                           0,
2072                                           colour),
2073                                           false))
2074                     {
2075                         seen_mushrooms++;
2076                     }
2077
2078                     processed_count++;
2079                     continue;
2080                 }
2081
2082                 // Verify that summoned creatures do not drop a corpse.
2083                 ASSERT(corpse < 0 || piety);
2084
2085                 break;
2086             }
2087
2088             default:
2089                 continue;
2090             }
2091         }
2092
2093         for (stack_iterator j(*i); j; ++j)
2094         {
2095             bool corpse_on_pos = false;
2096
2097             if (j->base_type == OBJ_CORPSES && j->sub_type == CORPSE_BODY)
2098             {
2099                 corpse_on_pos = true;
2100
2101                 const int trial_prob = mushroom_prob(*j);
2102                 const int target_count = 1 + binomial_generator(20, trial_prob);
2103                 int seen_per;
2104                 spawn_corpse_mushrooms(*j, target_count, seen_per,
2105                                        BEH_GOOD_NEUTRAL, true);
2106
2107                 // Either turn this corpse into a skeleton or destroy it.
2108                 if (mons_skeleton(j->mon_type))
2109                     turn_corpse_into_skeleton(*j);
2110                 else
2111                 {
2112                     item_was_destroyed(*j);
2113                     destroy_item(j->index());
2114                 }
2115
2116                 seen_mushrooms += seen_per;
2117
2118                 processed_count++;
2119             }
2120
2121             if (corpse_on_pos && you.see_cell(*i))
2122                 seen_corpses++;
2123         }
2124     }
2125
2126     if (seen_mushrooms > 0)
2127         mushroom_spawn_message(seen_mushrooms, seen_corpses);
2128
2129     if (kills)
2130         mpr("That felt like a moral victory.");
2131
2132     if (processed_count)
2133     {
2134         simple_god_message(" appreciates your contribution to the "
2135                            "ecosystem.");
2136         // Doubling the expected value per sacrifice to approximate the
2137         // extra piety gain blood god worshipers get for the initial kill.
2138         // -cao
2139
2140         int piety_gain = 0;
2141         for (int i = 0; i < processed_count * 2; ++i)
2142             piety_gain += random2(15); // avg 1.4 piety per corpse
2143         gain_piety(piety_gain, 10);
2144     }
2145
2146     return processed_count;
2147 }
2148
2149 static bool _create_plant(coord_def& target, int hp_adjust = 0)
2150 {
2151     if (actor_at(target) || !mons_class_can_pass(MONS_PLANT, grd(target)))
2152         return 0;
2153
2154     if (monster *plant = create_monster(mgen_data(MONS_PLANT,
2155                                             BEH_FRIENDLY,
2156                                             &you,
2157                                             0,
2158                                             0,
2159                                             target,
2160                                             MHITNOT,
2161                                             MG_FORCE_PLACE,
2162                                             GOD_FEDHAS)))
2163     {
2164         plant->flags |= MF_NO_REWARD;
2165         plant->flags |= MF_ATT_CHANGE_ATTEMPT;
2166
2167         mons_make_god_gift(plant, GOD_FEDHAS);
2168
2169         plant->max_hit_points += hp_adjust;
2170         plant->hit_points += hp_adjust;
2171
2172         if (you.see_cell(target))
2173         {
2174             if (hp_adjust)
2175             {
2176                 mprf("A plant, strengthened by %s, grows up from the ground.",
2177                      god_name(GOD_FEDHAS).c_str());
2178             }
2179             else
2180                 mpr("A plant grows up from the ground.");
2181         }
2182         return true;
2183     }
2184
2185     return false;
2186 }
2187
2188 #define SUNLIGHT_DURATION 80
2189
2190 spret_type fedhas_sunlight(bool fail)
2191 {
2192     dist spelld;
2193
2194     bolt temp_bolt;
2195     temp_bolt.colour = YELLOW;
2196
2197     direction_chooser_args args;
2198     args.restricts = DIR_TARGET;
2199     args.mode = TARG_HOSTILE_SUBMERGED;
2200     args.range = LOS_RADIUS;
2201     args.needs_path = false;
2202     args.may_target_monster = false;
2203     args.top_prompt = "Select sunlight destination.";
2204     direction(spelld, args);
2205
2206     if (!spelld.isValid)
2207         return SPRET_ABORT;
2208
2209     fail_check();
2210
2211     const coord_def base = spelld.target;
2212
2213     int revealed_count = 0;
2214
2215     for (adjacent_iterator ai(base, false); ai; ++ai)
2216     {
2217         if (!in_bounds(*ai) || cell_is_solid(*ai))
2218             continue;
2219
2220         for (size_t i = 0; i < env.sunlight.size(); ++i)
2221             if (env.sunlight[i].first == *ai)
2222             {
2223                 erase_any(env.sunlight, i);
2224                 break;
2225             }
2226         const int expiry = you.elapsed_time + (distance2(*ai, base) <= 1
2227                                                ? SUNLIGHT_DURATION
2228                                                : SUNLIGHT_DURATION / 2);
2229         env.sunlight.emplace_back(*ai, expiry);
2230
2231         temp_bolt.explosion_draw_cell(*ai);
2232
2233         monster *victim = monster_at(*ai);
2234         if (victim && you.see_cell(*ai) && !victim->visible_to(&you))
2235         {
2236             // Like entering/exiting angel halos, flipping autopickup would
2237             // be probably too much hassle.
2238             revealed_count++;
2239         }
2240
2241         if (victim)
2242             behaviour_event(victim, ME_ALERT, &you);
2243     }
2244
2245     {
2246         unwind_var<int> no_time(you.time_taken, 0);
2247         process_sunlights(false);
2248     }
2249
2250 #ifndef USE_TILE_LOCAL
2251     // Move the cursor out of the way (it looks weird).
2252     coord_def temp = grid2view(base);
2253     cgotoxy(temp.x, temp.y, GOTO_DNGN);
2254 #endif
2255     scaled_delay(200);
2256
2257     if (revealed_count)
2258     {
2259         mprf("In the bright light, you notice %s.", revealed_count == 1 ?
2260              "an invisible shape" : "some invisible shapes");
2261     }
2262
2263     return SPRET_SUCCESS;
2264 }
2265
2266 void process_sunlights(bool future)
2267 {
2268     int time_cap = future ? INT_MAX - SUNLIGHT_DURATION : you.elapsed_time;
2269
2270     int evap_count = 0;
2271
2272     for (int i = env.sunlight.size() - 1; i >= 0; --i)
2273     {
2274         coord_def c = env.sunlight[i].first;
2275         int until = env.sunlight[i].second;
2276
2277         if (until <= time_cap)
2278             erase_any(env.sunlight, i);
2279
2280         until = min(until, time_cap);
2281         int from = you.elapsed_time - you.time_taken;
2282
2283         // Deterministic roll, to guarantee evaporation when shined long enough.
2284         struct { level_id place; coord_def coord; int64_t game_start; } to_hash;
2285         to_hash.place = level_id::current();
2286         to_hash.coord = c;
2287         to_hash.game_start = you.birth_time;
2288         int h = hash32(&to_hash, sizeof(to_hash)) % SUNLIGHT_DURATION;
2289
2290         if ((from + h) / SUNLIGHT_DURATION == (until + h) / SUNLIGHT_DURATION)
2291             continue;
2292
2293         // Anything further on goes only on a successful evaporation roll, at
2294         // most once peer coord per invocation.
2295
2296         // If this is a water square we will evaporate it.
2297         dungeon_feature_type ftype = grd(c);
2298         dungeon_feature_type orig_type = ftype;
2299
2300         switch (ftype)
2301         {
2302         case DNGN_SHALLOW_WATER:
2303             ftype = DNGN_FLOOR;
2304             break;
2305
2306         case DNGN_DEEP_WATER:
2307             ftype = DNGN_SHALLOW_WATER;
2308             break;
2309
2310         default:
2311             break;
2312         }
2313
2314         if (orig_type != ftype)
2315         {
2316             dungeon_terrain_changed(c, ftype);
2317
2318             if (you.see_cell(c))
2319                 evap_count++;
2320
2321             // This is a little awkward but if we evaporated all the way to
2322             // the dungeon floor that may have given a monster
2323             // ENCH_AQUATIC_LAND, and if that happened the player should get
2324             // credit if the monster dies. The enchantment is inflicted via
2325             // the dungeon_terrain_changed call chain and that doesn't keep
2326             // track of what caused the terrain change. -cao
2327             monster* mons = monster_at(c);
2328             if (mons && ftype == DNGN_FLOOR
2329                 && mons->has_ench(ENCH_AQUATIC_LAND))
2330             {
2331                 mon_enchant temp = mons->get_ench(ENCH_AQUATIC_LAND);
2332                 temp.who = KC_YOU;
2333                 temp.source = MID_PLAYER;
2334                 mons->add_ench(temp);
2335             }
2336         }
2337     }
2338
2339     if (evap_count)
2340         mpr("Some water evaporates in the bright sunlight.");
2341
2342     invalidate_agrid(true);
2343 }
2344
2345 template<typename T>
2346 static bool less_second(const T & left, const T & right)
2347 {
2348     return left.second < right.second;
2349 }
2350
2351 typedef pair<coord_def, int> point_distance;
2352
2353 // Find the distance from origin to each of the targets, those results
2354 // are stored in distances (which is the same size as targets). Exclusion
2355 // is a set of points which are considered disconnected for the search.
2356 static void _path_distance(const coord_def& origin,
2357                            const vector<coord_def>& targets,
2358                            set<int> exclusion,
2359                            vector<int>& distances)
2360 {
2361     queue<point_distance> fringe;
2362     fringe.push(point_distance(origin,0));
2363     distances.clear();
2364     distances.resize(targets.size(), INT_MAX);
2365
2366     while (!fringe.empty())
2367     {
2368         point_distance current = fringe.front();
2369         fringe.pop();
2370
2371         // did we hit a target?
2372         for (unsigned i = 0; i < targets.size(); ++i)
2373         {
2374             if (current.first == targets[i])
2375             {
2376                 distances[i] = current.second;
2377                 break;
2378             }
2379         }
2380
2381         for (adjacent_iterator adj_it(current.first); adj_it; ++adj_it)
2382         {
2383             int idx = adj_it->x + adj_it->y * X_WIDTH;
2384             if (you.see_cell(*adj_it)
2385                 && !feat_is_solid(env.grid(*adj_it))
2386                 && *adj_it != you.pos()
2387                 && exclusion.insert(idx).second)
2388             {
2389                 monster* temp = monster_at(*adj_it);
2390                 if (!temp || (temp->attitude == ATT_HOSTILE
2391                               && !temp->is_stationary()))
2392                 {
2393                     fringe.push(point_distance(*adj_it, current.second+1));
2394                 }
2395             }
2396         }
2397     }
2398 }
2399
2400 // Find the minimum distance from each point of origin to one of the targets
2401 // The distance is stored in 'distances', which is the same size as origins.
2402 static void _point_point_distance(const vector<coord_def>& origins,
2403                                   const vector<coord_def>& targets,
2404                                   vector<int>& distances)
2405 {
2406     distances.clear();
2407     distances.resize(origins.size(), INT_MAX);
2408
2409     // Consider all points of origin as blocked (you can search outward
2410     // from one, but you can't form a path across a different one).
2411     set<int> base_exclusions;
2412     for (coord_def c : origins)
2413     {
2414         int idx = c.x + c.y * X_WIDTH;
2415         base_exclusions.insert(idx);
2416     }
2417
2418     vector<int> current_distances;
2419     for (unsigned i = 0; i < origins.size(); ++i)
2420     {
2421         // Find the distance from the point of origin to each of the targets.
2422         _path_distance(origins[i], targets, base_exclusions,
2423                        current_distances);
2424
2425         // Find the smallest of those distances
2426         int min_dist = current_distances[0];
2427         for (unsigned j = 1; j < current_distances.size(); ++j)
2428             if (current_distances[j] < min_dist)
2429                 min_dist = current_distances[j];
2430
2431         distances[i] = min_dist;
2432     }
2433 }
2434
2435 // So the idea is we want to decide which adjacent tiles are in the most 'danger'
2436 // We claim danger is proportional to the minimum distances from the point to a
2437 // (hostile) monster. This function carries out at most 7 searches to calculate
2438 // the distances in question.
2439 bool prioritise_adjacent(const coord_def &target, vector<coord_def>& candidates)
2440 {
2441     radius_iterator los_it(target, LOS_NO_TRANS, true);
2442
2443     vector<coord_def> mons_positions;
2444     // collect hostile monster positions in LOS
2445     for (; los_it; ++los_it)
2446     {
2447         monster* hostile = monster_at(*los_it);
2448
2449         if (hostile && hostile->attitude == ATT_HOSTILE
2450             && you.can_see(hostile))
2451         {
2452             mons_positions.push_back(hostile->pos());
2453         }
2454     }
2455
2456     if (mons_positions.empty())
2457     {
2458         shuffle_array(candidates);
2459         return true;
2460     }
2461
2462     vector<int> distances;
2463
2464     _point_point_distance(candidates, mons_positions, distances);
2465
2466     vector<point_distance> possible_moves(candidates.size());
2467
2468     for (unsigned i = 0; i < possible_moves.size(); ++i)
2469     {
2470         possible_moves[i].first  = candidates[i];
2471         possible_moves[i].second = distances[i];
2472     }
2473
2474     sort(possible_moves.begin(), possible_moves.end(),
2475               less_second<point_distance>);
2476
2477     for (unsigned i = 0; i < candidates.size(); ++i)
2478         candidates[i] = possible_moves[i].first;
2479
2480     return true;
2481 }
2482
2483 static bool _prompt_amount(int max, int& selected, const string& prompt)
2484 {
2485     selected = max;
2486     while (true)
2487     {
2488         msg::streams(MSGCH_PROMPT) << prompt << " (" << max << " max) " << endl;
2489
2490         const int keyin = get_ch();
2491
2492         // Cancel
2493         if (key_is_escape(keyin) || keyin == ' ' || keyin == '0')
2494         {
2495             canned_msg(MSG_OK);
2496             return false;
2497         }
2498
2499         // Default is max
2500         if (keyin == '\n' || keyin == '\r')
2501         {
2502             selected = max;
2503             return true;
2504         }
2505
2506         // Otherwise they should enter a digit
2507         if (isadigit(keyin))
2508         {
2509             selected = keyin - '0';
2510             if (selected > 0 && selected <= max)
2511                 return true;
2512         }
2513         // else they entered some garbage?
2514     }
2515
2516     return false;
2517 }
2518
2519 static int _collect_fruit(vector<pair<int,int> >& available_fruit)
2520 {
2521     int total = 0;
2522
2523     for (int i = 0; i < ENDOFPACK; i++)
2524     {
2525         if (you.inv[i].defined() && is_fruit(you.inv[i]))
2526         {
2527             total += you.inv[i].quantity;
2528             available_fruit.emplace_back(you.inv[i].quantity, i);
2529         }
2530     }
2531     sort(available_fruit.begin(), available_fruit.end());
2532
2533     return total;
2534 }
2535
2536 static void _decrease_amount(vector<pair<int, int> >& available, int amount)
2537 {
2538     const int total_decrease = amount;
2539     for (const auto &avail : available)
2540     {
2541         const int decrease_amount = min(avail.first, amount);
2542         amount -= decrease_amount;
2543         dec_inv_item_quantity(avail.second, decrease_amount);
2544     }
2545     if (total_decrease > 1)
2546         mprf("%d pieces of fruit are consumed!", total_decrease);
2547     else
2548         mpr("A piece of fruit is consumed!");
2549 }
2550
2551 // Create a ring or partial ring around the caster.  The user is
2552 // prompted to select a stack of fruit, and then plants are placed on open
2553 // squares adjacent to the user.  Of course, one piece of fruit is
2554 // consumed per plant, so a complete ring may not be formed.
2555 bool fedhas_plant_ring_from_fruit()
2556 {
2557     // How much fruit is available?
2558     vector<pair<int, int> > collected_fruit;
2559     int total_fruit = _collect_fruit(collected_fruit);
2560
2561     // How many adjacent open spaces are there?
2562     vector<coord_def> adjacent;
2563     for (adjacent_iterator adj_it(you.pos()); adj_it; ++adj_it)
2564     {
2565         if (monster_habitable_grid(MONS_PLANT, env.grid(*adj_it))
2566             && !actor_at(*adj_it))
2567         {
2568             adjacent.push_back(*adj_it);
2569         }
2570     }
2571
2572     const int max_use = min(total_fruit, static_cast<int>(adjacent.size()));
2573
2574     // Don't prompt if we can't do anything (due to having no fruit or
2575     // no squares to place plants on).
2576     if (max_use == 0)
2577     {
2578         if (adjacent.empty())
2579             mpr("No empty adjacent squares.");
2580         else
2581             mpr("No fruit available.");
2582
2583         return false;
2584     }
2585
2586     prioritise_adjacent(you.pos(), adjacent);
2587
2588     // Screwing around with display code I don't really understand. -cao
2589     targetter_smite range(&you, 1);
2590     range_view_annotator show_range(&range);
2591
2592     for (int i = 0; i < max_use; ++i)
2593     {
2594 #ifndef USE_TILE_LOCAL
2595         coord_def temp = grid2view(adjacent[i]);
2596         cgotoxy(temp.x, temp.y, GOTO_DNGN);
2597         put_colour_ch(GREEN, '1' + i);
2598 #endif
2599 #ifdef USE_TILE
2600         tiles.add_overlay(adjacent[i], TILE_INDICATOR + i);
2601 #endif
2602     }
2603
2604     // And how many plants does the user want to create?
2605     int target_count;
2606     if (!_prompt_amount(max_use, target_count,
2607                         "How many plants will you create?"))
2608     {
2609         // User cancelled at the prompt.
2610         return false;
2611     }
2612
2613     const int hp_adjust = you.skill(SK_INVOCATIONS, 10);
2614
2615     // The user entered a number, remove all number overlays which
2616     // are higher than that number.
2617 #ifndef USE_TILE_LOCAL
2618     unsigned not_used = adjacent.size() - unsigned(target_count);
2619     for (unsigned i = adjacent.size() - not_used; i < adjacent.size(); i++)
2620         view_update_at(adjacent[i]);
2621 #endif
2622 #ifdef USE_TILE
2623     // For tiles we have to clear all overlays and redraw the ones
2624     // we want.
2625     tiles.clear_overlays();
2626     for (int i = 0; i < target_count; ++i)
2627         tiles.add_overlay(adjacent[i], TILE_INDICATOR + i);
2628 #endif
2629
2630     int created_count = 0;
2631     for (int i = 0; i < target_count; ++i)
2632     {
2633         if (_create_plant(adjacent[i], hp_adjust))
2634             created_count++;
2635
2636         // Clear the overlay and draw the plant we just placed.
2637         // This is somewhat more complicated in tiles.
2638         view_update_at(adjacent[i]);
2639 #ifdef USE_TILE
2640         tiles.clear_overlays();
2641         for (int j = i + 1; j < target_count; ++j)
2642             tiles.add_overlay(adjacent[j], TILE_INDICATOR + j);
2643         viewwindow(false);
2644 #endif
2645         scaled_delay(200);
2646     }
2647
2648     if (created_count)
2649         _decrease_amount(collected_fruit, created_count);
2650     else
2651         canned_msg(MSG_NOTHING_HAPPENS);
2652
2653     return created_count;
2654 }
2655
2656 // Create a circle of water around the target, with a radius of
2657 // approximately 2.  This turns normal floor tiles into shallow water
2658 // and turns (unoccupied) shallow water into deep water.  There is a
2659 // chance of spawning plants or fungus on unoccupied dry floor tiles
2660 // outside of the rainfall area.  Return the number of plants/fungi
2661 // created.
2662 int fedhas_rain(const coord_def &target)
2663 {
2664     int spawned_count = 0;
2665     int processed_count = 0;
2666
2667     for (radius_iterator rad(target, LOS_NO_TRANS, true); rad; ++rad)
2668     {
2669         // Adjust the shape of the rainfall slightly to make it look
2670         // nicer.  I want a threshold of 2.5 on the euclidean distance,
2671         // so a threshold of 6 prior to the sqrt is close enough.
2672         int rain_thresh = 6;
2673         coord_def local = *rad - target;
2674
2675         dungeon_feature_type ftype = grd(*rad);
2676
2677         if (local.abs() > rain_thresh)
2678         {
2679             // Maybe spawn a plant on (dry, open) squares that are in
2680             // LOS but outside the rainfall area.  In open space, there
2681             // are 213 squares in LOS, and we are going to drop water on
2682             // (25-4) of those, so if we want x plants to spawn on
2683             // average in open space, the trial probability should be
2684             // x/192.
2685             if (x_chance_in_y(5, 192)
2686                 && !actor_at(*rad)
2687                 && ftype == DNGN_FLOOR)
2688             {
2689                 if (create_monster(mgen_data(
2690                                       coinflip() ? MONS_PLANT : MONS_FUNGUS,
2691                                       BEH_GOOD_NEUTRAL,
2692                                       &you,
2693                                       0,
2694                                       0,
2695                                       *rad,
2696                                       MHITNOT,
2697                                       MG_FORCE_PLACE,
2698                                       GOD_FEDHAS)))
2699                 {
2700                     spawned_count++;
2701                 }
2702
2703                 processed_count++;
2704             }
2705
2706             continue;
2707         }
2708
2709         // Turn regular floor squares only into shallow water.
2710         if (ftype == DNGN_FLOOR)
2711         {
2712             dungeon_terrain_changed(*rad, DNGN_SHALLOW_WATER);
2713
2714             processed_count++;
2715         }
2716         // We can also turn shallow water into deep water, but we're
2717         // just going to skip cases where there is something on the
2718         // shallow water.  Destroying items will probably be annoying,
2719         // and insta-killing monsters is clearly out of the question.
2720         else if (!actor_at(*rad)
2721                  && igrd(*rad) == NON_ITEM
2722                  && ftype == DNGN_SHALLOW_WATER)
2723         {
2724             dungeon_terrain_changed(*rad, DNGN_DEEP_WATER);
2725
2726             processed_count++;
2727         }
2728
2729         if (!feat_is_solid(ftype))
2730         {
2731             // Maybe place a raincloud.
2732             //
2733             // The rainfall area is 20 (5*5 - 4 (corners) - 1 (center));
2734             // the expected number of clouds generated by a fixed chance
2735             // per tile is 20 * p = expected.  Say an Invocations skill
2736             // of 27 gives expected 5 clouds.
2737             int max_expected = 5;
2738             int expected = you.skill_rdiv(SK_INVOCATIONS, max_expected, 27);
2739
2740             if (x_chance_in_y(expected, 20))
2741             {
2742                 place_cloud(CLOUD_RAIN, *rad, 10, &you);
2743
2744                 processed_count++;
2745             }
2746         }
2747     }
2748
2749     if (spawned_count > 0)
2750     {
2751         mprf("%s grow%s in the rain.",
2752              (spawned_count > 1 ? "Some plants" : "A plant"),
2753              (spawned_count > 1 ? "" : "s"));
2754     }
2755
2756     return processed_count;
2757 }
2758
2759 int count_corpses_in_los(vector<stack_iterator> *positions)
2760 {
2761     int count = 0;
2762
2763     for (radius_iterator rad(you.pos(), LOS_NO_TRANS, true); rad;
2764          ++rad)
2765     {
2766         if (actor_at(*rad))
2767             continue;
2768
2769         for (stack_iterator stack_it(*rad); stack_it; ++stack_it)
2770         {
2771             if (stack_it->base_type == OBJ_CORPSES
2772                 && stack_it->sub_type == CORPSE_BODY)
2773             {
2774                 if (positions)
2775                     positions->push_back(stack_it);
2776                 count++;
2777                 break;
2778             }
2779         }
2780     }
2781
2782     return count;
2783 }
2784
2785 int fedhas_check_corpse_spores(bool quiet)
2786 {
2787     vector<stack_iterator> positions;
2788     int count = count_corpses_in_los(&positions);
2789
2790     if (quiet || count == 0)
2791         return count;
2792
2793     viewwindow(false);
2794     for (const stack_iterator &si : positions)
2795     {
2796 #ifndef USE_TILE_LOCAL
2797         coord_def temp = grid2view(si->pos);
2798         cgotoxy(temp.x, temp.y, GOTO_DNGN);
2799
2800         unsigned colour = GREEN | COLFLAG_FRIENDLY_MONSTER;
2801         colour = real_colour(colour);
2802
2803         unsigned character = mons_char(MONS_GIANT_SPORE);
2804         put_colour_ch(colour, character);
2805 #endif
2806 #ifdef USE_TILE
2807         tiles.add_overlay(si->pos, TILE_SPORE_OVERLAY);
2808 #endif
2809     }
2810
2811     if (yesnoquit("Will you create these spores?", true, 'y') <= 0)
2812     {
2813         viewwindow(false);
2814         return -1;
2815     }
2816
2817     return count;
2818 }
2819
2820 // Destroy corpses in the player's LOS (first corpse on a stack only)
2821 // and make 1 giant spore per corpse.  Spores are given the input as
2822 // their starting behavior; the function returns the number of corpses
2823 // processed.
2824 int fedhas_corpse_spores(beh_type attitude)
2825 {
2826     vector<stack_iterator> positions;
2827     int count = count_corpses_in_los(&positions);
2828     ASSERT(attitude != BEH_FRIENDLY || count > 0);
2829
2830     if (count == 0)
2831         return count;
2832
2833     for (const stack_iterator &si : positions)
2834     {
2835         count++;
2836
2837         if (monster *plant = create_monster(mgen_data(MONS_GIANT_SPORE,
2838                                                attitude,
2839                                                &you,
2840                                                0,
2841                                                0,
2842                                                si->pos,
2843                                                MHITNOT,
2844                                                MG_FORCE_PLACE,
2845                                                GOD_FEDHAS)))
2846         {
2847             plant->flags |= MF_NO_REWARD;
2848
2849             if (attitude == BEH_FRIENDLY)
2850             {
2851                 plant->flags |= MF_ATT_CHANGE_ATTEMPT;
2852
2853                 mons_make_god_gift(plant, GOD_FEDHAS);
2854
2855                 plant->behaviour = BEH_WANDER;
2856                 plant->foe = MHITNOT;
2857             }
2858         }
2859
2860         if (mons_skeleton(si->mon_type))
2861             turn_corpse_into_skeleton(*si);
2862         else
2863         {
2864             item_was_destroyed(*si);
2865             destroy_item(si->index());
2866         }
2867     }
2868
2869     viewwindow(false);
2870
2871     return count;
2872 }
2873
2874 struct monster_conversion
2875 {
2876     monster_conversion() :
2877         base_monster(nullptr),
2878         piety_cost(0),
2879         fruit_cost(0)
2880     {
2881     }
2882
2883     monster* base_monster;
2884     int piety_cost;
2885     int fruit_cost;
2886     monster_type new_type;
2887 };
2888
2889 // Given a monster (which should be a plant/fungus), see if
2890 // fedhas_evolve_flora() can upgrade it, and set up a monster_conversion
2891 // structure for it.  Return true (and fill in possible_monster) if the
2892 // monster can be upgraded, and return false otherwise.
2893 static bool _possible_evolution(const monster* input,
2894                                 monster_conversion& possible_monster)
2895 {
2896     switch (input->type)
2897     {
2898     case MONS_PLANT:
2899     case MONS_BUSH:
2900     case MONS_BURNING_BUSH:
2901         possible_monster.new_type = MONS_OKLOB_PLANT;
2902         possible_monster.fruit_cost = 1;
2903         break;
2904
2905     case MONS_OKLOB_SAPLING:
2906         possible_monster.new_type = MONS_OKLOB_PLANT;
2907         possible_monster.piety_cost = 4;
2908         break;
2909
2910     case MONS_FUNGUS:
2911     case MONS_TOADSTOOL:
2912         possible_monster.new_type = MONS_WANDERING_MUSHROOM;
2913         possible_monster.piety_cost = 3;
2914         break;
2915
2916     case MONS_BALLISTOMYCETE:
2917         possible_monster.new_type = MONS_HYPERACTIVE_BALLISTOMYCETE;
2918         possible_monster.piety_cost = 4;
2919         break;
2920
2921     default:
2922         return false;
2923     }
2924
2925     return true;
2926 }
2927
2928 bool mons_is_evolvable(const monster* mon)
2929 {
2930     monster_conversion temp;
2931     return _possible_evolution(mon, temp);
2932 }
2933
2934 static bool _place_ballisto(const coord_def& pos)
2935 {
2936     if (monster *plant = create_monster(mgen_data(MONS_BALLISTOMYCETE,
2937                                                       BEH_FRIENDLY,
2938                                                       &you,
2939                                                       0,
2940                                                       0,
2941                                                       pos,
2942                                                       MHITNOT,
2943                                                       MG_FORCE_PLACE,
2944                                                       GOD_FEDHAS)))
2945     {
2946         plant->flags |= MF_NO_REWARD;
2947         plant->flags |= MF_ATT_CHANGE_ATTEMPT;
2948
2949         mons_make_god_gift(plant, GOD_FEDHAS);
2950
2951         remove_mold(pos);
2952         mpr("The mold grows into a ballistomycete.");
2953         mpr("Your piety has decreased.");
2954         lose_piety(1);
2955         return true;
2956     }
2957
2958     // Monster placement failing should be quite unusual, but it could happen.
2959     // Not entirely sure what to say about it, but a more informative message
2960     // might be good. -cao
2961     canned_msg(MSG_NOTHING_HAPPENS);
2962     return false;
2963 }
2964
2965 #define FEDHAS_EVOLVE_TARGET_KEY "fedhas_evolve_target"
2966
2967 bool fedhas_check_evolve_flora(bool quiet)
2968 {
2969     monster_conversion upgrade;
2970
2971     // This is a little sloppy, but cancel early if nothing useful is in
2972     // range.
2973     bool in_range = false;
2974     for (radius_iterator rad(you.pos(), LOS_NO_TRANS, true); rad; ++rad)
2975     {
2976         const monster* temp = monster_at(*rad);
2977         if (is_moldy(*rad) && mons_class_can_pass(MONS_BALLISTOMYCETE,
2978                                                   env.grid(*rad))
2979             || temp && mons_is_evolvable(temp))
2980         {
2981             in_range = true;
2982             break;
2983         }
2984     }
2985
2986     if (!in_range)
2987     {
2988         if (!quiet)
2989             mpr("No evolvable flora in sight.");
2990         return false;
2991     }
2992
2993     if (quiet) // just checking if there's something we can evolve here
2994         return true;
2995
2996     dist spelld;
2997
2998     direction_chooser_args args;
2999     args.restricts = DIR_TARGET;
3000     args.mode = TARG_EVOLVABLE_PLANTS;
3001     args.range = LOS_RADIUS;
3002     args.needs_path = false;
3003     args.may_target_monster = false;
3004     args.cancel_at_self = true;
3005     args.show_floor_desc = true;
3006     args.top_prompt = "Select plant or fungus to evolve.";
3007
3008     direction(spelld, args);
3009
3010     if (!spelld.isValid)
3011     {
3012         // Check for user cancel.
3013         canned_msg(MSG_OK);
3014         return false;
3015     }
3016
3017     monster* const plant = monster_at(spelld.target);
3018
3019     if (!plant)
3020     {
3021         if (!is_moldy(spelld.target)
3022             || !mons_class_can_pass(MONS_BALLISTOMYCETE,
3023                                     env.grid(spelld.target)))
3024         {
3025             if (feat_is_tree(env.grid(spelld.target)))
3026                 mpr("The tree has already reached the pinnacle of evolution.");
3027             else
3028                 mpr("You must target a plant or fungus.");
3029             return false;
3030         }
3031         you.props[FEDHAS_EVOLVE_TARGET_KEY].get_coord() = spelld.target;
3032         return true;
3033     }
3034
3035     if (!_possible_evolution(plant, upgrade))
3036     {
3037         if (plant->type == MONS_GIANT_SPORE)
3038             mpr("You can evolve only complete plants, not seeds.");
3039         else  if (mons_is_plant(plant))
3040         {
3041             simple_monster_message(plant, " has already reached the pinnacle"
3042                                    " of evolution.");
3043         }
3044         else
3045             mpr("Only plants or fungi may be evolved.");
3046
3047         return false;
3048     }
3049
3050     vector<pair<int, int> > collected_fruit;
3051     if (upgrade.fruit_cost)
3052     {
3053         const int total_fruit = _collect_fruit(collected_fruit);
3054
3055         if (total_fruit < upgrade.fruit_cost)
3056         {
3057             mpr("Not enough fruit available.");
3058             return false;
3059         }
3060     }
3061
3062     if (upgrade.piety_cost && upgrade.piety_cost > you.piety)
3063     {
3064         mpr("Not enough piety available.");
3065         return false;
3066     }
3067
3068     you.props[FEDHAS_EVOLVE_TARGET_KEY].get_coord() = spelld.target;
3069     return true;
3070 }
3071
3072 void fedhas_evolve_flora()
3073 {
3074     monster_conversion upgrade;
3075     const coord_def target = you.props[FEDHAS_EVOLVE_TARGET_KEY].get_coord();
3076     you.props.erase(FEDHAS_EVOLVE_TARGET_KEY);
3077
3078     monster* const plant = monster_at(target);
3079
3080     if (!plant)
3081     {
3082         ASSERT(is_moldy(target));
3083         _place_ballisto(target);
3084         return;
3085     }
3086
3087     ASSERT(_possible_evolution(plant, upgrade));
3088
3089     switch (plant->type)
3090     {
3091     case MONS_PLANT:
3092     case MONS_BUSH:
3093     {
3094         string evolve_desc = " can now spit acid";
3095         int skill = you.skill(SK_INVOCATIONS);
3096         if (skill >= 20)
3097             evolve_desc += " continuously";
3098         else if (skill >= 15)
3099             evolve_desc += " quickly";
3100         else if (skill >= 10)
3101             evolve_desc += " rather quickly";
3102         else if (skill >= 5)
3103             evolve_desc += " somewhat quickly";
3104         evolve_desc += ".";
3105
3106         simple_monster_message(plant, evolve_desc.c_str());
3107         break;
3108     }
3109
3110     case MONS_OKLOB_SAPLING:
3111         simple_monster_message(plant, " appears stronger.");
3112         break;
3113
3114     case MONS_FUNGUS:
3115     case MONS_TOADSTOOL:
3116         simple_monster_message(plant, " can now pick up its mycelia and move.");
3117         break;
3118
3119     case MONS_BALLISTOMYCETE:
3120         simple_monster_message(plant, " appears agitated.");
3121         env.level_state |= LSTATE_GLOW_MOLD;
3122         break;
3123
3124     default:
3125         break;
3126     }
3127
3128     plant->upgrade_type(upgrade.new_type, true, true);
3129
3130     plant->flags |= MF_NO_REWARD;
3131     plant->flags |= MF_ATT_CHANGE_ATTEMPT;
3132
3133     mons_make_god_gift(plant, GOD_FEDHAS);
3134
3135     plant->attitude = ATT_FRIENDLY;
3136
3137     behaviour_event(plant, ME_ALERT);
3138     mons_att_changed(plant);
3139
3140     // Try to remove slowly dying in case we are upgrading a
3141     // toadstool, and spore production in case we are upgrading a
3142     // ballistomycete.
3143     plant->del_ench(ENCH_SLOWLY_DYING);
3144     plant->del_ench(ENCH_SPORE_PRODUCTION);
3145
3146     if (plant->type == MONS_HYPERACTIVE_BALLISTOMYCETE)
3147         plant->add_ench(ENCH_EXPLODING);
3148     else if (plant->type == MONS_OKLOB_PLANT)
3149     {
3150         // frequency will be set by set_hit_dice below
3151         plant->spells = { { SPELL_SPIT_ACID, 0, MON_SPELL_NATURAL } };
3152     }
3153
3154     plant->set_hit_dice(plant->get_experience_level()
3155                         + you.skill_rdiv(SK_INVOCATIONS));
3156
3157     if (upgrade.fruit_cost)
3158     {
3159         vector<pair<int, int> > collected_fruit;
3160         _collect_fruit(collected_fruit);
3161         _decrease_amount(collected_fruit, upgrade.fruit_cost);
3162     }
3163
3164     if (upgrade.piety_cost)
3165     {
3166         lose_piety(upgrade.piety_cost);
3167         mpr("Your piety has decreased.");
3168     }
3169 }
3170
3171 static int _lugonu_warp_monster(monster* mon, int pow)
3172 {
3173     if (mon == nullptr)
3174         return 0;
3175
3176     if (coinflip())
3177         return 0;
3178
3179     if (!mon->friendly())
3180         behaviour_event(mon, ME_ANNOY, &you);
3181
3182     const int damage = 1 + random2(pow / 6);
3183     if (mons_genus(mon->type) == MONS_BLINK_FROG)
3184     {
3185         mprf("%s basks in the distortional energy.",
3186              mon->name(DESC_THE).c_str());
3187         mon->heal(damage, false);
3188     }
3189     else
3190     {
3191         mon->hurt(&you, damage);
3192         if (!mon->alive())
3193             return 1;
3194     }
3195
3196     if (!mon->no_tele(true, false))
3197         mon->blink();
3198
3199     return 1;
3200 }
3201
3202 static void _lugonu_warp_area(int pow)
3203 {
3204     apply_monsters_around_square(_lugonu_warp_monster, you.pos(), pow);
3205 }
3206
3207 void lugonu_bend_space()
3208 {
3209     const int pow = 4 + skill_bump(SK_INVOCATIONS);
3210     const bool area_warp = random2(pow) > 9;
3211
3212     mprf("Space bends %saround you!", area_warp ? "sharply " : "");
3213
3214     if (area_warp)
3215         _lugonu_warp_area(pow);
3216
3217     random_blink(false, true, true);
3218
3219     const int damage = roll_dice(1, 4);
3220     ouch(damage, KILLED_BY_WILD_MAGIC, MID_NOBODY, "a spatial distortion");
3221 }
3222
3223 void cheibriados_time_bend(int pow)
3224 {
3225     mpr("The flow of time bends around you.");
3226
3227     for (adjacent_iterator ai(you.pos()); ai; ++ai)
3228     {
3229         monster* mon = monster_at(*ai);
3230         if (mon && !mon->is_stationary())
3231         {
3232             int res_margin = roll_dice(mon->get_hit_dice(), 3)
3233                              - random2avg(pow, 2);
3234             if (res_margin > 0)
3235             {
3236                 mprf("%s%s",
3237                      mon->name(DESC_THE).c_str(),
3238                      mon->resist_margin_phrase(res_margin).c_str());
3239                 continue;
3240             }
3241
3242             simple_god_message(
3243                 make_stringf(" rebukes %s.",
3244                              mon->name(DESC_THE).c_str()).c_str(),
3245                              GOD_CHEIBRIADOS);
3246             do_slow_monster(mon, &you);
3247         }
3248     }
3249 }
3250
3251 static int _slouchable(coord_def where, int pow, int, actor* agent)
3252 {
3253     monster* mon = monster_at(where);
3254     if (mon == nullptr || mon->is_stationary() || mon->cannot_move()
3255         || mons_is_projectile(mon->type)
3256         || mon->asleep() && !mons_is_confused(mon))
3257     {
3258         return 0;
3259     }
3260
3261     int dmg = (mon->speed - 1000/player_movement_speed()/player_speed());
3262     return (dmg > 0) ? 1 : 0;
3263 }
3264
3265 static bool _act_slouchable(const actor *act)
3266 {
3267     if (act->is_player())
3268         return false;  // too slow-witted
3269     return _slouchable(act->pos(), 0, 0, 0);
3270 }
3271
3272 static int _slouch_monsters(coord_def where, int pow, int dummy, actor* agent)
3273 {
3274     if (!_slouchable(where, pow, dummy, agent))
3275         return 0;
3276
3277     monster* mon = monster_at(where);
3278     ASSERT(mon);
3279
3280     int dmg = (mon->speed - 1000/player_movement_speed()/player_speed());
3281     dmg = (dmg > 0 ? roll_dice(dmg*4, 3)/2 : 0);
3282
3283     mon->hurt(agent, dmg, BEAM_MMISSILE, KILLED_BY_BEAM, "", "", true);
3284     return 1;
3285 }
3286
3287 bool cheibriados_slouch(int pow)
3288 {
3289     int count = apply_area_visible(_slouchable, pow, &you);
3290     if (!count)
3291         if (!yesno("There's no one hasty visible. Invoke Slouch anyway?",
3292                    true, 'n'))
3293         {
3294             return false;
3295         }
3296
3297     targetter_los hitfunc(&you, LOS_DEFAULT);
3298     if (stop_attack_prompt(hitfunc, "harm", _act_slouchable))
3299         return false;
3300
3301     mpr("You can feel time thicken for a moment.");
3302     dprf("your speed is %d", player_movement_speed());
3303
3304     apply_area_visible(_slouch_monsters, pow, &you);
3305     return true;
3306 }
3307
3308 // A low-duration step from time, allowing monsters to get closer
3309 // to the player safely.
3310 void cheibriados_temporal_distortion()
3311 {
3312     const coord_def old_pos = you.pos();
3313
3314     const int time = 3 + random2(3);
3315     you.moveto(coord_def(0, 0));
3316     you.duration[DUR_TIME_STEP] = time;
3317
3318     do
3319     {
3320         run_environment_effects();
3321         handle_monsters();
3322         manage_clouds();
3323     }
3324     while (--you.duration[DUR_TIME_STEP] > 0);
3325
3326     monster* mon;
3327     if (mon = monster_at(old_pos))
3328     {
3329         mon->blink();
3330         if (mon = monster_at(old_pos))
3331             mon->teleport(true);
3332     }
3333
3334     you.moveto(old_pos);
3335     you.duration[DUR_TIME_STEP] = 0;
3336
3337     mpr("You warp the flow of time around you!");
3338 }
3339
3340 void cheibriados_time_step(int pow) // pow is the number of turns to skip
3341 {
3342     const coord_def old_pos = you.pos();
3343
3344     mpr("You step out of the flow of time.");
3345     flash_view(UA_PLAYER, LIGHTBLUE);
3346     you.moveto(coord_def(0, 0));
3347     you.duration[DUR_TIME_STEP] = pow;
3348
3349     you.time_taken = 10;
3350     do
3351     {
3352         run_environment_effects();
3353         handle_monsters();
3354         manage_clouds();
3355     }
3356     while (--you.duration[DUR_TIME_STEP] > 0);
3357     // Update corpses, etc.  This does also shift monsters, but only by
3358     // a tiny bit.
3359     update_level(pow * 10);
3360
3361 #ifndef USE_TILE_LOCAL
3362     scaled_delay(1000);
3363 #endif
3364
3365     monster* mon;
3366     if (mon = monster_at(old_pos))
3367     {
3368         mon->blink();
3369         if (mon = monster_at(old_pos))
3370             mon->teleport(true);
3371     }
3372
3373     you.moveto(old_pos);
3374     you.duration[DUR_TIME_STEP] = 0;
3375
3376     flash_view(UA_PLAYER, 0);
3377     mpr("You return to the normal time flow.");
3378 }
3379
3380 bool ashenzari_transfer_knowledge()
3381 {
3382     if (you.transfer_skill_points > 0 && !ashenzari_end_transfer())
3383         return false;
3384
3385     while (true)
3386     {
3387         skill_menu(SKMF_RESKILL_FROM);
3388         if (is_invalid_skill(you.transfer_from_skill))
3389         {
3390             redraw_screen();
3391             return false;
3392         }
3393
3394         you.transfer_skill_points = skill_transfer_amount(
3395                                                     you.transfer_from_skill);
3396
3397         skill_menu(SKMF_RESKILL_TO);
3398         if (is_invalid_skill(you.transfer_to_skill))
3399         {
3400             you.transfer_from_skill = SK_NONE;
3401             you.transfer_skill_points = 0;
3402             continue;
3403         }
3404
3405         break;
3406     }
3407
3408     // We reset the view to force view transfer next time.
3409     you.skill_menu_view = SKM_NONE;
3410
3411     mprf("As you forget about %s, you feel ready to understand %s.",
3412          skill_name(you.transfer_from_skill),
3413          skill_name(you.transfer_to_skill));
3414
3415     you.transfer_total_skill_points = you.transfer_skill_points;
3416
3417     redraw_screen();
3418     return true;
3419 }
3420
3421 bool ashenzari_end_transfer(bool finished, bool force)
3422 {
3423     if (!force && !finished)
3424     {
3425         mprf("You are currently transferring knowledge from %s to %s.",
3426              skill_name(you.transfer_from_skill),
3427              skill_name(you.transfer_to_skill));
3428         if (!yesno("Are you sure you want to cancel the transfer?", false, 'n'))
3429         {
3430             canned_msg(MSG_OK);
3431             return false;
3432         }
3433     }
3434
3435     mprf("You %s forgetting about %s and learning about %s.",
3436          finished ? "have finished" : "stop",
3437          skill_name(you.transfer_from_skill),
3438          skill_name(you.transfer_to_skill));
3439     you.transfer_from_skill = SK_NONE;
3440     you.transfer_to_skill = SK_NONE;
3441     you.transfer_skill_points = 0;
3442     you.transfer_total_skill_points = 0;
3443     return true;
3444 }
3445
3446 bool can_convert_to_beogh()
3447 {
3448     if (silenced(you.pos()))
3449         return false;
3450
3451     for (radius_iterator ri(you.pos(), LOS_NO_TRANS); ri; ++ri)
3452     {
3453         const monster * const mon = monster_at(*ri);
3454         if (mons_allows_beogh_now(mon))
3455             return true;
3456     }
3457
3458     return false;
3459 }
3460
3461 void spare_beogh_convert()
3462 {
3463     if (you.one_time_ability_used[GOD_BEOGH])
3464     {
3465         // You still get to convert, but orcs will remain hostile.
3466         mprf(MSGCH_TALK, "%s", getSpeakString("orc_priest_apostate").c_str());
3467         return;
3468     }
3469
3470     set<mid_t> witnesses;
3471
3472     you.religion = GOD_NO_GOD;
3473     for (radius_iterator ri(you.pos(), LOS_DEFAULT); ri; ++ri)
3474     {
3475         const monster *mon = monster_at(*ri);
3476         // An invis player converting is ok, for simplicity.