This is pray.c in view mode; [Download] [Up]
/* SCCS Id: @(#)pray.c 3.0 89/11/20 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ #include "hack.h" #ifdef THEOLOGY static int NDECL(in_trouble); static void FDECL(fix_worst_trouble,(int)); static void NDECL(angrygods); static void NDECL(pleased); static void NDECL(gods_upset); static void FDECL(consume_offering,(struct obj *)); #define ALIGNLIM (5L + (moves/200L)) struct ghods { char classlet; const char *law, *balance, *chaos; } gods[] = { 'A', /* Central American */ "Quetzalcotl", "Camaxtli", "Huhetotl", 'B', /* Celtic */ "Nuada", "Dagda", "Morrigan", 'C', /* Babylonian */ "Anu", "Ishtar", "Anshar", 'E', /* Elven */ "Solonor Thelandira", "Aerdrie Faenya", "Erevan Ilesere", 'H', /* Greek */ "Athena", "Hermes", "Poseidon", 'K', /* Celtic */ "Lugh", "Brigit", "Macannan Mac Lir", #ifdef NAMED_ITEMS /* It'd look funny if someone got a sword to steal souls for Arioch but Arioch * goes with the wrong character class... */ 'P', /* Hyborian */ "Mitra", "Crom", "Set", #else 'P', /* Melnibonean */ "Donblas", "Grome", "Arioch", #endif 'R', /* Nehwon */ "Votishal", "Death", "Rat God", 'S', /* Japanese */ "Amaterasu Omikami", "Raiden", "Susanowo", 'T', /* Chinese */ "Shan Lai Ching", "Chih Sung-tzu", "Huan Ti", 'V', /* Norse */ "Tyr", "Balder", "Loki", 'W', /* Egyptian */ "Ptah", "Thoth", "Anhur", 0,0,0,0 }; #define TROUBLE_STONED 9 #define TROUBLE_STRANGLED 8 #define TROUBLE_SICK 7 #define TROUBLE_STARVING 6 #define TROUBLE_HIT 5 #define TROUBLE_LYCANTHROPE 4 #define TROUBLE_STUCK_IN_WALL 3 #define TROUBLE_CURSED_BLINDFOLD 2 #define TROUBLE_CURSED_LEVITATION 1 #define TROUBLE_PUNISHED (-1) #define TROUBLE_CURSED_ITEMS (-2) #define TROUBLE_BLIND (-3) #define TROUBLE_HUNGRY (-4) #define TROUBLE_POISONED (-5) #define TROUBLE_WOUNDED_LEGS (-6) #define TROUBLE_STUNNED (-7) #define TROUBLE_CONFUSED (-8) #define TROUBLE_HALLUCINATION (-9) /* We could force rehumanize of polyselfed people, but we can't tell unintentional shape changes from the other kind. Oh well. */ /* Return 0 if nothing particular seems wrong, positive numbers for serious trouble, and negative numbers for comparative annoyances. This returns the worst problem. There may be others, and the gods may fix more than one. This could get as bizarre as noting surrounding opponents, (or hostile dogs), but that's really hard. */ #define ugod_is_angry() (u.ualign < 0) #ifdef ALTARS #define on_altar() IS_ALTAR(levl[u.ux][u.uy].typ) #define on_shrine() ((levl[u.ux][u.uy].altarmask & A_SHRINE) != 0) #endif static int in_trouble() { register struct obj *otmp; int i, j, count=0; /* Borrowed from eat.c */ #define SATIATED 0 #define NOT_HUNGRY 1 #define HUNGRY 2 #define WEAK 3 #define FAINTING 4 #define FAINTED 5 #define STARVED 6 if(Stoned) return(TROUBLE_STONED); if(Strangled) return(TROUBLE_STRANGLED); if(Sick) return(TROUBLE_SICK); if(u.uhs >= WEAK) return(TROUBLE_STARVING); if(u.uhp < 5 || (u.uhp*7 < u.uhpmax)) return(TROUBLE_HIT); for (i= -1; i<=1; i++) for(j= -1; j<=1; j++) { if (!i && !j) continue; if (!isok(u.ux+i, u.uy+j) || IS_ROCK(levl[u.ux+i][u.uy+j].typ)) count++; } #ifdef POLYSELF if(u.ulycn >= 0) return(TROUBLE_LYCANTHROPE); #endif if(count==8 #ifdef POLYSELF && !passes_walls(uasmon) #endif ) return(TROUBLE_STUCK_IN_WALL); if((uarmf && uarmf->otyp==LEVITATION_BOOTS && uarmf->cursed) || (uleft && uleft->otyp==RIN_LEVITATION && uleft->cursed) || (uright && uright->otyp==RIN_LEVITATION && uright->cursed)) return(TROUBLE_CURSED_LEVITATION); if(ublindf && ublindf->cursed) return(TROUBLE_CURSED_BLINDFOLD); if(Punished) return(TROUBLE_PUNISHED); for(otmp=invent; otmp; otmp=otmp->nobj) if((otmp->otyp==LOADSTONE || otmp->otyp==LUCKSTONE) && otmp->cursed) return(TROUBLE_CURSED_ITEMS); if((uarmh && uarmh->cursed) || /* helmet */ (uarms && uarms->cursed) || /* shield */ (uarmg && uarmg->cursed) || /* gloves */ (uarm && uarm->cursed) || /* armor */ (uarmc && uarmc->cursed) || /* cloak */ (uarmf && uarmf->cursed && uarmf->otyp != LEVITATION_BOOTS) || /* boots */ #ifdef SHIRT (uarmu && uarmu->cursed) || /* shirt */ #endif (uwep && welded(uwep)) || (uleft && uleft->cursed && uleft->otyp != RIN_LEVITATION) || (uright && uright->cursed && uright->otyp != RIN_LEVITATION) || (uamul && uamul->cursed)) return(TROUBLE_CURSED_ITEMS); if(Blinded > 1) return(TROUBLE_BLIND); if(u.uhs >= HUNGRY) return(TROUBLE_HUNGRY); for(i=0; i<A_MAX; i++) if(ABASE(i) < AMAX(i)) return(TROUBLE_POISONED); if(Wounded_legs) return (TROUBLE_WOUNDED_LEGS); if(HStun) return (TROUBLE_STUNNED); if(HConfusion) return (TROUBLE_CONFUSED); if(Hallucination) return(TROUBLE_HALLUCINATION); return(0); } const char leftglow[] = "left ring softly glows"; const char rightglow[] = "right ring softly glows"; static void fix_worst_trouble(trouble) register int trouble; { int i; struct obj *otmp = (struct obj *)0; const char *what = NULL; u.ublesscnt += rnz(100); switch (trouble) { case TROUBLE_STONED: You("feel more limber."); Stoned = 0; break; case TROUBLE_STRANGLED: You("can breathe again."); Strangled = 0; break; case TROUBLE_HUNGRY: case TROUBLE_STARVING: Your("stomach feels content."); init_uhunger (); losestr(-1); flags.botl = 1; break; case TROUBLE_SICK: You("feel better."); make_sick(0L,FALSE); break; case TROUBLE_HIT: if (!Blind) { pline("%s glow surrounds you.", An(Hallucination ? hcolor() : golden)); } else You("feel much better."); if (u.uhpmax < u.ulevel * 5 + 11) u.uhp = u.uhpmax += rnd(5); else u.uhp = u.uhpmax; flags.botl = 1; break; case TROUBLE_STUCK_IN_WALL: Your("surroundings change."); tele(); break; case TROUBLE_CURSED_LEVITATION: if (uarmf && uarmf->otyp==LEVITATION_BOOTS && uarmf->cursed) otmp = uarmf; else if (uleft && uleft->otyp==RIN_LEVITATION && uleft->cursed) { otmp = uleft; what = leftglow; } else { otmp = uright; what = rightglow; } goto decurse; case TROUBLE_CURSED_BLINDFOLD: otmp = ublindf; goto decurse; case TROUBLE_PUNISHED: Your("chain disappears."); unpunish(); break; #ifdef POLYSELF case TROUBLE_LYCANTHROPE: You("feel purified."); if(uasmon == &mons[u.ulycn] && !Polymorph_control) rehumanize(); u.ulycn = -1; /* now remove the curse */ break; #endif case TROUBLE_CURSED_ITEMS: if (uarmh && uarmh->cursed) /* helmet */ otmp = uarmh; else if (uarms && uarms->cursed) /* shield */ otmp = uarms; else if (uarmg && uarmg->cursed) /* gloves */ otmp = uarmg; else if (uarm && uarm->cursed) /* armor */ otmp = uarm; else if (uarmc && uarmc->cursed) /* cloak */ otmp = uarmc; else if (uarmf && uarmf->cursed) /* boots */ otmp = uarmf; #ifdef SHIRT else if (uarmu && uarmu->cursed) /* shirt */ otmp = uarmu; #endif else if (uleft && uleft->cursed) { otmp = uleft; what = leftglow; } else if (uright && uright->cursed) { otmp = uright; what = rightglow; } else if (uamul && uamul->cursed) /* amulet */ otmp = uamul; else if (welded(uwep)) otmp = uwep; else { for(otmp=invent; otmp; otmp=otmp->nobj) if ((otmp->otyp==LOADSTONE || otmp->otyp==LUCKSTONE) && otmp->cursed) break; } decurse: otmp->cursed = 0; otmp->bknown = 1; if (!Blind) Your("%s %s.", what ? what : (const char *)aobjnam (otmp, "softly glow"), Hallucination ? hcolor() : amber); break; case TROUBLE_HALLUCINATION: pline ("Looks like you are back in Kansas."); make_hallucinated(0L,FALSE); break; case TROUBLE_BLIND: Your("%s feel better.", makeplural(body_part(EYE))); make_blinded(0L,FALSE); break; case TROUBLE_POISONED: if (Hallucination) pline("There's a tiger in your tank."); else You("feel in good health again."); for(i=0; i<A_MAX; i++) { if(ABASE(i) < AMAX(i)) { ABASE(i) = AMAX(i); flags.botl = 1; } } break; case TROUBLE_WOUNDED_LEGS: heal_legs(); break; case TROUBLE_STUNNED: make_stunned(0L,TRUE); break; case TROUBLE_CONFUSED: make_confused(0L,TRUE); break; } } static void angrygods() { register int tmp; u.ublessed = 0; /* changed from tmp = u.ugangr + abs (u.uluck) -- rph */ tmp = 3*u.ugangr + (Luck > 0 || u.ualign > 3 ? -Luck/3 : -Luck); if (tmp < 0) tmp = 0; /* possible if bad alignment but good luck */ tmp = (tmp > 15 ? 15 : tmp); /* lets be a little reasonable */ switch (tmp ? rn2(tmp): 0) { case 0: case 1: if (Hallucination) You("feel a%sholy dread.", u.ualigntyp == U_CHAOTIC ? "n un" : " "); else You("feel that %s is %s.", # ifdef ALTARS on_altar() ? a_gname() : u_gname(), # else u_gname(), # endif u.ualigntyp == U_NEUTRAL ? "offended" : "angry"); break; case 2: case 3: pline("A voice thunders:"); # ifdef POLYSELF pline("\"Thou %s, %s.\"", ugod_is_angry() ? "hast strayed from the path" : "art arrogant", u.usym == S_HUMAN ? "mortal" : "creature"); # else pline("\"Thou %s, mortal.\"", ugod_is_angry() ? "hast strayed from the path" : "art arrogant"); # endif verbalize("Thou must relearn thy lessons!"); adjattrib(A_WIS, -1, FALSE); if (u.ulevel > 1) { losexp(); if(u.uhp < 1) u.uhp = 1; if(u.uhpmax < 1) u.uhpmax = 1; } else { u.uexp = 0; flags.botl = 1; } break; case 6: if (!Punished) { punish((struct obj *)0); break; } /* else fall thru */ case 4: case 5: if (!Blind) pline("%s glow surrounds you.", An(Hallucination ? hcolor() : black)); rndcurse(); break; case 7: case 8: pline("A voice booms out:"); verbalize("Thou durst call upon me?"); # ifdef POLYSELF pline("\"Then die, %s!\"", u.usym == S_HUMAN ? "mortal" : "creature"); # else verbalize("Then die, mortal!"); # endif (void) makemon(&mons[ndemon()], u.ux, u.uy); break; default: pline("Suddenly, a bolt of lightning strikes you!"); if (Reflecting) { shieldeff(u.ux, u.uy); if (Blind) pline("For some reason you're unaffected."); else { if (Reflecting & W_AMUL) { pline("It reflects from your medallion."); makeknown(AMULET_OF_REFLECTION); } else { pline("It reflects from your shield."); makeknown(SHIELD_OF_REFLECTION); } } You("hear a cosmic sigh, and sense a decision being made."); pline("A wide-angle disintegration beam hits you!"); goto ohno; } else if (Shock_resistance) { shieldeff(u.ux, u.uy); pline("It seems not to affect you."); pline("However, the ensuing disintegration beam does."); ohno: if (Disint_resistance) { You("bask in the disintegration beam for a minute..."); pline("A voice rings out:"); verbalize("I believe it not!"); break; } } You("fry to a crisp."); killer_format = KILLED_BY_AN; killer = "holy wrath"; done(DIED); break; } u.ublesscnt = rnz(300); return; } static void pleased() { int trouble = in_trouble (); /* what's your worst difficulty? */ int pat_on_head = 0; You("feel that %s is pleased.", #ifndef ALTARS u_gname()); #else on_altar() ? a_gname() : u_gname()); /* not your deity */ if (on_altar() && (levl[u.ux][u.uy].altarmask & ~A_SHRINE) != u.ualigntyp + 1) { adjalign(-1); return; } else if (u.ualign < 2) adjalign(1); #endif /* depending on your luck, the gods will: - fix your worst problem if it's major. - fix all your major problems. - fix your worst problem if it's minor. - fix all of your problems. - do you a gratuitous favor. if you make it to the the last category, you roll randomly again to see what they do for you. If your luck is at least 0, then you are guaranteed rescued from your worst major problem. */ if (!trouble) pat_on_head = 1; else { #ifdef ALTARS int action = rn1(on_altar() ? 3 + on_shrine() : 2, Luck+1); if (!on_altar()) action = max(action,2); #else int action = rn1(4,Luck+1); #endif switch(min(action,5)) { case 5: pat_on_head = 1; case 4: do fix_worst_trouble(trouble); while(trouble = in_trouble()); break; case 3: fix_worst_trouble(trouble); case 2: while((trouble = in_trouble()) > 0) fix_worst_trouble(trouble); break; case 1: if (trouble > 0) fix_worst_trouble(trouble); } } if(pat_on_head) switch(rn2((Luck + 6)>>1)) { case 0: break; case 1: if(uwep && (uwep->olet == WEAPON_SYM || uwep->otyp == PICK_AXE) && (!uwep->blessed)) { if (uwep->cursed) { uwep->cursed = 0; uwep->bknown = 1; if (!Blind) Your("%s %s.", aobjnam(uwep, "softly glow"), Hallucination ? hcolor() : amber); } else if(uwep->otyp < BOW) { uwep->blessed = uwep->bknown = 1; if (!Blind) { Your("%s with %s aura.", aobjnam(uwep, "softly glow"), an(Hallucination ? hcolor() : light_blue)); } } } break; case 3: #if defined(STRONGHOLD) && defined(MUSIC) /* takes 2 hints to get the music to enter the stronghold */ if (flags.soundok) { if(music_heard < 1) { pline("A voice rings out:"); # ifdef POLYSELF pline("\"Hark, %s!\"", u.usym == S_HUMAN ? "mortal" : "creature"); # else verbalize("Hark, mortal!"); # endif verbalize("To enter the castle, thou must play the right tune!"); music_heard++; break; } else if (music_heard < 2) { You("hear a divine music..."); pline("It sounds like: \"%s\".", tune); music_heard++; break; } } /* Otherwise, falls into next case */ #endif case 2: if (!Blind) You("are surrounded by %s glow.", an(Hallucination ? hcolor() : golden)); u.uhp = u.uhpmax += 5; ABASE(A_STR) = AMAX(A_STR); if (u.uhunger < 900) init_uhunger(); if (u.uluck < 0) u.uluck = 0; make_blinded(0L,TRUE); flags.botl = 1; break; case 4: { register struct obj *otmp; if (Blind) You("feel the power of %s.", u_gname()); else You("are surrounded by %s aura.", an(Hallucination ? hcolor() : light_blue)); for(otmp=invent; otmp; otmp=otmp->nobj) { if (otmp->cursed) { otmp->cursed = 0; if (!Blind) Your("%s %s.", aobjnam(otmp, "softly glow"), Hallucination ? hcolor() : amber); } } break; } case 5: { const char *msg="\"and thus I grant thee the gift of %s!\""; pline("A voice booms out:"); verbalize("Thou hast pleased me with thy progress,"); if (!(HTelepat & INTRINSIC)) { HTelepat |= INTRINSIC; pline(msg, "Telepathy"); } else if (!(Fast & INTRINSIC)) { Fast |= INTRINSIC; pline(msg, "Speed"); } else if (!(Stealth & INTRINSIC)) { Stealth |= INTRINSIC; pline(msg, "Stealth"); } else { if (!(Protection & INTRINSIC)) { Protection |= INTRINSIC; if (!u.ublessed) u.ublessed = rnd(3) + 1; } else u.ublessed++; pline(msg, "my protection"); } verbalize("Use it wisely in my name!"); break; } case 7: case 8: #ifdef ELBERETH if (u.ualign > 3 && !u.uhand_of_elbereth) { u.uhand_of_elbereth = TRUE; HSee_invisible |= INTRINSIC; HFire_resistance |= INTRINSIC; HCold_resistance |= INTRINSIC; HPoison_resistance |= INTRINSIC; pline("A voice booms out:"); if (u.ualigntyp != U_CHAOTIC) { verbalize("I crown thee... The Hand of Elbereth!"); #ifdef NAMED_ITEMS if(uwep && (uwep->otyp == LONG_SWORD)) { bless(uwep); uwep->bknown = 1; uwep->rustfree = 1; (void)oname(uwep, "Excalibur", 1); } #endif } else { register struct obj *obj; #ifdef NAMED_ITEMS const char *Stormbringer = "Stormbringer"; /* This does the same damage as Excalibur. * Disadvantages: doesn't do bonuses to undead; * doesn't aid searching. * Advantages: part of that bonus is a level * drain. * Disadvantage: player cannot start with a * +5 weapon and turn it into a Stormbringer. * Advantage: they don't need to already have a * sword of the right type to get it... * However, if Stormbringer already exists in * the game, an ordinary good broadsword is * given and the messages are a bit different. */ obj = mksobj(BROADSWORD, FALSE); if (exist_artifact(obj, Stormbringer)) verbalize("Thou art chosen to take lives for Arioch!"); else verbalize("Thou art chosen to steal souls for Arioch!"); if (Blind) pline("Something appears at your %s.", makeplural(body_part(FOOT))); else pline("%s sword appears at your %s!", An(exist_artifact(obj, Stormbringer) ? (const char *)"wide" : Hallucination ? hcolor() : black), makeplural(body_part(FOOT))); obj->rustfree = 1; obj->cursed = 0; /* Why bless it? Why not. After all, chaotic gods * will bless regular weapons. And blessed really * means given sanctified to a deity, which is certainly * sensible even for Stormbringer and a chaotic deity... */ obj->blessed = 1; /* if not "Stormbringer", make it a bit better otherwise */ if (exist_artifact(obj, Stormbringer)) obj->spe = 3; else obj->spe = 1; /* existence of "Stormbringer" is checked in oname() */ obj = oname(obj, Stormbringer, 0); dropy(obj); #else verbalize("Thou shalt become the servant of Arioch!"); #endif } break; } #endif case 6: pline ("An object appears at your %s!", makeplural(body_part(FOOT))); #ifdef SPELLS bless(mkobj_at(SPBOOK_SYM, u.ux, u.uy)); #else bless(mkobj_at(SCROLL_SYM, u.ux, u.uy)); #endif break; default: impossible("Confused deity!"); break; } u.ublesscnt = rnz(350); #ifdef HARD # ifndef ELBERETH u.ublesscnt += (u.udemigod * rnz(1000)); # else u.ublesscnt += ((u.udemigod + u.uhand_of_elbereth) * rnz(1000)); # endif #endif return; } static void gods_upset() { #ifdef HARD u.ugangr++; angrygods(); #else if (u.ugangr++) angrygods(); else { /* exactly one warning */ # ifdef ALTARS pline("The voice of %s booms out:", on_altar() ? a_gname() : u_gname()); # else pline("A voice booms out:"); # endif verbalize("Thou hast angered me."); verbalize("Disturb me again at thine own peril!"); } #endif } #ifdef ENDGAME static const char sacrifice_types[] = { FOOD_SYM, AMULET_SYM, 0 }; #endif static void consume_offering(otmp) register struct obj *otmp; { if (Hallucination) Your("sacrifice sprouts wings and a propeller and roars away!"); else if (Blind && u.ualigntyp == U_LAWFUL) Your("sacrifice disappears!"); else Your("sacrifice is consumed in a %s!", u.ualigntyp == U_LAWFUL ? "flash of light" : "burst of flame"); if (carried(otmp)) useup(otmp); else useupf(otmp); } int dosacrifice() { register struct obj *otmp; int value = 0; #ifdef ALTARS /* Note: normal altar aligns are 0, 1, 2; this is -1, 0, 1 so it */ /* can be compared with u.ualigntyp */ int altaralign = (levl[u.ux][u.uy].altarmask & ~A_SHRINE) - 1; if (!on_altar()) { You("are not standing on an altar."); return 0; } #endif /* ALTARS /**/ #ifdef ENDGAME if (dlevel == ENDLEVEL) { if (!(otmp = getobj(sacrifice_types, "sacrifice"))) return 0; } else if (!(otmp = floorfood("sacrifice", 0))) return 0; #else if (!(otmp = floorfood("sacrifice", 0))) return 0; #endif /* Was based on nutritional value and aging behavior (< 50 moves). Sacrificing a food ration got you max luck instantly, making the gods as easy to please as an angry dog! Now only accepts corpses, based on the games evaluation of their toughness. Human sacrifice, as well as sacrificing unicorns of your alignment, is strongly discouraged. (We can't tell whether a pet corpse was tame, so you can still sacrifice it.) */ #define MAXVALUE 24 /* Highest corpse value (besides Wiz) */ if (otmp->otyp == CORPSE) { register struct permonst *mtmp = &mons[otmp->corpsenm]; extern int monstr[]; if (otmp->corpsenm == PM_ACID_BLOB || (monstermoves <= otmp->age + 50)) value = monstr[otmp->corpsenm] + 1; if (otmp->oeaten) value = eaten_stat(value, otmp); if (is_human(mtmp)) { /* Human sacrifice! */ #ifdef POLYSELF if (is_demon(uasmon)) You("find the idea very satisfying."); else #endif if (u.ualigntyp != U_CHAOTIC) pline("You'll regret this infamous offense!"); #ifdef ALTARS if (altaralign != U_CHAOTIC) { /* curse the lawful/neutral altar */ pline("The altar is stained with human blood."); levl[u.ux][u.uy].altarmask = A_CHAOS; angry_priest(); } else { register struct monst *dmon; /* Human sacrifice on a chaotic altar is equivalent to demon summoning */ #ifdef THEOLOGY if (altaralign == U_CHAOTIC) pline("The blood covers the altar!"); else { #endif pline("The blood floods over the altar, which vanishes in %s cloud!", an(Hallucination ? hcolor() : black)); levl[u.ux][u.uy].typ = ROOM; levl[u.ux][u.uy].altarmask = 0; #ifdef THEOLOGY } #endif change_luck(2); if(Invisible) newsym(u.ux, u.uy); if(dmon = makemon(&mons[dlord()], u.ux, u.uy)) { You("have summoned a demon lord!"); if (u.ualigntyp == U_CHAOTIC) dmon->mpeaceful = 1; You("are terrified, and unable to move."); nomul(-3); } else pline("The cloud dissipates."); } #endif if (u.ualigntyp != U_CHAOTIC) { adjalign(-5); u.ugangr += 3; adjattrib(A_WIS, -1, TRUE); if (!Inhell) angrygods(); change_luck(-5); } else adjalign(5); if (carried(otmp)) useup(otmp); else useupf(otmp); return(1); } else if (is_undead(mtmp)) { /* Not demons--no demon corpses */ if (u.ualigntyp != U_CHAOTIC) value += 1; } else if (mtmp->mlet == S_UNICORN) { int unicalign; if (mtmp == &mons[PM_BLACK_UNICORN]) unicalign = -1; else if (mtmp == &mons[PM_GRAY_UNICORN]) unicalign = 0; else if (mtmp == &mons[PM_WHITE_UNICORN]) unicalign = 1; #ifdef __GNULINT__ else { impossible("Bad unicorn type??"); unicalign = 0; } #endif /* If same as altar, always a very bad action. */ if (unicalign == altaralign) { pline("Such an action is an insult to %s!", (unicalign== -1) ? "chaos" : unicalign ? "law" : "neutrality"); adjattrib(A_WIS, -1, TRUE); value = -5; } else if (u.ualigntyp == altaralign) { /* If different from altar, and altar is same as yours, */ /* get maximum alignment */ if (u.ualign < ALIGNLIM) You("feel stridently %s!", (u.ualigntyp== U_CHAOTIC) ? "chaotic" : u.ualigntyp ? "lawful" : "neutral"); else You("feel you are thoroughly on the right path."); u.ualign = ALIGNLIM; value += 3; } else if (unicalign == u.ualigntyp) { /* If sacrificing unicorn of your alignment to altar not of */ /* your alignment, your god gets angry and it's a conversion */ u.ualign = -1; value = 1; } else value += 3; } } #ifdef ENDGAME if (otmp->otyp == AMULET_OF_YENDOR) { if (dlevel != ENDLEVEL) { if (otmp->spe == 0) { if (Hallucination) You("feel homesick."); else You("feel an urge to return to the surface."); return (1); } } else if (otmp->spe < 0) { /* fake! */ if (flags.soundok) You("hear a nearby thunderclap."); if (!otmp->known) { You("realize you have made a %s.", Hallucination ? "boo-boo" : "mistake"); otmp->known = 1; return (1); } else { /* don't you dare try to fool the gods */ change_luck(-3); u.ugangr += 3; value = -3; } } else { /* The final Test. Did you win? */ if(uamul == otmp) Amulet_off(); if(carried(otmp)) useup(otmp); /* well, it's gone now */ else useupf(otmp); You("offer the Amulet to %s...", a_gname()); if (u.ualigntyp != altaralign) { /* And the opposing team picks him up and carries him off on their shoulders */ pline("%s accepts your gift, and gains dominion over %s...", a_gname(), u_gname()); pline("%s is enraged...", u_gname()); pline("Fortunately, %s permits you to live...", a_gname()); pline("A cloud of %s smoke surrounds you...", Hallucination ? hcolor() : (const char *)"orange"); done(ESCAPED); } else { /* super big win */ pline("An invisible choir sings, and you are bathed in radiance..."); verbalize("Congratulations, mortal!"); more(); verbalize("In return for thy service, I grant thee the gift of Immortality!"); You("ascend to the status of Demigod..."); done(ASCENDED); } } } #endif /* ENDGAME */ #ifndef ALTARS /* No altars in shops */ if (otmp->unpaid && u.ualigntyp != U_CHAOTIC) { You("realize sacrificing what is not yours is a very chaotic act."); value = -3; } #endif if (value == 0 #ifndef ALTARS || Inhell #endif ) { pline(nothing_happens); return (1); } if (value < 0) /* I don't think the gods are gonna like this... */ gods_upset(); else { int saved_anger = u.ugangr; int saved_cnt = u.ublesscnt; int saved_luck = u.uluck; boolean consumed = FALSE; #ifdef ALTARS /* Sacrificing at an altar of a different alignment */ if (u.ualigntyp != altaralign) { /* Is this a conversion ? */ if(ugod_is_angry()) { if(u.ualignbase[0] == u.ualignbase[1]) { consume_offering(otmp); You("have a strong feeling that %s is angry...", u_gname()); pline("%s accepts your allegiance.",a_gname()); You("have a sudden sense of a new direction."); /* The player wears a helm of opposite alignment? */ if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT) u.ualignbase[0] = altaralign; else u.ualigntyp = u.ualignbase[0] = altaralign; flags.botl = 1; /* Beware, Conversion is costly */ change_luck(-3); u.ublesscnt += 300; adjalign((int)(u.ualignbase[1] * (ALIGNLIM / 2))); } else { pline("%s rejects your sacrifice!", a_gname()); pline("The voice of %s booms:", u_gname()); verbalize("Suffer, infidel!"); adjalign(-5); u.ugangr += 3; adjattrib(A_WIS, -2, TRUE); if (!Inhell) angrygods(); change_luck(-5); } return(1); } else { consume_offering(otmp); consumed = TRUE; You("sense a conflict between %s and %s.", u_gname(), a_gname()); if (rn2(8 + (int)u.ulevel) > 5) { You("feel the power of %s increase.", u_gname()); change_luck(1); levl[u.ux][u.uy].altarmask &= A_SHRINE; /* the following accommodates stupid compilers */ levl[u.ux][u.uy].altarmask = levl[u.ux][u.uy].altarmask | (u.ualigntyp + 1); if (!Blind) pline("The newly consecrated altar glows %s.", Hallucination ? hcolor() : u.ualigntyp == U_LAWFUL ? white : u.ualigntyp ? black : (const char *)"gray"); } else { pline("Unluckily, you feel the power of %s decrease.", u_gname()); change_luck(-1); } return(1); } } #endif if(!consumed) consume_offering(otmp); /* OK, you get brownie points. */ if(u.ugangr) { u.ugangr -= ((value * (u.ualigntyp == U_CHAOTIC ? 2 : 3)) / MAXVALUE); if(u.ugangr < 0) u.ugangr = 0; if(u.ugangr != saved_anger) { if (u.ugangr) { if(Hallucination) pline("The gods seem %s.", hcolor()); else pline("The gods seem slightly mollified."); if ((int)u.uluck < 0) change_luck(1); } else { if (Hallucination) pline("The gods seem cosmic (not a new fact)."); else pline ("The gods seem mollified."); if ((int)u.uluck < 0) u.uluck = 0; } } else { /* not satisfied yet */ if (Hallucination) pline("The gods seem tall."); else You("have a feeling of inadequacy."); } } else if (u.ublesscnt > 0) { u.ublesscnt -= ((value * (u.ualigntyp == U_CHAOTIC ? 500 : 300)) / MAXVALUE); if(u.ublesscnt < 0) u.ublesscnt = 0; if(u.ublesscnt != saved_cnt) { if (u.ublesscnt) { if (Hallucination) You("realize that the gods are not like you and I."); else You("have a hopeful feeling."); if ((int)u.uluck < 0) change_luck(1); } else { if (Hallucination) pline("Overall, there is a smell of fried onions."); else You("have a feeling of reconciliation."); if ((int)u.uluck < 0) u.uluck = 0; } } } else { /* you were already in pretty good standing */ #if defined(ALTARS) && defined(NAMED_ITEMS) /* The player can gain an artifact */ if(!rn2(10)) { otmp = mk_aligned_artifact((unsigned)(levl[u.ux][u.uy].altarmask & ~A_SHRINE)); if(otmp) { if (otmp->spe < 0) otmp->spe = 0; if (otmp->cursed) otmp->cursed = 0; dropy(otmp); pline("An object appears at your %s!", makeplural(body_part(FOOT))); return(1); } } #endif change_luck((value * LUCKMAX) / (MAXVALUE * 2)); if (u.uluck != saved_luck) { if (Blind) You("think something brushed your %s.", body_part(FOOT)); else You(Hallucination ? "see crabgrass at your %s. A funny thing in a dungeon." : "glimpse a four-leaf clover at your %s.", makeplural(body_part(FOOT))); } } } return(1); } int dopray() { /* M. Stephenson (1.0.3b) */ int trouble = in_trouble(); #ifdef ALTARS int aligntyp = on_altar() ? (int)(levl[u.ux][u.uy].altarmask & ~A_SHRINE) - 1 : u.ualigntyp; int align; if (u.ualigntyp && u.ualigntyp == -aligntyp) align = -u.ualign; /* Opposite alignment altar */ else if (u.ualigntyp != aligntyp) align = u.ualign / 2; /* Different (but non-opposite) alignment altar */ else align = u.ualign; #else int aligntyp = u.ualigntyp; int align = u.ualign; #endif #ifdef POLYSELF if (is_undead(uasmon)) { if (aligntyp == 1 || (aligntyp == 0 && !rn2(10))) { verbalize(aligntyp == 1 ? "Vile creature, thou durst call upon me?" : "Walk no more, perversion of nature!"); You("feel like you are falling apart."); rehumanize(); losehp(rnd(20), "residual undead turning effect", KILLED_BY_AN); return(1); } } if (is_demon(uasmon) && (aligntyp != -1)) { pline("The very idea of praying to a %s god is repugnant to you.", u.ualigntyp ? "lawful" : "neutral"); return(0); } #endif if (Inhell && u.ualigntyp != U_CHAOTIC) { pline("Since you are in hell, %s won't help you.", # ifdef ALTARS on_altar() ? a_gname() : # endif u_gname()); aggravate(); return(0); } #ifdef WIZARD if (wizard) { pline("Force the gods to be pleased? "); if (yn() == 'y') { u.ublesscnt = 0; if (u.uluck < 0) u.uluck = 0; u.ugangr = 0; if (align < 1) align = 1; } } #endif if ((!trouble && (u.ublesscnt > 0)) || ((trouble < 0) && (u.ublesscnt > 100)) /* minor difficulties */ || ((trouble > 0) && (u.ublesscnt > 200)) /* big trouble */ ) { u.ublesscnt += rnz(250); change_luck(-3); gods_upset(); } else if ((int)Luck < 0 || u.ugangr || align < 0) angrygods(); /* naughty */ else if (align >= 0) pleased(); /* nice */ nomovemsg = "You finish your prayer."; nomul(-3); return(1); } #endif /* THEOLOGY */ int doturn() { /* Knights & Priest(esse)s only please */ register struct monst *mtmp; register int xlev = 6; if((pl_character[0] != 'P') && (pl_character[0] != 'K')) { #ifdef SPELLS /* Try to use turn undead spell. */ if (objects[SPE_TURN_UNDEAD].oc_name_known) { register int sp_no; for (sp_no = 0; sp_no < MAXSPELL && spl_book[sp_no].sp_id != NO_SPELL && spl_book[sp_no].sp_id != SPE_TURN_UNDEAD; sp_no++); if (sp_no < MAXSPELL && spl_book[sp_no].sp_id == SPE_TURN_UNDEAD) return spelleffects(++sp_no, TRUE); } #endif You("don't know how to turn undead!"); return(0); } #if defined(POLYSELF) || defined(THEOLOGY) if ( # ifdef POLYSELF (u.ualigntyp != U_CHAOTIC && (is_demon(uasmon) || is_undead(uasmon))) # endif # if defined(POLYSELF) && defined(THEOLOGY) || # endif # ifdef THEOLOGY u.ugangr > 6 /* "Die, mortal!" */ # endif ) { pline("For some reason, the gods seem to ignore you."); aggravate(); return(0); } #endif if (Inhell && u.ualigntyp != U_CHAOTIC) { #ifdef THEOLOGY pline("Since you are in hell, %s won't help you.", u_gname()); #else pline("Since you are in hell, the gods won't help you."); #endif aggravate(); return(0); } #ifdef THEOLOGY pline("Calling upon %s, you chant an arcane formula.", u_gname()); #else pline("Calling upon the gods, you chant an arcane formula."); #endif for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(cansee(mtmp->mx,mtmp->my)) { if(!mtmp->mtame && !mtmp->mpeaceful && (is_undead(mtmp->data) || (is_demon(mtmp->data) && (u.ulevel > (MAXULEV/2))))) { if(Confusion) { pline("Unfortunately, your voice falters."); mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0; mtmp->mcanmove = 1; } else if (! resist(mtmp, '\0', 0, TELL)) switch (mtmp->data->mlet) { /* this is intentional, lichs are tougher than zombies. */ case S_LICH: xlev += 2; case S_GHOST: xlev += 2; case S_VAMPIRE: xlev += 2; case S_WRAITH: xlev += 2; case S_MUMMY: xlev += 2; case S_ZOMBIE: mtmp->mflee = 1; /* at least */ if(u.ulevel >= xlev) { if(!resist(mtmp, '\0', 0, NOTELL)) { if(u.ualigntyp == U_CHAOTIC) { mtmp->mpeaceful = 1; /* make them friendly */ } else { /* damn them */ You("destroy %s!", mon_nam(mtmp)); mondied(mtmp); } } } break; default: mtmp->mflee = 1; break; } } } nomul(-5); return(1); } #ifdef ALTARS const char * a_gname() { return(a_gname_at(u.ux, u.uy)); } const char * a_gname_at(x,y) /* returns the name of an altar's deity */ xchar x, y; { register int align; if(!IS_ALTAR(levl[x][y].typ)) return((char *)0); align = levl[x][y].altarmask & ~A_SHRINE; # ifdef THEOLOGY {struct ghods *aghod; for(aghod=gods; aghod->classlet; aghod++) if(aghod->classlet == pl_character[0]) switch(align) { case A_CHAOS: return(aghod->chaos); case A_NEUTRAL: return(aghod->balance); case A_LAW: return(aghod->law); default: impossible("unknown altar alignment."); return("Balance"); } impossible("Altar to unknown character's god?"); return("someone"); } # else switch(align) { case A_CHAOS: return("Chaos"); case A_NEUTRAL: return("Balance"); case A_LAW: return("Law"); default: impossible("unknown altar alignment."); return("Balance"); } # endif /* THEOLOGY */ } # ifdef THEOLOGY void altar_wrath(x, y) register int x, y; { if(!strcmp(a_gname_at(x,y), u_gname())) { pline("The voice of %s booms:", a_gname_at(x,y)); verbalize("How darest thou desecrate my altar!"); adjattrib(A_WIS, -1, FALSE); } else { pline("A voice whispers in your ear:"); verbalize("Thou shalt pay, infidel!"); change_luck(-1); } } # endif /* THEOLOGY */ #endif /* ALTARS */ #ifdef THEOLOGY const char * u_gname() { /* returns the name of the player's deity */ register struct ghods *aghod; for(aghod=gods; aghod->classlet; aghod++) if(aghod->classlet == pl_character[0]) switch(u.ualigntyp) { case 1: return(aghod->law); case 0: return(aghod->balance); case -1: return(aghod->chaos); default: impossible("unknown character alignment."); return("Balance"); } impossible("atheist player?"); return("someone"); } #endif /* THEOLOGY */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.