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