1 /*
2  * PROPRIETARY INFORMATION.  This software is proprietary to POWDER
3  * Development, and is not to be reproduced, transmitted, or disclosed
4  * in any way without written permission.
5  *
6  * Produced by:	Jeff Lait
7  *
8  *      	POWDER Development
9  *
10  * NAME:        piety.cpp ( POWDER Library, C++ )
11  *
12  * COMMENTS:
13  *	This implements all the piety handling code.
14  */
15 
16 #include "glbdef.h"
17 #include "assert.h"
18 #include <stdio.h>
19 #include "creature.h"
20 #include "piety.h"
21 #include "sramstream.h"
22 #include "item.h"
23 #include "itemstack.h"
24 #include "msg.h"
25 #include "map.h"
26 #include "encyc_support.h"
27 
28 //
29 // This stores our total piety & total action points.
30 //
31 s16 glbPiety[NUM_GODS];
32 s16 glbGodPoints[NUM_GODS];
33 GOD_NAMES	glbChosenGod = GOD_AGNOSTIC;
34 GOD_NAMES	glbWhimOfXOM;
35 u8 glbWhimOfXOMTimer;
36 u8 glbFlameStrikeTimer;
37 GOD_NAMES glbFlameGod;
38 
39 //
40 // Global Piety Functions
41 //
42 GOD_NAMES
piety_randomnonxomgod()43 piety_randomnonxomgod()
44 {
45     int		god;
46 
47     while (1)
48     {
49 	god = rand_choice(NUM_GODS);
50 	if (god == GOD_AGNOSTIC || god == GOD_CULTIST)
51 	    continue;
52 	break;
53     }
54 
55     return (GOD_NAMES) god;
56 }
57 
58 void
piety_init()59 piety_init()
60 {
61     GOD_NAMES	god;
62 
63     FOREACH_GOD(god)
64     {
65 	glbPiety[god] = 0;
66 	glbGodPoints[god] = 0;
67     }
68 
69     // We do not set our god here as it was set in the god selection
70     // stage
71     // glbChosenGod = GOD_AGNOSTIC;
72     glbWhimOfXOM = piety_randomnonxomgod();
73     glbWhimOfXOMTimer = rand_range(100, 200);
74     glbFlameStrikeTimer = 0;
75     glbFlameGod = GOD_AGNOSTIC;
76 }
77 
78 GOD_NAMES
piety_chosengod()79 piety_chosengod()
80 {
81     return glbChosenGod;
82 }
83 
84 int
piety_chosengodspiety()85 piety_chosengodspiety()
86 {
87     GOD_NAMES	god = piety_chosengod();
88 
89     if (god == GOD_AGNOSTIC)
90 	return 0;
91 
92     return glbPiety[god];
93 }
94 
95 void
piety_setgod(GOD_NAMES god)96 piety_setgod(GOD_NAMES god)
97 {
98     glbChosenGod = god;
99 }
100 
101 void
piety_load(SRAMSTREAM & is)102 piety_load(SRAMSTREAM &is)
103 {
104     int		val;
105     GOD_NAMES	god;
106 
107     FOREACH_GOD(god)
108     {
109 	is.read(val, 16);
110 	glbPiety[god] = val;
111 	is.read(val, 16);
112 	glbGodPoints[god] = val;
113     }
114 
115     is.read(val, 8);
116     glbChosenGod = (GOD_NAMES) val;
117 
118     is.read(val, 8);
119     glbWhimOfXOM = (GOD_NAMES) val;
120 
121     is.read(val, 8);
122     glbWhimOfXOMTimer = val;
123 
124     is.read(val, 8);
125     glbFlameStrikeTimer = val;
126     is.read(val, 8);
127     glbFlameGod = (GOD_NAMES) val;
128 }
129 
130 void
piety_save(SRAMSTREAM & os)131 piety_save(SRAMSTREAM &os)
132 {
133     GOD_NAMES	god;
134 
135     FOREACH_GOD(god)
136     {
137 	os.write(glbPiety[god], 16);
138 	os.write(glbGodPoints[god], 16);
139     }
140 
141     os.write(glbChosenGod, 8);
142     os.write(glbWhimOfXOM, 8);
143     os.write(glbWhimOfXOMTimer, 8);
144     os.write(glbFlameStrikeTimer, 8);
145     os.write(glbFlameGod, 8);
146 }
147 
148 //
149 // MOB::piety Functions
150 //
151 void
pietyKill(MOB * mob,ATTACKSTYLE_NAMES attackstyle)152 MOB::pietyKill(MOB *mob, ATTACKSTYLE_NAMES attackstyle)
153 {
154     int		val;
155 
156     // Check to see if we are a slave.  If so, grant the piety
157     // to our master as well.
158     MOB		*master;
159     master = getMaster();
160     if (master)
161     {
162 	master->pietyKill(mob, ATTACKSTYLE_MINION);
163     }
164 
165     val = mob->getExpLevel();
166 
167     if (val < getExpLevel() - 5)
168 	val = 1;
169     else if (val < getExpLevel() + 2)
170 	val = 2;
171     else
172 	val = 3;
173 
174     if (attackstyle != ATTACKSTYLE_SPELL)
175         pietyGrant(GOD_FIGHTER, val * 2);
176 
177     if (attackstyle == ATTACKSTYLE_MELEE)
178         pietyGrant(GOD_BARB, val);
179     else
180 	pietyGrant(GOD_NECRO, val);
181 
182     if (attackstyle == ATTACKSTYLE_SPELL)
183 	pietyGrant(GOD_WIZARD, val);
184 
185     if (attackstyle == ATTACKSTYLE_THROWN)
186 	pietyGrant(GOD_ROGUE, val);
187 
188     if (mob->defn().mobtype == MOBTYPE_UNDEAD)
189     {
190 	pietyGrant(GOD_CLERIC, val);
191     }
192 }
193 
194 void
pietyEat(ITEM * item,int foodval)195 MOB::pietyEat(ITEM *item, int foodval)
196 {
197     if (item->getCorpseMob())
198     {
199 	// Fallen foe....
200 	// Only counts if you aren't hungry.
201 	if (getHungerLevel() > HUNGER_HUNGRY)
202 	    pietyGrant(GOD_CLERIC, -2);
203     }
204 }
205 
206 void
pietyDress(INTRINSIC_NAMES intrinsic)207 MOB::pietyDress(INTRINSIC_NAMES intrinsic)
208 {
209     // Only one in 5 chance of actually responding to this state.
210     if (rand_choice(5))
211 	return;
212 
213     if (intrinsic == INTRINSIC_DRESSED_WIZARD)
214 	pietyGrant(GOD_WIZARD, 1);
215     if (intrinsic == INTRINSIC_DRESSED_FIGHTER)
216 	pietyGrant(GOD_FIGHTER, 1);
217     if (intrinsic == INTRINSIC_DRESSED_RANGER)
218 	pietyGrant(GOD_ROGUE, 1);
219     if (intrinsic == INTRINSIC_DRESSED_CLERIC)
220     {
221 	// Pax isn't too impressed by all this..
222 	if (rand_choice(8))
223 	    return;
224 	pietyGrant(GOD_CLERIC, 1);
225     }
226     if (intrinsic == INTRINSIC_DRESSED_NECROMANCER)
227     {
228 	// Necros should not be about piety.
229 	if (rand_choice(4))
230 	    return;
231 	pietyGrant(GOD_NECRO, 1);
232     }
233     if (intrinsic == INTRINSIC_DRESSED_BARBARIAN)
234     {
235 	// H'ruth isn't into fashion.
236 	if (rand_choice(8))
237 	    return;
238 	pietyGrant(GOD_BARB, 1);
239     }
240 }
241 
242 void
pietyZapWand(ITEM * wand)243 MOB::pietyZapWand(ITEM *wand)
244 {
245     pietyGrant(GOD_ROGUE, 2);
246     pietyGrant(GOD_WIZARD, 1);
247     pietyGrant(GOD_BARB, -1);
248 }
249 
250 void
pietySurrounded(int numenemy)251 MOB::pietySurrounded(int numenemy)
252 {
253     // Barbarian bonus:
254     if (numenemy > 1)
255     {
256 	// TODO: This would be a good time to grant BERSERK.
257 	pietyGrant(GOD_BARB, numenemy * 2);
258 
259 	// Wizards do not like to be surrounded.
260 	pietyGrant(GOD_WIZARD, -1);
261     }
262 }
263 
264 void
pietyHeal(int amount,bool self,bool enemy,bool vampiric)265 MOB::pietyHeal(int amount, bool self, bool enemy, bool vampiric)
266 {
267     // Necros are rewarded for healing enemies, as it is assumed
268     // one merely wants them to suffer longer.
269     // Otherwise, it isn't something one should be doing.
270     if (enemy || vampiric)
271 	pietyGrant(GOD_NECRO, 1);
272     else
273 	pietyGrant(GOD_NECRO, -5);
274 
275     // Clerics are of two minds of enemy healing.  It is a no-op
276     // as otherwise it would encourage uncleric like behaviour.
277     // We get massive bonuses for healing our pets.
278     if (!enemy)
279     {
280 	// vampiric styles of healing are not appreciated.
281 	if (vampiric)
282 	    pietyGrant(GOD_CLERIC, -1);
283 	else
284 	    pietyGrant(GOD_CLERIC, self ? 1 : 3);
285     }
286 }
287 
288 void
pietyCastSpell(SPELL_NAMES spell)289 MOB::pietyCastSpell(SPELL_NAMES spell)
290 {
291     int		val;
292 
293     val = glb_spelldefs[spell].mpcost +
294 	  (glb_spelldefs[spell].hpcost/2) +
295 	  (glb_spelldefs[spell].xpcost/10);
296 
297     // An additional point is given for every 5 vals.
298     val /= 5;
299     if (val <= 0) val = 1;
300 
301     pietyGrant(GOD_WIZARD, val);
302 
303     if (glb_spelldefs[spell].type == SPELLTYPE_DEATH)
304     {
305 	pietyGrant(GOD_NECRO, (val + 1) / 2);
306 	pietyGrant(GOD_CLERIC, -val, true);
307     }
308     if (glb_spelldefs[spell].type == SPELLTYPE_HEAL)
309     {
310 	pietyGrant(GOD_NECRO, -val, true);
311 	pietyGrant(GOD_CLERIC, (val + 1) / 2);
312     }
313 
314     // Forbidden for barbarians!
315     pietyGrant(GOD_BARB, -val, true);
316 }
317 
318 void
pietyCreateTrap()319 MOB::pietyCreateTrap()
320 {
321     pietyGrant(GOD_ROGUE, 5);
322 }
323 
324 void
pietyFindSecret()325 MOB::pietyFindSecret()
326 {
327     pietyGrant(GOD_ROGUE, 5);
328 }
329 
330 void
pietyAttack(MOB * mob,const ATTACK_DEF * attack,ATTACKSTYLE_NAMES style)331 MOB::pietyAttack(MOB *mob, const ATTACK_DEF *attack, ATTACKSTYLE_NAMES style)
332 {
333     // Determine if it is a friendly attack.
334     ATTITUDE_NAMES		attitude;
335 
336     attitude = mob->getAttitude(this);
337 
338     // Check for attacking friendly or what not.
339     if (attitude == ATTITUDE_FRIENDLY)
340     {
341 	// Killing friendly undead is an act of mercy.
342 	if (mob->defn().mobtype != MOBTYPE_UNDEAD)
343 	    pietyGrant(GOD_CLERIC, -5);
344     }
345     if (attitude == ATTITUDE_NEUTRAL)
346     {
347 	// It is not *that* bad to start combat.
348 	// However, if the target is undead, Pax has no issues.
349 	if (mob->defn().mobtype != MOBTYPE_UNDEAD)
350 	    pietyGrant(GOD_CLERIC, -1);
351     }
352 
353     if ( ( mob->hasIntrinsic(INTRINSIC_PARALYSED) &&
354 	  !mob->hasIntrinsic(INTRINSIC_FREEDOM)) ||
355 	 (mob->hasIntrinsic(INTRINSIC_ASLEEP)) )
356     {
357 	// Strike helpless.
358 	pietyGrant(GOD_ROGUE, 1);
359 	pietyGrant(GOD_NECRO, 2);
360 
361 	// The exception is undead.  You are free to
362 	// engage them regardless of their status.
363 	if (mob->defn().mobtype != MOBTYPE_UNDEAD)
364 	{
365 	    pietyGrant(GOD_CLERIC, -2);
366 	}
367     }
368 
369     if (style == ATTACKSTYLE_THROWN)
370     {
371 	// Ranged attack.
372 	pietyGrant(GOD_ROGUE, 1);
373 	pietyGrant(GOD_BARB, -2);
374     }
375 
376     if (style == ATTACKSTYLE_MELEE)
377     {
378 	// Melee attack
379 	if (!rand_choice(5))
380 	{
381 	    pietyGrant(GOD_WIZARD, -1);
382 	    pietyGrant(GOD_NECRO, -1);
383 	}
384     }
385 }
386 
387 void
pietyMakeNoise(int noiselevel)388 MOB::pietyMakeNoise(int noiselevel)
389 {
390     if (noiselevel > 2)
391     {
392 	if (!rand_choice(30))
393 	    pietyGrant(GOD_ROGUE, -1 * (noiselevel - 2));
394     }
395 }
396 
397 void
pietyIdentify(ITEM_NAMES)398 MOB::pietyIdentify(ITEM_NAMES /*itemdef*/)
399 {
400     pietyGrant(GOD_ROGUE, 5);
401     pietyGrant(GOD_WIZARD, 3);
402 }
403 
404 void
pietyBreak(ITEM * item)405 MOB::pietyBreak(ITEM *item)
406 {
407     if (glbWhimOfXOM == GOD_CLERIC)
408     {
409 	// The hint makes it seem like that breaking things abuses
410 	// ><0|V|  The wiki picked up on this and I'd hate for
411 	// it to be incorrect so I've retconned this pathway
412 	pietyGrant(GOD_CULTIST, -2);
413     }
414 }
415 
416 void
pietyGrant(GOD_NAMES god,int amount,bool forbidden)417 MOB::pietyGrant(GOD_NAMES god, int amount, bool forbidden)
418 {
419     // Only record piety for the avatar.
420     if (!isAvatar())
421 	return;
422 
423     // If this god is CULTIST, we need to see what the current
424     // whim of ><0|V| is, and act accordingly.
425     if (god == glbWhimOfXOM)
426     {
427 	pietyGrant(GOD_CULTIST, amount, forbidden);
428     }
429 
430     // If the action is forbidden, we want to zero out
431     // our piety in one go.
432     if (forbidden && glbPiety[god] > 0)
433     {
434 	// You will likely invoke the wrath of the god.  If it is
435 	// your god, you will wipe your xp.
436 	pietyTransgress(god);
437 	glbPiety[god] += amount*10;
438     }
439 
440     // If the piety is negative, and it is your chosen god,
441     // it is twice as bad.
442     if (god == glbChosenGod && amount < 0)
443 	amount *= 2;
444 
445     // DIminish returns on positive piety gain to prevent people
446     // stacking up 10k piety for constant healing
447     if (amount > 0)
448     {
449 	if (glbPiety[god] > 200)
450 	{
451 	    // Lose 1/16th chance for every 100 piety above this
452 	    // up to 15 * 100 + 200 = 1700..
453 	    int		goal = (glbPiety[god]-200)/100;
454 	    if (goal >= 15)
455 		goal = 14;
456 	    if (rand_choice(16) <= goal)
457 		amount = 0;
458 
459 	    // Double jeopardy for every 1000 there on (Caps at 10k)
460 	    if (glbPiety[god] > 2000)
461 	    {
462 		if (rand_choice(16) < (glbPiety[god]-2000)/1000)
463 		{
464 		    amount = 0;
465 		}
466 	    }
467 	}
468     }
469 
470     // Adjust our piety & god points.
471     if (glbPiety[god] * amount > 0)
472     {
473 	// Both piety & amount have same sign, increment god points.
474 	if (amount > 0)
475 	    glbGodPoints[god] += amount;
476 	else
477 	    glbGodPoints[god] -= amount;
478     }
479     glbPiety[god] += amount;
480 
481     // Clamp piety to reasonable limits to avoid overflow/underflow
482     if (glbPiety[god] > 10000)
483 	glbPiety[god] = 10000;
484     if (glbPiety[god] < -10000)
485 	glbPiety[god] = -10000;
486 
487     // Reduce god points to not become larger than piety.
488     if (abs(glbPiety[god]) < glbGodPoints[god])
489 	glbGodPoints[god] = abs(glbPiety[god]);
490 
491 #if 0
492     BUF		buf;
493 
494     buf.sprintf("%s: %d:%d.  ",
495 		glb_goddefs[god].name,
496 		glbPiety[god],
497 		amount);
498     msg_report(buf);
499 #endif
500 }
501 
502 void
pietyTransgress(GOD_NAMES god)503 MOB::pietyTransgress(GOD_NAMES god)
504 {
505     // The user did something forbidden to this god.
506     // The penalty is determined by:
507     // 1) If you are currently following this god, wipe experience,
508     //    report transgression, and dump all god piety into punishment.
509     // 2) If you are not, check to see if the god points are more than
510     //    your current god's piety.  If so, punish.  Otherwise it is
511     //    assumed that your own god stood in the way.
512     //
513     //    We wipe out our god points, but don't wipe out our piety.
514     BUF		buf;
515 
516     // First, the god is given as many points as he wants to play with!
517     glbGodPoints[god] = glbPiety[god];
518 
519     if (god == glbChosenGod)
520     {
521 	const char *abusemsg[] =
522 	{
523 	    "Your Actions Defile Me!",
524 	    "Do you value me so little?",
525 	    "Respect My Commands!"
526 	};
527 
528 	buf.sprintf("%s: %s  ", glb_goddefs[god].name,
529 				abusemsg[rand_choice(3)]);
530 	msg_announce(buf);
531 	wipeExp();
532 	pietyPunish(god);
533     }
534     else
535     {
536 	if (glbChosenGod == GOD_AGNOSTIC)
537 	{
538 	    const char *agnosticsavemsg[] =
539 	    {
540 		"You sense celestial displeasure.  ",
541 		"You wonder if there are gods after all?  ",
542 		"A painful hangnail briefly distracts you.  "
543 	    };
544 
545 	    msg_announce(agnosticsavemsg[rand_choice(3)]);
546 
547 	    // Your powers of disbelief succeed.
548 	    glbGodPoints[god] = 0;
549 	}
550 	else if (glbGodPoints[god] > glbPiety[glbChosenGod])
551 	{
552 	    // Your current god cannot come to your rescue.
553 	    const char *abusemsg[] =
554 	    {
555 		"%s: Do not look to %s to protect you!  ",
556 		"%s: You should obey Me!  ",
557 		"%s: You cannot hide from Me!  "
558 	    };
559 	    buf.sprintf(abusemsg[rand_choice(3)],
560 			glb_goddefs[god].name,
561 			glb_goddefs[glbChosenGod].name);
562 	    msg_announce(buf);
563 	    pietyPunish(god);
564 	}
565 	else
566 	{
567 	    // Let the player know a divine struggle just occurred.
568 	    const char *godsavemsg[] =
569 	    {
570 		"%s: %s shall not meddle with my disciple!  ",
571 		"%s: Fear not %s while you follow me!  ",
572 		"%s: %s!  Leave my people alone!  "
573 	    };
574 	    buf.sprintf(godsavemsg[rand_choice(3)],
575 			glb_goddefs[glbChosenGod].name,
576 			glb_goddefs[god].name);
577 	    msg_announce(buf);
578 	    // This will cost you piety with your god!
579 	    glbPiety[glbChosenGod] -= glbGodPoints[god];
580 	    // We may have moved our piety to 0.  If we leave
581 	    // our god points, this could result in us being
582 	    // punished!
583 	    // Thus, we ensure god points are less than piety.
584 	    if (glbGodPoints[glbChosenGod] > abs(glbPiety[glbChosenGod]))
585 		glbGodPoints[glbChosenGod] = abs(glbPiety[glbChosenGod]);
586 	    // They all get nullified against your chosen god.
587 	    glbGodPoints[god] = 0;
588 	}
589     }
590 
591     glbPiety[god] = glbGodPoints[god];
592     glbGodPoints[god] = 0;
593 }
594 
595 void
pietyPunish(GOD_NAMES god)596 MOB::pietyPunish(GOD_NAMES god)
597 {
598     // Choose a punishment that fits the god and fits the available points.
599     PUNISH_NAMES	valid[NUM_PUNISHS];
600     int			numvalid = 0;
601     int			points;
602     PUNISH_NAMES	punish;
603     BUF			buf;
604 
605     points = glbGodPoints[god];
606 
607     FOREACH_PUNISH(punish)
608     {
609 	if (glb_punishdefs[punish].points <= points)
610 	{
611 	    if (strchr(glb_punishdefs[punish].god, (char) god))
612 	    {
613 		// This god is willing to do this punishment.
614 		valid[numvalid++] = punish;
615 	    }
616 	}
617     }
618 
619     // If there is no valid punishments, quit.
620     if (!numvalid)
621 	return;
622 
623     punish = valid[rand_choice(numvalid)];
624 
625     // Subtract the points & apply the punishment.
626     glbGodPoints[god] -= glb_punishdefs[punish].points;
627 
628     switch (punish)
629     {
630 	case PUNISH_FLAMESTRIKE:
631 	{
632 	    formatAndReport("%U <smell> sulphur.");
633 	    glbFlameStrikeTimer = rand_range(3, 6);
634 	    glbFlameGod = god;
635 	    break;
636 	}
637 
638 	case PUNISH_SUMMON:
639 	{
640 	    buf.sprintf("%s: Prove your worth!  ",
641 			 glb_goddefs[god].name);
642 	    msg_announce(buf);
643 
644 	    MOB		*mob;
645 	    int		 dx, dy;
646 
647 	    for (dy = -1; dy <= 1; dy++)
648 	    {
649 		for (dx = -1; dx <= 1; dx++)
650 		{
651 		    if (glbCurLevel->getMob(getX()+dx,
652 					    getY()+dy))
653 			continue;
654 
655 		    mob = MOB::createNPC(getExpLevel()+3);
656 		    if (!mob->canMove(getX() + dx,
657 				      getY() + dy,
658 				      true))
659 		    {
660 			delete mob;
661 			continue;
662 		    }
663 
664 		    mob->move(getX() + dx,
665 			      getY() + dy,
666 			      true);
667 		    glbCurLevel->registerMob(mob);
668 
669 		    mob->formatAndReport("%U <appear> out of thin air!");
670 
671 		    // Ensure we want to kill the target, which is this.
672 		    mob->setAITarget(this);
673 		}
674 	    }
675 
676 	    break;
677 	}
678 
679 	case PUNISH_CURSE_WORN:
680 	{
681 	    buf.sprintf("%s: To the pits with you!  ",
682 			glb_goddefs[god].name);
683 	    msg_announce(buf);
684 
685 	    // Curse only equpped items.
686 	    receiveCurse(true, false);
687 	    break;
688 	}
689 
690 	case PUNISH_CURSE_ANY:
691 	{
692 	    buf.sprintf("%s: A pox on you!  ",
693 			glb_goddefs[god].name);
694 	    msg_announce(buf);
695 
696 	    // Curse all items with equal chance.
697 	    receiveCurse(false, true);
698 	    break;
699 	}
700 
701 	case PUNISH_DISENCHANT_WEAPON:
702 	{
703 	    buf.sprintf("%s: You are an inferior tool!  ",
704 			glb_goddefs[god].name);
705 	    msg_announce(buf);
706 
707 	    // gods do not invoke shuddering.
708 	    receiveWeaponEnchant(-1, false);
709 	    break;
710 	}
711 
712 	case PUNISH_DISENCHANT_ARMOUR:
713 	{
714 	    buf.sprintf("%s: You deserve no protection!  ",
715 			glb_goddefs[god].name);
716 	    msg_announce(buf);
717 
718 	    // gods do not invoke shuddering.
719 	    receiveArmourEnchant((ITEMSLOT_NAMES)-1, -1, false);
720 	    break;
721 	}
722 
723 	case PUNISH_POISON:
724 	{
725 	    buf.sprintf("%s: Drink the poison you have brewed!  ",
726 			glb_goddefs[god].name);
727 	    msg_announce(buf);
728 
729 	    setTimedIntrinsic(0, INTRINSIC_POISON_STRONG, 20);
730 
731 	    break;
732 	}
733 
734 	case PUNISH_PARALYSE:
735 	{
736 	    buf.sprintf("%s: Freeze with Fright at my Wrath!  ",
737 			glb_goddefs[god].name);
738 	    msg_announce(buf);
739 
740 	    setTimedIntrinsic(0, INTRINSIC_PARALYSED, 5);
741 	    break;
742 	}
743 
744 	case PUNISH_SLEEP:
745 	{
746 	    buf.sprintf("%s: Dream in Terror!  ",
747 			glb_goddefs[god].name);
748 	    msg_announce(buf);
749 
750 	    setTimedIntrinsic(0, INTRINSIC_ASLEEP, 30);
751 	    break;
752 	}
753 
754 	case PUNISH_POLY:
755 	{
756 	    MOB_NAMES		mob;
757 
758 	    // Determine a suitable pathetic beast.
759 	    MOB_NAMES		targets[3] =
760 			{
761 			    MOB_MOUSE,
762 			    MOB_BROWNSLUG,
763 			    MOB_GRIDBUG
764 			};
765 
766 	    if (god == GOD_NECRO)
767 		mob = MOB_SKELETON;
768 	    else
769 		mob = targets[rand_choice(3)];
770 
771 	    buf.sprintf("%s: Learn Humility!  ",
772 			 glb_goddefs[god].name);
773 	    msg_announce(buf);
774 
775 	    // And poly the loser into it!
776 	    actionPolymorph(false, true, mob);
777 	    break;
778 	}
779 
780 	case PUNISH_MANADRAIN:
781 	{
782 	    buf.sprintf("%s: Your Magic Will Not Avail You!  ",
783 			    glb_goddefs[god].name);
784 	    msg_announce(buf);
785 
786 	    // drain magic.
787 	    // 50 + 5d10 turns.
788 	    setTimedIntrinsic(0, INTRINSIC_MAGICDRAIN,
789 			   rand_dice(5, 10, 50));
790 	    break;
791 	}
792 
793 	case PUNISH_POLYWEAPON:
794 	{
795 	    ITEM		*weapon;
796 
797 	    weapon = getEquippedItem(ITEMSLOT_RHAND);
798 	    if (!weapon)
799 	    {
800 		// Should not occur?
801 		buf.sprintf("%s: I have caught you empty handed!  Ha!  ",
802 			glb_goddefs[god].name);
803 		msg_announce(buf);
804 		break;
805 	    }
806 
807 	    BUF weapname = weapon->getName();
808 	    buf.sprintf("%s: Your over use of %s bores me!  ",
809 			glb_goddefs[god].name,
810 			weapname.buffer());
811 	    msg_announce(buf);
812 
813 	    // polymorph the weapon...
814 	    ITEM		*newweapon;
815 
816 	    newweapon = weapon->polymorph(this);
817 
818 	    // If the polymorph fails, we don't want to delete
819 	    // their weapon!
820 	    if (!newweapon)
821 	    {
822 		// We haven't yet dropped the old weapon,
823 		// so just break for status quo
824 		break;
825 	    }
826 
827 	    // Some day I will make a less error prone way of writing
828 	    // this.  This is not that day!
829 	    weapon = dropItem(weapon->getX(), weapon->getY());
830 
831 	    // If the weapon has a stack, we split & reacquire.  Otherwise
832 	    // we destroy.
833 	    if (weapon->getStackCount() > 1)
834 	    {
835 		weapon->splitAndDeleteStack();
836 		// Try and reacquire as a non-weapon.
837 		if (!acquireItem(weapon))
838 		{
839 		    // Failed to put in inventory, drop.
840 		    formatAndReport("%U <lack> room for %IU.", weapon);
841 		    glbCurLevel->acquireItem(weapon, getX(), getY(), 0);
842 		}
843 	    }
844 	    else
845 	    {
846 		// Toss the item silently
847 		delete weapon;
848 	    }
849 
850 	    // Re-equip the new item. This could fail.
851 	    // First, we need it in our inventory.
852 	    if (!acquireItem(newweapon, &newweapon))
853 	    {
854 		// Failed to acquire, drop on ground.
855 		formatAndReport("%U <lack> room for %IU.", newweapon);
856 		glbCurLevel->acquireItem(newweapon, getX(), getY(), 0);
857 	    }
858 	    else
859 	    {
860 		// It is now in our inventory.  Try to equip it,
861 		// including failure messages!
862 		actionEquip(newweapon->getX(), newweapon->getY(), ITEMSLOT_RHAND);
863 	    }
864 
865 	    break;
866 	}
867 
868 	case NUM_PUNISHS:
869 	{
870 	    // Confusion!
871 	    buf.sprintf("%s wails in confusion.  ",
872 			glb_goddefs[god].name);
873 	    msg_announce(buf);
874 	    break;
875 	}
876     }
877 }
878 
879 bool
pietyBoonValid(BOON_NAMES boon)880 MOB::pietyBoonValid(BOON_NAMES boon)
881 {
882     ITEM		*item;
883     bool		 haswater = false;
884     bool		 hascursed = false;
885     bool		 hasweapon = false;
886     bool		 hasarmour = false;
887     bool		 hasnonid = false;
888 
889     // Check for items needed.
890     for (item = myInventory; item; item = item->getNext())
891     {
892 	// Check for potential sanctify:
893 	if ( item->getDefinition() == ITEM_WATER &&
894 	    !item->isBlessed())
895 	    haswater = true;
896 
897 	// Check if the item is an unided artifact or unided
898 	// magic type.
899 	if (!item->isIdentified() && item->getMagicType() != MAGICTYPE_NONE)
900 	    hasnonid = true;
901 
902 	if (item->getArtifact() && !item->isFullyIdentified())
903 	    hasnonid = true;
904 
905 	// Check for an uncursing.
906 	if (item->isCursed() && item->getX() == 0)
907 	    hascursed = true;
908 
909 	if (item->getX() == 0 &&
910 	    item->getY() == ITEMSLOT_RHAND)
911 	    hasweapon = true;
912 
913 	if (item->getX() == 0 &&
914 	    (item->getY() == ITEMSLOT_LHAND ||
915 	     item->getY() == ITEMSLOT_HEAD ||
916 	     item->getY() == ITEMSLOT_BODY ||
917 	     item->getY() == ITEMSLOT_FEET))
918 	    hasarmour = true;
919     }
920 
921     switch (boon)
922     {
923 	case BOON_UNCURSE:
924 	    return hascursed;
925 
926 	case BOON_HEAL:
927 	    if (getHP() < getMaxHP() / 3)
928 		return true;
929 	    return false;
930 
931 	case BOON_LICHFORM:
932 	    if (getHP() < getMaxHP() / 4)
933 		return true;
934 	    return false;
935 
936 	case BOON_CURE:
937 	    return aiIsPoisoned();
938 
939 	case BOON_SANCTIFY:
940 	    return haswater;
941 
942 	case BOON_SURROUNDATTACK:
943 	    // Verify you are surrounded by a foe...
944 	    if (calculateFoesSurrounding() > 1)
945 	    {
946 		return true;
947 	    }
948 	    break;
949 
950 	case BOON_UNSTONE:
951 	    // If you are turning to stone, and are not actively resisting
952 	    // turning to stone, then help.
953 	    return hasIntrinsic(INTRINSIC_STONING) &&
954 		    !hasIntrinsic(INTRINSIC_RESISTSTONING) &&
955 		    !hasIntrinsic(INTRINSIC_UNCHANGING);
956 
957 	case BOON_ENCHANT_WEAPON:
958 	    return hasweapon;
959 
960 	case BOON_ENCHANT_ARMOUR:
961 	    return hasarmour;
962 
963 	case BOON_GRANT_SPELL:
964 	    // TODO: Find if we have any holes in our spell schools.
965 	    return true;
966 
967 	// Trivially true boons:
968 	case BOON_GIFT_WEAPON:
969 	case BOON_GIFT_ARMOUR:
970 	case BOON_GIFT_WAND:
971 	case BOON_GIFT_SPELLBOOK:
972 	case BOON_GIFT_STAFF:
973 	    return true;
974 
975 	case BOON_IDENTIFY:
976 	    return hasnonid;
977 
978 	case NUM_BOONS:
979 	    break;
980     }
981 
982     return false;
983 }
984 
985 void
pietyBoon(GOD_NAMES god)986 MOB::pietyBoon(GOD_NAMES god)
987 {
988     BOON_NAMES		valid[NUM_BOONS], boon;
989     int			numvalid = 0;
990     BUF			buf;
991     ITEM		*item;
992     bool		hasrescue = false;
993 
994     // Run through the boons determining if they apply and if they
995     // can be paid for.
996     FOREACH_BOON(boon)
997     {
998 	// See if we can afford the cost.
999 	if (glb_boondefs[boon].points > glbGodPoints[god])
1000 	    continue;
1001 
1002 	// See if this is a valid god.
1003 	if (!strchr(glb_boondefs[boon].god, (char) god))
1004 	    continue;
1005 
1006 	// Check to see if it applies.  Eg, no point curing
1007 	// someone not poisoned.
1008 	if (pietyBoonValid(boon))
1009 	{
1010 	    if (hasrescue && !glb_boondefs[boon].isrescue)
1011 		continue;
1012 
1013 	    if (glb_boondefs[boon].isrescue && !hasrescue)
1014 	    {
1015 		hasrescue = true;
1016 		numvalid = 0;
1017 	    }
1018 	    valid[numvalid++] = boon;
1019 	}
1020     }
1021 
1022     // If no valid boons, quit.
1023     if (!numvalid)
1024 	return;
1025 
1026     boon = valid[rand_choice(numvalid)];
1027 
1028     // Pay the cost.
1029     glbGodPoints[god] -= glb_boondefs[boon].points;
1030 
1031     // Do the boon:
1032     switch (boon)
1033     {
1034 	case BOON_UNCURSE:
1035 	    buf.sprintf("%s: Allow me to aid you.  ",
1036 			    glb_goddefs[god].name);
1037 	    msg_announce(buf);
1038 	    receiveUncurse(false);
1039 	    break;
1040 
1041 	case BOON_HEAL:
1042 	    buf.sprintf("%s: Your flesh shall mend!  ",
1043 			    glb_goddefs[god].name);
1044 	    msg_announce(buf);
1045 	    // Full heal
1046 	    receiveHeal(getMaxHP() - getHP(), 0);
1047 	    break;
1048 
1049 	case BOON_LICHFORM:
1050 	    buf.sprintf("%s: Show your devotion!  ",
1051 			    glb_goddefs[god].name);
1052 	    msg_announce(buf);
1053 	    setTimedIntrinsic(0, INTRINSIC_LICHFORM, 2);
1054 	    break;
1055 
1056 	case BOON_SURROUNDATTACK:
1057 	{
1058 	    buf.sprintf("%s: You've proven your worth!",
1059 			glb_goddefs[god].name);
1060 	    msg_announce(buf);
1061 
1062 	    int		dx, dy;
1063 
1064 	    FORALL_4DIR(dx, dy)
1065 	    {
1066 		MOB		*mob;
1067 
1068 		mob = glbCurLevel->getMob(getX()+dx, getY()+dy);
1069 
1070 		if (mob && mob->getAttitude(this) == ATTITUDE_HOSTILE)
1071 		{
1072 		    mob->receiveAttack(ATTACK_SURROUNDSMITE, 0, 0, 0,
1073 					    ATTACKSTYLE_SPELL);
1074 		}
1075 	    }
1076 	    break;
1077 	}
1078 
1079 	case BOON_CURE:
1080 	    buf.sprintf("%s: Your affliction pains me!  ",
1081 			    glb_goddefs[god].name);
1082 	    msg_announce(buf);
1083 
1084 	    receiveCure();
1085 	    break;
1086 
1087 	case BOON_UNSTONE:
1088 	    buf.sprintf("%s: I wish no more statues.  ",
1089 			    glb_goddefs[god].name);
1090 	    msg_announce(buf);
1091 
1092 	    clearIntrinsic(INTRINSIC_STONING);
1093 	    setTimedIntrinsic(0, INTRINSIC_RESISTSTONING, 10);
1094 	    break;
1095 
1096 	case BOON_SANCTIFY:
1097 	{
1098 	    buf.sprintf("%s: Your water is blessed!  ",
1099 			    glb_goddefs[god].name);
1100 	    msg_announce(buf);
1101 
1102 	    for (item = myInventory; item; item = item->getNext())
1103 	    {
1104 		if (item->getDefinition() == ITEM_WATER)
1105 		{
1106 		    // Twice to ensure we end up at blessed status.
1107 		    item->makeBlessed();
1108 		    item->makeBlessed();
1109 		    // It is rather obvious that the water must now be
1110 		    // holy water.
1111 		    item->markCursedKnown();
1112 		}
1113 	    }
1114 
1115 	    break;
1116 	}
1117 
1118 	case BOON_ENCHANT_WEAPON:
1119 	{
1120 	    buf.sprintf("%s: You are my weapon: Cut Deeply!  ",
1121 		    glb_goddefs[god].name);
1122 	    msg_announce(buf);
1123 
1124 	    receiveWeaponEnchant(1, false);
1125 	    break;
1126 	}
1127 
1128 	case BOON_ENCHANT_ARMOUR:
1129 	{
1130 	    buf.sprintf("%s: Accept my protection.  ",
1131 		    glb_goddefs[god].name);
1132 	    msg_announce(buf);
1133 
1134 	    receiveArmourEnchant((ITEMSLOT_NAMES) -1, 1, false);
1135 	    break;
1136 	}
1137 
1138 	case BOON_GRANT_SPELL:
1139 	{
1140 	    buf.sprintf("%s: Knowledge is Power!  ",
1141 			glb_goddefs[god].name);
1142 	    msg_announce(buf);
1143 
1144 	    // Random spell..
1145 	    SPELL_NAMES			spell;
1146 
1147 	    spell = findSpell(god);
1148 
1149 	    if (spell == SPELL_NONE)
1150 	    {
1151 		// You are so cool you already know all
1152 		// the spells you can!  Deity is suitably impressed.
1153 		msg_announce("You already have knowledge.  Now gain power!  ");
1154 
1155 		// Maximize MP.
1156 		if (getMP() < getMaxMP())
1157 		{
1158 		    formatAndReport("%U <be> energized.");
1159 		    myMP = getMaxMP();
1160 		}
1161 
1162 		// Bonus XP.
1163 		formatAndReport("%U <gain> experience.");
1164 		receiveExp(100);
1165 	    }
1166 	    else
1167 		learnSpell(spell);
1168 	    break;
1169 	}
1170 
1171 	case BOON_GIFT_WEAPON:
1172 	case BOON_GIFT_ARMOUR:
1173 	case BOON_GIFT_WAND:
1174 	case BOON_GIFT_SPELLBOOK:
1175 	case BOON_GIFT_STAFF:
1176 	{
1177 	    buf.sprintf("%s: Use my gift wisely.  ",
1178 			glb_goddefs[god].name);
1179 	    msg_announce(buf);
1180 
1181 	    ITEM		*gift;
1182 
1183 	    gift = ITEM::createRandomType((ITEMTYPE_NAMES)
1184 					    glb_boondefs[boon].gifttype);
1185 
1186 	    // Ensure it is blessed and a +3 enchant.
1187 	    gift->makeBlessed();
1188 	    gift->makeBlessed();
1189 
1190 	    gift->enchant(3 - gift->getEnchantment());
1191 
1192 	    // Drop at feet:
1193 	    buf = formatToString("%IU <I:appear> by %R %B1.",
1194 		    this, 0, 0, gift,
1195 		    getSlotName(ITEMSLOT_FEET) ?
1196 			    getSlotName(ITEMSLOT_FEET) :
1197 			    "shadow");
1198 	    reportMessage(buf);
1199 
1200 	    glbCurLevel->acquireItem(gift, getX(), getY(), 0);
1201 	    break;
1202 	}
1203 
1204 	case BOON_IDENTIFY:
1205 	{
1206 	    ITEMSTACK		 stack;
1207 	    ITEM		*item;
1208 
1209 	    buf.sprintf("%s: Know Your Tools!  ",
1210 			glb_goddefs[god].name);
1211 	    msg_announce(buf);
1212 
1213 	    for (item = myInventory; item; item = item->getNext())
1214 	    {
1215 		if (!item->isIdentified() && item->getMagicType() != MAGICTYPE_NONE)
1216 		    stack.append(item);
1217 		else if (item->getArtifact() && !item->isFullyIdentified())
1218 		    stack.append(item);
1219 	    }
1220 
1221 	    UT_ASSERT(stack.entries());
1222 	    if (!stack.entries())
1223 		break;
1224 
1225 	    item = stack(rand_choice(stack.entries()));
1226 
1227 	    if (isAvatar())
1228 		item->markIdentified();
1229 
1230 	    formatAndReport("%U <gain> insight into the nature of %IU.", item);
1231 	    break;
1232 	}
1233 
1234 	case NUM_BOONS:
1235 	    // Should not occur.
1236 	    break;
1237     }
1238 }
1239 
1240 void
pietyAnnounceWhimOfXom()1241 MOB::pietyAnnounceWhimOfXom()
1242 {
1243     // If you worship ><0|V|, you get a clue as to his new preference.
1244     if (glbChosenGod == GOD_CULTIST)
1245     {
1246 	msg_announce(glb_goddefs[glbWhimOfXOM].whimofxom);
1247     }
1248 }
1249 
1250 void
pietyRungods()1251 MOB::pietyRungods()
1252 {
1253     GOD_NAMES		god;
1254 
1255     // Only run the god code on the avatar.
1256     if (!isAvatar())
1257 	return;
1258 
1259     // Update ><0|V|s whim.
1260     if (rand_chance(80))
1261 	glbWhimOfXOMTimer--;
1262 
1263     if (!glbWhimOfXOMTimer)
1264     {
1265 	glbWhimOfXOMTimer = rand_range(100, 200);
1266 	glbWhimOfXOM = piety_randomnonxomgod();
1267 
1268 	pietyAnnounceWhimOfXom();
1269     }
1270 
1271     // If we are worshipping no one god, we get no benefits or punishments.
1272     if (glbChosenGod == GOD_AGNOSTIC)
1273     {
1274 	return;
1275     }
1276 
1277     if (glbFlameStrikeTimer)
1278     {
1279 	glbFlameStrikeTimer--;
1280 
1281 	if (!glbFlameStrikeTimer)
1282 	{
1283 	    BUF		buf;
1284 
1285 	    buf.sprintf("%s: Suffer my Wrath!  ",
1286 			glb_goddefs[glbFlameGod].name);
1287 	    msg_announce(buf);
1288 
1289 	    // Peform flamestrike.
1290 	    // TODO: Have MOBs for placeholders for the gods.
1291 	    receiveAttack(ATTACK_FLAMESTRIKE, 0, 0, 0,
1292 				    ATTACKSTYLE_SPELL);
1293 	    return;
1294 	}
1295     }
1296 
1297     FOREACH_GOD(god)
1298     {
1299 	// Fickle gods do not always act.
1300 	// this is broken and should be continue, not return, or we bias
1301 	// against later gods.
1302 	if (!rand_choice(10))
1303 	    return;
1304 	if (glbGodPoints[god] > 100)
1305 	{
1306 	    // Consider granting a boon.
1307 	    // TODO: Track number of levels gained and bias
1308 	    // accordingly.
1309 	    if (god == glbChosenGod || !rand_choice(50))
1310 	    {
1311 		if (glbPiety[god] > 0)
1312 		    pietyBoon((GOD_NAMES) god);
1313 		else
1314 		    pietyPunish((GOD_NAMES) god);
1315 
1316 		// Do not test anything else in case we died
1317 		return;
1318 	    }
1319 	}
1320     }
1321 }
1322 
1323 void
pietyGainLevel()1324 MOB::pietyGainLevel()
1325 {
1326     GOD_NAMES		 godlist[NUM_GODS], god;
1327     int			 numvalid = 0, i, choice, y;
1328     int			 aorb = 0;
1329     MOB			*base;
1330     SPELL_NAMES		 spell = (SPELL_NAMES) -1;
1331     BUF			 buf;
1332     SKILL_NAMES		 skill = SKILL_NONE;
1333     int			 newpts;
1334 
1335     base = myBaseType.getMob();
1336 
1337     const char *gainmsg[] =
1338     {
1339 	"You have gained a level!  ",
1340 	"Welcome to the next level.  ",
1341 	"Level Up!  ",
1342 	"You learn from experience.  ",
1343 	"Another kill, Another level.  "
1344     };
1345     // This message announce helps avoid accidental button presses.
1346     msg_announce(gainmsg[rand_choice(5)]);
1347 
1348     // Report current god...
1349     BUF		curgod;
1350     curgod.sprintf("You currently worship %s.  ", glb_goddefs[glbChosenGod].name);
1351     msg_report(curgod);
1352 
1353     FOREACH_GOD(god)
1354     {
1355 	// Is this a valid god?  Agnostic is always valid.
1356 	if (god == GOD_AGNOSTIC ||
1357 	    glbPiety[god] >= 10)
1358 	{
1359 	    godlist[numvalid++] = god;
1360 	}
1361     }
1362 
1363     // Ask the user to pick a level.
1364     char		**menu;
1365 
1366     menu = new char *[numvalid+2];
1367     // First choice is a sentinel to insure rapid clickers don't get
1368     // get the wrong choice.
1369     menu[0] = "Select a god";
1370     for (i = 0; i < numvalid; i++)
1371     {
1372 	if (godlist[i] != GOD_AGNOSTIC)
1373 	{
1374 	    // Give some detailed info about the god.
1375 	    // I think providing both numbers is a bit confusing, so
1376 	    // we'll stick with the Piety
1377 	    menu[i+1] = new char [30];
1378 	    sprintf(menu[i+1], "%-11s (%d)",
1379 		    glb_goddefs[godlist[i]].classname,
1380 		    glbPiety[godlist[i]]);
1381 	}
1382 	else
1383 	    menu[i+1] = (char *) glb_goddefs[godlist[i]].classname;
1384     }
1385     menu[numvalid+1] = 0;
1386 
1387     while (1)
1388     {
1389 	choice = gfx_selectmenu(30 - 20, 3, (const char **)menu, aorb);
1390 	for (y = 3; y < 19; y++)
1391 	    gfx_cleartextline(y);
1392 
1393 	if (hamfake_forceQuit())
1394 	{
1395 	    // We sadly have to force-pick a god to be able
1396 	    // to save successfully.  Adventurer is likely the safest.
1397 	    god = GOD_AGNOSTIC;
1398 	    break;
1399 	}
1400 
1401 	// Valid choices,,,,
1402 	if (choice >= 1 && !aorb)
1403 	{
1404 	    BUF		godchoice;
1405 
1406 	    // Fix off by one due to sentinel
1407 	    choice--;
1408 
1409 	    // User chose godlist[choice].
1410 	    god = godlist[choice];
1411 
1412 	    // Inform the user of their future decision.
1413 	    // Display the info text.
1414 	    encyc_viewentry("GOD", god);
1415 
1416 	    godchoice.sprintf("Follow %s?", glb_goddefs[god].name);
1417 
1418 	    // Verify user is serious.
1419 	    if (gfx_yesnomenu(godchoice))
1420 		break;
1421 	}
1422     }
1423 
1424     // Wipe out our menu.
1425     for (i = 0; i < numvalid; i++)
1426     {
1427 	if (godlist[i] != GOD_AGNOSTIC)
1428 	{
1429 	    delete [] menu[i+1];
1430 	}
1431     }
1432     delete [] menu;
1433 
1434     glbChosenGod = god;
1435 
1436     formatAndReport("%U <worship> %B1.",
1437 		glb_goddefs[god].name);
1438 
1439     // Add an exp level.
1440     myExpLevel++;
1441 
1442     // Add our health & magic.
1443     myHitDie += glb_goddefs[god].physical;
1444 
1445     // 3-5 points per level with a bias to 4.  Considered having it
1446     // controled by piety but that just forces people away from
1447     // experimentation.
1448     // 2d2+1
1449     newpts = rand_dice(glb_goddefs[god].physical*2, 2, glb_goddefs[god].physical);
1450     incrementMaxHP(newpts);
1451 
1452     if (base)
1453     {
1454 	base->myHitDie += glb_goddefs[god].physical;
1455     }
1456 
1457     myMagicDie += glb_goddefs[god].mental;
1458     newpts = rand_dice(glb_goddefs[god].mental*2, 2, glb_goddefs[god].mental);
1459     incrementMaxMP(newpts);
1460 
1461     if (base)
1462     {
1463 	base->myMagicDie += glb_goddefs[god].mental;
1464     }
1465 
1466     int		numskill = 0, numspell = 0;
1467 
1468     skill = findSkill(god, &numskill);
1469     spell = findSpell(god, &numspell);
1470 
1471     // You only get one of skill or spell, never both.
1472     // We bias according to the number of valid choices.
1473     if (spell != SPELL_NONE && skill != SKILL_NONE)
1474     {
1475 	if (rand_choice(numspell + numskill) < numskill)
1476 	    spell = SPELL_NONE;
1477 	else
1478 	    skill = SKILL_NONE;
1479     }
1480 
1481     // Special cases for gods...
1482     switch (god)
1483     {
1484 	case GOD_CULTIST:
1485 	{
1486 	    // Gain random hit & magic dice.
1487 	    int		phys, ment;
1488 
1489 	    phys = rand_choice(5);
1490 	    ment = rand_choice(5);
1491 	    myHitDie += phys;
1492 	    myMagicDie += ment;
1493 	    if (base)
1494 	    {
1495 		base->myHitDie += phys;
1496 		base->myMagicDie += ment;
1497 	    }
1498 
1499 	    phys = rand_choice(phys * 10);
1500 	    ment = rand_choice(ment * 10);
1501 
1502 	    incrementMaxHP(phys);
1503 	    incrementMaxMP(ment);
1504 	    break;
1505 	}
1506 
1507 	case GOD_WIZARD:
1508 	{
1509 	    break;
1510 	}
1511 
1512 	case GOD_CLERIC:
1513 	{
1514 	    break;
1515 	}
1516 
1517 	case GOD_NECRO:
1518 	{
1519 	    break;
1520 	}
1521 
1522 	case GOD_AGNOSTIC:
1523 	{
1524 	    // Do nothing!
1525 	    break;
1526 	}
1527 
1528 	case GOD_FIGHTER:
1529 	{
1530 	    break;
1531 	}
1532 
1533 	case GOD_ROGUE:
1534 	{
1535 	    break;
1536 	}
1537 
1538 	case GOD_BARB:
1539 	{
1540 	    break;
1541 	}
1542 
1543 	case NUM_GODS:
1544 	{
1545 	    break;
1546 	}
1547     }
1548 
1549     learnSpell(spell);
1550     learnSkill(skill);
1551 
1552     // Report number of free slots
1553     buf.sprintf("You have %d free spell and %d free skill slots.",
1554 		    getFreeSpellSlots(),
1555 		    getFreeSkillSlots());
1556     reportMessage(buf);
1557 
1558     // If you just started following Xom, pretty important.
1559     pietyAnnounceWhimOfXom();
1560 }
1561 
1562 void
pietyReport()1563 MOB::pietyReport()
1564 {
1565     char		*menu[NUM_GODS + 1];
1566     int			 dressiness[NUM_GODS];
1567 
1568     int			 i, aorb;
1569     GOD_NAMES		 god;
1570 
1571     determineClassiness(dressiness);
1572 
1573     FOREACH_GOD(god)
1574     {
1575 	menu[god] = new char[30];
1576 
1577 	sprintf(menu[god], "%10s: %d (%d)",
1578 		glb_goddefs[god].name,
1579 		glbPiety[god],
1580 		glbGodPoints[god]);
1581 	if (dressiness[god])
1582 	{
1583 	    // Pad out a tad
1584 	    strcat(menu[god], " ");
1585 	}
1586 	for (int i = 2; i <= dressiness[god]; i+=2)
1587 	    strcat(menu[god], "*");
1588 	if (dressiness[god] & 1)
1589 	    strcat(menu[god], "+");
1590     }
1591     menu[NUM_GODS] = 0;
1592 
1593     {
1594 	BUF		buf;
1595 	buf.sprintf("Now Worshipping: %s", glb_goddefs[glbChosenGod].name);
1596 	gfx_printtext(2, 4, buf.buffer());
1597     }
1598 
1599     gfx_selectmenu(5, 6, (const char **) menu, aorb, glbChosenGod);
1600 
1601     // And clear it...
1602     for (i = 3; i < 18; i++)
1603     {
1604 	gfx_cleartextline(i);
1605     }
1606 
1607     for (i = 0; i < NUM_GODS; i++)
1608 	delete [] menu[i];
1609 }
1610