1 | /* SCCS Id: @(#)pray.c 3.3 2000/06/29 */
2 | /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
3 | /* NetHack may be freely redistributed. See license for details. */
4 |
5 | #include "hack.h"
6 | #include "epri.h"
7 |
8 | STATIC_PTR int NDECL(prayer_done);
9 | STATIC_DCL int NDECL(in_trouble);
10 | STATIC_DCL void FDECL(fix_worst_trouble,(int));
11 | STATIC_DCL void FDECL(angrygods,(ALIGNTYP_P));
12 | STATIC_DCL void FDECL(pleased,(ALIGNTYP_P));
13 | STATIC_DCL void FDECL(godvoice,(ALIGNTYP_P,const char*));
14 | STATIC_DCL void FDECL(god_zaps_you,(ALIGNTYP_P));
15 | STATIC_DCL void FDECL(fry_by_god,(ALIGNTYP_P));
16 | STATIC_DCL void FDECL(gods_angry,(ALIGNTYP_P));
17 | STATIC_DCL void FDECL(gods_upset,(ALIGNTYP_P));
18 | STATIC_DCL void FDECL(consume_offering,(struct obj *));
19 | STATIC_DCL boolean FDECL(water_prayer,(BOOLEAN_P));
20 | STATIC_DCL boolean FDECL(blocked_boulder,(int,int));
21 |
22 | /*
23 | * Logic behind deities and altars and such:
24 | * + prayers are made to your god if not on an altar, and to the altar's god
25 | * if you are on an altar
26 | * + If possible, your god answers all prayers, which is why bad things happen
27 | * if you try to pray on another god's altar
28 | * + sacrifices work basically the same way, but the other god may decide to
29 | * accept your allegiance, after which they are your god. If rejected,
30 | * your god takes over with your punishment.
31 | * + if you're in Gehennom, all messages come from Moloch
32 | */
33 |
34 | /*
35 | * Moloch, who dwells in Gehennom, is the "renegade" cruel god
36 | * responsible for the theft of the Amulet from Marduk, the Creator.
37 | * Moloch is unaligned.
38 | */
39 | static const char *Moloch = "Moloch";
40 |
41 | static const char *godvoices[] = {
42 | "booms out",
43 | "thunders",
44 | "rings out",
45 | "booms",
46 | };
47 |
48 | /* values calculated when prayer starts, and used when completed */
49 | static aligntyp p_aligntyp;
50 | static int p_trouble;
51 | static int p_type; /* (-1)-3: (-1)=really naughty, 3=really good */
52 |
53 | #define PIOUS 20
54 | #define DEVOUT 14
55 | #define FERVENT 9
56 | #define STRIDENT 4
57 |
58 | #define TROUBLE_STONED 12
59 | #define TROUBLE_SLIMED 11
60 | #define TROUBLE_STRANGLED 10
61 | #define TROUBLE_LAVA 9
62 | #define TROUBLE_SICK 8
63 | #define TROUBLE_STARVING 7
64 | #define TROUBLE_HIT 6
65 | #define TROUBLE_LYCANTHROPE 5
66 | #define TROUBLE_COLLAPSING 4
67 | #define TROUBLE_STUCK_IN_WALL 3
68 | #define TROUBLE_CURSED_BLINDFOLD 2
69 | #define TROUBLE_CURSED_LEVITATION 1
70 |
71 | #define TROUBLE_PUNISHED (-1)
72 | #define TROUBLE_CURSED_ITEMS (-2)
73 | #define TROUBLE_BLIND (-3)
74 | #define TROUBLE_POISONED (-4)
75 | #define TROUBLE_WOUNDED_LEGS (-5)
76 | #define TROUBLE_HUNGRY (-6)
77 | #define TROUBLE_STUNNED (-7)
78 | #define TROUBLE_CONFUSED (-8)
79 | #define TROUBLE_HALLUCINATION (-9)
80 |
81 | /* We could force rehumanize of polyselfed people, but we can't tell
82 | unintentional shape changes from the other kind. Oh well. */
83 |
84 | /* Return 0 if nothing particular seems wrong, positive numbers for
85 | serious trouble, and negative numbers for comparative annoyances. This
86 | returns the worst problem. There may be others, and the gods may fix
87 | more than one.
88 |
89 | This could get as bizarre as noting surrounding opponents, (or hostile dogs),
90 | but that's really hard.
91 | */
92 |
93 | #define ugod_is_angry() (u.ualign.record < 0)
94 | #define on_altar() IS_ALTAR(levl[u.ux][u.uy].typ)
95 | #define on_shrine() ((levl[u.ux][u.uy].altarmask & AM_SHRINE) != 0)
96 | #define a_align(x,y) ((aligntyp)Amask2align(levl[x][y].altarmask & AM_MASK))
97 |
98 | STATIC_OVL int
99 | in_trouble()
100 | {
101 | register struct obj *otmp;
102 | int i, j, count=0;
103 |
104 | /* Borrowed from eat.c */
105 |
106 | #define SATIATED 0
107 | #define NOT_HUNGRY 1
108 | #define HUNGRY 2
109 | #define WEAK 3
110 | #define FAINTING 4
111 | #define FAINTED 5
112 | #define STARVED 6
113 |
114 | if(Stoned) return(TROUBLE_STONED);
115 | if(Slimed) return(TROUBLE_SLIMED);
116 | if(Strangled) return(TROUBLE_STRANGLED);
117 | if(u.utrap && u.utraptype == TT_LAVA) return(TROUBLE_LAVA);
118 | if(Sick) return(TROUBLE_SICK);
119 | if(u.uhs >= WEAK) return(TROUBLE_STARVING);
120 | if (Upolyd ? (u.mh <= 5 || u.mh*7 <= u.mhmax) :
121 | (u.uhp <= 5 || u.uhp*7 <= u.uhpmax)) return TROUBLE_HIT;
122 | if(u.ulycn >= LOW_PM) return(TROUBLE_LYCANTHROPE);
123 | if(near_capacity() >= EXT_ENCUMBER && AMAX(A_STR)-ABASE(A_STR) > 3)
124 | return(TROUBLE_COLLAPSING);
125 |
126 | for (i= -1; i<=1; i++) for(j= -1; j<=1; j++) {
127 | if (!i && !j) continue;
128 | if (!isok(u.ux+i, u.uy+j) || IS_ROCK(levl[u.ux+i][u.uy+j].typ)
129 | || (blocked_boulder(i,j) && !throws_rocks(youmonst.data)))
130 | count++;
131 | }
132 | if (count == 8 && !Passes_walls)
133 | return(TROUBLE_STUCK_IN_WALL);
134 |
135 | if((uarmf && uarmf->otyp==LEVITATION_BOOTS && uarmf->cursed) ||
136 | (uleft && uleft->otyp==RIN_LEVITATION && uleft->cursed) ||
137 | (uright && uright->otyp==RIN_LEVITATION && uright->cursed))
138 | return(TROUBLE_CURSED_LEVITATION);
139 | if(Blindfolded && ublindf->cursed) return(TROUBLE_CURSED_BLINDFOLD);
140 |
141 | if(Punished) return(TROUBLE_PUNISHED);
142 | for(otmp=invent; otmp; otmp=otmp->nobj)
143 | if((otmp->otyp==LOADSTONE || otmp->otyp==LUCKSTONE) &&
144 | otmp->cursed)
145 | return(TROUBLE_CURSED_ITEMS);
146 | if((uarmh && uarmh->cursed) || /* helmet */
147 | (uarms && uarms->cursed) || /* shield */
148 | (uarmg && uarmg->cursed) || /* gloves */
149 | (uarm && uarm->cursed) || /* armor */
150 | (uarmc && uarmc->cursed) || /* cloak */
151 | (uarmf && uarmf->cursed && uarmf->otyp != LEVITATION_BOOTS) ||
152 | /* boots */
153 | (ublindf && ublindf->otyp == LENSES && ublindf->cursed) ||
154 | /* lenses: blindfold is TROUBLE_CURSED_BLINDFOLD */
155 | #ifdef TOURIST
156 | (uarmu && uarmu->cursed) || /* shirt */
157 | #endif
158 | (welded(uwep)) ||
159 | (uleft && uleft->cursed && uleft->otyp != RIN_LEVITATION) ||
160 | (uright && uright->cursed && uright->otyp != RIN_LEVITATION) ||
161 | (uamul && uamul->cursed))
162 | return(TROUBLE_CURSED_ITEMS);
163 |
164 | if(Blinded > 1) return(TROUBLE_BLIND);
165 | for(i=0; i<A_MAX; i++)
166 | if(ABASE(i) < AMAX(i)) return(TROUBLE_POISONED);
167 | if(Wounded_legs) return (TROUBLE_WOUNDED_LEGS);
168 | if(u.uhs >= HUNGRY) return(TROUBLE_HUNGRY);
169 | if(HStun) return (TROUBLE_STUNNED);
170 | if(HConfusion) return (TROUBLE_CONFUSED);
171 | if(Hallucination) return(TROUBLE_HALLUCINATION);
172 |
173 | return(0);
174 | }
175 |
176 | const char leftglow[] = "left ring softly glows";
177 | const char rightglow[] = "right ring softly glows";
178 |
179 | STATIC_OVL void
180 | fix_worst_trouble(trouble)
181 | register int trouble;
182 | {
183 | int i;
184 | struct obj *otmp;
185 | const char *what = (const char *)0;
186 |
187 | switch (trouble) {
188 | case TROUBLE_STONED:
189 | You_feel("more limber.");
190 | Stoned = 0;
191 | delayed_killer = 0;
192 | break;
193 | case TROUBLE_SLIMED:
194 | pline_The("slime disappears.");
195 | Slimed = 0;
196 | delayed_killer = 0;
197 | break;
198 | case TROUBLE_STRANGLED:
199 | if (uamul && uamul->otyp == AMULET_OF_STRANGULATION) {
200 | Your("amulet vanishes!");
201 | useup(uamul);
202 | }
203 | You("can breathe again.");
204 | Strangled = 0;
205 | break;
206 | case TROUBLE_LAVA:
207 | You("are back on solid ground.");
208 | /* teleport should always succeed, but if not,
209 | * just untrap them.
210 | */
211 | if(!safe_teleds())
212 | u.utrap = 0;
213 | break;
214 | case TROUBLE_STARVING:
215 | losestr(-1);
216 | /* fall into... */
217 | case TROUBLE_HUNGRY:
218 | Your("stomach feels content.");
219 | init_uhunger();
220 | flags.botl = 1;
221 | break;
222 | case TROUBLE_SICK:
223 | You_feel("better.");
224 | make_sick(0L, (char *) 0, FALSE, SICK_ALL);
225 | break;
226 | case TROUBLE_HIT:
227 | /* "fix all troubles" will keep trying if hero has
228 | 5 or less hit points, so make sure they're always
229 | boosted to be more than that */
230 | You_feel("much better.");
231 | if (Upolyd) {
232 | u.mhmax += rnd(5);
233 | if (u.mhmax <= 5) u.mhmax = 5+1;
234 | u.mh = u.mhmax;
235 | }
236 | if (u.uhpmax < u.ulevel * 5 + 11) u.uhpmax += rnd(5);
237 | if (u.uhpmax <= 5) u.uhpmax = 5+1;
238 | u.uhp = u.uhpmax;
239 | flags.botl = 1;
240 | break;
241 | case TROUBLE_COLLAPSING:
242 | ABASE(A_STR) = AMAX(A_STR);
243 | flags.botl = 1;
244 | break;
245 | case TROUBLE_STUCK_IN_WALL:
246 | Your("surroundings change.");
247 | /* no control, but works on no-teleport levels */
248 | (void) safe_teleds();
249 | break;
250 | case TROUBLE_CURSED_LEVITATION:
251 | if (uarmf && uarmf->otyp==LEVITATION_BOOTS
252 | && uarmf->cursed)
253 | otmp = uarmf;
254 | else if (uleft && uleft->otyp==RIN_LEVITATION
255 | && uleft->cursed) {
256 | otmp = uleft;
257 | what = leftglow;
258 | } else {
259 | otmp = uright;
260 | what = rightglow;
261 | }
262 | goto decurse;
263 | case TROUBLE_CURSED_BLINDFOLD:
264 | otmp = ublindf;
265 | goto decurse;
266 | case TROUBLE_LYCANTHROPE:
267 | you_unwere(TRUE);
268 | break;
269 | case TROUBLE_PUNISHED:
270 | Your("chain disappears.");
271 | unpunish();
272 | break;
273 | case TROUBLE_CURSED_ITEMS:
274 | /* weapon takes precedence if it interferes
275 | with taking off a ring or shield */
276 | if (welded(uwep) && /* weapon */
277 | (uright || (bimanual(uwep) && (uleft || uarms))))
278 | otmp = uwep;
279 | /* gloves come next, due to rings */
280 | else if (uarmg && uarmg->cursed) /* gloves */
281 | otmp = uarmg;
282 | /* then shield due to two handed weapons and spells */
283 | else if (uarms && uarms->cursed) /* shield */
284 | otmp = uarms;
285 | /* then cloak due to body armor */
286 | else if (uarmc && uarmc->cursed) /* cloak */
287 | otmp = uarmc;
288 | else if (uarm && uarm->cursed) /* armor */
289 | otmp = uarm;
290 | else if (uarmh && uarmh->cursed) /* helmet */
291 | otmp = uarmh;
292 | else if (uarmf && uarmf->cursed) /* boots */
293 | otmp = uarmf;
294 | #ifdef TOURIST
295 | else if (uarmu && uarmu->cursed) /* shirt */
296 | otmp = uarmu;
297 | #endif
298 | /* (perhaps amulet should take precedence over rings?) */
299 | else if (uleft && uleft->cursed) {
300 | otmp = uleft;
301 | what = leftglow;
302 | } else if (uright && uright->cursed) {
303 | otmp = uright;
304 | what = rightglow;
305 | } else if (uamul && uamul->cursed) /* amulet */
306 | otmp = uamul;
307 | else if (ublindf && ublindf->cursed) /* eyewear */
308 | otmp = ublindf; /* must be non-blinding lenses */
309 | /* if weapon wasn't handled above, do it now */
310 | else if (welded(uwep)) /* weapon */
311 | otmp = uwep;
312 | else {
313 | for(otmp=invent; otmp; otmp=otmp->nobj)
314 | if ((otmp->otyp==LOADSTONE ||
315 | otmp->otyp==LUCKSTONE) && otmp->cursed)
316 | break;
317 | }
318 | decurse:
319 | if (!otmp) {
320 | impossible("fix_worst_trouble: nothing to uncurse.");
321 | return;
322 | }
323 | uncurse(otmp);
324 | otmp->bknown = TRUE;
325 | if (!Blind)
326 | Your("%s %s.",
327 | what ? what :
328 | (const char *)aobjnam (otmp, "softly glow"),
329 | hcolor(amber));
330 | break;
331 | case TROUBLE_POISONED:
332 | if (Hallucination)
333 | pline("There's a tiger in your tank.");
334 | else
335 | You_feel("in good health again.");
336 | for(i=0; i<A_MAX; i++) {
337 | if(ABASE(i) < AMAX(i)) {
338 | ABASE(i) = AMAX(i);
339 | flags.botl = 1;
340 | }
341 | }
342 | (void) encumber_msg();
343 | break;
344 | case TROUBLE_BLIND:
345 | Your("%s feel better.", makeplural(body_part(EYE)));
346 | make_blinded(0L,FALSE);
347 | break;
348 | case TROUBLE_WOUNDED_LEGS:
349 | heal_legs();
350 | break;
351 | case TROUBLE_STUNNED:
352 | make_stunned(0L,TRUE);
353 | break;
354 | case TROUBLE_CONFUSED:
355 | make_confused(0L,TRUE);
356 | break;
357 | case TROUBLE_HALLUCINATION:
358 | pline ("Looks like you are back in Kansas.");
359 | make_hallucinated(0L,FALSE,0L);
360 | break;
361 | }
362 | }
363 |
364 | /* "I am sometimes shocked by... the nuns who never take a bath without
365 | * wearing a bathrobe all the time. When asked why, since no man can see them,
366 | * they reply 'Oh, but you forget the good God'. Apparently they conceive of
367 | * the Deity as a Peeping Tom, whose omnipotence enables Him to see through
368 | * bathroom walls, but who is foiled by bathrobes." --Bertrand Russell, 1943
369 | * Divine wrath, dungeon walls, and armor follow the same principle.
370 | */
371 | STATIC_OVL void
372 | god_zaps_you(resp_god)
373 | aligntyp resp_god;
374 | {
375 | if (u.uswallow) {
376 | pline("Suddenly a bolt of lightning comes down at you from the heavens!");
377 | pline("It strikes %s!", mon_nam(u.ustuck));
378 | if (!resists_elec(u.ustuck)) {
379 | pline("%s fries to a crisp!", Monnam(u.ustuck));
380 | /* Yup, you get experience. It takes guts to successfully
381 | * pull off this trick on your god, anyway.
382 | */
383 | xkilled(u.ustuck, 0);
384 | } else
385 | pline("%s seems unaffected.", Monnam(u.ustuck));
386 | } else {
387 | pline("Suddenly, a bolt of lightning strikes you!");
388 | if (Reflecting) {
389 | shieldeff(u.ux, u.uy);
390 | if (Blind)
391 | pline("For some reason you're unaffected.");
392 | else
393 | (void) ureflects("%s reflects from your %s.", "It");
394 | } else if (Shock_resistance) {
395 | shieldeff(u.ux, u.uy);
396 | pline("It seems not to affect you.");
397 | } else
398 | fry_by_god(resp_god);
399 | }
400 |
401 | pline("%s is not deterred...", align_gname(resp_god));
402 | if (u.uswallow) {
403 | pline("A wide-angle disintegration beam aimed at you hits %s!",
404 | mon_nam(u.ustuck));
405 | if (!resists_disint(u.ustuck)) {
406 | pline("%s fries to a crisp!", Monnam(u.ustuck));
407 | xkilled(u.ustuck, 2); /* no corpse */
408 | } else
409 | pline("%s seems unaffected.", Monnam(u.ustuck));
410 | } else {
411 | pline("A wide-angle disintegration beam hits you!");
412 |
413 | /* disintegrate shield and body armor before disintegrating
414 | * the impudent mortal, like black dragon breath -3.
415 | */
416 | if (uarms && !(EReflecting & W_ARMS) &&
417 | !(EDisint_resistance & W_ARMS))
418 | (void) destroy_arm(uarms);
419 | if (uarmc && !(EReflecting & W_ARMC) &&
420 | !(EDisint_resistance & W_ARMC))
421 | (void) destroy_arm(uarmc);
422 | if (uarm && !(EReflecting & W_ARM) &&
423 | !(EDisint_resistance & W_ARM) && !uarmc)
424 | (void) destroy_arm(uarm);
425 | #ifdef TOURIST
426 | if (uarmu && !uarm && !uarmc) (void) destroy_arm(uarmu);
427 | #endif
428 | if (!Disint_resistance)
429 | fry_by_god(resp_god);
430 | else {
431 | You("bask in its %s glow for a minute...", Black);
432 | godvoice(resp_god, "I believe it not!");
433 | }
434 | if (Is_astralevel(&u.uz) || Is_sanctum(&u.uz)) {
435 | /* one more try for high altars */
436 | verbalize("Thou cannot escape my wrath, mortal!");
437 | summon_minion(resp_god, FALSE);
438 | summon_minion(resp_god, FALSE);
439 | summon_minion(resp_god, FALSE);
440 | verbalize("Destroy %s, my servants!", him[flags.female]);
441 | }
442 | }
443 | }
444 |
445 | STATIC_OVL void
446 | fry_by_god(resp_god)
447 | aligntyp resp_god;
448 | {
449 | char killerbuf[64];
450 |
451 | You("fry to a crisp.");
452 | killer_format = KILLED_BY;
453 | Sprintf(killerbuf, "the wrath of %s", align_gname(resp_god));
454 | killer = killerbuf;
455 | done(DIED);
456 | }
457 |
458 | STATIC_OVL void
459 | angrygods(resp_god)
460 | aligntyp resp_god;
461 | {
462 | register int maxanger;
463 |
464 | if(Inhell) resp_god = A_NONE;
465 | u.ublessed = 0;
466 |
467 | /* changed from tmp = u.ugangr + abs (u.uluck) -- rph */
468 | /* added test for alignment diff -dlc */
469 | if(resp_god != u.ualign.type)
470 | maxanger = u.ualign.record/2 + (Luck > 0 ? -Luck/3 : -Luck);
471 | else
472 | maxanger = 3*u.ugangr +
473 | ((Luck > 0 || u.ualign.record >= STRIDENT) ? -Luck/3 : -Luck);
474 | if (maxanger < 1) maxanger = 1; /* possible if bad align & good luck */
475 | else if (maxanger > 15) maxanger = 15; /* be reasonable */
476 |
477 | switch (rn2(maxanger)) {
478 | case 0:
479 | case 1: You_feel("that %s is %s.", align_gname(resp_god),
480 | Hallucination ? "bummed" : "displeased");
481 | break;
482 | case 2:
483 | case 3:
484 | godvoice(resp_god,(char *)0);
485 | pline("\"Thou %s, %s.\"",
486 | (ugod_is_angry() && resp_god == u.ualign.type)
487 | ? "hast strayed from the path" :
488 | "art arrogant",
489 | youmonst.data->mlet == S_HUMAN ? "mortal" : "creature");
490 | verbalize("Thou must relearn thy lessons!");
491 | (void) adjattrib(A_WIS, -1, FALSE);
492 | losexp((char *)0);
493 | break;
494 | case 6: if (!Punished) {
495 | gods_angry(resp_god);
496 | punish((struct obj *)0);
497 | break;
498 | } /* else fall thru */
499 | case 4:
500 | case 5: gods_angry(resp_god);
501 | if (!Blind && !Antimagic)
502 | pline("%s glow surrounds you.",
503 | An(hcolor(Black)));
504 | rndcurse();
505 | break;
506 | case 7:
507 | case 8: godvoice(resp_god,(char *)0);
508 | verbalize("Thou durst %s me?",
509 | (on_altar() &&
510 | (a_align(u.ux,u.uy) != resp_god)) ?
511 | "scorn":"call upon");
512 | pline("\"Then die, %s!\"",
513 | youmonst.data->mlet == S_HUMAN ? "mortal" : "creature");
514 | summon_minion(resp_god, FALSE);
515 | break;
516 |
517 | default: gods_angry(resp_god);
518 | god_zaps_you(resp_god);
519 | break;
520 | }
521 | u.ublesscnt = rnz(300);
522 | return;
523 | }
524 |
525 | STATIC_OVL void
526 | pleased(g_align)
527 | aligntyp g_align;
528 | {
529 | int trouble = p_trouble; /* what's your worst difficulty? */
530 | int pat_on_head = 0, kick_on_butt;
531 |
532 | You_feel("that %s is %s.", align_gname(g_align),
533 | u.ualign.record >= DEVOUT ?
534 | Hallucination ? "pleased as punch" : "well-pleased" :
535 | u.ualign.record >= STRIDENT ?
536 | Hallucination ? "ticklish" : "pleased" :
537 | Hallucination ? "full" : "satisfied");
538 |
539 | /* not your deity */
540 | if (on_altar() && p_aligntyp != u.ualign.type) {
541 | adjalign(-1);
542 | return;
543 | } else if (u.ualign.record < 2 && trouble <= 0) adjalign(1);
544 |
545 | /* depending on your luck & align level, the god you prayed to will:
546 | - fix your worst problem if it's major.
547 | - fix all your major problems.
548 | - fix your worst problem if it's minor.
549 | - fix all of your problems.
550 | - do you a gratuitous favor.
551 |
552 | if you make it to the the last category, you roll randomly again
553 | to see what they do for you.
554 |
555 | If your luck is at least 0, then you are guaranteed rescued
556 | from your worst major problem. */
557 |
558 | if (!trouble && u.ualign.record >= DEVOUT) pat_on_head = 1;
559 | else {
560 | int action = rn1(on_altar() ? 3 + on_shrine() : 2, Luck+1);
561 |
562 | if (!on_altar()) action = max(action,2);
563 | if (u.ualign.record < STRIDENT)
564 | action = (u.ualign.record > 0 || !rnl(2)) ? 1 : 0;
565 |
566 | switch(min(action,5)) {
567 | case 5: pat_on_head = 1;
568 | case 4: do fix_worst_trouble(trouble);
569 | while ((trouble = in_trouble()) != 0);
570 | break;
571 |
572 | case 3: fix_worst_trouble(trouble);
573 | case 2: while ((trouble = in_trouble()) > 0)
574 | fix_worst_trouble(trouble);
575 | break;
576 |
577 | case 1: if (trouble > 0) fix_worst_trouble(trouble);
578 | case 0: break; /* your god blows you off, too bad */
579 | }
580 | }
581 |
582 | if(pat_on_head)
583 | switch(rn2((Luck + 6)>>1)) {
584 | case 0: break;
585 | case 1:
586 | if (uwep && (welded(uwep) || uwep->oclass == WEAPON_CLASS ||
587 | is_weptool(uwep))) {
588 | char repair_buf[BUFSZ];
589 |
590 | *repair_buf = '\0';
591 | if (uwep->oeroded || uwep->oeroded2)
592 | Sprintf(repair_buf, " and %s now as good as new",
593 | uwep->quan == 1L ? "is" : "are");
594 |
595 | if (uwep->cursed) {
596 | uncurse(uwep);
597 | uwep->bknown = TRUE;
598 | if (!Blind)
599 | Your("%s %s%s.", aobjnam(uwep, "softly glow"),
600 | hcolor(amber), repair_buf);
601 | else You_feel("the power of %s over your %s.",
602 | u_gname(), xname(uwep));
603 | *repair_buf = '\0';
604 | } else if (!uwep->blessed) {
605 | bless(uwep);
606 | uwep->bknown = TRUE;
607 | if (!Blind)
608 | Your("%s with %s aura%s.",
609 | aobjnam(uwep, "softly glow"),
610 | an(hcolor(light_blue)), repair_buf);
611 | else You_feel("the blessing of %s over your %s.",
612 | u_gname(), xname(uwep));
613 | *repair_buf = '\0';
614 | }
615 |
616 | /* fix any rust/burn/rot damage, but don't protect
617 | against future damage */
618 | if (uwep->oeroded || uwep->oeroded2) {
619 | uwep->oeroded = uwep->oeroded2 = 0;
620 | /* only give this message if we didn't just bless
621 | or uncurse (which has already given a message) */
622 | if (*repair_buf)
623 | Your("%s as good as new!",
624 | aobjnam(uwep, Blind ? "feel" : "look"));
625 | }
626 | }
627 | break;
628 | case 3:
629 | /* takes 2 hints to get the music to enter the stronghold */
630 | if (flags.soundok && !u.uevent.uopened_dbridge) {
631 | if(u.uevent.uheard_tune < 1) {
632 | godvoice(g_align,(char *)0);
633 | verbalize("Hark, %s!",
634 | youmonst.data->mlet == S_HUMAN ? "mortal" : "creature");
635 | verbalize(
636 | "To enter the castle, thou must play the right tune!");
637 | u.uevent.uheard_tune++;
638 | break;
639 | } else if (u.uevent.uheard_tune < 2) {
640 | You_hear(Hallucination ? "a funeral march..." : "a divine music...");
641 | pline("It sounds like: \"%s\".", tune);
642 | u.uevent.uheard_tune++;
643 | break;
644 | }
645 | }
646 | /* Otherwise, falls into next case */
647 | case 2:
648 | if (!Blind)
649 | You("are surrounded by %s glow.",
650 | an(hcolor(golden)));
651 | if (Upolyd) u.mh = u.mhmax += 5;
652 | u.uhp = u.uhpmax += 5;
653 | ABASE(A_STR) = AMAX(A_STR);
654 | if (u.uhunger < 900) init_uhunger();
655 | if (u.uluck < 0) u.uluck = 0;
656 | make_blinded(0L,TRUE);
657 | flags.botl = 1;
658 | break;
659 | case 4: {
660 | register struct obj *otmp;
661 |
662 | if (Blind)
663 | You_feel("the power of %s.", u_gname());
664 | else You("are surrounded by %s aura.",
665 | an(hcolor(light_blue)));
666 | for(otmp=invent; otmp; otmp=otmp->nobj) {
667 | if (otmp->cursed) {
668 | uncurse(otmp);
669 | if (!Blind) {
670 | Your("%s %s.", aobjnam(otmp, "softly glow"),
671 | hcolor(amber));
672 | otmp->bknown = TRUE;
673 | }
674 | }
675 | }
676 | break;
677 | }
678 | case 5: {
679 | const char *msg="\"and thus I grant thee the gift of %s!\"";
680 | godvoice(u.ualign.type, "Thou hast pleased me with thy progress,");
681 | if (!(HTelepat & INTRINSIC)) {
682 | HTelepat |= FROMOUTSIDE;
683 | pline(msg, "Telepathy");
684 | if (Blind) see_monsters();
685 | } else if (!(HFast & INTRINSIC)) {
686 | HFast |= FROMOUTSIDE;
687 | pline(msg, "Speed");
688 | } else if (!(HStealth & INTRINSIC)) {
689 | HStealth |= FROMOUTSIDE;
690 | pline(msg, "Stealth");
691 | } else {
692 | if (!(HProtection & INTRINSIC)) {
693 | HProtection |= FROMOUTSIDE;
694 | if (!u.ublessed) u.ublessed = rn1(3, 2);
695 | } else u.ublessed++;
696 | pline(msg, "my protection");
697 | }
698 | verbalize("Use it wisely in my name!");
699 | break;
700 | }
701 | case 7:
702 | case 8:
703 | case 9: /* KMH -- can occur during full moons */
704 | #ifdef ELBERETH
705 | if (u.ualign.record >= PIOUS && !u.uevent.uhand_of_elbereth) {
706 | register struct obj *obj = uwep; /* to be blessed */
707 | boolean already_exists, in_hand;
708 | const char *dropped_item;
709 | int sp_no;
710 |
711 | HSee_invisible |= FROMOUTSIDE;
712 | HFire_resistance |= FROMOUTSIDE;
713 | HCold_resistance |= FROMOUTSIDE;
714 | HPoison_resistance |= FROMOUTSIDE;
715 | godvoice(u.ualign.type,(char *)0);
716 |
717 | switch(u.ualign.type) {
718 | case A_LAWFUL:
719 | u.uevent.uhand_of_elbereth = 1;
720 | verbalize("I crown thee... The Hand of Elbereth!");
721 | if (obj && (obj->otyp == LONG_SWORD) && !obj->oartifact) {
722 | obj = oname(obj, artiname(ART_EXCALIBUR));
723 | if (obj && obj->oartifact == ART_EXCALIBUR) u.ugifts++;
724 | }
725 | /* acquire this skill regardless of weapon */
726 | unrestrict_weapon_skill(P_LONG_SWORD);
727 | if (obj && obj->oartifact == ART_EXCALIBUR)
728 | discover_artifact(ART_EXCALIBUR);
729 | break;
730 | case A_NEUTRAL:
731 | u.uevent.uhand_of_elbereth = 2;
732 | verbalize("Thou shalt be my Envoy of Balance!");
733 | dropped_item = 0;
734 | if (uwep && uwep->oartifact == ART_VORPAL_BLADE) {
735 | obj = uwep; /* to be blessed and rustproofed */
736 | Your("%s goes snicker-snack!", xname(obj));
737 | obj->dknown = TRUE;
738 | } else if (Role_if(PM_WIZARD) &&
739 | !carrying(SPE_FINGER_OF_DEATH)) {
740 | obj = mksobj(SPE_FINGER_OF_DEATH, TRUE, FALSE);
741 | bless(obj);
742 | dropped_item = "A spellbook appears";
743 | } else if (!exist_artifact(LONG_SWORD,
744 | artiname(ART_VORPAL_BLADE))) {
745 | obj = mksobj(LONG_SWORD, FALSE, FALSE);
746 | obj = oname(obj, artiname(ART_VORPAL_BLADE));
747 | obj->spe = 1;
748 | dropped_item = "A sword appears";
749 | }
750 | if (dropped_item) {
751 | if (Blind) dropped_item = "Something lands";
752 | pline("%s %s your %s!", dropped_item,
753 | Levitation ? "beneath" : "at",
754 | makeplural(body_part(FOOT)));
755 | dropy(obj);
756 | u.ugifts++;
757 | }
758 | /* acquire this skill regardless of weapon (or book) */
759 | unrestrict_weapon_skill(P_LONG_SWORD);
760 | if (obj && obj->oartifact == ART_VORPAL_BLADE)
761 | discover_artifact(ART_VORPAL_BLADE);
762 | /* when getting a new book for known spell, enhance
763 | currently wielded weapon rather than the book */
764 | if (obj && obj->otyp == SPE_FINGER_OF_DEATH) {
765 | for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
766 | if (spl_book[sp_no].sp_id == SPE_FINGER_OF_DEATH) {
767 | if (uwep) obj = uwep; /* to be blessed,&c */
768 | break;
769 | }
770 | }
771 | break;
772 | case A_CHAOTIC:
773 | u.uevent.uhand_of_elbereth = 3;
774 | in_hand = (uwep && uwep->oartifact == ART_STORMBRINGER);
775 | already_exists = exist_artifact(RUNESWORD,
776 | artiname(ART_STORMBRINGER));
777 | verbalize("Thou art chosen to %s for My Glory!",
778 | already_exists && !in_hand ?
779 | "take lives" : "steal souls");
780 | if (in_hand) {
781 | obj = uwep; /* to be blessed and rustproofed */
782 | } else if (!already_exists) {
783 | obj = mksobj(RUNESWORD, FALSE, FALSE);
784 | obj = oname(obj, artiname(ART_STORMBRINGER));
785 | pline("%s %s %s your %s!", Blind ? Something :
786 | An(hcolor(Black)),
787 | Blind ? "lands" : "sword appears",
788 | Levitation ? "beneath" : "at",
789 | makeplural(body_part(FOOT)));
790 | obj->spe = 1;
791 | dropy(obj);
792 | u.ugifts++;
793 | }
794 | /* acquire this skill regardless of weapon */
795 | unrestrict_weapon_skill(P_BROAD_SWORD);
796 | if (obj && obj->oartifact == ART_STORMBRINGER)
797 | discover_artifact(ART_STORMBRINGER);
798 | break;
799 | default:
800 | obj = 0; /* lint */
801 | break;
802 | }
803 | /* enhance weapon regardless of alignment or artifact status */
804 | if (obj && (obj->oclass == WEAPON_CLASS || is_weptool(obj))) {
805 | bless(obj);
806 | obj->oeroded = obj->oeroded2 = 0;
807 | obj->oerodeproof = TRUE;
808 | obj->bknown = obj->rknown = TRUE;
809 | if (obj->spe < 1) obj->spe = 1;
810 | /* acquire skill in this weapon */
811 | unrestrict_weapon_skill(weapon_type(obj));
812 | } else if (obj && (obj->oclass == SPBOOK_CLASS)) {
813 | obj->bknown = TRUE;
814 | } else /* opportunity knocked, but there was nobody home... */
815 | You_feel("unworthy.");
816 | break;
817 | }
818 | #endif /*ELBERETH*/
819 |
820 | case 6: {
821 | struct obj *otmp;
822 | int sp_no, trycnt = u.ulevel + 1;
823 |
824 | pline("An object appears at your %s!",
825 | makeplural(body_part(FOOT)));
826 | /* not yet known spells given preference over already known ones */
827 | otmp = mkobj(SPBOOK_CLASS, TRUE);
828 | while (--trycnt > 0) {
829 | if (otmp->otyp != SPE_BLANK_PAPER) {
830 | for (sp_no = 0; sp_no < MAXSPELL; sp_no++)
831 | if (spl_book[sp_no].sp_id == otmp->otyp) break;
832 | if (sp_no == MAXSPELL) break; /* not yet known */
833 | } else {
834 | if (!objects[SPE_BLANK_PAPER].oc_name_known ||
835 | carrying(MAGIC_MARKER)) break;
836 | }
837 | otmp->otyp = rnd_class(bases[SPBOOK_CLASS], SPE_BLANK_PAPER);
838 | }
839 | bless(otmp);
840 | place_object(otmp, u.ux, u.uy);
841 | break;
842 | }
843 | default: impossible("Confused deity!");
844 | break;
845 | }
846 |
847 | u.ublesscnt = rnz(350);
848 | kick_on_butt = u.uevent.udemigod ? 1 : 0;
849 | #ifdef ELBERETH
850 | if (u.uevent.uhand_of_elbereth) kick_on_butt++;
851 | #endif
852 | if (kick_on_butt) u.ublesscnt += kick_on_butt * rnz(1000);
853 |
854 | return;
855 | }
856 |
857 | /* either blesses or curses water on the altar,
858 | * returns true if it found any water here.
859 | */
860 | STATIC_OVL boolean
861 | water_prayer(bless_water)
862 | boolean bless_water;
863 | {
864 | register struct obj* otmp;
865 | register long changed = 0;
866 | boolean other = FALSE, bc_known = !(Blind || Hallucination);
867 |
868 | for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere) {
869 | /* turn water into (un)holy water */
870 | if (otmp->otyp == POT_WATER && (boolean)otmp->blessed != bless_water) {
871 | otmp->blessed = bless_water;
872 | otmp->cursed = !bless_water;
873 | otmp->bknown = bc_known;
874 | changed += otmp->quan;
875 | } else if(otmp->oclass == POTION_CLASS)
876 | other = TRUE;
877 | }
878 | if(!Blind && changed) {
879 | pline("%s potion%s on the altar glow%s %s for a moment.",
880 | ((other && changed > 1L) ? "Some of the" :
881 | (other ? "One of the" : "The")),
882 | ((other || changed > 1L) ? "s" : ""), (changed > 1L ? "" : "s"),
883 | (bless_water ? hcolor(light_blue) : hcolor(Black)));
884 | }
885 | return((boolean)(changed > 0L));
886 | }
887 |
888 | STATIC_OVL void
889 | godvoice(g_align, words)
890 | aligntyp g_align;
891 | const char *words;
892 | {
893 | const char *quot = "";
894 | if(words)
895 | quot = "\"";
896 | else
897 | words = "";
898 |
899 | pline_The("voice of %s %s: %s%s%s", align_gname(g_align),
900 | godvoices[rn2(SIZE(godvoices))], quot, words, quot);
901 | }
902 |
903 | STATIC_OVL void
904 | gods_angry(g_align)
905 | aligntyp g_align;
906 | {
907 | godvoice(g_align, "Thou hast angered me.");
908 | }
909 |
910 | /* The g_align god is upset with you. */
911 | STATIC_OVL void
912 | gods_upset(g_align)
913 | aligntyp g_align;
914 | {
915 | if(g_align == u.ualign.type) u.ugangr++;
916 | else if(u.ugangr) u.ugangr--;
917 | angrygods(g_align);
918 | }
919 |
920 | static NEARDATA const char sacrifice_types[] = { FOOD_CLASS, AMULET_CLASS, 0 };
921 |
922 | STATIC_OVL void
923 | consume_offering(otmp)
924 | register struct obj *otmp;
925 | {
926 | if (Hallucination)
927 | switch (rn2(3)) {
928 | case 0:
929 | Your("sacrifice sprouts wings and a propeller and roars away!");
930 | break;
931 | case 1:
932 | Your("sacrifice puffs up, swelling bigger and bigger, and pops!");
933 | break;
934 | case 2:
935 | Your("sacrifice collapses into a cloud of dancing particles and fades away!");
936 | break;
937 | }
938 | else if (Blind && u.ualign.type == A_LAWFUL)
939 | Your("sacrifice disappears!");
940 | else Your("sacrifice is consumed in a %s!",
941 | u.ualign.type == A_LAWFUL ? "flash of light" : "burst of flame");
942 | if (carried(otmp)) useup(otmp);
943 | else useupf(otmp, 1L);
944 | exercise(A_WIS, TRUE);
945 | }
946 |
947 | int
948 | dosacrifice()
949 | {
950 | register struct obj *otmp;
951 | int value = 0;
952 | int pm;
953 | aligntyp altaralign = a_align(u.ux,u.uy);
954 |
955 | if (!on_altar()) {
956 | You("are not standing on an altar.");
957 | return 0;
958 | }
959 |
960 | if (In_endgame(&u.uz)) {
961 | if (!(otmp = getobj(sacrifice_types, "sacrifice"))) return 0;
962 | } else {
963 | if (!(otmp = floorfood("sacrifice", 1))) return 0;
964 | }
965 | /*
966 | Was based on nutritional value and aging behavior (< 50 moves).
967 | Sacrificing a food ration got you max luck instantly, making the
968 | gods as easy to please as an angry dog!
969 |
970 | Now only accepts corpses, based on the game's evaluation of their
971 | toughness. Human and pet sacrifice, as well as sacrificing unicorns
972 | of your alignment, is strongly discouraged.
973 | */
974 |
975 | #define MAXVALUE 24 /* Highest corpse value (besides Wiz) */
976 |
977 | if (otmp->otyp == CORPSE) {
978 | register struct permonst *ptr = &mons[otmp->corpsenm];
979 | struct monst *mtmp;
980 | extern const int monstr[];
981 |
982 | /* KMH, conduct */
983 | u.uconduct.gnostic++;
984 |
985 | /* you're handling this corpse, even if it was killed upon the altar */
986 | feel_cockatrice(otmp, TRUE);
987 |
988 | if (otmp->corpsenm == PM_ACID_BLOB
989 | || (monstermoves <= peek_at_iced_corpse_age(otmp) + 50)) {
990 | value = monstr[otmp->corpsenm] + 1;
991 | if (otmp->oeaten)
992 | value = eaten_stat(value, otmp);
993 | }
994 |
995 | if (your_race(ptr)) {
996 | if (is_demon(youmonst.data)) {
997 | You("find the idea very satisfying.");
998 | exercise(A_WIS, TRUE);
999 | } else if (u.ualign.type != A_CHAOTIC) {
1000 | pline("You'll regret this infamous offense!");
1001 | exercise(A_WIS, FALSE);
1002 | }
1003 |
1004 | if (altaralign != A_CHAOTIC && altaralign != A_NONE) {
1005 | /* curse the lawful/neutral altar */
1006 | pline_The("altar is stained with %s blood.", urace.adj);
1007 | if(!Is_astralevel(&u.uz))
1008 | levl[u.ux][u.uy].altarmask = AM_CHAOTIC;
1009 | angry_priest();
1010 | } else {
1011 | struct monst *dmon;
1012 | const char *demonless_msg;
1013 |
1014 | /* Human sacrifice on a chaotic or unaligned altar */
1015 | /* is equivalent to demon summoning */
1016 | if (altaralign == A_CHAOTIC && u.ualign.type != A_CHAOTIC) {
1017 | pline(
1018 | "The blood floods the altar, which vanishes in %s cloud!",
1019 | an(hcolor(Black)));
1020 | levl[u.ux][u.uy].typ = ROOM;
1021 | levl[u.ux][u.uy].altarmask = 0;
1022 | if(Invisible) newsym(u.ux, u.uy);
1023 | angry_priest();
1024 | demonless_msg = "cloud dissipates";
1025 | } else {
1026 | /* either you're chaotic or altar is Moloch's or both */
1027 | pline_The("blood covers the altar!");
1028 | change_luck(altaralign == A_NONE ? -2 : 2);
1029 | demonless_msg = "blood coagulates";
1030 | }
1031 | if ((pm = dlord(altaralign)) != NON_PM &&
1032 | (dmon = makemon(&mons[pm], u.ux, u.uy, NO_MM_FLAGS))) {
1033 | You("have summoned %s!", a_monnam(dmon));
1034 | if (sgn(u.ualign.type) == sgn(dmon->data->maligntyp))
1035 | dmon->mpeaceful = TRUE;
1036 | You("are terrified, and unable to move.");
1037 | nomul(-3);
1038 | } else pline_The("%s.", demonless_msg);
1039 | }
1040 |
1041 | if (u.ualign.type != A_CHAOTIC) {
1042 | adjalign(-5);
1043 | u.ugangr += 3;
1044 | (void) adjattrib(A_WIS, -1, TRUE);
1045 | if (!Inhell) angrygods(u.ualign.type);
1046 | change_luck(-5);
1047 | } else adjalign(5);
1048 | if (carried(otmp)) useup(otmp);
1049 | else useupf(otmp, 1L);
1050 | return(1);
1051 | } else if (otmp->oxlth && otmp->oattached == OATTACHED_MONST
1052 | && ((mtmp = get_mtraits(otmp, FALSE)) != (struct monst *)0)
1053 | && mtmp->mtame) {
1054 | /* mtmp is a temporary pointer to a tame monster's attributes,
1055 | * not a real monster */
1056 | pline("So this is how you repay loyalty?");
1057 | adjalign(-3);
1058 | value = -1;
1059 | HAggravate_monster |= FROMOUTSIDE;
1060 | } else if (is_undead(ptr)) { /* Not demons--no demon corpses */
1061 | if (u.ualign.type != A_CHAOTIC)
1062 | value += 1;
1063 | } else if (is_unicorn(ptr)) {
1064 | int unicalign = sgn(ptr->maligntyp);
1065 |
1066 | /* If same as altar, always a very bad action. */
1067 | if (unicalign == altaralign) {
1068 | pline("Such an action is an insult to %s!",
1069 | (unicalign == A_CHAOTIC)
1070 | ? "chaos" : unicalign ? "law" : "balance");
1071 | (void) adjattrib(A_WIS, -1, TRUE);
1072 | value = -5;
1073 | } else if (u.ualign.type == altaralign) {
1074 | /* If different from altar, and altar is same as yours, */
1075 | /* it's a very good action */
1076 | if (u.ualign.record < ALIGNLIM)
1077 | You_feel("appropriately %s.", align_str(u.ualign.type));
1078 | else You_feel("you are thoroughly on the right path.");
1079 | adjalign(5);
1080 | value += 3;
1081 | } else
1082 | /* If sacrificing unicorn of your alignment to altar not of */
1083 | /* your alignment, your god gets angry and it's a conversion */
1084 | if (unicalign == u.ualign.type) {
1085 | u.ualign.record = -1;
1086 | value = 1;
1087 | } else value += 3;
1088 | }
1089 | } /* corpse */
1090 |
1091 | if (otmp->otyp == AMULET_OF_YENDOR) {
1092 | if (!In_endgame(&u.uz)) {
1093 | if (Hallucination)
1094 | You_feel("homesick.");
1095 | else
1096 | You_feel("an urge to return to the surface.");
1097 | return 1;
1098 | } else {
1099 | /* The final Test. Did you win? */
1100 | if(uamul == otmp) Amulet_off();
1101 | u.uevent.ascended = 1;
1102 | if(carried(otmp)) useup(otmp); /* well, it's gone now */
1103 | else useupf(otmp, 1L);
1104 | You("offer the Amulet of Yendor to %s...", a_gname());
1105 | if (u.ualign.type != altaralign) {
1106 | /* And the opposing team picks you up and
1107 | carries you off on their shoulders */
1108 | adjalign(-99);
1109 | pline("%s accepts your gift, and gains dominion over %s...",
1110 | a_gname(), u_gname());
1111 | pline("%s is enraged...", u_gname());
1112 | pline("Fortunately, %s permits you to live...", a_gname());
1113 | pline("A cloud of %s smoke surrounds you...",
1114 | hcolor((const char *)"orange"));
1115 | done(ESCAPED);
1116 | } else { /* super big win */
1117 | adjalign(10);
1118 | pline("An invisible choir sings, and you are bathed in radiance...");
1119 | godvoice(altaralign, "Congratulations, mortal!");
1120 | display_nhwindow(WIN_MESSAGE, FALSE);
1121 | verbalize("In return for thy service, I grant thee the gift of Immortality!");
1122 | You("ascend to the status of Demigod%s...",
1123 | flags.female ? "dess" : "");
1124 | done(ASCENDED);
1125 | }
1126 | }
1127 | } /* real Amulet */
1128 |
1129 | if (otmp->otyp == FAKE_AMULET_OF_YENDOR) {
1130 | if (flags.soundok)
1131 | You_hear("a nearby thunderclap.");
1132 | if (!otmp->known) {
1133 | You("realize you have made a %s.",
1134 | Hallucination ? "boo-boo" : "mistake");
1135 | otmp->known = TRUE;
1136 | change_luck(-1);
1137 | return 1;
1138 | } else {
1139 | /* don't you dare try to fool the gods */
1140 | change_luck(-3);
1141 | adjalign(-1);
1142 | u.ugangr += 3;
1143 | value = -3;
1144 | }
1145 | } /* fake Amulet */
1146 |
1147 | if (value == 0) {
1148 | pline(nothing_happens);
1149 | return (1);
1150 | }
1151 |
1152 | if (altaralign != u.ualign.type &&
1153 | (Is_astralevel(&u.uz) || Is_sanctum(&u.uz))) {
1154 | /*
1155 | * REAL BAD NEWS!!! High altars cannot be converted. Even an attempt
1156 | * gets the god who owns it truely pissed off.
1157 | */
1158 | You_feel("the air around you grow charged...");
1159 | pline("Suddenly, you realize that %s has noticed you...", a_gname());
1160 | godvoice(altaralign, "So, mortal! You dare desecrate my High Temple!");
1161 | /* Throw everything we have at the player */
1162 | god_zaps_you(altaralign);
1163 | } else if (value < 0) { /* I don't think the gods are gonna like this... */
1164 | gods_upset(altaralign);
1165 | } else {
1166 | int saved_anger = u.ugangr;
1167 | int saved_cnt = u.ublesscnt;
1168 | int saved_luck = u.uluck;
1169 |
1170 | /* Sacrificing at an altar of a different alignment */
1171 | if (u.ualign.type != altaralign) {
1172 | /* Is this a conversion ? */
1173 | /* An unaligned altar in Gehennom will always elicit rejection. */
1174 | if (ugod_is_angry() || (altaralign == A_NONE && Inhell)) {
1175 | if(u.ualignbase[A_CURRENT] == u.ualignbase[A_ORIGINAL] &&
1176 | altaralign != A_NONE) {
1177 | You("have a strong feeling that %s is angry...", u_gname());
1178 | consume_offering(otmp);
1179 | pline("%s accepts your allegiance.", a_gname());
1180 |
1181 | /* The player wears a helm of opposite alignment? */
1182 | if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT)
1183 | u.ualignbase[A_CURRENT] = altaralign;
1184 | else
1185 | u.ualign.type = u.ualignbase[A_CURRENT] = altaralign;
1186 | u.ublessed = 0;
1187 | flags.botl = 1;
1188 |
1189 | You("have a sudden sense of a new direction.");
1190 | /* Beware, Conversion is costly */
1191 | change_luck(-3);
1192 | u.ublesscnt += 300;
1193 | adjalign((int)(u.ualignbase[A_ORIGINAL] * (ALIGNLIM / 2)));
1194 | } else {
1195 | u.ugangr += 3;
1196 | adjalign(-5);
1197 | pline("%s rejects your sacrifice!", a_gname());
1198 | godvoice(altaralign, "Suffer, infidel!");
1199 | change_luck(-5);
1200 | (void) adjattrib(A_WIS, -2, TRUE);
1201 | if (!Inhell) angrygods(u.ualign.type);
1202 | }
1203 | return(1);
1204 | } else {
1205 | consume_offering(otmp);
1206 | You("sense a conflict between %s and %s.",
1207 | u_gname(), a_gname());
1208 | if (rn2(8 + u.ulevel) > 5) {
1209 | struct monst *pri;
1210 | You_feel("the power of %s increase.", u_gname());
1211 | exercise(A_WIS, TRUE);
1212 | change_luck(1);
1213 | /* Yes, this is supposed to be &=, not |= */
1214 | levl[u.ux][u.uy].altarmask &= AM_SHRINE;
1215 | /* the following accommodates stupid compilers */
1216 | levl[u.ux][u.uy].altarmask =
1217 | levl[u.ux][u.uy].altarmask | (Align2amask(u.ualign.type));
1218 | if (!Blind)
1219 | pline_The("altar glows %s.",
1220 | hcolor(
1221 | u.ualign.type == A_LAWFUL ? White :
1222 | u.ualign.type ? Black : (const char *)"gray"));
1223 |
1224 | if (rnl(u.ulevel) > 6 && u.ualign.record > 0 &&
1225 | rnd(u.ualign.record) > (3*ALIGNLIM)/4)
1226 | summon_minion(altaralign, TRUE);
1227 | /* anger priest; test handles bones files */
1228 | if((pri = findpriest(temple_occupied(u.urooms))) &&
1229 | !p_coaligned(pri))
1230 | angry_priest();
1231 | } else {
1232 | pline("Unluckily, you feel the power of %s decrease.",
1233 | u_gname());
1234 | change_luck(-1);
1235 | exercise(A_WIS, FALSE);
1236 | if (rnl(u.ulevel) > 6 && u.ualign.record > 0 &&
1237 | rnd(u.ualign.record) > (7*ALIGNLIM)/8)
1238 | summon_minion(altaralign, TRUE);
1239 | }
1240 | return(1);
1241 | }
1242 | }
1243 |
1244 | consume_offering(otmp);
1245 | /* OK, you get brownie points. */
1246 | if(u.ugangr) {
1247 | u.ugangr -=
1248 | ((value * (u.ualign.type == A_CHAOTIC ? 2 : 3)) / MAXVALUE);
1249 | if(u.ugangr < 0) u.ugangr = 0;
1250 | if(u.ugangr != saved_anger) {
1251 | if (u.ugangr) {
1252 | pline("%s seems %s.", u_gname(),
1253 | Hallucination ? "groovy" : "slightly mollified");
1254 |
1255 | if ((int)u.uluck < 0) change_luck(1);
1256 | } else {
1257 | pline("%s seems %s.", u_gname(), Hallucination ?
1258 | "cosmic (not a new fact)" : "mollified");
1259 |
1260 | if ((int)u.uluck < 0) u.uluck = 0;
1261 | }
1262 | } else { /* not satisfied yet */
1263 | if (Hallucination)
1264 | pline_The("gods seem tall.");
1265 | else You("have a feeling of inadequacy.");
1266 | }
1267 | } else if(ugod_is_angry()) {
1268 | if(value > MAXVALUE) value = MAXVALUE;
1269 | if(value > -u.ualign.record) value = -u.ualign.record;
1270 | adjalign(value);
1271 | You_feel("partially absolved.");
1272 | } else if (u.ublesscnt > 0) {
1273 | u.ublesscnt -=
1274 | ((value * (u.ualign.type == A_CHAOTIC ? 500 : 300)) / MAXVALUE);
1275 | if(u.ublesscnt < 0) u.ublesscnt = 0;
1276 | if(u.ublesscnt != saved_cnt) {
1277 | if (u.ublesscnt) {
1278 | if (Hallucination)
1279 | You("realize that the gods are not like you and I.");
1280 | else
1281 | You("have a hopeful feeling.");
1282 | if ((int)u.uluck < 0) change_luck(1);
1283 | } else {
1284 | if (Hallucination)
1285 | pline("Overall, there is a smell of fried onions.");
1286 | else
1287 | You("have a feeling of reconciliation.");
1288 | if ((int)u.uluck < 0) u.uluck = 0;
1289 | }
1290 | }
1291 | } else {
1292 | int nartifacts = nartifact_exist();
1293 |
1294 | /* you were already in pretty good standing */
1295 | /* The player can gain an artifact */
1296 | /* The chance goes down as the number of artifacts goes up */
1297 | if (u.ulevel > 2 && !rn2(10 + (2 * u.ugifts * nartifacts))) {
1298 | otmp = mk_artifact((struct obj *)0, a_align(u.ux,u.uy));
1299 | if (otmp) {
1300 | if (otmp->spe < 0) otmp->spe = 0;
1301 | if (otmp->cursed) uncurse(otmp);
1302 | dropy(otmp);
1303 | pline("An object appears at your %s!",
1304 | makeplural(body_part(FOOT)));
1305 | godvoice(u.ualign.type, "Use my gift wisely!");
1306 | u.ugifts++;
1307 | u.ublesscnt = rnz(300 + (50 * nartifacts));
1308 | exercise(A_WIS, TRUE);
1309 | /* make sure we can use this weapon */
1310 | unrestrict_weapon_skill(weapon_type(otmp));
1311 | discover_artifact(otmp->oartifact);
1312 | return(1);
1313 | }
1314 | }
1315 | change_luck((value * LUCKMAX) / (MAXVALUE * 2));
1316 | if (u.uluck != saved_luck) {
1317 | if (Blind)
1318 | You("think %s brushed your %s.",something, body_part(FOOT));
1319 | else You(Hallucination ?
1320 | "see crabgrass at your %s. A funny thing in a dungeon." :
1321 | "glimpse a four-leaf clover at your %s.",
1322 | makeplural(body_part(FOOT)));
1323 | }
1324 | }
1325 | }
1326 | return(1);
1327 | }
1328 |
1329 |
1330 | /* determine prayer results in advance; also used for enlightenment */
1331 | boolean
1332 | can_pray(praying)
1333 | boolean praying; /* false means no messages should be given */
1334 | {
1335 | int alignment;
1336 |
1337 | p_aligntyp = on_altar() ? a_align(u.ux,u.uy) : u.ualign.type;
1338 | p_trouble = in_trouble();
1339 |
1340 | if (is_demon(youmonst.data) && (p_aligntyp != A_CHAOTIC)) {
1341 | if (praying)
1342 | pline_The("very idea of praying to a %s god is repugnant to you.",
1343 | p_aligntyp ? "lawful" : "neutral");
1344 | return FALSE;
1345 | }
1346 |
1347 | if (praying)
1348 | You("begin praying to %s.", align_gname(p_aligntyp));
1349 |
1350 | if (u.ualign.type && u.ualign.type == -p_aligntyp)
1351 | alignment = -u.ualign.record; /* Opposite alignment altar */
1352 | else if (u.ualign.type != p_aligntyp)
1353 | alignment = u.ualign.record / 2; /* Different alignment altar */
1354 | else alignment = u.ualign.record;
1355 |
1356 | if ((p_trouble > 0) ? (u.ublesscnt > 200) : /* big trouble */
1357 | (p_trouble < 0) ? (u.ublesscnt > 100) : /* minor difficulties */
1358 | (u.ublesscnt > 0)) /* not in trouble */
1359 | p_type = 0; /* too soon... */
1360 | else if ((int)Luck < 0 || u.ugangr || alignment < 0)
1361 | p_type = 1; /* too naughty... */
1362 | else /* alignment >= 0 */ {
1363 | if(on_altar() && u.ualign.type != p_aligntyp)
1364 | p_type = 2;
1365 | else
1366 | p_type = 3;
1367 | }
1368 |
1369 | if (is_undead(youmonst.data) && !Inhell &&
1370 | (p_aligntyp == A_LAWFUL || (p_aligntyp == A_NEUTRAL && !rn2(10))))
1371 | p_type = -1;
1372 | /* Note: when !praying, the random factor for neutrals makes the
1373 | return value a non-deterministic approximation for enlightenment.
1374 | This case should be uncommon enough to live with... */
1375 |
1376 | return !praying ? (boolean)(p_type == 3 && !Inhell) : TRUE;
1377 | }
1378 |
1379 | int
1380 | dopray()
1381 | {
1382 | /* Confirm accidental slips of Alt-P */
1383 | if (flags.prayconfirm)
1384 | if (yn("Are you sure you want to pray?") == 'n')
1385 | return (0);
1386 | u.uconduct.gnostic++;
1387 |
1388 | /* set up p_type and p_alignment */
1389 | if (!can_pray(TRUE)) return 0;
1390 |
1391 | #ifdef WIZARD
1392 | if (wizard && p_type >= 0) {
1393 | if (yn("Force the gods to be pleased?") == 'y') {
1394 | u.ublesscnt = 0;
1395 | if (u.uluck < 0) u.uluck = 0;
1396 | if (u.ualign.record <= 0) u.ualign.record = 1;
1397 | u.ugangr = 0;
1398 | if(p_type < 2) p_type = 3;
1399 | }
1400 | }
1401 | #endif
1402 | nomul(-3);
1403 | nomovemsg = "You finish your prayer.";
1404 | afternmv = prayer_done;
1405 |
1406 | if(p_type == 3 && !Inhell) {
1407 | /* if you've been true to your god you can't die while you pray */
1408 | if (!Blind)
1409 | You("are surrounded by a shimmering light.");
1410 | u.uinvulnerable = TRUE;
1411 | }
1412 |
1413 | return(1);
1414 | }
1415 |
1416 | STATIC_PTR int
1417 | prayer_done() /* M. Stephenson (1.0.3b) */
1418 | {
1419 | aligntyp alignment = p_aligntyp;
1420 |
1421 | u.uinvulnerable = FALSE;
1422 | if(p_type == -1) {
1423 | godvoice(alignment,
1424 | alignment == A_LAWFUL ?
1425 | "Vile creature, thou durst call upon me?" :
1426 | "Walk no more, perversion of nature!");
1427 | You_feel("like you are falling apart.");
1428 | /* KMH -- Gods have mastery over unchanging */
1429 | rehumanize();
1430 | losehp(rnd(20), "residual undead turning effect", KILLED_BY_AN);
1431 | exercise(A_CON, FALSE);
1432 | return(1);
1433 | }
1434 | if (Inhell) {
1435 | pline("Since you are in Gehennom, %s won't help you.",
1436 | align_gname(alignment));
1437 | /* haltingly aligned is least likely to anger */
1438 | if (u.ualign.record <= 0 || rnl(u.ualign.record))
1439 | angrygods(u.ualign.type);
1440 | return(0);
1441 | }
1442 |
1443 | if (p_type == 0) {
1444 | if(on_altar() && u.ualign.type != alignment)
1445 | (void) water_prayer(FALSE);
1446 | u.ublesscnt += rnz(250);
1447 | change_luck(-3);
1448 | gods_upset(u.ualign.type);
1449 | } else if(p_type == 1) {
1450 | if(on_altar() && u.ualign.type != alignment)
1451 | (void) water_prayer(FALSE);
1452 | angrygods(u.ualign.type); /* naughty */
1453 | } else if(p_type == 2) {
1454 | if(water_prayer(FALSE)) {
1455 | /* attempted water prayer on a non-coaligned altar */
1456 | u.ublesscnt += rnz(250);
1457 | change_luck(-3);
1458 | gods_upset(u.ualign.type);
1459 | } else pleased(alignment);
1460 | } else {
1461 | /* coaligned */
1462 | if(on_altar())
1463 | (void) water_prayer(TRUE);
1464 | pleased(alignment); /* nice */
1465 | }
1466 | return(1);
1467 | }
1468 |
1469 | int
1470 | doturn()
1471 | { /* Knights & Priest(esse)s only please */
1472 |
1473 | struct monst *mtmp, *mtmp2;
1474 | int once, range, xlev;
1475 |
1476 | if (!Role_if(PM_PRIEST) && !Role_if(PM_KNIGHT)) {
1477 | /* Try to use turn undead spell. */
1478 | if (objects[SPE_TURN_UNDEAD].oc_name_known) {
1479 | register int sp_no;
1480 | for (sp_no = 0; sp_no < MAXSPELL &&
1481 | spl_book[sp_no].sp_id != NO_SPELL &&
1482 | spl_book[sp_no].sp_id != SPE_TURN_UNDEAD; sp_no++);
1483 |
1484 | if (sp_no < MAXSPELL &&
1485 | spl_book[sp_no].sp_id == SPE_TURN_UNDEAD)
1486 | return spelleffects(sp_no, TRUE);
1487 | }
1488 |
1489 | You("don't know how to turn undead!");
1490 | return(0);
1491 | }
1492 | if ((u.ualign.type != A_CHAOTIC &&
1493 | (is_demon(youmonst.data) || is_undead(youmonst.data))) ||
1494 | u.ugangr > 6 /* "Die, mortal!" */) {
1495 |
1496 | pline("For some reason, %s seems to ignore you.", u_gname());
1497 | aggravate();
1498 | exercise(A_WIS, FALSE);
1499 | return(0);
1500 | }
1501 |
1502 | if (Inhell) {
1503 | pline("Since you are in Gehennom, %s won't help you.", u_gname());
1504 | aggravate();
1505 | return(0);
1506 | }
1507 | pline("Calling upon %s, you chant an arcane formula.", u_gname());
1508 | exercise(A_WIS, TRUE);
1509 | u.uconduct.gnostic++;
1510 |
1511 | /* note: does not perform unturn_dead() on victims' inventories */
1512 | range = BOLT_LIM + (u.ulevel / 5); /* 5 to 11 */
1513 | range *= range;
1514 | once = 0;
1515 | for(mtmp = fmon; mtmp; mtmp = mtmp2) {
1516 | mtmp2 = mtmp->nmon;
1517 |
1518 | if (DEADMONSTER(mtmp)) continue;
1519 | if (!cansee(mtmp->mx,mtmp->my) ||
1520 | distu(mtmp->mx,mtmp->my) > range) continue;
1521 |
1522 | if (!mtmp->mpeaceful && (is_undead(mtmp->data) ||
1523 | (is_demon(mtmp->data) && (u.ulevel > (MAXULEV/2))))) {
1524 |
1525 | mtmp->msleeping = 0;
1526 | if (Confusion) {
1527 | if (!once++)
1528 | pline("Unfortunately, your voice falters.");
1529 | mtmp->mflee = 0;
1530 | mtmp->mfrozen = 0;
1531 | mtmp->mcanmove = 1;
1532 | } else if (!resist(mtmp, '\0', 0, TELL)) {
1533 | xlev = 6;
1534 | switch (mtmp->data->mlet) {
1535 | /* this is intentional, lichs are tougher
1536 | than zombies. */
1537 | case S_LICH: xlev += 2;
1538 | case S_GHOST: xlev += 2;
1539 | case S_VAMPIRE: xlev += 2;
1540 | case S_WRAITH: xlev += 2;
1541 | case S_MUMMY: xlev += 2;
1542 | case S_ZOMBIE:
1543 | mtmp->mflee = 1; /* at least */
1544 | if(u.ulevel >= xlev &&
1545 | !resist(mtmp, '\0', 0, NOTELL)) {
1546 | if(u.ualign.type == A_CHAOTIC) {
1547 | mtmp->mpeaceful = 1;
1548 | } else { /* damn them */
1549 | killed(mtmp);
1550 | }
1551 | }
1552 | break;
1553 | default: mtmp->mflee = 1;
1554 | break;
1555 | }
1556 | }
1557 | }
1558 | }
1559 | nomul(-5);
1560 | return(1);
1561 | }
1562 |
1563 | const char *
1564 | a_gname()
1565 | {
1566 | return(a_gname_at(u.ux, u.uy));
1567 | }
1568 |
1569 | const char *
1570 | a_gname_at(x,y) /* returns the name of an altar's deity */
1571 | xchar x, y;
1572 | {
1573 | if(!IS_ALTAR(levl[x][y].typ)) return((char *)0);
1574 |
1575 | return align_gname(a_align(x,y));
1576 | }
1577 |
1578 | const char *
1579 | u_gname() /* returns the name of the player's deity */
1580 | {
1581 | return align_gname(u.ualign.type);
1582 | }
1583 |
1584 | const char *
1585 | align_gname(alignment)
1586 | aligntyp alignment;
1587 | {
1588 | const char *gnam;
1589 |
1590 | switch (alignment) {
1591 | case A_NONE: gnam = Moloch; break;
1592 | case A_LAWFUL: gnam = urole.lgod; break;
1593 | case A_NEUTRAL: gnam = urole.ngod; break;
1594 | case A_CHAOTIC: gnam = urole.cgod; break;
1595 | default: impossible("unknown alignment.");
1596 | gnam = "someone"; break;
1597 | }
1598 | if (*gnam == '_') ++gnam;
1599 | return gnam;
1600 | }
1601 |
1602 | /* hallucination handling for priest/minion names: select a random god
1603 | iff character is hallucinating */
1604 | const char *
1605 | halu_gname(alignment)
1606 | aligntyp alignment;
1607 | {
1608 | const char *gnam;
1609 | int which;
1610 |
1611 | if (!Hallucination) return align_gname(alignment);
1612 |
1613 | which = randrole();
1614 | switch (rn2(3)) {
1615 | case 0: gnam = roles[which].lgod; break;
1616 | case 1: gnam = roles[which].ngod; break;
1617 | case 2: gnam = roles[which].cgod; break;
1618 | default: gnam = 0; break; /* lint suppression */
1619 | }
1620 | if (!gnam) gnam = Moloch;
1621 | if (*gnam == '_') ++gnam;
1622 | return gnam;
1623 | }
1624 |
1625 | /* deity's title */
1626 | const char *
1627 | align_gtitle(alignment)
1628 | aligntyp alignment;
1629 | {
1630 | const char *gnam, *result = "god";
1631 |
1632 | switch (alignment) {
1633 | case A_LAWFUL: gnam = urole.lgod; break;
1634 | case A_NEUTRAL: gnam = urole.ngod; break;
1635 | case A_CHAOTIC: gnam = urole.cgod; break;
1636 | default: gnam = 0; break;
1637 | }
1638 | if (gnam && *gnam == '_') result = "goddess";
1639 | return result;
1640 | }
1641 |
1642 | void
1643 | altar_wrath(x, y)
1644 | register int x, y;
1645 | {
1646 | aligntyp altaralign = a_align(x,y);
1647 |
1648 | if(!strcmp(align_gname(altaralign), u_gname())) {
1649 | godvoice(altaralign, "How darest thou desecrate my altar!");
1650 | (void) adjattrib(A_WIS, -1, FALSE);
1651 | } else {
1652 | pline("A voice (could it be %s?) whispers:",
1653 | align_gname(altaralign));
1654 | verbalize("Thou shalt pay, infidel!");
1655 | change_luck(-1);
1656 | }
1657 | }
1658 |
1659 | /* assumes isok() at one space away, but not necessarily at two */
1660 | STATIC_OVL boolean
1661 | blocked_boulder(dx,dy)
1662 | int dx,dy;
1663 | {
1664 | register struct obj *otmp;
1665 | long count = 0L;
1666 |
1667 | for(otmp = level.objects[u.ux+dx][u.uy+dy]; otmp; otmp = otmp->nexthere) {
1668 | if(otmp->otyp == BOULDER)
1669 | count += otmp->quan;
1670 | }
1671 |
1672 | switch(count) {
1673 | case 0: return FALSE; /* no boulders--not blocked */
1674 | case 1: break; /* possibly blocked depending on if it's pushable */
1675 | default: return TRUE; /* >1 boulder--blocked after they push the top
1676 | one; don't force them to push it first to find out */
1677 | }
1678 |
1679 | if (!isok(u.ux+2*dx, u.uy+2*dy))
1680 | return TRUE;
1681 | if (IS_ROCK(levl[u.ux+2*dx][u.uy+2*dy].typ))
1682 | return TRUE;
1683 | if (sobj_at(BOULDER, u.ux+2*dx, u.uy+2*dy))
1684 | return TRUE;
1685 |
1686 | return FALSE;
1687 | }
1688 |
1689 | /*pray.c*/