Don't offer to shatter the chains uncursed (12524)
[crawl.git] / crawl-ref / source / religion.cc
1 /**
2  * @file
3  * @brief Misc religion related functions.
4 **/
5
6 #include "AppHdr.h"
7
8 #include "religion.h"
9
10 #include <algorithm>
11 #include <cmath>
12 #include <cstdio>
13 #include <cstdlib>
14 #include <cstring>
15 #include <functional>
16 #include <sstream>
17
18 #include "ability.h"
19 #include "acquire.h"
20 #include "act-iter.h"
21 #include "areas.h"
22 #include "attitude-change.h"
23 #include "branch.h"
24 #include "chardump.h"
25 #include "coordit.h"
26 #include "dactions.h"
27 #include "database.h"
28 #include "decks.h"
29 #include "delay.h"
30 #include "describe-god.h"
31 #include "dgn-event.h"
32 #include "dlua.h"
33 #include "english.h"
34 #include "env.h"
35 #include "god-abil.h"
36 #include "god-companions.h"
37 #include "god-conduct.h"
38 #include "god-item.h"
39 #include "god-passive.h"
40 #include "god-prayer.h"
41 #include "god-wrath.h"
42 #include "hints.h"
43 #include "hiscores.h"
44 #include "invent.h"
45 #include "item-name.h"
46 #include "item-prop.h"
47 #include "item-status-flag-type.h"
48 #include "items.h"
49 #include "level-state-type.h"
50 #include "libutil.h"
51 #include "makeitem.h"
52 #include "message.h"
53 #include "mon-gear.h" // give_shield
54 #include "mon-place.h"
55 #include "mutation.h"
56 #include "nearby-danger.h"
57 #include "notes.h"
58 #include "output.h"
59 #include "player-equip.h"
60 #include "player-stats.h"
61 #include "prompt.h"
62 #include "randbook.h"
63 #include "shopping.h"
64 #include "skills.h"
65 #include "spl-book.h"
66 #include "sprint.h"
67 #include "state.h"
68 #include "stringutil.h"
69 #include "tag-version.h"
70 #include "terrain.h"
71 #include "transform.h"
72 #include "view.h"
73
74 #ifdef DEBUG_RELIGION
75 #    define DEBUG_DIAGNOSTICS
76 #    define DEBUG_GIFTS
77 #    define DEBUG_SACRIFICE
78 #    define DEBUG_PIETY
79 #endif
80
81 #define PIETY_HYSTERESIS_LIMIT 1
82
83 static weapon_type _hepliaklqana_weapon_type(monster_type mc, int HD);
84 static brand_type _hepliaklqana_weapon_brand(monster_type mc, int HD);
85 static armour_type _hepliaklqana_shield_type(monster_type mc, int HD);
86 static special_armour_type _hepliaklqana_shield_ego(int HD);
87
88 const vector<god_power> god_powers[NUM_GODS] =
89 {
90     // no god
91     { },
92
93     // Zin
94     {   { 1, ABIL_ZIN_RECITE, "recite Zin's Axioms of Law" },
95         { 2, ABIL_ZIN_VITALISATION, "call upon Zin for vitalisation" },
96         { 3, ABIL_ZIN_IMPRISON, "call upon Zin to imprison the lawless" },
97         { 5, ABIL_ZIN_SANCTUARY, "call upon Zin to create a sanctuary" },
98         { 6, "Zin will now cleanse your potions of mutation.",
99              "Zin will no longer cleanse your potions of mutation.",
100              "Zin will cleanse your potions of mutation." },
101         {-1, ABIL_ZIN_DONATE_GOLD, "donate money to Zin" },
102     },
103
104     // TSO
105     {   { 1, "You and your allies can now gain power from killing the unholy and evil.",
106              "You and your allies can no longer gain power from killing the unholy and evil.",
107              "You and your allies can gain power from killing the unholy and evil." },
108         { 2, ABIL_TSO_DIVINE_SHIELD, "call upon the Shining One for a divine shield" },
109         { 4, ABIL_TSO_CLEANSING_FLAME, "channel blasts of cleansing flame", },
110         { 5, ABIL_TSO_SUMMON_DIVINE_WARRIOR, "summon a divine warrior" },
111         { 7, ABIL_TSO_BLESS_WEAPON,
112              "The Shining One will bless your weapon with holy wrath... once.",
113              "The Shining One is no longer ready to bless your weapon." },
114     },
115
116     // Kikubaaqudgha
117     {   { 1, ABIL_KIKU_RECEIVE_CORPSES, "receive cadavers from Kikubaaqudgha" },
118         { 2, "Kikubaaqudgha is now protecting you from necromantic miscasts and death curses.",
119              "Kikubaaqudgha will no longer protect you from necromantic miscasts or death curses.",
120              "Kikubaaqudgha protects you from necromantic miscasts and death curses." },
121         { 4, "Kikubaaqudgha is now protecting you from unholy torment.",
122              "Kikubaaqudgha will no longer protect you from unholy torment.",
123              "Kikubaaqudgha protects you from unholy torment." },
124         { 5, ABIL_KIKU_TORMENT, "invoke torment by sacrificing a corpse" },
125         { 7, ABIL_KIKU_BLESS_WEAPON,
126              "Kikubaaqudgha will grant you a Necronomicon or bloody your weapon with pain... once.",
127              "Kikubaaqudgha is no longer ready to enhance your necromancy." },
128         { 7, ABIL_KIKU_GIFT_NECRONOMICON,
129              "Kikubaaqudgha will grant you a Necronomicon.",
130              "Kikubaaqudgha is no longer ready to enhance your necromancy." },
131     },
132
133     // Yredelemnul
134     {   { 1, ABIL_YRED_ANIMATE_REMAINS, "animate remains" },
135         { 2, ABIL_YRED_RECALL_UNDEAD_SLAVES, "recall your undead slaves" },
136         { 2, ABIL_YRED_INJURY_MIRROR, "mirror injuries on your foes" },
137         { 3, ABIL_YRED_ANIMATE_DEAD, "animate legions of the dead" },
138         { 3, "Yredelemnul will now gift you servants as you gain piety.",
139              "Yredelemnul will no longer gift you servants.",
140              "Yredelemnul will gift you servants as you gain piety." },
141         { 4, ABIL_YRED_DRAIN_LIFE, "drain ambient life force" },
142         { 5, ABIL_YRED_ENSLAVE_SOUL, "enslave living souls" },
143     },
144
145     // Xom
146     { },
147
148     // Vehumet
149     {   { 1, "gain magical power from killing" },
150         { 3, "Vehumet is now aiding your destructive spells.",
151              "Vehumet will no longer aid your destructive spells.",
152              "Vehumet aids your destructive spells." },
153         { 4, "Vehumet is now extending the range of your destructive spells.",
154              "Vehumet will no longer extend the range of your destructive spells.",
155              "Vehumet extends the range of your destructive spells." },
156     },
157
158     // Okawaru
159     {   { 1, ABIL_OKAWARU_HEROISM, "gain great but temporary skills" },
160         { 3, "Okawaru will now gift you ammunition as you gain piety.",
161              "Okawaru will no longer gift you ammunition.",
162              "Okawaru will gift you ammunition as you gain piety." },
163         { 5, ABIL_OKAWARU_FINESSE, "speed up your combat" },
164         { 5, "Okawaru will now gift you equipment as you gain piety.",
165              "Okawaru will no longer gift you equipment.",
166              "Okawaru will gift you equipment as you gain piety." },
167     },
168
169     // Makhleb
170     {   { 1, "gain health from killing" },
171         { 2, ABIL_MAKHLEB_MINOR_DESTRUCTION,
172              "harness Makhleb's destructive might" },
173         { 3, ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB,
174              "summon a lesser servant of Makhleb" },
175         { 4, ABIL_MAKHLEB_MAJOR_DESTRUCTION,
176              "hurl Makhleb's greater destruction" },
177         { 5, ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB,
178              "summon a greater servant of Makhleb" },
179     },
180
181     // Sif Muna
182     {   { 1, ABIL_SIF_MUNA_CHANNEL_ENERGY,
183              "call upon Sif Muna for magical energy" },
184         { 3, ABIL_SIF_MUNA_FORGET_SPELL,
185              "freely open your mind to new spells",
186              "forget spells at will" },
187         { 4, ABIL_SIF_MUNA_DIVINE_EXEGESIS,
188              "call upon Sif Muna to cast any spell from your library" },
189         { 5, "Sif Muna will now gift you books as you gain piety.",
190              "Sif Muna will no longer gift you books.",
191              "Sif Muna will gift you books as you gain piety." },
192     },
193
194     // Trog
195     {
196         { 1, ABIL_TROG_BERSERK, "go berserk at will" },
197         { 2, ABIL_TROG_HAND,
198              "call upon Trog for regeneration and willpower" },
199         { 4, ABIL_TROG_BROTHERS_IN_ARMS, "call in reinforcements" },
200         { 5, "Trog will now gift you melee weapons as you gain piety.",
201              "Trog will no longer gift you weapons.",
202              "Trog will gift you melee weapons as you gain piety." },
203     },
204
205     // Nemelex
206     {
207         { 0, "draw from decks of power" },
208         { 1, "Nemelex will now gift you decks of power as you gain piety.",
209              "Nemelex will no longer gift you decks.",
210              "Nemelex will gift you decks of power as you gain piety." },
211         { 3, ABIL_NEMELEX_TRIPLE_DRAW, "choose one out of three cards" },
212         { 4, ABIL_NEMELEX_DEAL_FOUR, "deal four cards at a time" },
213         { 5, ABIL_NEMELEX_STACK_FIVE, "stack five cards from your decks",
214                                     "stack cards" },
215     },
216
217     // Elyvilon
218     {   { 1, ABIL_ELYVILON_LESSER_HEALING, "provide lesser healing for yourself" },
219         { 2, ABIL_ELYVILON_HEAL_OTHER, "heal and attempt to pacify others" },
220         { 3, ABIL_ELYVILON_PURIFICATION, "purify yourself" },
221         { 4, ABIL_ELYVILON_GREATER_HEALING, "provide greater healing for yourself" },
222         { 5, ABIL_ELYVILON_DIVINE_VIGOUR, "call upon Elyvilon for divine vigour" },
223         { 1, ABIL_ELYVILON_LIFESAVING, "call on Elyvilon to save your life" },
224     },
225
226     // Lugonu
227     {   { 1, ABIL_LUGONU_ABYSS_EXIT,
228              "depart the Abyss",
229              "depart the Abyss at will" },
230         { 2, ABIL_LUGONU_BEND_SPACE, "bend space around yourself" },
231         { 3, ABIL_LUGONU_BANISH, "banish your foes" },
232         { 4, ABIL_LUGONU_CORRUPT, "corrupt the fabric of space" },
233         { 5, ABIL_LUGONU_ABYSS_ENTER, "gate yourself to the Abyss" },
234         { 7, ABIL_LUGONU_BLESS_WEAPON,
235              "Lugonu will corrupt your weapon with distortion... once.",
236              "Lugonu is no longer ready to corrupt your weapon." },
237     },
238
239     // Beogh
240     {   { 2, ABIL_BEOGH_SMITING, "smite your foes" },
241         { 3, "gain orcish followers" },
242         { 4, ABIL_BEOGH_RECALL_ORCISH_FOLLOWERS, "recall your orcish followers" },
243         { 5, "walk on water" },
244         { 5, ABIL_BEOGH_GIFT_ITEM, "give items to your followers" },
245         { 6, ABIL_BEOGH_RESURRECTION, "revive fallen orcs" },
246     },
247
248     // Jiyva
249     {   { 1, ABIL_JIYVA_CALL_JELLY, "request a jelly" },
250         { 3, "Jiyva will now mutate your body and modify your attributes as you gain piety.",
251              "Jiyva will no longer mutate your body and modify your attributes.",
252              "Jiyva will mutate your body and modify your attributes as you gain piety." },
253         { 3, "Jiyva is now protecting you from corrosive effects.",
254              "Jiyva will no longer protect you from corrosive effects.",
255              "Jiyva protects you from corrosive effects." },
256         { 4, ABIL_JIYVA_SLIMIFY, "turn your foes to slime" },
257         { 5, "You may now expel jellies when seriously injured.",
258              "You will no longer expel jellies when injured.",
259              "You may expel jellies when seriously injured." },
260         { 5, ABIL_JIYVA_CURE_BAD_MUTATION,
261              "call upon Jiyva to remove your harmful mutations" },
262     },
263
264     // Fedhas
265     {
266         { 2, ABIL_FEDHAS_WALL_OF_BRIARS, "encircle yourself with summoned briar patches"},
267         { 3, ABIL_FEDHAS_GROW_BALLISTOMYCETE, "grow a ballistomycete" },
268         { 4, ABIL_FEDHAS_OVERGROW, "transform dungeon walls and trees into plant allies"},
269         { 5, ABIL_FEDHAS_GROW_OKLOB, "grow an oklob plant" },
270     },
271
272     // Cheibriados
273     {   { 0, ABIL_CHEIBRIADOS_TIME_BEND, "bend time to slow others" },
274         { 1, "Cheibriados is now slowing the effects of poison on you.",
275              "Cheibriados will no longer slow the effects of poison on you.",
276              "Cheibriados slows the effects of poison on you." },
277         { 3, ABIL_CHEIBRIADOS_DISTORTION, "warp the flow of time around you" },
278         { 4, ABIL_CHEIBRIADOS_SLOUCH, "inflict damage on those overly hasty" },
279         { 5, ABIL_CHEIBRIADOS_TIME_STEP, "step out of the flow of time" },
280     },
281
282     // Ashenzari
283     {   { 1, "The more cursed you are, the more Ashenzari will now support your skills.",
284              "Ashenzari will no longer support your skills.",
285              "The more cursed you are, the more Ashenzari supports your skills." },
286         { 2, "Ashenzari will now reveal the unseen.",
287              "Ashenzari will no longer reveal the unseen.",
288              "Ashenzari reveals the unseen." },
289         { 3, "Ashenzari will now keep your mind clear.",
290              "Ashenzari will no longer keep your mind clear.",
291              "Ashenzari keeps your mind clear." },
292         { 4, "Ashenzari will now grant you astral sight.",
293              "Ashenzari will no longer grant you astral sight.",
294              "Ashenzari grants you astral sight." },
295     },
296
297     // Dithmenos
298     {   { 2, ABIL_DITHMENOS_SHADOW_STEP,
299              "step into the shadows of nearby creatures" },
300         { 3, "You will now sometimes bleed smoke when heavily injured by enemies.",
301              "You will no longer bleed smoke.",
302              "You sometimes bleed smoke when heavily injured by enemies." },
303         { 4, "Your shadow now sometimes tangibly mimics your actions.",
304              "Your shadow no longer tangibly mimics your actions.",
305              "Your shadow sometimes tangibly mimics your actions." },
306         { 5, ABIL_DITHMENOS_SHADOW_FORM,
307              "transform into a swirling mass of shadows" },
308     },
309
310     // Gozag
311     {   { 0, ABIL_GOZAG_POTION_PETITION, "petition Gozag for potion effects" },
312         { 0, ABIL_GOZAG_CALL_MERCHANT,
313              "fund merchants seeking to open stores in the dungeon" },
314         { 0, ABIL_GOZAG_BRIBE_BRANCH,
315              "bribe branches to halt enemies' attacks and recruit allies" },
316     },
317
318     // Qazlal
319     {
320         { 0, "Qazlal grants you and your divine allies immunity to clouds." },
321         { 1, "You are now surrounded by a storm.",
322              "Your storm dissipates completely.",
323              "You are surrounded by a storm." },
324         { 2, ABIL_QAZLAL_UPHEAVAL, "call upon nature to destroy your foes" },
325         { 3, ABIL_QAZLAL_ELEMENTAL_FORCE, "give life to nearby clouds" },
326         { 4, "The storm surrounding you is now powerful enough to repel missiles.",
327              "The storm surrounding you is now too weak to repel missiles.",
328              "The storm surrounding you is powerful enough to repel missiles." },
329         { 4, "You will now adapt resistances upon receiving elemental damage.",
330              "You will no longer adapt resistances upon receiving elemental damage.",
331              "You adapt resistances upon receiving elemental damage." },
332         { 5, ABIL_QAZLAL_DISASTER_AREA,
333              "call upon nature's wrath in a wide area around you" },
334     },
335
336     // Ru
337     {   { 1, "You now exude an aura of power that intimidates your foes.",
338              "You no longer exude an aura of power that intimidates your foes.",
339              "You now exude an aura of power that intimidates your foes." },
340         { 2, "Your aura of power can now strike those that harm you.",
341              "Your aura of power no longer strikes those that harm you.",
342              "Your aura of power can strike those that harm you." },
343         { 3, ABIL_RU_DRAW_OUT_POWER, "heal your body and restore your magic" },
344         { 4, ABIL_RU_POWER_LEAP, "gather your power into a mighty leap" },
345         { 5, ABIL_RU_APOCALYPSE, "wreak a terrible wrath on your foes" },
346     },
347
348 #if TAG_MAJOR_VERSION == 34
349     // Pakellas
350     {
351         { 0, "gain magical power from killing" },
352         { 3, ABIL_PAKELLAS_DEVICE_SURGE,
353              "spend magic to empower your devices" },
354     },
355 #endif
356
357     // Uskayaw
358     {
359         { 1, ABIL_USKAYAW_STOMP, "stomp with the beat" },
360         { 2, ABIL_USKAYAW_LINE_PASS, "pass through a line of other dancers" },
361         { 3, "Uskayaw will force your foes to helplessly watch your dance.",
362              "Uskayaw will no longer force your foes to helplessly watch your dance."},
363         { 4, "Uskayaw will force your foes to share their pain.",
364              "Uskayaw will no longer force your foes to share their pain."},
365         { 5, ABIL_USKAYAW_GRAND_FINALE, "merge with and destroy a victim" },
366     },
367
368     // Hepliaklqana
369     {   { 0, ABIL_HEPLIAKLQANA_RECALL, "recall your ancestor" },
370         { 0, ABIL_HEPLIAKLQANA_IDENTITY, "remember your ancestor's identity" },
371         { 3, ABIL_HEPLIAKLQANA_TRANSFERENCE, "swap creatures with your ancestor" },
372         { 4, ABIL_HEPLIAKLQANA_IDEALISE, "heal and protect your ancestor" },
373         { 5, "drain nearby creatures when transferring your ancestor"},
374     },
375
376     // Wu Jian
377     {   { 0, "perform damaging attacks by moving towards foes",
378              "perform lunging strikes" },
379         { 1, "lightly attack monsters by moving around them",
380              "perform spinning attacks" },
381         { 2, ABIL_WU_JIAN_WALLJUMP,
382              "perform airborne attacks" },
383         { 3, ABIL_WU_JIAN_SERPENTS_LASH, "briefly move at supernatural speeds",
384              "move at supernatural speeds" },
385         { 5, ABIL_WU_JIAN_HEAVENLY_STORM,
386              "summon a storm of heavenly clouds to empower your attacks",
387              "summon a storm of heavenly clouds" },
388     },
389 };
390
391 vector<god_power> get_god_powers(god_type god)
392 {
393     vector<god_power> ret;
394     for (const auto& power : god_powers[god])
395     {
396         if (!(power.abil != ABIL_NON_ABILITY
397               && fixup_ability(power.abil) == ABIL_NON_ABILITY))
398         {
399             ret.push_back(power);
400         }
401     }
402     return ret;
403 }
404
405 /**
406  * Print a description of getting/losing this power.
407  *
408  * @param gaining If true, use this->gain; otherwise, use this->loss.
409  * @param fmt  A string containing "%s" that will be used as a format
410  *             string with our string as parameter; it is not used if
411  *             our string begins with a capital letter. IF THIS DOES
412  *             NOT CONTAIN "%s", OR CONTAINS OTHER FORMAT SPECIFIERS,
413  *             BEHAVIOUR IS UNDEFINED.
414  * @return a string suitable for being read by the user.
415  */
416 void god_power::display(bool gaining, const char* fmt) const
417 {
418     // hack: don't mention the necronomicon alone unless it wasn't
419     // already mentioned by the other message
420     if (abil == ABIL_KIKU_GIFT_NECRONOMICON
421         && you.species != SP_FELID)
422     {
423         return;
424     }
425     const char* str = gaining ? gain : loss;
426     if (isupper(str[0]))
427         god_speaks(you.religion, str);
428     else
429         god_speaks(you.religion, make_stringf(fmt, str).c_str());
430 }
431
432 static void _place_delayed_monsters();
433
434 bool is_evil_god(god_type god)
435 {
436     return god == GOD_KIKUBAAQUDGHA
437            || god == GOD_MAKHLEB
438            || god == GOD_YREDELEMNUL
439            || god == GOD_BEOGH
440            || god == GOD_LUGONU
441            || god == GOD_DITHMENOS;
442 }
443
444 bool is_good_god(god_type god)
445 {
446     return god == GOD_ZIN
447            || god == GOD_SHINING_ONE
448            || god == GOD_ELYVILON;
449 }
450
451 bool is_chaotic_god(god_type god)
452 {
453     return god == GOD_XOM
454            || god == GOD_MAKHLEB
455            || god == GOD_LUGONU
456            || god == GOD_JIYVA;
457 }
458
459 bool is_unknown_god(god_type god)
460 {
461     return god == GOD_NAMELESS;
462 }
463
464 // Not appearing in new games, but still extant.
465 static bool _is_disabled_god(god_type god)
466 {
467     switch (god)
468     {
469 #if TAG_MAJOR_VERSION == 34
470     // Disabled, pending a rework.
471     case GOD_PAKELLAS:
472         return true;
473 #endif
474
475     default:
476         return false;
477     }
478 }
479
480 bool is_unavailable_god(god_type god)
481 {
482     if (_is_disabled_god(god))
483         return true;
484
485     if (god == GOD_JIYVA && jiyva_is_dead())
486         return true;
487
488     return false;
489 }
490
491 bool god_has_name(god_type god)
492 {
493     return god != GOD_NO_GOD && god != GOD_NAMELESS;
494 }
495
496 god_type random_god()
497 {
498     god_type god;
499
500     do
501     {
502         god = static_cast<god_type>(random2(NUM_GODS - 1) + 1);
503     }
504     while (is_unavailable_god(god));
505
506     return god;
507 }
508
509
510 god_iterator::god_iterator() :
511     i(0) { } // might be ok to start with GOD_ZIN instead?
512
513 god_iterator::operator bool() const
514 {
515     return i < NUM_GODS;
516 }
517
518 god_type god_iterator::operator*() const
519 {
520     if (i < NUM_GODS)
521         return (god_type)i;
522     else
523         return GOD_NO_GOD;
524 }
525
526 god_type god_iterator::operator->() const
527 {
528     return **this;
529 }
530
531 god_iterator& god_iterator::operator++()
532 {
533     ++i;
534     return *this;
535 }
536
537 god_iterator god_iterator::operator++(int)
538 {
539     god_iterator copy = *this;
540     ++(*this);
541     return copy;
542 }
543
544
545 bool active_penance(god_type god)
546 {
547     // Good gods only have active wrath when they hate your current god.
548     return player_under_penance(god)
549            && !is_unavailable_god(god)
550            && god != GOD_ASHENZARI
551            && god != GOD_GOZAG
552            && god != GOD_RU
553            && god != GOD_HEPLIAKLQANA
554 #if TAG_MAJOR_VERSION == 34
555            && god != GOD_PAKELLAS
556 #endif
557            && god != GOD_ELYVILON
558            && (god == you.religion && !is_good_god(god)
559                || god_hates_your_god(god, you.religion));
560 }
561
562 // True for gods whose wrath is passive and expires with XP gain.
563 bool xp_penance(god_type god)
564 {
565     return player_under_penance(god)
566            && !is_unavailable_god(god)
567            && (god == GOD_ASHENZARI
568                || god == GOD_GOZAG
569                || god == GOD_HEPLIAKLQANA
570 #if TAG_MAJOR_VERSION == 34
571                || god == GOD_PAKELLAS
572 #endif
573                || god == GOD_ELYVILON)
574            && god_hates_your_god(god, you.religion);
575 }
576
577 void dec_penance(god_type god, int val)
578 {
579     if (val <= 0 || you.penance[god] <= 0)
580         return;
581
582 #ifdef DEBUG_PIETY
583     mprf(MSGCH_DIAGNOSTICS, "Decreasing penance by %d", val);
584 #endif
585     if (you.penance[god] <= val)
586     {
587         const bool had_halo = have_passive(passive_t::halo);
588         const bool had_umbra = have_passive(passive_t::umbra);
589
590         you.penance[god] = 0;
591
592         mark_milestone("god.mollify",
593                        "mollified " + god_name(god) + ".");
594
595         const bool dead_jiyva = (god == GOD_JIYVA && jiyva_is_dead());
596
597         simple_god_message(
598             make_stringf(" seems mollified%s.",
599                          dead_jiyva ? ", and vanishes" : "").c_str(),
600             god);
601
602         if (dead_jiyva)
603             add_daction(DACT_REMOVE_JIYVA_ALTARS);
604
605         take_note(Note(NOTE_MOLLIFY_GOD, god));
606
607         if (you_worship(god))
608         {
609             // Redraw piety display and, in case the best skill is Invocations,
610             // redraw the god title.
611             you.redraw_title = true;
612
613             // TSO's halo is once more available.
614             if (!had_halo && have_passive(passive_t::halo))
615             {
616                 mprf(MSGCH_GOD, "Your divine halo returns!");
617                 invalidate_agrid(true);
618             }
619             if (!had_umbra && have_passive(passive_t::umbra))
620             {
621                 mprf(MSGCH_GOD, "Your aura of darkness returns!");
622                 invalidate_agrid(true);
623             }
624             if (have_passive(passive_t::sinv))
625             {
626                 mprf(MSGCH_GOD, "Your vision regains its divine sight.");
627                 autotoggle_autopickup(false);
628             }
629             if (have_passive(passive_t::stat_boost))
630             {
631                 simple_god_message(" restores the support of your attributes.");
632                 redraw_screen();
633                 update_screen();
634                 notify_stat_change();
635             }
636             if (have_passive(passive_t::storm_shield))
637             {
638                 mprf(MSGCH_GOD, "A storm instantly forms around you!");
639                 you.redraw_armour_class = true; // also handles shields
640             }
641             // When you've worked through all your penance, you get
642             // another chance to make hostile slimes strict neutral.
643
644             if (have_passive(passive_t::neutral_slimes))
645                 add_daction(DACT_SLIME_NEW_ATTEMPT);
646
647             if (have_passive(passive_t::friendly_plants)
648                 && env.forest_awoken_until)
649             {
650                 // XXX: add a dact here & on-join to handle offlevel
651                 // awakened forests?
652                 for (monster_iterator mi; mi; ++mi)
653                      mi->del_ench(ENCH_AWAKEN_FOREST);
654             }
655         }
656         else
657         {
658 #if TAG_MAJOR_VERSION == 34
659             if (god == GOD_PAKELLAS)
660             {
661                 // Penance just ended w/o worshipping Pakellas;
662                 // notify the player that MP regeneration will start again.
663                 mprf(MSGCH_GOD, god, "You begin regenerating magic.");
664             }
665             else
666 #endif
667             if (god == GOD_HEPLIAKLQANA)
668             {
669                 calc_hp(); // frailty ends
670                 mprf(MSGCH_GOD, god, "Your full life essence returns.");
671             }
672         }
673     }
674     else
675     {
676         you.penance[god] -= val;
677         return;
678     }
679
680     // We only get this far if we just mollified a god.
681     // If we just mollified a god, see if we have any angry gods left.
682     // If we don't, clear the stored wrath / XP counter.
683     god_iterator it;
684     for (; it; ++it)
685     {
686         if (active_penance(*it))
687             break;
688     }
689
690     if (it)
691         return;
692
693     you.attribute[ATTR_GOD_WRATH_COUNT] = 0;
694     you.attribute[ATTR_GOD_WRATH_XP] = 0;
695 }
696
697 void dec_penance(int val)
698 {
699     dec_penance(you.religion, val);
700 }
701
702 // TODO: find out what this is duplicating & deduplicate it
703 static bool _need_water_walking()
704 {
705     return you.ground_level() && you.species != SP_MERFOLK
706            && env.grid(you.pos()) == DNGN_DEEP_WATER;
707 }
708
709 static void _grant_temporary_waterwalk()
710 {
711     mprf("Your water-walking will last only until you reach solid ground.");
712     you.props[TEMP_WATERWALK_KEY] = true;
713 }
714
715 bool jiyva_is_dead()
716 {
717     return you.royal_jelly_dead
718            && !you_worship(GOD_JIYVA) && !you.penance[GOD_JIYVA];
719 }
720
721 void set_penance_xp_timeout()
722 {
723     if (you.attribute[ATTR_GOD_WRATH_XP] > 0)
724         return;
725
726     // TODO: make this more random?
727     you.attribute[ATTR_GOD_WRATH_XP] +=
728         max(div_rand_round(exp_needed(you.experience_level + 1)
729                           - exp_needed(you.experience_level),
730                           200),
731             1);
732 }
733
734 static void _inc_penance(god_type god, int val)
735 {
736     if (val <= 0)
737         return;
738
739     if (!player_under_penance(god))
740     {
741         god_acting gdact(god, true);
742
743         take_note(Note(NOTE_PENANCE, god));
744
745         const bool had_halo = have_passive(passive_t::halo);
746         const bool had_umbra = have_passive(passive_t::umbra);
747
748         you.penance[god] += val;
749         you.penance[god] = min((uint8_t)MAX_PENANCE, you.penance[god]);
750
751         if (had_halo && !have_passive(passive_t::halo))
752         {
753             mprf(MSGCH_GOD, god, "Your divine halo fades away.");
754             invalidate_agrid();
755         }
756         if (had_umbra && !have_passive(passive_t::umbra))
757         {
758             mprf(MSGCH_GOD, god, "Your aura of darkness fades away.");
759             invalidate_agrid();
760         }
761
762         if (will_have_passive(passive_t::water_walk)
763             && _need_water_walking() && !have_passive(passive_t::water_walk))
764         {
765             _grant_temporary_waterwalk();
766         }
767
768         if (will_have_passive(passive_t::stat_boost))
769         {
770             redraw_screen();
771             update_screen();
772             notify_stat_change();
773         }
774
775         if (god == GOD_TROG)
776         {
777             if (you.duration[DUR_TROGS_HAND])
778                 trog_remove_trogs_hand();
779
780             make_god_gifts_disappear();
781         }
782         else if (god == GOD_ZIN)
783         {
784             if (you.duration[DUR_DIVINE_STAMINA])
785                 zin_remove_divine_stamina();
786             if (env.sanctuary_time)
787                 remove_sanctuary();
788         }
789         else if (god == GOD_SHINING_ONE)
790         {
791             if (you.duration[DUR_DIVINE_SHIELD])
792                 tso_remove_divine_shield();
793
794             make_god_gifts_disappear();
795         }
796         else if (god == GOD_ELYVILON)
797         {
798             if (you.duration[DUR_DIVINE_VIGOUR])
799                 elyvilon_remove_divine_vigour();
800         }
801         else if (god == GOD_JIYVA)
802         {
803             if (you.duration[DUR_SLIMIFY])
804                 you.duration[DUR_SLIMIFY] = 0;
805         }
806         else if (god == GOD_QAZLAL)
807         {
808             // Can't use have_passive(passive_t::storm_shield) because we
809             // just gained penance.
810             if (you.piety >= piety_breakpoint(0))
811             {
812                 mprf(MSGCH_GOD, god, "The storm surrounding you dissipates.");
813                 you.redraw_armour_class = true;
814             }
815             if (you.duration[DUR_QAZLAL_FIRE_RES])
816             {
817                 mprf(MSGCH_DURATION, "Your resistance to fire fades away.");
818                 you.duration[DUR_QAZLAL_FIRE_RES] = 0;
819             }
820             if (you.duration[DUR_QAZLAL_COLD_RES])
821             {
822                 mprf(MSGCH_DURATION, "Your resistance to cold fades away.");
823                 you.duration[DUR_QAZLAL_COLD_RES] = 0;
824             }
825             if (you.duration[DUR_QAZLAL_ELEC_RES])
826             {
827                 mprf(MSGCH_DURATION,
828                      "Your resistance to electricity fades away.");
829                 you.duration[DUR_QAZLAL_ELEC_RES] = 0;
830             }
831             if (you.duration[DUR_QAZLAL_AC])
832             {
833                 mprf(MSGCH_DURATION,
834                      "Your resistance to physical damage fades away.");
835                 you.duration[DUR_QAZLAL_AC] = 0;
836                 you.redraw_armour_class = true;
837             }
838         }
839 #if TAG_MAJOR_VERSION == 34
840         else if (god == GOD_PAKELLAS)
841         {
842             if (you.duration[DUR_DEVICE_SURGE])
843                 you.duration[DUR_DEVICE_SURGE] = 0;
844         }
845 #endif
846         else if (god == GOD_SIF_MUNA)
847         {
848             if (you.duration[DUR_CHANNEL_ENERGY])
849                 you.duration[DUR_CHANNEL_ENERGY] = 0;
850 #if TAG_MAJOR_VERSION == 34
851             if (you.attribute[ATTR_DIVINE_ENERGY])
852                 you.attribute[ATTR_DIVINE_ENERGY] = 0;
853 #endif
854         }
855         else if (god == GOD_OKAWARU)
856         {
857             if (you.duration[DUR_HEROISM])
858                 okawaru_remove_heroism();
859             if (you.duration[DUR_FINESSE])
860                 okawaru_remove_finesse();
861         }
862
863         if (you_worship(god))
864         {
865             // Redraw piety display and, in case the best skill is Invocations,
866             // redraw the god title.
867             you.redraw_title = true;
868         }
869     }
870     else
871     {
872         you.penance[god] += val;
873         you.penance[god] = min((uint8_t)MAX_PENANCE, you.penance[god]);
874     }
875
876     set_penance_xp_timeout();
877 }
878
879 static void _inc_penance(int val)
880 {
881     _inc_penance(you.religion, val);
882 }
883
884 static void _set_penance(god_type god, int val)
885 {
886     you.penance[god] = val;
887 }
888
889 static void _set_wrath_penance(god_type god)
890 {
891     _set_penance(god, initial_wrath_penance_for(god));
892 }
893
894 static void _inc_gift_timeout(int val)
895 {
896     if (200 - you.gift_timeout < val)
897         you.gift_timeout = 200;
898     else
899         you.gift_timeout += val;
900 }
901
902 // These are sorted in order of power.
903 static monster_type _yred_servants[] =
904 {
905     MONS_MUMMY, MONS_WIGHT, MONS_FLYING_SKULL, MONS_WRAITH,
906     MONS_VAMPIRE, MONS_PHANTASMAL_WARRIOR, MONS_SKELETAL_WARRIOR,
907     MONS_FLAYED_GHOST, MONS_VAMPIRE_KNIGHT, MONS_GHOUL, MONS_BONE_DRAGON,
908     MONS_PROFANE_SERVITOR
909 };
910
911 #define MIN_YRED_SERVANT_THRESHOLD 3
912 #define MAX_YRED_SERVANT_THRESHOLD ARRAYSZ(_yred_servants)
913
914 static bool _yred_high_level_servant(monster_type type)
915 {
916     return type == MONS_BONE_DRAGON
917            || type == MONS_PROFANE_SERVITOR;
918 }
919
920 int yred_random_servants(unsigned int threshold, bool force_hostile)
921 {
922     if (threshold == 0)
923     {
924         if (force_hostile)
925         {
926             // This implies wrath - scale the threshold with XL.
927             threshold =
928                 MIN_YRED_SERVANT_THRESHOLD
929                 + (MAX_YRED_SERVANT_THRESHOLD - MIN_YRED_SERVANT_THRESHOLD)
930                   * you.experience_level / 27;
931         }
932         else
933             threshold = ARRAYSZ(_yred_servants);
934     }
935     else
936     {
937         threshold = min(static_cast<unsigned int>(ARRAYSZ(_yred_servants)),
938                         threshold);
939     }
940
941     const unsigned int servant = random2(threshold);
942
943     // Skip some of the weakest servants, once the threshold is high.
944     if ((servant + 2) * 2 < threshold)
945         return -1;
946
947     monster_type mon_type = _yred_servants[servant];
948
949     // Cap some of the strongest servants.
950     if (!force_hostile && _yred_high_level_servant(mon_type))
951     {
952         int current_high_level = 0;
953         for (auto &entry : companion_list)
954         {
955             monster* mons = monster_by_mid(entry.first);
956             if (!mons)
957                 mons = &entry.second.mons.mons;
958             if (_yred_high_level_servant(mons->type))
959                 current_high_level++;
960         }
961
962         if (current_high_level >= 3)
963             return -1;
964     }
965
966     int how_many = (mon_type == MONS_FLYING_SKULL) ? 2 + random2(4)
967                                                    : 1;
968
969     mgen_data mg(mon_type, !force_hostile ? BEH_FRIENDLY : BEH_HOSTILE,
970                  you.pos(), MHITYOU);
971     mg.set_summoned(!force_hostile ? &you : 0, 0, 0, GOD_YREDELEMNUL);
972
973     if (force_hostile)
974         mg.non_actor_summoner = "the anger of Yredelemnul";
975
976     int created = 0;
977     if (force_hostile)
978     {
979         mg.extra_flags |= (MF_NO_REWARD | MF_HARD_RESET);
980
981         for (; how_many > 0; --how_many)
982         {
983             if (create_monster(mg))
984                 created++;
985         }
986     }
987     else
988     {
989         for (; how_many > 0; --how_many)
990             delayed_monster(mg);
991     }
992
993     return created;
994 }
995
996 static bool _want_missile_gift()
997 {
998     skill_type sk = best_skill(SK_SLINGS, SK_THROWING);
999     // Default to throwing if all missile skills are at zero.
1000     if (you.skills[sk] == 0)
1001         sk = SK_THROWING;
1002     return you.piety >= piety_breakpoint(2)
1003            && random2(you.piety) > 70
1004            && one_chance_in(8)
1005            && x_chance_in_y(1 + you.skills[sk], 12);
1006 }
1007
1008 static bool _want_nemelex_gift()
1009 {
1010     if (you.piety < piety_breakpoint(0))
1011         return false;
1012     const int piety_over_one_star = you.piety - piety_breakpoint(0);
1013
1014     // Nemelex will give at least one gift early.
1015     if (!you.num_total_gifts[GOD_NEMELEX_XOBEH]
1016         && x_chance_in_y(piety_over_one_star + 1, piety_breakpoint(1)))
1017     {
1018         return true;
1019     }
1020
1021     return one_chance_in(3) && x_chance_in_y(piety_over_one_star + 1, MAX_PIETY);
1022 }
1023
1024 static bool _give_nemelex_gift(bool forced = false)
1025 {
1026     if (!forced && !_want_nemelex_gift())
1027         return false;
1028
1029     if (gift_cards())
1030     {
1031         simple_god_message(" deals you some cards!");
1032         mprf(MSGCH_GOD, "You now have %s.", deck_summary().c_str());
1033     }
1034     else
1035         simple_god_message(" goes to deal, but finds you have enough cards.");
1036     _inc_gift_timeout(5 + random2avg(9, 2));
1037     you.num_current_gifts[you.religion]++;
1038     you.num_total_gifts[you.religion]++;
1039     take_note(Note(NOTE_GOD_GIFT, you.religion));
1040     return true;
1041 }
1042
1043 #if TAG_MAJOR_VERSION == 34
1044 /**
1045  * From the given list of items, return a random unseen item, if there are any.
1046  * Otherwise, just return any of them at random.
1047  *
1048  * If we cared, we could make this a template function to return more specific
1049  * types than 'int'. (That's probably not important, though.)
1050  *
1051  * @param item_types        A list of item types to choose from.
1052  * @param seen_func         How to tell whether the item was seen.
1053  * @return                  A random item type; e.g. WAND_ACID.
1054  */
1055 static int _preferably_unseen_item(const vector<int> &item_types,
1056                                    function<bool(int)> seen_func)
1057 {
1058     ASSERT(item_types.size());
1059     vector<int> unseen;
1060     for (auto item : item_types)
1061         if (!seen_func(item))
1062             unseen.emplace_back(item);
1063
1064     if (unseen.size())
1065         return unseen[random2(unseen.size())];
1066     return item_types[random2(item_types.size())];
1067 }
1068 #endif
1069
1070 static void _delayed_gift_callback(const mgen_data &/*mg*/, monster *&mon,
1071                                    int placed)
1072 {
1073     if (placed <= 0)
1074         return;
1075     ASSERT(mon);
1076
1077     // Make sure monsters are shown.
1078     viewwindow();
1079     update_screen();
1080     more();
1081     _inc_gift_timeout(4 + random2avg(7, 2));
1082     you.num_current_gifts[you.religion]++;
1083     you.num_total_gifts[you.religion]++;
1084     string gift;
1085     if (placed == 1)
1086         gift = mon->name(DESC_A);
1087     else
1088     {
1089         gift = make_stringf("%d %s", placed,
1090                             pluralise(mon->name(DESC_PLAIN)).c_str());
1091     }
1092
1093     take_note(Note(NOTE_GOD_GIFT, you.religion, 0, gift));
1094 }
1095
1096 static bool _jiyva_mutate()
1097 {
1098     simple_god_message(" alters your body.");
1099
1100     const int rand = random2(100);
1101
1102     if (rand < 5)
1103         return delete_mutation(RANDOM_SLIME_MUTATION, "Jiyva's grace", true, false, true);
1104     else if (rand < 30)
1105         return delete_mutation(RANDOM_NON_SLIME_MUTATION, "Jiyva's grace", true, false, true);
1106     else if (rand < 55)
1107         return mutate(RANDOM_MUTATION, "Jiyva's grace", true, false, true);
1108     else if (rand < 75)
1109         return mutate(RANDOM_SLIME_MUTATION, "Jiyva's grace", true, false, true);
1110     else
1111         return mutate(RANDOM_GOOD_MUTATION, "Jiyva's grace", true, false, true);
1112 }
1113
1114 bool vehumet_is_offering(spell_type spell)
1115 {
1116     return you.vehumet_gifts.count(spell);
1117 }
1118
1119 void vehumet_accept_gift(spell_type spell)
1120 {
1121     if (vehumet_is_offering(spell))
1122     {
1123         you.vehumet_gifts.erase(spell);
1124         you.duration[DUR_VEHUMET_GIFT] = 0;
1125     }
1126 }
1127
1128 static void _add_to_old_gifts(spell_type spell)
1129 {
1130     you.old_vehumet_gifts.insert(spell);
1131 }
1132
1133 static bool _is_old_gift(spell_type spell)
1134 {
1135     return you.old_vehumet_gifts.count(spell);
1136 }
1137
1138 static set<spell_type> _vehumet_eligible_gift_spells(set<spell_type> excluded_spells)
1139 {
1140     set<spell_type> eligible_spells;
1141
1142     const int gifts = you.num_total_gifts[you.religion];
1143     if (gifts >= NUM_VEHUMET_GIFTS)
1144         return eligible_spells;
1145
1146     const int min_lev[] = {1,1,2,3,3,4,4,5,5,5,5,6,8};
1147     const int max_lev[] = {1,2,3,4,5,7,7,7,7,7,7,8,9};
1148     COMPILE_CHECK(ARRAYSZ(min_lev) == NUM_VEHUMET_GIFTS);
1149     COMPILE_CHECK(ARRAYSZ(max_lev) == NUM_VEHUMET_GIFTS);
1150     int min_level = min_lev[gifts];
1151     int max_level = max_lev[gifts];
1152
1153     if (min_level > you.experience_level)
1154         return eligible_spells;
1155
1156     set<spell_type> backup_spells;
1157     for (int i = 0; i < NUM_SPELLS; ++i)
1158     {
1159         spell_type spell = static_cast<spell_type>(i);
1160         if (!is_valid_spell(spell))
1161             continue;
1162
1163         if (excluded_spells.count(spell))
1164             continue;
1165
1166         if (vehumet_supports_spell(spell)
1167             && !you.has_spell(spell)
1168             && !you.spell_library[spell]
1169             && is_player_book_spell(spell)
1170             && spell_difficulty(spell) <= max_level
1171             && spell_difficulty(spell) >= min_level)
1172         {
1173             if (!_is_old_gift(spell))
1174                 eligible_spells.insert(spell);
1175             else
1176                 backup_spells.insert(spell);
1177         }
1178     }
1179     // Don't get stuck just because all spells have been seen/offered.
1180     if (eligible_spells.empty())
1181     {
1182         if (backup_spells.empty())
1183         {
1184             // This is quite improbable to happen, but in this case just
1185             // skip the gift and increment the gift counter.
1186             if (gifts <= 12)
1187             {
1188                 you.num_current_gifts[you.religion]++;
1189                 you.num_total_gifts[you.religion]++;
1190             }
1191         }
1192         return backup_spells;
1193     }
1194     return eligible_spells;
1195 }
1196
1197 static int _vehumet_weighting(spell_type spell)
1198 {
1199     int bias = 100 + elemental_preference(spell, 10);
1200     return bias;
1201 }
1202
1203 static spell_type _vehumet_find_spell_gift(set<spell_type> excluded_spells)
1204 {
1205     set<spell_type> eligible_spells = _vehumet_eligible_gift_spells(excluded_spells);
1206     spell_type spell = SPELL_NO_SPELL;
1207     int total_weight = 0;
1208     int this_weight = 0;
1209     for (auto elig : eligible_spells)
1210     {
1211         this_weight = _vehumet_weighting(elig);
1212         total_weight += this_weight;
1213         if (x_chance_in_y(this_weight, total_weight))
1214             spell = elig;
1215     }
1216     return spell;
1217 }
1218
1219 static set<spell_type> _vehumet_get_spell_gifts()
1220 {
1221     set<spell_type> offers;
1222     unsigned int num_offers = you.num_total_gifts[you.religion] == 12 ? 3 : 1;
1223     while (offers.size() < num_offers)
1224     {
1225         spell_type offer = _vehumet_find_spell_gift(offers);
1226         if (offer == SPELL_NO_SPELL)
1227             break;
1228         offers.insert(offer);
1229     }
1230     return offers;
1231 }
1232
1233 #if TAG_MAJOR_VERSION == 34
1234 /// Has the player ID'd the given type of wand?
1235 static bool _seen_wand(int wand)
1236 {
1237     return get_ident_type(OBJ_WANDS, wand);
1238 }
1239
1240 static int _pakellas_low_wand()
1241 {
1242     static const vector<int> low_wands = {
1243         WAND_FLAME,
1244         WAND_POLYMORPH,
1245         WAND_RANDOM_EFFECTS,
1246     };
1247
1248     return _preferably_unseen_item(low_wands, _seen_wand);
1249 }
1250
1251 static int _pakellas_high_wand()
1252 {
1253     vector<int> high_wands = {
1254         WAND_PARALYSIS,
1255         WAND_ICEBLAST,
1256         WAND_ACID,
1257     };
1258     if (!you.get_mutation_level(MUT_NO_LOVE))
1259         high_wands.emplace_back(WAND_CHARMING);
1260
1261     return _preferably_unseen_item(high_wands, _seen_wand);
1262 }
1263
1264 static int _pakellas_low_misc()
1265 {
1266     // Limited uses, so any of these are fine even if they've been seen before.
1267     return random_choose(MISC_BOX_OF_BEASTS,
1268                          MISC_PHANTOM_MIRROR);
1269 }
1270
1271 static int _pakellas_high_misc()
1272 {
1273     static const vector<int> high_miscs = {
1274         MISC_PHIAL_OF_FLOODS,
1275         MISC_LIGHTNING_ROD,
1276     };
1277
1278     return _preferably_unseen_item(high_miscs, [](int misc) {
1279         return you.seen_misc[misc];
1280     });
1281 }
1282
1283 static bool _give_pakellas_gift()
1284 {
1285     // Break early if giving a gift now means it would be lost.
1286     if (feat_eliminates_items(env.grid(you.pos())))
1287         return false;
1288
1289     bool success = false;
1290     object_class_type basetype = OBJ_UNASSIGNED;
1291     int subtype = -1;
1292
1293     if (you.piety >= piety_breakpoint(0)
1294         && you.num_total_gifts[GOD_PAKELLAS] == 0)
1295     {
1296         basetype = OBJ_WANDS;
1297         subtype = _pakellas_low_wand();
1298     }
1299     else if (you.piety >= piety_breakpoint(1)
1300              && you.num_total_gifts[GOD_PAKELLAS] == 1)
1301     {
1302         // All the evoker options here are summon-based, so give another
1303         // low-level wand instead under Sacrifice Love.
1304         if (you.get_mutation_level(MUT_NO_LOVE))
1305         {
1306             basetype = OBJ_WANDS;
1307             subtype = _pakellas_low_wand();
1308         }
1309         else
1310         {
1311             basetype = OBJ_MISCELLANY;
1312             subtype = _pakellas_low_misc();
1313         }
1314     }
1315     else if (you.piety >= piety_breakpoint(2)
1316              && you.num_total_gifts[GOD_PAKELLAS] == 2)
1317     {
1318         basetype = OBJ_WANDS;
1319         subtype = _pakellas_high_wand();
1320     }
1321     else if (you.piety >= piety_breakpoint(3)
1322              && you.num_total_gifts[GOD_PAKELLAS] == 3)
1323     {
1324         basetype = OBJ_MISCELLANY;
1325         subtype = _pakellas_high_misc();
1326     }
1327     else if (you.piety >= piety_breakpoint(4)
1328              && you.num_total_gifts[GOD_PAKELLAS] == 4)
1329     {
1330         basetype = random_choose(OBJ_WANDS, OBJ_MISCELLANY);
1331         subtype = (basetype == OBJ_WANDS) ? _pakellas_high_wand()
1332                                           : _pakellas_high_misc();
1333     }
1334
1335     if (basetype == OBJ_UNASSIGNED)
1336         return false;
1337     else
1338     {
1339         ASSERT(subtype >= 0);
1340         int thing_created = items(true, basetype, subtype, 1, 0,
1341                                   you.religion);
1342
1343         if (thing_created == NON_ITEM)
1344             return false;
1345
1346         move_item_to_grid(&thing_created, you.pos(), true);
1347
1348         if (thing_created != NON_ITEM)
1349             success = true;
1350     }
1351
1352     if (success)
1353     {
1354         simple_god_message(" grants you a gift!");
1355         // included in default force_more_message
1356
1357         you.num_current_gifts[you.religion]++;
1358         you.num_total_gifts[you.religion]++;
1359         take_note(Note(NOTE_GOD_GIFT, you.religion));
1360
1361         return true;
1362     }
1363
1364     return false;
1365 }
1366 #endif
1367
1368 static bool _give_trog_oka_gift(bool forced)
1369 {
1370     // Break early if giving a gift now means it would be lost.
1371     if (feat_eliminates_items(env.grid(you.pos())))
1372         return false;
1373
1374     // Should gift catnip instead.
1375     if (you.species == SP_FELID)
1376         return false;
1377
1378     const bool want_equipment = forced
1379                                 || (you.piety >= piety_breakpoint(4)
1380                                     && random2(you.piety) > 120
1381                                     && one_chance_in(4));
1382     // Oka can gift missiles, but if equipment is successful, we choose
1383     // equipment unless the gift was forced by wizard mode. In that case,
1384     // missiles, weapons, and armour all get equal weight below.
1385     const bool want_missiles = you_worship(GOD_OKAWARU)
1386                                && (forced
1387                                    || !want_equipment && _want_missile_gift());
1388     object_class_type gift_type;
1389
1390     if (you_worship(GOD_TROG) && want_equipment)
1391         gift_type = OBJ_WEAPONS;
1392     else if (you_worship(GOD_OKAWARU) && (want_equipment || want_missiles))
1393     {
1394         gift_type = random_choose_weighted(
1395                 want_equipment, OBJ_WEAPONS,
1396                 want_equipment, OBJ_ARMOUR,
1397                 want_missiles,  OBJ_MISSILES);
1398     }
1399     else
1400         return false;
1401
1402     const bool success =
1403         acquirement_create_item(gift_type, you.religion,
1404                 false, you.pos()) != NON_ITEM;
1405     if (success)
1406     {
1407         if (gift_type == OBJ_MISSILES)
1408         {
1409             simple_god_message(" grants you ammunition!");
1410             _inc_gift_timeout(4 + roll_dice(2, 4));
1411         }
1412         else
1413         {
1414             if (gift_type == OBJ_WEAPONS)
1415                 simple_god_message(" grants you a weapon!");
1416             else
1417                 simple_god_message(" grants you armour!");
1418             // Okawaru charges extra for armour acquirements.
1419             if (you_worship(GOD_OKAWARU) && gift_type == OBJ_ARMOUR)
1420                 _inc_gift_timeout(30 + random2avg(15, 2));
1421
1422             _inc_gift_timeout(30 + random2avg(19, 2));
1423         }
1424         you.num_current_gifts[you.religion]++;
1425         you.num_total_gifts[you.religion]++;
1426         take_note(Note(NOTE_GOD_GIFT, you.religion));
1427     }
1428     return success;
1429 }
1430
1431 static bool _give_yred_gift(bool forced)
1432 {
1433     bool success = false;
1434     if (forced || (random2(you.piety) >= piety_breakpoint(2)
1435                    && one_chance_in(4)))
1436     {
1437         unsigned int threshold = MIN_YRED_SERVANT_THRESHOLD
1438                                  + you.num_current_gifts[you.religion] / 2;
1439         threshold = max(threshold,
1440             static_cast<unsigned int>(MIN_YRED_SERVANT_THRESHOLD));
1441         threshold = min(threshold,
1442             static_cast<unsigned int>(MAX_YRED_SERVANT_THRESHOLD));
1443
1444         if (yred_random_servants(threshold) != -1)
1445         {
1446             delayed_monster_done(" grants you @servant@!",
1447                                  _delayed_gift_callback);
1448             success = true;
1449         }
1450     }
1451     return success;
1452 }
1453
1454 static bool _gift_jiyva_gift(bool forced)
1455 {
1456     if (forced || you.piety >= piety_breakpoint(2)
1457                   && random2(you.piety) > 50
1458                   && one_chance_in(4) && !you.gift_timeout
1459                   && you.can_safely_mutate())
1460     {
1461         if (_jiyva_mutate())
1462         {
1463             _inc_gift_timeout(15 + roll_dice(2, 4));
1464             you.num_current_gifts[you.religion]++;
1465             you.num_total_gifts[you.religion]++;
1466             return true;
1467         }
1468         else
1469             mpr("You feel as though nothing has changed.");
1470     }
1471     return false;
1472 }
1473
1474 static bool _handle_uskayaw_ability_unlocks()
1475 {
1476     bool success = false;
1477     // Uskayaw's triggered abilities trigger if you set the timer to -1.
1478     // We do this so that we trigger at the end of the round instead of
1479     // at the time we deal damage.
1480     if (you.piety == piety_breakpoint(2)
1481         && you.props[USKAYAW_AUDIENCE_TIMER].get_int() == 0)
1482     {
1483         you.props[USKAYAW_AUDIENCE_TIMER] = -1;
1484         success = true;
1485     }
1486     else if (you.piety == piety_breakpoint(3)
1487         && you.props[USKAYAW_BOND_TIMER].get_int() == 0)
1488     {
1489         you.props[USKAYAW_BOND_TIMER] = -1;
1490         success = true;
1491     }
1492     return success;
1493 }
1494
1495 static bool _gift_sif_kiku_gift(bool forced)
1496 {
1497     bool success = false;
1498     book_type gift = NUM_BOOKS;
1499     // Break early if giving a gift now means it would be lost.
1500     if (feat_eliminates_items(env.grid(you.pos())))
1501         return false;
1502
1503     // Kikubaaqudgha gives the lesser Necromancy books in a quick
1504     // succession.
1505     if (you_worship(GOD_KIKUBAAQUDGHA))
1506     {
1507         if (you.piety >= piety_breakpoint(0)
1508             && you.num_total_gifts[you.religion] == 0)
1509         {
1510             gift = BOOK_NECROMANCY;
1511         }
1512         else if (you.piety >= piety_breakpoint(2)
1513                  && you.num_total_gifts[you.religion] == 1)
1514         {
1515             gift = BOOK_DEATH;
1516         }
1517     }
1518     else if (forced
1519              || you.piety >= piety_breakpoint(4) && random2(you.piety) > 100)
1520     {
1521         // Sif Muna special: Keep quiet if acquirement fails
1522         // because the player already has seen all spells.
1523         if (you_worship(GOD_SIF_MUNA))
1524         {
1525             int item_index = acquirement_create_item(OBJ_BOOKS, you.religion,
1526                                                      true, you.pos());
1527             success = (item_index != NON_ITEM);
1528         }
1529     }
1530
1531     if (gift != NUM_BOOKS)
1532     {
1533         int thing_created = items(true, OBJ_BOOKS, gift, 1, 0,
1534                                   you.religion);
1535         // Replace a Kiku gift by a custom-random book.
1536         if (you_worship(GOD_KIKUBAAQUDGHA))
1537         {
1538             make_book_kiku_gift(env.item[thing_created],
1539                                 gift == BOOK_NECROMANCY);
1540         }
1541         if (thing_created == NON_ITEM)
1542             return false;
1543
1544         move_item_to_grid(&thing_created, you.pos(), true);
1545
1546         if (thing_created != NON_ITEM)
1547             success = true;
1548     }
1549
1550     if (success)
1551     {
1552         simple_god_message(" grants you a gift!");
1553         // included in default force_more_message
1554
1555         you.num_current_gifts[you.religion]++;
1556         you.num_total_gifts[you.religion]++;
1557         // Timeouts are meaningless for Kiku.
1558         if (!you_worship(GOD_KIKUBAAQUDGHA))
1559             _inc_gift_timeout(40 + random2avg(19, 2));
1560         take_note(Note(NOTE_GOD_GIFT, you.religion));
1561     }
1562
1563     return success;
1564 }
1565
1566 static bool _handle_veh_gift(bool forced)
1567 {
1568     bool success = false;
1569     const int gifts = you.num_total_gifts[you.religion];
1570     if (forced || !you.duration[DUR_VEHUMET_GIFT]
1571                   && (you.piety >= piety_breakpoint(0) && gifts == 0
1572                       || you.piety >= piety_breakpoint(0) + random2(6) + 18 * gifts && gifts <= 5
1573                       || you.piety >= piety_breakpoint(4) && gifts <= 11 && one_chance_in(20)
1574                       || you.piety >= piety_breakpoint(5) && gifts <= 12 && one_chance_in(20)))
1575     {
1576         set<spell_type> offers = _vehumet_get_spell_gifts();
1577         if (!offers.empty())
1578         {
1579             you.vehumet_gifts = offers;
1580             string prompt = " offers you knowledge of ";
1581             for (auto it = offers.begin(); it != offers.end(); ++it)
1582             {
1583                 if (it != offers.begin())
1584                 {
1585                     if (offers.size() > 2)
1586                         prompt += ",";
1587                     prompt += " ";
1588                     auto next = it;
1589                     next++;
1590                     if (next == offers.end())
1591                         prompt += "and ";
1592                 }
1593                 prompt += spell_title(*it);
1594                 _add_to_old_gifts(*it);
1595                 take_note(Note(NOTE_OFFERED_SPELL, *it));
1596             }
1597             prompt += ".";
1598             if (gifts >= NUM_VEHUMET_GIFTS - 1)
1599             {
1600                 prompt += " These spells will remain available"
1601                           " as long as you worship Vehumet.";
1602             }
1603
1604             you.duration[DUR_VEHUMET_GIFT] = (100 + random2avg(100, 2)) * BASELINE_DELAY;
1605             if (gifts >= 5)
1606                 _inc_gift_timeout(30 + random2avg(30, 2));
1607             you.num_current_gifts[you.religion]++;
1608             you.num_total_gifts[you.religion]++;
1609
1610             simple_god_message(prompt.c_str());
1611             // included in default force_more_message
1612
1613             success = true;
1614         }
1615     }
1616     return success;
1617 }
1618
1619 void mons_make_god_gift(monster& mon, god_type god)
1620 {
1621     const god_type acting_god =
1622         (crawl_state.is_god_acting()) ? crawl_state.which_god_acting()
1623                                       : GOD_NO_GOD;
1624
1625     if (god == GOD_NO_GOD && acting_god == GOD_NO_GOD)
1626         return;
1627
1628     if (god == GOD_NO_GOD)
1629         god = acting_god;
1630
1631     if (mon.flags & MF_GOD_GIFT)
1632     {
1633         dprf("Monster '%s' was already a gift of god '%s', now god '%s'.",
1634              mon.name(DESC_PLAIN, true).c_str(),
1635              god_name(mon.god).c_str(),
1636              god_name(god).c_str());
1637     }
1638
1639     mon.god = god;
1640     mon.flags |= MF_GOD_GIFT;
1641 }
1642
1643 bool mons_is_god_gift(const monster& mon, god_type god)
1644 {
1645     return (mon.flags & MF_GOD_GIFT) && mon.god == god;
1646 }
1647
1648 bool is_yred_undead_slave(const monster& mon)
1649 {
1650     return mon.alive() && mon.holiness() & MH_UNDEAD
1651            && mon.attitude == ATT_FRIENDLY
1652            && mons_is_god_gift(mon, GOD_YREDELEMNUL);
1653 }
1654
1655 bool is_orcish_follower(const monster& mon)
1656 {
1657     return mon.alive() && mon.attitude == ATT_FRIENDLY
1658            && mons_is_god_gift(mon, GOD_BEOGH);
1659 }
1660
1661 bool is_fellow_slime(const monster& mon)
1662 {
1663     return mon.alive() && mons_is_slime(mon)
1664            && mon.attitude == ATT_STRICT_NEUTRAL
1665            && mons_is_god_gift(mon, GOD_JIYVA);
1666 }
1667
1668 static bool _is_plant_follower(const monster* mon)
1669 {
1670     return mon->alive() && mons_is_plant(*mon)
1671            && mon->attitude == ATT_FRIENDLY;
1672 }
1673
1674 static bool _has_jelly()
1675 {
1676     ASSERT(you_worship(GOD_JIYVA));
1677
1678     for (monster_iterator mi; mi; ++mi)
1679         if (mons_is_god_gift(**mi, GOD_JIYVA))
1680             return true;
1681     return false;
1682 }
1683
1684 bool is_follower(const monster& mon)
1685 {
1686     if (you_worship(GOD_YREDELEMNUL))
1687         return is_yred_undead_slave(mon);
1688     else if (will_have_passive(passive_t::convert_orcs))
1689         return is_orcish_follower(mon);
1690     else if (you_worship(GOD_JIYVA))
1691         return is_fellow_slime(mon);
1692     else if (you_worship(GOD_FEDHAS))
1693         return _is_plant_follower(&mon);
1694     else
1695     {
1696         return mon.alive() && mon.attitude == ATT_FRIENDLY
1697                && !mons_is_conjured(mon.type);
1698     }
1699 }
1700
1701 /**
1702  * What's the name of the ally Hepliaklqana granted the player?
1703  *
1704  * @return      The ally's name.
1705  */
1706 string hepliaklqana_ally_name()
1707 {
1708     return you.props[HEPLIAKLQANA_ALLY_NAME_KEY].get_string();
1709 }
1710
1711 /**
1712  * How much HD should the ally granted by Hepliaklqana have?
1713  *
1714  * @return      The player's xl * 2/3.
1715  */
1716 static int _hepliaklqana_ally_hd()
1717 {
1718     if (!crawl_state.need_save) // on main menu or otherwise don't have 'you'
1719         return 27; // v0v
1720     // round up
1721     return (you.experience_level - 1) * 2 / 3 + 1;
1722 }
1723
1724 /**
1725  * How much max HP should the ally granted by Hepliaklqana have?
1726  *
1727  * @return      5/hd from 1-11 HD, 10/hd from 12-18.
1728  *              (That is, 5 HP at 1 HD, 120 at 18.)
1729  */
1730 int hepliaklqana_ally_hp()
1731 {
1732     const int HD = _hepliaklqana_ally_hd();
1733     return HD * 5 + max(0, (HD - 12) * 5);
1734 }
1735
1736 /**
1737  * Creates a mgen_data with the information needed to create the ancestor
1738  * granted by Hepliaklqana.
1739  *
1740  * XXX: should this be populating a mgen_data passed by reference, rather than
1741  * returning one on the stack?
1742  *
1743  * @return    The mgen_data that creates a hepliaklqana ancestor.
1744  */
1745 mgen_data hepliaklqana_ancestor_gen_data()
1746 {
1747     const monster_type type = you.props.exists(HEPLIAKLQANA_ALLY_TYPE_KEY) ?
1748         (monster_type)you.props[HEPLIAKLQANA_ALLY_TYPE_KEY].get_int() :
1749         MONS_ANCESTOR;
1750     mgen_data mg(type, BEH_FRIENDLY, you.pos(), MHITYOU, MG_AUTOFOE);
1751     mg.set_summoned(&you, 0, 0, GOD_HEPLIAKLQANA);
1752     mg.hd = _hepliaklqana_ally_hd();
1753     mg.hp = hepliaklqana_ally_hp();
1754     mg.extra_flags |= MF_NO_REWARD;
1755     mg.mname = hepliaklqana_ally_name();
1756     mg.props[MON_GENDER_KEY]
1757         = you.props[HEPLIAKLQANA_ALLY_GENDER_KEY].get_int();
1758     return mg;
1759 }
1760
1761 /// Print a message for an ancestor's *something* being gained.
1762 static void _regain_memory(const monster &ancestor, string memory)
1763 {
1764     mprf("%s regains the memory of %s %s.",
1765          ancestor.name(DESC_YOUR, true).c_str(),
1766          ancestor.pronoun(PRONOUN_POSSESSIVE, true).c_str(),
1767          memory.c_str());
1768 }
1769
1770 static string _item_ego_name(object_class_type base_type, int brand)
1771 {
1772     switch (base_type)
1773     {
1774     case OBJ_WEAPONS:
1775     {
1776         // 'remembers... draining' reads better than 'drain', but 'flame'
1777         // reads better than 'flaming'
1778         const bool terse = brand == SPWPN_FLAMING
1779                            || brand == SPWPN_ANTIMAGIC;
1780         return brand_type_name((brand_type) brand, terse);
1781     }
1782     case OBJ_ARMOUR:
1783         // XXX: hack
1784         return "reflection";
1785     default:
1786         die("unsupported object type");
1787     }
1788 }
1789
1790 /// Print a message for an ancestor's item being gained/type upgraded.
1791 static void _regain_item_memory(const monster &ancestor,
1792                                 object_class_type base_type,
1793                                 int sub_type,
1794                                 int brand)
1795 {
1796     const string base_name = item_base_name(base_type, sub_type);
1797     if (!brand)
1798     {
1799         _regain_memory(ancestor, base_name);
1800         return;
1801     }
1802
1803     const string ego_name = _item_ego_name(base_type, brand);
1804     const string item_name
1805         = make_stringf("%s of %s",
1806                        item_base_name(base_type, sub_type).c_str(),
1807                        ego_name.c_str());
1808     _regain_memory(ancestor, item_name);
1809 }
1810
1811 /**
1812  * Update the ancestor's stats after the player levels up. Upgrade HD and HP,
1813  * and give appropriate messaging for that and any other notable upgrades
1814  * (spells, resists, etc).
1815  *
1816  * @param quiet_force     Whether to squash messages & force upgrades,
1817  *                        even if the HD is unchanged.
1818  */
1819 void upgrade_hepliaklqana_ancestor(bool quiet_force)
1820 {
1821     monster* ancestor = hepliaklqana_ancestor_mon();
1822     if (!ancestor || !ancestor->alive())
1823         return;
1824
1825     // housekeeping
1826     ancestor->mname = hepliaklqana_ally_name();
1827     ancestor->props[MON_GENDER_KEY]
1828         = you.props[HEPLIAKLQANA_ALLY_GENDER_KEY].get_int();
1829
1830     const int old_hd = ancestor->get_experience_level();
1831     const int hd = _hepliaklqana_ally_hd();
1832     ancestor->set_hit_dice(hd);
1833     if (old_hd == hd && !quiet_force)
1834         return; // assume nothing changes except at different HD
1835
1836     const int old_mhp = ancestor->max_hit_points;
1837     ancestor->max_hit_points = hepliaklqana_ally_hp();
1838     ancestor->hit_points =
1839         div_rand_round(ancestor->hit_points * ancestor->max_hit_points,
1840                        old_mhp);
1841
1842     if (!quiet_force)
1843     {
1844         mprf("%s remembers more of %s old skill.",
1845              ancestor->name(DESC_YOUR, true).c_str(),
1846              ancestor->pronoun(PRONOUN_POSSESSIVE, true).c_str());
1847     }
1848
1849     set_ancestor_spells(*ancestor, !quiet_force);
1850
1851     const bool ancestor_offlevel = companion_is_elsewhere(ancestor->mid);
1852     if (ancestor_offlevel)
1853         add_daction(DACT_UPGRADE_ANCESTOR);
1854
1855     // assumption: ancestors can lose weapons (very rarely - tukima's),
1856     // and it's weird for them to just reappear, so only upgrade existing ones
1857     if (ancestor->weapon())
1858     {
1859         if (!ancestor_offlevel)
1860             upgrade_hepliaklqana_weapon(ancestor->type, *ancestor->weapon());
1861
1862         const weapon_type wpn = _hepliaklqana_weapon_type(ancestor->type, hd);
1863         const brand_type brand = _hepliaklqana_weapon_brand(ancestor->type, hd);
1864         if (wpn != _hepliaklqana_weapon_type(ancestor->type, old_hd)
1865             && !quiet_force)
1866         {
1867             _regain_item_memory(*ancestor, OBJ_WEAPONS, wpn, brand);
1868         }
1869         else if (brand != _hepliaklqana_weapon_brand(ancestor->type, old_hd)
1870                  && !quiet_force)
1871         {
1872             mprf("%s remembers %s %s %s.",
1873                  ancestor->name(DESC_YOUR, true).c_str(),
1874                  ancestor->pronoun(PRONOUN_POSSESSIVE, true).c_str(),
1875                  apostrophise(item_base_name(OBJ_WEAPONS, wpn)).c_str(),
1876                  brand_type_name(brand, brand != SPWPN_DRAINING));
1877         }
1878     }
1879     // but shields can't be lost, and *can* be gained (knight at hd 5)
1880     // so give them out as appropriate
1881     if (!ancestor_offlevel)
1882     {
1883         if (ancestor->shield())
1884             upgrade_hepliaklqana_shield(*ancestor, *ancestor->shield());
1885         else
1886             give_shield(ancestor);
1887     }
1888
1889     const armour_type shld = _hepliaklqana_shield_type(ancestor->type, hd);
1890     if (shld != _hepliaklqana_shield_type(ancestor->type, old_hd)
1891         && !quiet_force)
1892     {
1893         // doesn't currently support egos varying separately from shield types
1894         _regain_item_memory(*ancestor, OBJ_ARMOUR, shld,
1895                             _hepliaklqana_shield_ego(hd));
1896     }
1897
1898     if (quiet_force)
1899         return;
1900 }
1901
1902 /**
1903  * What type of weapon should an ancestor of the given HD have?
1904  *
1905  * @param mc   The type of ancestor in question.
1906  * @param HD   The HD of the ancestor in question.
1907  * @return     An appropriate weapon_type.
1908  */
1909 static weapon_type _hepliaklqana_weapon_type(monster_type mc, int HD)
1910 {
1911     switch (mc)
1912     {
1913     case MONS_ANCESTOR_HEXER:
1914         return HD < 16 ? WPN_DAGGER : WPN_QUICK_BLADE;
1915     case MONS_ANCESTOR_KNIGHT:
1916         return HD < 10 ? WPN_FLAIL : WPN_BROAD_AXE;
1917     case MONS_ANCESTOR_BATTLEMAGE:
1918         return HD < 13 ? WPN_QUARTERSTAFF : WPN_LAJATANG;
1919     default:
1920         return NUM_WEAPONS; // should never happen
1921     }
1922 }
1923
1924 /**
1925  * What brand should an ancestor of the given HD's weapon have, if any?
1926  *
1927  * @param mc   The type of ancestor in question.
1928  * @param HD   The HD of the ancestor in question.
1929  * @return     An appropriate weapon_type.
1930  */
1931 static brand_type _hepliaklqana_weapon_brand(monster_type mc, int HD)
1932 {
1933     switch (mc)
1934     {
1935         case MONS_ANCESTOR_HEXER:
1936             return HD < 16 ?   SPWPN_DRAINING :
1937                                SPWPN_ANTIMAGIC;
1938         case MONS_ANCESTOR_KNIGHT:
1939             return HD < 10 ?   SPWPN_NORMAL :
1940                    HD < 16 ?   SPWPN_FLAMING :
1941                                SPWPN_SPEED;
1942         case MONS_ANCESTOR_BATTLEMAGE:
1943             return HD < 13 ?   SPWPN_NORMAL :
1944                                SPWPN_FREEZING;
1945         default:
1946             return SPWPN_NORMAL;
1947     }
1948 }
1949
1950 /**
1951  * Setup an ancestor's weapon after their class is chosen, when the player
1952  * levels up, or after they're resummoned (or initially created for wrath).
1953  *
1954  * @param[in]   mtyp          The ancestor for whom the weapon is intended.
1955  * @param[out]  item          The item to be configured.
1956  * @param       notify        Whether messages should be printed when something
1957  *                            changes. (Weapon type or brand.)
1958  */
1959 void upgrade_hepliaklqana_weapon(monster_type mtyp, item_def &item)
1960 {
1961     ASSERT(mons_is_hepliaklqana_ancestor(mtyp));
1962     if (mtyp == MONS_ANCESTOR)
1963         return; // bare-handed!
1964
1965     item.base_type = OBJ_WEAPONS;
1966     item.sub_type = _hepliaklqana_weapon_type(mtyp,
1967                                               _hepliaklqana_ally_hd());
1968     item.brand = _hepliaklqana_weapon_brand(mtyp,
1969                                             _hepliaklqana_ally_hd());
1970     item.plus = 0;
1971     item.flags |= ISFLAG_KNOW_TYPE | ISFLAG_SUMMONED;
1972 }
1973
1974 /**
1975  * What kind of shield should an ancestor of the given HD be given?
1976  *
1977  * @param mc        The type of ancestor in question.
1978  * @param HD        The HD (XL) of the ancestor in question.
1979  * @return          An appropriate type of shield, or NUM_ARMOURS.
1980  */
1981 static armour_type _hepliaklqana_shield_type(monster_type mc, int HD)
1982 {
1983     if (mc != MONS_ANCESTOR_KNIGHT)
1984         return NUM_ARMOURS;
1985     if (HD < 13)
1986         return ARM_KITE_SHIELD;
1987     return ARM_TOWER_SHIELD;
1988 }
1989
1990 static special_armour_type _hepliaklqana_shield_ego(int HD)
1991 {
1992     return HD < 13 ? SPARM_NORMAL : SPARM_REFLECTION;
1993 }
1994
1995 /**
1996  * Setup an ancestor's weapon after their class is chosen, when the player
1997  * levels up, or after they're resummoned (or initially created for wrath).
1998  *
1999  * @param[in]   ancestor      The ancestor for whom the weapon is intended.
2000  * @param[out]  item          The item to be configured.
2001  * @return                    True iff the ancestor should have a weapon.
2002  */
2003 void upgrade_hepliaklqana_shield(const monster &ancestor, item_def &item)
2004 {
2005     ASSERT(mons_is_hepliaklqana_ancestor(ancestor.type));
2006     const int HD = ancestor.get_experience_level();
2007     const armour_type shield_type = _hepliaklqana_shield_type(ancestor.type,
2008                                                               HD);
2009     if (shield_type == NUM_ARMOURS)
2010         return; // no shield yet!
2011
2012     item.base_type = OBJ_ARMOUR;
2013     item.sub_type = shield_type;
2014     item.brand = _hepliaklqana_shield_ego(HD);
2015     item.plus = 0;
2016     item.flags |= ISFLAG_KNOW_TYPE | ISFLAG_SUMMONED;
2017     item.quantity = 1;
2018 }
2019
2020 ///////////////////////////////
2021 bool do_god_gift(bool forced)
2022 {
2023     ASSERT(!you_worship(GOD_NO_GOD));
2024
2025     god_acting gdact;
2026
2027 #if defined(DEBUG_DIAGNOSTICS) || defined(DEBUG_GIFTS)
2028     int old_num_current_gifts = you.num_current_gifts[you.religion];
2029     int old_num_total_gifts = you.num_total_gifts[you.religion];
2030 #endif
2031
2032     bool success = false;
2033
2034     // Consider a gift if we don't have a timeout and aren't under penance
2035     if (forced || !player_under_penance() && !you.gift_timeout)
2036     {
2037         // Remember to check for water/lava.
2038         switch (you.religion)
2039         {
2040         default:
2041             break;
2042
2043         case GOD_NEMELEX_XOBEH:
2044             success = _give_nemelex_gift(forced);
2045             break;
2046
2047 #if TAG_MAJOR_VERSION == 34
2048         case GOD_PAKELLAS:
2049             success = _give_pakellas_gift();
2050             break;
2051 #endif
2052
2053         case GOD_OKAWARU:
2054         case GOD_TROG:
2055             success = _give_trog_oka_gift(forced);
2056             break;
2057
2058         case GOD_YREDELEMNUL:
2059             success = _give_yred_gift(forced);
2060             break;
2061
2062         case GOD_JIYVA:
2063             success = _gift_jiyva_gift(forced);
2064             break;
2065
2066         case GOD_USKAYAW:
2067             success = _handle_uskayaw_ability_unlocks();
2068             break;
2069
2070         case GOD_KIKUBAAQUDGHA:
2071         case GOD_SIF_MUNA:
2072             success = _gift_sif_kiku_gift(forced);
2073             break;
2074
2075         case GOD_VEHUMET:
2076             success = _handle_veh_gift(forced);
2077             break;
2078         }                       // switch (you.religion)
2079     }                           // End of gift giving.
2080
2081     if (success)
2082         stop_running(false);
2083
2084 #if defined(DEBUG_DIAGNOSTICS) || defined(DEBUG_GIFTS)
2085     if (old_num_current_gifts < you.num_current_gifts[you.religion])
2086     {
2087         mprf(MSGCH_DIAGNOSTICS, "Current number of gifts from this god: %d",
2088              you.num_current_gifts[you.religion]);
2089     }
2090     if (old_num_total_gifts < you.num_total_gifts[you.religion])
2091     {
2092         mprf(MSGCH_DIAGNOSTICS, "Total number of gifts from this god: %d",
2093              you.num_total_gifts[you.religion]);
2094     }
2095 #endif
2096     return success;
2097 }
2098
2099 string god_name(god_type which_god, bool long_name)
2100 {
2101     if (which_god == GOD_JIYVA)
2102     {
2103         return god_name_jiyva(long_name) +
2104                (long_name? " the Shapeless" : "");
2105     }
2106
2107     if (long_name)
2108     {
2109         const string shortname = god_name(which_god, false);
2110         const string longname = getMiscString(shortname + " lastname");
2111         return longname.empty()? shortname : longname;
2112     }
2113
2114     switch (which_god)
2115     {
2116     case GOD_NO_GOD:        return "No God";
2117     case GOD_RANDOM:        return "random";
2118     case GOD_NAMELESS:      return "nameless";
2119     case GOD_ZIN:           return "Zin";
2120     case GOD_SHINING_ONE:   return "the Shining One";
2121     case GOD_KIKUBAAQUDGHA: return "Kikubaaqudgha";
2122     case GOD_YREDELEMNUL:   return "Yredelemnul";
2123     case GOD_VEHUMET:       return "Vehumet";
2124     case GOD_OKAWARU:       return "Okawaru";
2125     case GOD_MAKHLEB:       return "Makhleb";
2126     case GOD_SIF_MUNA:      return "Sif Muna";
2127     case GOD_TROG:          return "Trog";
2128     case GOD_NEMELEX_XOBEH: return "Nemelex Xobeh";
2129     case GOD_ELYVILON:      return "Elyvilon";
2130     case GOD_LUGONU:        return "Lugonu";
2131     case GOD_BEOGH:         return "Beogh";
2132     case GOD_FEDHAS:        return "Fedhas";
2133     case GOD_CHEIBRIADOS:   return "Cheibriados";
2134     case GOD_XOM:           return "Xom";
2135     case GOD_ASHENZARI:     return "Ashenzari";
2136     case GOD_DITHMENOS:     return "Dithmenos";
2137     case GOD_GOZAG:         return "Gozag";
2138     case GOD_QAZLAL:        return "Qazlal";
2139     case GOD_RU:            return "Ru";
2140 #if TAG_MAJOR_VERSION == 34
2141     case GOD_PAKELLAS:      return "Pakellas";
2142 #endif
2143     case GOD_USKAYAW:       return "Uskayaw";
2144     case GOD_HEPLIAKLQANA:  return "Hepliaklqana";
2145     case GOD_WU_JIAN:     return "Wu Jian";
2146     case GOD_JIYVA: // This is handled at the beginning of the function
2147     case GOD_ECUMENICAL:    return "an unknown god";
2148     case NUM_GODS:          return "Buggy";
2149     }
2150     return "";
2151 }
2152
2153 string god_name_jiyva(bool second_name)
2154 {
2155     string name = "Jiyva";
2156     if (second_name)
2157         name += " " + you.jiyva_second_name;
2158
2159     return name;
2160 }
2161
2162 string wu_jian_random_sifu_name()
2163 {
2164     switch (random2(7))
2165     {
2166         case 0: return "Deng Ai";
2167         case 1: return "Jiang Wei";
2168         case 2: return "Zhang Bao";
2169         case 3: return "Ma Yunglu";
2170         case 4: return "Sun Luban";
2171         case 5: return "Gene Jian Bin";
2172         case 6: return "Cai Fang";
2173         default: return "Bug";
2174     }
2175 }
2176
2177 god_type str_to_god(const string &_name, bool exact)
2178 {
2179     string target(_name);
2180     trim_string(target);
2181     lowercase(target);
2182
2183     if (target.empty())
2184         return GOD_NO_GOD;
2185
2186     int      num_partials = 0;
2187     god_type partial      = GOD_NO_GOD;
2188     for (god_iterator it; it; ++it)
2189     {
2190         god_type god = *it;
2191         string name = lowercase_string(god_name(god, false));
2192
2193         if (name == target)
2194             return god;
2195
2196         if (!exact && name.find(target) != string::npos)
2197         {
2198             // Return nothing for ambiguous partial names.
2199             num_partials++;
2200             if (num_partials > 1)
2201                 return GOD_NO_GOD;
2202             partial = god;
2203         }
2204     }
2205
2206     if (!exact && num_partials == 1)
2207         return partial;
2208
2209     return GOD_NO_GOD;
2210 }
2211
2212 void god_speaks(god_type god, const char *mesg)
2213 {
2214     ASSERT(!crawl_state.game_is_arena());
2215
2216     int orig_mon = env.mgrid(you.pos());
2217
2218     monster fake_mon;
2219     fake_mon.type       = MONS_PROGRAM_BUG;
2220     fake_mon.mid        = MID_NOBODY;
2221     fake_mon.hit_points = 1;
2222     fake_mon.god        = god;
2223     fake_mon.set_position(you.pos());
2224     fake_mon.foe        = MHITYOU;
2225     fake_mon.mname      = "FAKE GOD MONSTER";
2226
2227     mprf(MSGCH_GOD, god, "%s", do_mon_str_replacements(mesg, fake_mon).c_str());
2228
2229     fake_mon.reset();
2230     env.mgrid(you.pos()) = orig_mon;
2231 }
2232
2233 void religion_turn_start()
2234 {
2235     if (you.turn_is_over)
2236         religion_turn_end();
2237
2238     crawl_state.clear_god_acting();
2239 }
2240
2241 void religion_turn_end()
2242 {
2243     ASSERT(you.turn_is_over);
2244     _place_delayed_monsters();
2245 }
2246
2247 /** Punish the character for some divine transgression.
2248  *
2249  * @param piety_loss The amount of penance imposed; may be scaled.
2250  * @param penance The amount of penance imposed; may be scaled.
2251  */
2252 void dock_piety(int piety_loss, int penance)
2253 {
2254     static int last_piety_lecture   = -1;
2255     static int last_penance_lecture = -1;
2256
2257     if (piety_loss <= 0 && penance <= 0)
2258         return;
2259
2260     piety_loss = piety_scale(piety_loss);
2261     penance    = piety_scale(penance);
2262
2263     if (piety_loss)
2264     {
2265         if (last_piety_lecture != you.num_turns)
2266         {
2267             // output guilt message:
2268             mprf("You feel%sguilty.",
2269                  (piety_loss == 1) ? " a little " :
2270                  (piety_loss <  5) ? " " :
2271                  (piety_loss < 10) ? " very "
2272                                    : " extremely ");
2273         }
2274
2275         last_piety_lecture = you.num_turns;
2276         lose_piety(piety_loss);
2277     }
2278
2279     if (you.piety < 1)
2280         excommunication();
2281     else if (penance)       // only if still in religion
2282     {
2283         if (last_penance_lecture != you.num_turns)
2284         {
2285             god_speaks(you.religion,
2286                        "\"You will pay for your transgression, mortal!\"");
2287         }
2288         last_penance_lecture = you.num_turns;
2289         _inc_penance(penance);
2290     }
2291 }
2292
2293 // Scales a piety number, applying modifiers (faith).
2294 int piety_scale(int piety)
2295 {
2296     return piety + (you.faith() * div_rand_round(piety, 4));
2297 }
2298
2299 /** Gain or lose piety to reach a certain value.
2300  *
2301  * If the player cannot gain piety (because they worship Xom, Gozag, or
2302  * no god), their piety will be unchanged.
2303  *
2304  * @param piety The new piety value.
2305  * @pre piety is between 0 and MAX_PIETY, inclusive.
2306  */
2307 void set_piety(int piety)
2308 {
2309     ASSERT(piety >= 0);
2310     ASSERT(piety <= MAX_PIETY);
2311
2312     // Ru max piety is 6*
2313     if (you_worship(GOD_RU) && piety > piety_breakpoint(5))
2314         piety = piety_breakpoint(5);
2315
2316     // We have to set the exact piety value this way, because diff may
2317     // be decreased to account for things like penance and gift timeout.
2318     int diff;
2319     do
2320     {
2321         diff = piety - you.piety;
2322         if (diff > 0)
2323         {
2324             if (!gain_piety(diff, 1, false))
2325                 break;
2326         }
2327         else if (diff < 0)
2328             lose_piety(-diff);
2329     }
2330     while (diff != 0);
2331 }
2332
2333 static void _gain_piety_point()
2334 {
2335     // check to see if we owe anything first
2336     if (player_under_penance(you.religion))
2337     {
2338         dec_penance(1);
2339         return;
2340     }
2341     else if (you.gift_timeout > 0)
2342     {
2343         you.gift_timeout--;
2344
2345         // Slow down piety gain to account for the fact that gifts
2346         // no longer have a piety cost for getting them.
2347         // Jiyva is an exception because there's usually a time-out and
2348         // the gifts aren't that precious.
2349         if (!one_chance_in(4) && !you_worship(GOD_JIYVA)
2350             && !you_worship(GOD_NEMELEX_XOBEH))
2351         {
2352 #ifdef DEBUG_PIETY
2353             mprf(MSGCH_DIAGNOSTICS, "Piety slowdown due to gift timeout.");
2354 #endif
2355             return;
2356         }
2357     }
2358
2359     // slow down gain at upper levels of piety
2360     if (!you_worship(GOD_RU))
2361     {
2362         if (you.piety >= MAX_PIETY
2363             || you.piety >= piety_breakpoint(5) && one_chance_in(3)
2364             || you.piety >= piety_breakpoint(3) && one_chance_in(3))
2365         {
2366             do_god_gift();
2367             return;
2368         }
2369     }
2370     else
2371     {
2372         // Ru piety doesn't modulate or taper and Ru doesn't give gifts.
2373         // Ru max piety is 160 (6*)
2374         if (you.piety >= piety_breakpoint(5))
2375             return;
2376     }
2377
2378     int old_piety = you.piety;
2379     // Apply hysteresis.
2380     // piety_hysteresis is the amount of _loss_ stored up, so this
2381     // may look backwards.
2382     if (you.piety_hysteresis)
2383         you.piety_hysteresis--;
2384     else if (you.piety < MAX_PIETY)
2385         you.piety++;
2386
2387     if (piety_rank() > piety_rank(old_piety))
2388     {
2389         // Redraw piety display and, in case the best skill is Invocations,
2390         // redraw the god title.
2391         you.redraw_title = true;
2392
2393         const int rank = piety_rank();
2394         take_note(Note(NOTE_PIETY_RANK, you.religion, rank));
2395         for (const auto& power : get_god_powers(you.religion))
2396         {
2397             if (power.rank == rank
2398                 || power.rank == 7 && can_do_capstone_ability(you.religion))
2399             {
2400                 power.display(true, "You can now %s.");
2401 #ifdef USE_TILE_LOCAL
2402                 tiles.layout_statcol();
2403                 redraw_screen();
2404                 update_screen();
2405 #endif
2406                 learned_something_new(HINT_NEW_ABILITY_GOD);
2407                 // Preserve the old hotkey
2408                 if (power.abil == ABIL_YRED_ANIMATE_DEAD)
2409                 {
2410                     replace(begin(you.ability_letter_table),
2411                             end(you.ability_letter_table),
2412                             ABIL_YRED_ANIMATE_REMAINS, ABIL_YRED_ANIMATE_DEAD);
2413                 }
2414             }
2415         }
2416         if (rank == rank_for_passive(passive_t::halo))
2417             mprf(MSGCH_GOD, "A divine halo surrounds you!");
2418         if (rank == rank_for_passive(passive_t::umbra))
2419             mprf(MSGCH_GOD, "You are shrouded in an aura of darkness!");
2420         if (rank == rank_for_passive(passive_t::sinv))
2421             autotoggle_autopickup(false);
2422         if (rank == rank_for_passive(passive_t::clarity))
2423         {
2424             // Inconsistent with donning amulets, but matches the
2425             // message better and is not abusable.
2426             you.duration[DUR_CONF] = 0;
2427         }
2428         if (rank >= rank_for_passive(passive_t::identify_items))
2429             auto_id_inventory();
2430
2431         // TODO: add one-time ability check in have_passive
2432         if (have_passive(passive_t::unlock_slime_vaults) && can_do_capstone_ability(you.religion))
2433         {
2434             simple_god_message(" will now unseal the treasures of the "
2435                                "Slime Pits.");
2436             dlua.callfn("dgn_set_persistent_var", "sb",
2437                         "fix_slime_vaults", true);
2438             // If we're on Slime:$, pretend we just entered the level
2439             // in order to bring down the vault walls.
2440             if (level_id::current() == level_id(BRANCH_SLIME, brdepth[BRANCH_SLIME]))
2441                 dungeon_events.fire_event(DET_ENTERED_LEVEL);
2442
2443             you.one_time_ability_used.set(you.religion);
2444         }
2445         if (you_worship(GOD_HEPLIAKLQANA)
2446             && rank == 2 && !you.props.exists(HEPLIAKLQANA_ALLY_TYPE_KEY))
2447         {
2448            god_speaks(you.religion,
2449                       "You may now remember your ancestor's life.");
2450         }
2451     }
2452
2453     // The player's symbol depends on Beogh piety.
2454     if (you_worship(GOD_BEOGH))
2455         update_player_symbol();
2456
2457     if (have_passive(passive_t::stat_boost)
2458         && chei_stat_boost(old_piety) < chei_stat_boost())
2459     {
2460         string msg = " raises the support of your attributes";
2461         if (have_passive(passive_t::slowed))
2462             msg += " as your movement slows";
2463         msg += ".";
2464         simple_god_message(msg.c_str());
2465         notify_stat_change();
2466     }
2467
2468     if (you_worship(GOD_QAZLAL)
2469         && qazlal_sh_boost(old_piety) != qazlal_sh_boost())
2470     {
2471         you.redraw_armour_class = true;
2472     }
2473
2474     if (have_passive(passive_t::halo) || have_passive(passive_t::umbra))
2475     {
2476         // Piety change affects halo / umbra radius.
2477         invalidate_agrid(true);
2478     }
2479
2480     do_god_gift();
2481 }
2482
2483 /**
2484  * Gain an amount of piety.
2485  *
2486  * @param original_gain The numerator of the nominal piety gain.
2487  * @param denominator The denominator of the nominal piety gain.
2488  * @param should_scale_piety Should the piety gain be scaled by faith/Sprint?
2489  * @return True if something happened, or if another call with the same
2490  *   arguments might cause something to happen (because of random number
2491  *   rolls).
2492  */
2493 bool gain_piety(int original_gain, int denominator, bool should_scale_piety)
2494 {
2495     if (original_gain <= 0)
2496         return false;
2497
2498     // Xom uses piety differently; Gozag doesn't at all.
2499     if (you_worship(GOD_NO_GOD)
2500         || you_worship(GOD_XOM)
2501         || you_worship(GOD_GOZAG))
2502     {
2503         return false;
2504     }
2505
2506     int pgn = should_scale_piety ? piety_scale(original_gain) : original_gain;
2507
2508     if (crawl_state.game_is_sprint() && should_scale_piety)
2509         pgn = sprint_modify_piety(pgn);
2510
2511     pgn = div_rand_round(pgn, denominator);
2512     while (pgn-- > 0)
2513         _gain_piety_point();
2514     if (you.piety > you.piety_max[you.religion])
2515     {
2516         if (you.piety >= piety_breakpoint(5)
2517             && you.piety_max[you.religion] < piety_breakpoint(5))
2518         {
2519             mark_milestone("god.maxpiety", "became the Champion of "
2520                            + god_name(you.religion) + ".");
2521         }
2522         you.piety_max[you.religion] = you.piety;
2523     }
2524     return true;
2525 }
2526
2527 /** Reduce piety and handle side-effects.
2528  *
2529  * Appropriate for cases where the player has not sinned, but must lose piety
2530  * anyway, such as costs for abilities.
2531  *
2532  * @param pgn The precise amount of piety lost.
2533  */
2534 void lose_piety(int pgn)
2535 {
2536     if (pgn <= 0)
2537         return;
2538
2539     const int old_piety = you.piety;
2540
2541     // Apply hysteresis.
2542     const int old_hysteresis = you.piety_hysteresis;
2543     you.piety_hysteresis = min<int>(PIETY_HYSTERESIS_LIMIT,
2544                                     you.piety_hysteresis + pgn);
2545     const int pgn_borrowed = (you.piety_hysteresis - old_hysteresis);
2546     pgn -= pgn_borrowed;
2547 #ifdef DEBUG_PIETY
2548     mprf(MSGCH_DIAGNOSTICS,
2549          "Piety decreasing by %d (and %d added to hysteresis)",
2550          pgn, pgn_borrowed);
2551 #endif
2552
2553     if (you.piety - pgn < 0)
2554         you.piety = 0;
2555     else
2556         you.piety -= pgn;
2557
2558     // Don't bother printing out these messages if you're under
2559     // penance, you wouldn't notice since all these abilities
2560     // are withheld.
2561     if (!player_under_penance()
2562         && piety_rank(old_piety) > piety_rank())
2563     {
2564         // Redraw piety display and, in case the best skill is Invocations,
2565         // redraw the god title.
2566         you.redraw_title = true;
2567
2568         const int old_rank = piety_rank(old_piety);
2569
2570         for (const auto& power : get_god_powers(you.religion))
2571         {
2572             if (power.rank == old_rank
2573                 || power.rank == 7 && old_rank == 6
2574                    && !you.one_time_ability_used[you.religion])
2575             {
2576                 power.display(false, "You can no longer %s.");
2577                 // Preserve the old hotkey
2578                 if (power.abil == ABIL_YRED_ANIMATE_DEAD)
2579                 {
2580                     replace(begin(you.ability_letter_table),
2581                             end(you.ability_letter_table),
2582                             ABIL_YRED_ANIMATE_DEAD, ABIL_YRED_ANIMATE_REMAINS);
2583                 }
2584 #if TAG_MAJOR_VERSION == 34
2585                 // Deactivate the toggle
2586                 if (power.abil == ABIL_SIF_MUNA_DIVINE_ENERGY)
2587                     you.attribute[ATTR_DIVINE_ENERGY] = 0;
2588 #endif
2589             }
2590         }
2591 #ifdef USE_TILE_LOCAL
2592         tiles.layout_statcol();
2593         redraw_screen();
2594         update_screen();
2595 #endif
2596     }
2597
2598     if (you.piety > 0 && you.piety <= 5)
2599         learned_something_new(HINT_GOD_DISPLEASED);
2600
2601     if (will_have_passive(passive_t::water_walk) && _need_water_walking()
2602         && !have_passive(passive_t::water_walk))
2603     {
2604         _grant_temporary_waterwalk();
2605     }
2606     if (will_have_passive(passive_t::stat_boost)
2607         && chei_stat_boost(old_piety) > chei_stat_boost())
2608     {
2609         string msg = " lowers the support of your attributes";
2610         if (will_have_passive(passive_t::slowed))
2611             msg += " as your movement quickens";
2612         msg += ".";
2613         simple_god_message(msg.c_str());
2614         notify_stat_change();
2615     }
2616
2617     if (you_worship(GOD_QAZLAL)
2618         && qazlal_sh_boost(old_piety) != qazlal_sh_boost())
2619     {
2620         you.redraw_armour_class = true;
2621     }
2622
2623     if (will_have_passive(passive_t::halo)
2624         || will_have_passive(passive_t::umbra))
2625     {
2626         // Piety change affects halo / umbra radius.
2627         invalidate_agrid(true);
2628     }
2629 }
2630
2631 // Fedhas worshipers are on the hook for most plants and fungi
2632 //
2633 // If fedhas worshipers kill a protected monster they lose piety,
2634 // if they attack a friendly one they get penance,
2635 // if a friendly one dies they lose piety.
2636 static bool _fedhas_protects_species(monster_type mc)
2637 {
2638     return mons_class_is_plant(mc)
2639            && mons_class_holiness(mc) & MH_PLANT;
2640 }
2641
2642 bool fedhas_protects(const monster *target)
2643 {
2644     return target
2645         ? _fedhas_protects_species(mons_base_type(*target))
2646         : false;
2647 }
2648
2649 // Fedhas neutralises most plants and fungi
2650 bool fedhas_neutralises(const monster& target)
2651 {
2652     return mons_is_plant(target)
2653            && target.holiness() & MH_PLANT
2654            && target.type != MONS_SNAPLASHER_VINE
2655            && target.type != MONS_SNAPLASHER_VINE_SEGMENT;
2656 }
2657
2658 static string _god_hates_your_god_reaction(god_type god, god_type your_god)
2659 {
2660     if (god_hates_your_god(god, your_god))
2661     {
2662         // Non-good gods always hate your current god.
2663         if (!is_good_god(god))
2664             return "";
2665
2666         // Zin hates chaotic gods.
2667         if (god == GOD_ZIN && is_chaotic_god(your_god))
2668             return " for chaos";
2669
2670         if (is_evil_god(your_god))
2671             return " for evil";
2672     }
2673
2674     return "";
2675 }
2676
2677 /**
2678  * When you abandon this god, how much penance do you gain? (How long does the
2679  * wrath last?
2680  *
2681  * @param god   The god in question.
2682  * @return      The initial penance for the given god's wrath.
2683  */
2684 int initial_wrath_penance_for(god_type god)
2685 {
2686     // TODO: transform to data (tables)
2687     switch (god)
2688     {
2689         case GOD_ASHENZARI:
2690         case GOD_BEOGH:
2691         case GOD_ELYVILON:
2692         case GOD_GOZAG:
2693         case GOD_HEPLIAKLQANA:
2694         case GOD_LUGONU:
2695         case GOD_NEMELEX_XOBEH:
2696         case GOD_TROG:
2697         case GOD_XOM:
2698             return 50;
2699         case GOD_FEDHAS:
2700         case GOD_KIKUBAAQUDGHA:
2701         case GOD_JIYVA:
2702         case GOD_SHINING_ONE:
2703         case GOD_SIF_MUNA:
2704         case GOD_YREDELEMNUL:
2705             return 30;
2706         case GOD_CHEIBRIADOS:
2707         case GOD_DITHMENOS:
2708         case GOD_MAKHLEB:
2709 #if TAG_MAJOR_VERSION == 34
2710         case GOD_PAKELLAS:
2711 #endif
2712         case GOD_QAZLAL:
2713         case GOD_VEHUMET:
2714         case GOD_ZIN:
2715         default:
2716             return 25;
2717         case GOD_RU:
2718             return 0;
2719     }
2720 }
2721
2722 static void _ash_uncurse()
2723 {
2724     bool uncursed = false;
2725     for (int eq_typ = EQ_FIRST_EQUIP; eq_typ < NUM_EQUIP; eq_typ++)
2726     {
2727         const int slot = you.equip[eq_typ];
2728         if (slot == -1)
2729             continue;
2730         if (!uncursed)
2731         {
2732             mprf(MSGCH_GOD, GOD_ASHENZARI, "Your curses shatter.");
2733             uncursed = true;
2734         }
2735         unequip_item(static_cast<equipment_type>(eq_typ));
2736     }
2737 }
2738
2739 void excommunication(bool voluntary, god_type new_god)
2740 {
2741     const god_type old_god = you.religion;
2742     ASSERT(old_god != new_god);
2743     ASSERT(old_god != GOD_NO_GOD);
2744
2745     const bool had_halo       = have_passive(passive_t::halo);
2746     const bool had_umbra      = have_passive(passive_t::umbra);
2747     const bool had_water_walk = have_passive(passive_t::water_walk);
2748     const bool had_stat_boost = have_passive(passive_t::stat_boost);
2749     const int  old_piety      = you.piety;
2750
2751     god_acting gdact(old_god, true);
2752
2753     take_note(Note(NOTE_LOSE_GOD, old_god));
2754
2755     you.duration[DUR_PIETY_POOL] = 0; // your loss
2756     you.duration[DUR_RECITE] = 0;
2757     you.piety = 0;
2758     you.piety_hysteresis = 0;
2759
2760     // so that the player isn't punished for "switching" between good gods via aX
2761     if (is_good_god(old_god) && voluntary)
2762     {
2763         you.saved_good_god_piety = old_piety;
2764         you.previous_good_god = old_god;
2765     }
2766     else
2767     {
2768         you.saved_good_god_piety = 0;
2769         you.previous_good_god = GOD_NO_GOD;
2770     }
2771
2772     you.num_current_gifts[old_god] = 0;
2773
2774     you.religion = GOD_NO_GOD;
2775
2776     you.redraw_title = true;
2777
2778     // Renouncing may have changed the conducts on our wielded or
2779     // quivered weapons, so refresh the display.
2780     you.wield_change = true;
2781     quiver::set_needs_redraw();
2782
2783     mpr("You have lost your religion!");
2784     // included in default force_more_message
2785
2786     if (old_god == GOD_BEOGH)
2787     {
2788         // The player's symbol depends on Beogh worship.
2789         update_player_symbol();
2790     }
2791
2792     mark_milestone("god.renounce", "abandoned " + god_name(old_god) + ".");
2793 #ifdef DGL_WHEREIS
2794     whereis_record();
2795 #endif
2796
2797     if (god_hates_your_god(old_god, new_god))
2798     {
2799         simple_god_message(
2800             make_stringf(" does not appreciate desertion%s!",
2801                          _god_hates_your_god_reaction(old_god, new_god).c_str()).c_str(),
2802             old_god);
2803     }
2804
2805     if (had_halo)
2806     {
2807         mprf(MSGCH_GOD, old_god, "Your divine halo fades away.");
2808         invalidate_agrid(true);
2809     }
2810     if (had_umbra)
2811     {
2812         mprf(MSGCH_GOD, old_god, "Your aura of darkness fades away.");
2813         invalidate_agrid(true);
2814     }
2815     // You might have lost water walking at a bad time...
2816     if (had_water_walk && _need_water_walking())
2817         _grant_temporary_waterwalk();
2818     if (had_stat_boost)
2819     {
2820         redraw_screen();
2821         update_screen();
2822         notify_stat_change();
2823     }
2824
2825     switch (old_god)
2826     {
2827     case GOD_KIKUBAAQUDGHA:
2828         mprf(MSGCH_GOD, old_god, "You sense decay."); // in the state of Denmark
2829         add_daction(DACT_ROT_CORPSES);
2830         break;
2831
2832     case GOD_YREDELEMNUL:
2833         you.duration[DUR_MIRROR_DAMAGE] = 0;
2834         if (query_daction_counter(DACT_ALLY_YRED_SLAVE))
2835         {
2836             simple_god_message(" reclaims all of your granted undead slaves!",
2837                                old_god);
2838             add_daction(DACT_ALLY_YRED_SLAVE);
2839             remove_all_companions(GOD_YREDELEMNUL);
2840         }
2841         break;
2842
2843     case GOD_VEHUMET:
2844         you.vehumet_gifts.clear();
2845         you.duration[DUR_VEHUMET_GIFT] = 0;
2846         break;
2847
2848     case GOD_MAKHLEB:
2849         make_god_gifts_disappear();
2850         break;
2851
2852     case GOD_TROG:
2853         if (you.duration[DUR_TROGS_HAND])
2854             trog_remove_trogs_hand();
2855         make_god_gifts_disappear();
2856         break;
2857
2858     case GOD_BEOGH:
2859         if (query_daction_counter(DACT_ALLY_BEOGH))
2860         {
2861             simple_god_message("'s voice booms out, \"Who do you think you "
2862                                "are?\"", old_god);
2863             mprf(MSGCH_MONSTER_ENCHANT, "All of your followers decide to abandon you.");
2864             add_daction(DACT_ALLY_BEOGH);
2865             remove_all_companions(GOD_BEOGH);
2866         }
2867
2868         env.level_state |= LSTATE_BEOGH;
2869         break;
2870
2871     case GOD_SIF_MUNA:
2872         if (you.duration[DUR_CHANNEL_ENERGY])
2873             you.duration[DUR_CHANNEL_ENERGY] = 0;
2874 #if TAG_MAJOR_VERSION == 34
2875         if (you.attribute[ATTR_DIVINE_ENERGY])
2876             you.attribute[ATTR_DIVINE_ENERGY] = 0;
2877 #endif
2878         break;
2879
2880     case GOD_NEMELEX_XOBEH:
2881         reset_cards();
2882         mprf(MSGCH_GOD, old_god, "Your access to %s's decks is revoked.",
2883              god_name(old_god).c_str());
2884         break;
2885
2886     case GOD_SHINING_ONE:
2887         if (you.duration[DUR_DIVINE_SHIELD])
2888             tso_remove_divine_shield();
2889
2890         make_god_gifts_disappear();
2891         break;
2892
2893     case GOD_ZIN:
2894         if (you.duration[DUR_DIVINE_STAMINA])
2895             zin_remove_divine_stamina();
2896
2897         if (env.sanctuary_time)
2898             remove_sanctuary();
2899         break;
2900
2901     case GOD_ELYVILON:
2902         you.duration[DUR_LIFESAVING] = 0;
2903         if (you.duration[DUR_DIVINE_VIGOUR])
2904             elyvilon_remove_divine_vigour();
2905         you.exp_docked[old_god] = exp_needed(min<int>(you.max_level, 27) + 1)
2906                                   - exp_needed(min<int>(you.max_level, 27));
2907         you.exp_docked_total[old_god] = you.exp_docked[old_god];
2908         break;
2909
2910     case GOD_JIYVA:
2911         if (you.duration[DUR_SLIMIFY])
2912             you.duration[DUR_SLIMIFY] = 0;
2913
2914         if (query_daction_counter(DACT_ALLY_SLIME))
2915         {
2916             mprf(MSGCH_MONSTER_ENCHANT, "All of your fellow slimes turn on you.");
2917             add_daction(DACT_ALLY_SLIME);
2918         }
2919         break;
2920
2921     case GOD_FEDHAS:
2922         if (query_daction_counter(DACT_ALLY_PLANT))
2923         {
2924             mprf(MSGCH_MONSTER_ENCHANT, "The plants of the dungeon turn on you.");
2925             add_daction(DACT_ALLY_PLANT);
2926         }
2927         break;
2928
2929     case GOD_ASHENZARI:
2930         you.exp_docked[old_god] = exp_needed(min<int>(you.max_level, 27) + 1)
2931                                   - exp_needed(min<int>(you.max_level, 27));
2932         you.exp_docked_total[old_god] = you.exp_docked[old_god];
2933         _ash_uncurse();
2934         break;
2935
2936     case GOD_DITHMENOS:
2937         if (you.form == transformation::shadow)
2938             untransform();
2939         break;
2940
2941     case GOD_GOZAG:
2942         if (you.attribute[ATTR_GOZAG_SHOPS_CURRENT])
2943         {
2944             mprf(MSGCH_GOD, old_god, "Your funded stores close, unable to pay "
2945                                      "their debts without your funds.");
2946             you.attribute[ATTR_GOZAG_SHOPS_CURRENT] = 0;
2947         }
2948         you.duration[DUR_GOZAG_GOLD_AURA] = 0;
2949         for (branch_iterator it; it; ++it)
2950             branch_bribe[it->id] = 0;
2951         add_daction(DACT_BRIBE_TIMEOUT);
2952         add_daction(DACT_REMOVE_GOZAG_SHOPS);
2953         shopping_list.remove_dead_shops();
2954         you.exp_docked[old_god] = exp_needed(min<int>(you.max_level, 27) + 1)
2955                                   - exp_needed(min<int>(you.max_level, 27));
2956         you.exp_docked_total[old_god] = you.exp_docked[old_god];
2957         break;
2958
2959     case GOD_QAZLAL:
2960         if (old_piety >= piety_breakpoint(0))
2961         {
2962             mprf(MSGCH_GOD, old_god, "Your storm instantly dissipates.");
2963             you.redraw_armour_class = true;
2964         }
2965         if (you.duration[DUR_QAZLAL_FIRE_RES])
2966         {
2967             mprf(MSGCH_DURATION, "Your resistance to fire fades away.");
2968             you.duration[DUR_QAZLAL_FIRE_RES] = 0;
2969         }
2970         if (you.duration[DUR_QAZLAL_COLD_RES])
2971         {
2972             mprf(MSGCH_DURATION, "Your resistance to cold fades away.");
2973             you.duration[DUR_QAZLAL_COLD_RES] = 0;
2974         }
2975         if (you.duration[DUR_QAZLAL_ELEC_RES])
2976         {
2977             mprf(MSGCH_DURATION,
2978                  "Your resistance to electricity fades away.");
2979             you.duration[DUR_QAZLAL_ELEC_RES] = 0;
2980         }
2981         if (you.duration[DUR_QAZLAL_AC])
2982         {
2983             mprf(MSGCH_DURATION,
2984                  "Your resistance to physical damage fades away.");
2985             you.duration[DUR_QAZLAL_AC] = 0;
2986             you.redraw_armour_class = true;
2987         }
2988         break;
2989
2990 #if TAG_MAJOR_VERSION == 34
2991     case GOD_PAKELLAS:
2992         simple_god_message(" continues to block your magic from regenerating.",
2993                            old_god);
2994         if (you.duration[DUR_DEVICE_SURGE])
2995             you.duration[DUR_DEVICE_SURGE] = 0;
2996         you.exp_docked[old_god] = exp_needed(min<int>(you.max_level, 27) + 1)
2997                                   - exp_needed(min<int>(you.max_level, 27));
2998         you.exp_docked_total[old_god] = you.exp_docked[old_god];
2999         break;
3000 #endif
3001
3002     case GOD_CHEIBRIADOS:
3003         simple_god_message(" continues to slow your movements.", old_god);
3004         break;
3005
3006     case GOD_HEPLIAKLQANA:
3007         add_daction(DACT_ALLY_HEPLIAKLQANA);
3008         remove_all_companions(GOD_HEPLIAKLQANA);
3009
3010         you.exp_docked[old_god] = exp_needed(min<int>(you.max_level, 27) + 1)
3011                                     - exp_needed(min<int>(you.max_level, 27));
3012         you.exp_docked_total[old_god] = you.exp_docked[old_god];
3013         break;
3014
3015     case GOD_WU_JIAN:
3016         you.attribute[ATTR_SERPENTS_LASH] = 0;
3017         if (you.props.exists(WU_JIAN_HEAVENLY_STORM_KEY))
3018             wu_jian_end_heavenly_storm();
3019         break;
3020
3021     case GOD_OKAWARU:
3022         if (you.duration[DUR_HEROISM])
3023             okawaru_remove_heroism();
3024         if (you.duration[DUR_FINESSE])
3025             okawaru_remove_finesse();
3026         break;
3027
3028     default:
3029         break;
3030     }
3031
3032     _set_wrath_penance(old_god);
3033
3034 #ifdef USE_TILE_LOCAL
3035     tiles.layout_statcol();
3036     redraw_screen();
3037     update_screen();
3038 #endif
3039
3040     // Evil hack.
3041     learned_something_new(HINT_EXCOMMUNICATE,
3042                           coord_def((int)new_god, old_piety));
3043
3044     for (ability_type abil : get_god_abilities())
3045         you.skills_to_hide.insert(abil_skill(abil));
3046
3047     update_can_currently_train();
3048     reset_training();
3049
3050     // Perhaps we abandoned Trog with everything but Spellcasting maxed out.
3051     check_selected_skills();
3052 }
3053
3054 void nemelex_death_message()
3055 {
3056     const int rank = min(random2(you.piety) / 30, 2);
3057
3058     static const char *messages[NUM_PIETY_GAIN] =
3059     {
3060         "<lightgrey>Your body disappears without a glow.</lightgrey>",
3061         "Your body glows slightly and disappears.",
3062         "<white>Your body glows with a rainbow of weird colours and disappears.</white>",
3063     };
3064
3065     static const char *glowing_messages[NUM_PIETY_GAIN] =
3066     {
3067         "<lightgrey>Your body disappears without additional glow.</lightgrey>",
3068         "Your body glows slightly brighter and disappears.",
3069         "<white>Your body glows with a rainbow of weird colours and disappears.</white>",
3070     };
3071
3072     mpr((you.backlit() ? glowing_messages : messages)[rank]);
3073 }
3074
3075 bool god_hates_attacking_friend(god_type god, const monster& fr)
3076 {
3077     if (fr.kill_alignment() != KC_FRIENDLY)
3078         return false;
3079
3080     monster_type species = fr.mons_species();
3081
3082     if (mons_is_object(species))
3083         return false;
3084     switch (god)
3085     {
3086         case GOD_ZIN:
3087         case GOD_SHINING_ONE:
3088         case GOD_ELYVILON:
3089         case GOD_OKAWARU:
3090             return true;
3091         case GOD_BEOGH: // added penance to avoid killings for loot
3092             return mons_genus(species) == MONS_ORC;
3093         case GOD_JIYVA:
3094             return mons_class_is_slime(species);
3095         case GOD_FEDHAS:
3096             return _fedhas_protects_species(species);
3097         default:
3098             return false;
3099     }
3100 }
3101
3102 static bool _transformed_player_can_join_god(god_type which_god)
3103 {
3104     if (which_god == GOD_ZIN && you.form != transformation::none)
3105         return false; // zin hates everything
3106     // all these clauses are written with a ! in front of them, so that
3107     // the stuff to the right of that is uniformly "gods that hate this form"
3108     switch (you.form)
3109     {
3110     case transformation::lich:
3111         return !is_good_god(which_god);
3112     case transformation::statue:
3113     case transformation::wisp:
3114         return !(which_god == GOD_YREDELEMNUL);
3115     default:
3116         return true;
3117     }
3118 }
3119
3120 int gozag_service_fee()
3121 {
3122     if (you.char_class == JOB_MONK && had_gods() == 0)
3123         return 0;
3124
3125     if (crawl_state.game_is_sprint())
3126         return 0;
3127
3128     const int gold = you.attribute[ATTR_GOLD_GENERATED];
3129     int fee = (int)(gold - gold / log10(gold + 10.0))/2;
3130
3131     dprf("found %d gold, fee %d", gold, fee);
3132     return fee;
3133 }
3134
3135 static bool _god_rejects_loveless(god_type god)
3136 {
3137     switch (god)
3138     {
3139     case GOD_BEOGH:
3140     case GOD_JIYVA:
3141     case GOD_HEPLIAKLQANA:
3142     case GOD_FEDHAS:
3143     case GOD_YREDELEMNUL:
3144         return true;
3145     default:
3146         return false;
3147     }
3148 }
3149
3150 bool player_can_join_god(god_type which_god)
3151 {
3152     if (you.species == SP_DEMIGOD)
3153         return false;
3154
3155     if (is_good_god(which_god) && you.undead_or_demonic())
3156         return false;
3157
3158     if (which_god == GOD_YREDELEMNUL && you.is_nonliving())
3159         return false;
3160
3161     if (which_god == GOD_BEOGH && !species_is_orcish(you.species))
3162         return false;
3163
3164     if (which_god == GOD_GOZAG && you.gold < gozag_service_fee())
3165         return false;
3166
3167     if (you.get_mutation_level(MUT_NO_LOVE) && _god_rejects_loveless(which_god))
3168         return false;
3169
3170 #if TAG_MAJOR_VERSION == 34
3171     if (you.get_mutation_level(MUT_NO_ARTIFICE)
3172         && which_god == GOD_PAKELLAS)
3173     {
3174         return false;
3175     }
3176 #endif
3177
3178     return _transformed_player_can_join_god(which_god);
3179 }
3180
3181 // Handle messaging and identification for items/equipment on conversion.
3182 static void _god_welcome_handle_gear()
3183 {
3184     // Check for amulets of faith.
3185     item_def *amulet = you.slot_item(EQ_AMULET, false);
3186     if (amulet && amulet->sub_type == AMU_FAITH && !is_useless_item(*amulet))
3187     {
3188         mprf(MSGCH_GOD, "Your amulet flashes!");
3189         flash_view_delay(UA_PLAYER, god_colour(you.religion), 300);
3190     }
3191
3192     if (have_passive(passive_t::identify_items))
3193         auto_id_inventory();
3194
3195     if (have_passive(passive_t::detect_portals))
3196         ash_detect_portals(true);
3197
3198     // Give a reminder to remove any disallowed equipment.
3199     for (int i = EQ_FIRST_EQUIP; i < NUM_EQUIP; i++)
3200     {
3201         const item_def* item = you.slot_item(static_cast<equipment_type>(i));
3202         if (item && god_hates_item(*item))
3203         {
3204             mprf(MSGCH_GOD, "%s warns you to remove %s.",
3205                  uppercase_first(god_name(you.religion)).c_str(),
3206                  item->name(DESC_YOUR, false, false, false).c_str());
3207         }
3208     }
3209
3210     // Refresh wielded/quivered weapons in case we have a new conduct
3211     // on them.
3212     you.wield_change = true;
3213     quiver::set_needs_redraw();
3214 }
3215
3216 /* Make a CrawlStoreValue an empty vector with the requested item type.
3217  * It is an error if the value already had a different type.
3218  */
3219 static void _make_empty_vec(CrawlStoreValue &v, store_val_type vectype)
3220 {
3221     const store_val_type currtype = v.get_type();
3222     ASSERT(currtype == SV_NONE || currtype == SV_VEC);
3223
3224     if (currtype == SV_NONE)
3225         v.new_vector(vectype);
3226     else
3227     {
3228         CrawlVector &vec = v.get_vector();
3229         const store_val_type old_vectype = vec.get_type();
3230         ASSERT(old_vectype == SV_NONE || old_vectype == vectype);
3231         vec.clear();
3232     }
3233 }
3234
3235 // Note: we're trying for a behaviour where the player gets
3236 // to keep their assigned invocation slots if they get excommunicated
3237 // and then rejoin (but if they spend time with another god we consider
3238 // the old invocation slots void and erase them). We also try to
3239 // protect any bindings the character might have made into the
3240 // traditional invocation slots (a-e and X). -- bwr
3241 void set_god_ability_slots()
3242 {
3243     ASSERT(!you_worship(GOD_NO_GOD));
3244
3245     if (find(begin(you.ability_letter_table), end(you.ability_letter_table),
3246              ABIL_RENOUNCE_RELIGION) == end(you.ability_letter_table)
3247         && you.ability_letter_table[letter_to_index('X')] == ABIL_NON_ABILITY)
3248     {
3249         you.ability_letter_table[letter_to_index('X')] = ABIL_RENOUNCE_RELIGION;
3250     }
3251
3252     // Clear out other god invocations.
3253     for (ability_type& slot : you.ability_letter_table)
3254     {
3255         for (god_iterator it; it; ++it)
3256         {
3257             if (slot == ABIL_NON_ABILITY)
3258                 break;
3259             if (*it == you.religion)
3260                 continue;
3261             for (const god_power& power : god_powers[*it])
3262                 if (slot == power.abil)
3263                     slot = ABIL_NON_ABILITY;
3264         }
3265     }
3266
3267     int num = letter_to_index('a');
3268     // Not using get_god_powers, so that hotkeys remain stable across games
3269     // even if you can't use a particular ability in a given game.
3270     for (const god_power& power : god_powers[you.religion])
3271     {
3272         if (power.abil != ABIL_NON_ABILITY
3273             // Animate Dead doesn't have its own hotkey; it steals
3274             // Animate Remains'
3275             && power.abil != ABIL_YRED_ANIMATE_DEAD
3276             // hep ident goes to G, so don't take b for it (hack alert)
3277             && power.abil != ABIL_HEPLIAKLQANA_IDENTITY
3278             && find(begin(you.ability_letter_table),
3279                     end(you.ability_letter_table), power.abil)
3280                == end(you.ability_letter_table)
3281             && you.ability_letter_table[num] == ABIL_NON_ABILITY)
3282         {
3283             // Assign sequentially: first ability 'a', third ability 'c',
3284             // etc., even if one is remapped.
3285             if (find_ability_slot(power.abil, index_to_letter(num)) < 0)
3286             {
3287                 you.ability_letter_table[num] = power.abil;
3288                 auto_assign_ability_slot(num);
3289             }
3290             ++num;
3291         }
3292     }
3293 }
3294
3295 /// Check if the monk's joining bonus should be given. (Except Gozag's.)
3296 static void _apply_monk_bonus()
3297 {
3298     if (you.char_class != JOB_MONK || had_gods() > 0)
3299         return;
3300
3301     // monks get bonus piety for first god
3302     if (you_worship(GOD_RU))
3303         you.props[RU_SACRIFICE_PROGRESS_KEY] = 9999;
3304     else if (you_worship(GOD_ASHENZARI))
3305         you.props[ASHENZARI_CURSE_PROGRESS_KEY] = 9999;
3306     else if (you_worship(GOD_USKAYAW))  // Gaining piety past this point does nothing
3307         gain_piety(15, 1, false); // of value with this god and looks weird.
3308     else
3309         gain_piety(35, 1, false);
3310 }
3311
3312 /// Transfer some piety from an old good god to a new one, if applicable.
3313 static void _transfer_good_god_piety()
3314 {
3315     if (!is_good_god(you.religion))
3316         return;
3317
3318     const god_type old_god = you.previous_good_god;
3319     const uint8_t old_piety = you.saved_good_god_piety;
3320
3321     if (!is_good_god(old_god))
3322         return;
3323
3324     if (you.religion != old_god)
3325     {
3326         static const map<god_type, const char*> farewell_messages = {
3327             { GOD_ELYVILON, "aid the meek" },
3328             { GOD_SHINING_ONE, "vanquish evil" },
3329             { GOD_ZIN, "enforce order" },
3330         };
3331
3332         // Some feedback that piety moved over.
3333         simple_god_message(make_stringf(" says: Farewell. Go and %s with %s.",
3334                                         lookup(farewell_messages, you.religion,
3335                                                "become a bug"),
3336                                         god_name(you.religion).c_str()).c_str(),
3337
3338                            old_god);
3339     }
3340
3341     // Give a piety bonus when switching between good gods, or back to the
3342     // same good god.
3343     if (old_piety > piety_breakpoint(0))
3344         gain_piety(old_piety - piety_breakpoint(0), 2, false);
3345 }
3346
3347
3348 /**
3349  * Give an appropriate message for the given good god to give in response to
3350  * the player joining a god that brings down their wrath.
3351  *
3352  * @param good_god    The good god in question.
3353  */
3354 static string _good_god_wrath_message(god_type good_god)
3355 {
3356     switch (good_god)
3357     {
3358         case GOD_ELYVILON:
3359             return "Your evil deeds will not go unpunished";
3360         case GOD_SHINING_ONE:
3361             return "You will pay for your evil ways, mortal";
3362         case GOD_ZIN:
3363             return make_stringf("You will suffer for embracing such %s",
3364                                 is_chaotic_god(you.religion) ? "chaos"
3365                                                              : "evil");
3366         default:
3367             return "You will be buggily punished for this";
3368     }
3369 }
3370
3371 /**
3372  * Check if joining the current god will cause wrath for any previously-
3373  * worshipped good gods. If so, message & set penance timeouts.
3374  *
3375  * @param old_god    The previous god worshipped; may be GOD_NO_GOD.
3376  */
3377 static void _check_good_god_wrath(god_type old_god)
3378 {
3379     for (god_type good_god : { GOD_ELYVILON, GOD_SHINING_ONE, GOD_ZIN })
3380     {
3381         if (old_god == good_god || !you.penance[good_god]
3382             || !god_hates_your_god(good_god, you.religion))
3383         {
3384             continue;
3385         }
3386
3387         const string wrath_message
3388             = make_stringf(" says: %s!",
3389                            _good_god_wrath_message(good_god).c_str());
3390         simple_god_message(wrath_message.c_str(), good_god);
3391         set_penance_xp_timeout();
3392     }
3393 }
3394
3395 void initialize_ashenzari_props()
3396 {
3397     if (!you.props.exists(ASHENZARI_CURSE_PROGRESS_KEY))
3398         you.props[ASHENZARI_CURSE_PROGRESS_KEY] = 0;
3399     if (!you.props.exists(ASHENZARI_CURSE_DELAY_KEY))
3400     {
3401         int delay = 50;
3402         if (crawl_state.game_is_sprint())
3403             delay /= SPRINT_MULTIPLIER;
3404         you.props[ASHENZARI_CURSE_DELAY_KEY] = delay;
3405     }
3406 }
3407
3408 /// Handle basic god piety & related setup for a new-joined god.
3409 static void _set_initial_god_piety()
3410 {
3411     // Currently, penance is just zeroed. This could be much more
3412     // interesting.
3413     you.penance[you.religion] = 0;
3414
3415     switch (you.religion)
3416     {
3417     case GOD_XOM:
3418         // Xom uses piety and gift_timeout differently.
3419         you.piety = HALF_MAX_PIETY;
3420         you.gift_timeout = random2(40) + random2(40);
3421         break;
3422
3423     case GOD_ASHENZARI:
3424         you.piety = ASHENZARI_BASE_PIETY;
3425         you.piety_hysteresis = 0;
3426         you.gift_timeout = 0;
3427         initialize_ashenzari_props();
3428         break;
3429
3430     case GOD_RU:
3431         you.piety = 10; // one moderate sacrifice should get you to *.
3432         you.piety_hysteresis = 0;
3433         you.gift_timeout = 0;
3434
3435         // I'd rather this be in on_join(), but then it overrides the
3436         // monk bonus...
3437         you.props[RU_SACRIFICE_PROGRESS_KEY] = 0;
3438         // offer the first sacrifice faster than normal
3439         {
3440             int delay = 50;
3441             if (crawl_state.game_is_sprint())
3442                 delay /= SPRINT_MULTIPLIER;
3443             you.props[RU_SACRIFICE_DELAY_KEY] = delay;
3444         }
3445         you.props[RU_SACRIFICE_PENALTY_KEY] = 0;
3446         break;
3447
3448     default:
3449         you.piety = 15; // to prevent near instant excommunication
3450         if (you.piety_max[you.religion] < 15)
3451             you.piety_max[you.religion] = 15;
3452         you.piety_hysteresis = 0;
3453         you.gift_timeout = 0;
3454         break;
3455     }
3456
3457     // Tutorial needs berserk usable.
3458     if (crawl_state.game_is_tutorial())
3459         gain_piety(30, 1, false);
3460
3461     _apply_monk_bonus();
3462     _transfer_good_god_piety();
3463 }
3464
3465 /// Setup when joining the greedy magnates of Gozag.
3466 static void _join_gozag()
3467 {
3468     // Handle the fee.
3469     const int fee = gozag_service_fee();
3470     if (fee > 0)
3471     {
3472         ASSERT(you.gold >= fee);
3473         mprf(MSGCH_GOD, "You pay a service fee of %d gold.", fee);
3474         you.gold -= fee;
3475         you.attribute[ATTR_GOZAG_GOLD_USED] += fee;
3476     }
3477     else
3478         simple_god_message(" waives the service fee.");
3479
3480     // Note relevant powers.
3481     bool needs_redraw = false;
3482     for (const auto& power : get_god_powers(you.religion))
3483     {
3484         if (you.gold >= get_gold_cost(power.abil))
3485         {
3486             power.display(true, "You have enough gold to %s.");
3487             needs_redraw = true;
3488         }
3489     }
3490
3491     if (needs_redraw)
3492     {
3493 #ifdef USE_TILE_LOCAL
3494         tiles.layout_statcol();
3495         redraw_screen();
3496         update_screen();
3497 #else
3498         ;
3499 #endif
3500     }
3501
3502     // Move gold to top of piles & detect it.
3503     add_daction(DACT_GOLD_ON_TOP);
3504 }
3505
3506 /**
3507  * Choose an antique name for a Hepliaklqana-granted ancestor.
3508  *
3509  * @param female    Whether the ancestor is female or male.
3510  * @return          An appropriate name; e.g. Hrodulf, Citali, Aat.
3511  */
3512 static string _make_ancestor_name(bool female)
3513 {
3514     const string gender_name = female ? "female" : "male";
3515     const string suffix = " " + gender_name + " name";
3516     const string name = getRandNameString("ancestor", suffix);
3517     return name.empty() ? make_name() : name;
3518 }
3519
3520 /// Setup when joining the devoted followers of Hepliaklqana.
3521 static void _join_hepliaklqana()
3522 {
3523     // initial setup.
3524     if (!you.props.exists(HEPLIAKLQANA_ALLY_NAME_KEY))
3525     {
3526         const bool female = coinflip();
3527         you.props[HEPLIAKLQANA_ALLY_NAME_KEY] = _make_ancestor_name(female);
3528         you.props[HEPLIAKLQANA_ALLY_GENDER_KEY] = female ? GENDER_FEMALE
3529                            &n