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