billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 63
Archive-name: nethack3p9/Part18
Supersedes: NetHack3: Volume 7, Issue 56-93
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 18 (of 56)."
# Contents: src/dokick.c src/pray.c
# Wrapped by billr@saab on Wed Jul 11 17:11:15 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/dokick.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/dokick.c'\"
else
echo shar: Extracting \"'src/dokick.c'\" \(18914 characters\)
sed "s/^X//" >'src/dokick.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)dokick.c 3.0 89/6/9
X/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X#include "eshk.h"
X
X#define martial() ((pl_character[0] == 'S' || pl_character[0] == 'P'))
X
Xstatic struct rm NEARDATA *maploc;
X
X#ifdef KICK
X
X# ifdef WORM
Xextern boolean notonhead;
X# endif
X
Xstatic void FDECL(kickdmg, (struct monst *, BOOLEAN_P));
Xstatic void FDECL(kick_monster, (int, int));
Xstatic int FDECL(kick_object, (int, int));
Xstatic char *NDECL(kickstr);
X
Xstatic struct obj NEARDATA *kickobj;
X
Xstatic void
Xkickdmg(mon, clumsy)
Xregister struct monst *mon;
Xregister boolean clumsy;
X{
X register int mdx, mdy;
X register int dmg = (((uarmg &&
X uarmg->otyp == GAUNTLETS_OF_POWER) ?
X 25 : ACURR(A_STR) > 18 ? 18 : ACURR(A_STR))+
X ACURR(A_DEX)+ACURR(A_CON))/15;
X
X /* excessive wt affects dex, so it affects dmg */
X if(clumsy) dmg = dmg/2;
X
X /* kicking a dragon or an elephant will not harm it */
X if(thick_skinned(mon->data)) dmg = 0;
X
X
X /* squeeze some guilt feelings... */
X if(mon->mtame) {
X# ifdef SOUNDS
X if (rn2(10)) yelp(mon);
X else growl(mon); /* give them a moment's worry */
X# endif
X mon->mtame--;
X mon->mflee = mon->mtame ? 1 : 0;
X# ifdef HISX
X mon->mfleetim = mon->mfleetim + (dmg ? rnd(dmg) : 1);
X# else
X mon->mfleetim += (dmg ? rnd(dmg) : 1);
X# endif
X }
X
X if (dmg)
X mon->mhp -= (!martial() ? rnd(dmg) :
X rnd(dmg)+rnd(ACURR(A_DEX)/2));
X if(mon->mhp < 1) {
X (void) passive(mon, TRUE, 0, TRUE);
X killed(mon);
X return;
X }
X if(martial() && !bigmonst(mon->data) && !rn2(3) && mon->mcanmove) {
X /* see if the monster has a place to move into */
X mdx = mon->mx + u.dx;
X mdy = mon->my + u.dy;
X if(goodpos(mdx, mdy, mon->data)) {
X kludge("%s reels from the blow.", Monnam(mon));
X remove_monster(mon->mx, mon->my);
X place_monster(mon, mdx, mdy);
X pmon(mon);
X set_apparxy(mon);
X }
X }
X (void) passive(mon, FALSE, 1, TRUE);
X
X/* it is unchivalrous to attack the defenseless or from behind */
X if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL &&
X u.ualign > -10 && (!mon->mcanmove || mon->msleep || mon->mflee))
X adjalign(-1);
X
X}
X
Xstatic void
Xkick_monster(x, y)
Xregister int x, y;
X{
X register boolean clumsy = FALSE;
X register struct monst *mon = m_at(x, y);
X register int i, j;
X
X if(special_case(mon)) return;
X setmangry(mon);
X#ifdef POLYSELF
X /* Kick attacks by kicking monsters are normal attacks, not special.
X * If you have >1 kick attack, you get all of them.
X */
X if (attacktype(uasmon, AT_KICK)) {
X schar tmp = find_roll_to_hit(mon);
X for(i=0; i<NATTK; i++) {
X int sum = 0;
X if (uasmon->mattk[i].aatyp == AT_KICK && multi >= 0) {
X /* check multi; maybe they had 2 kicks and the first */
X /* was a kick against a floating eye */
X j = 1;
X if (tmp > rnd(20)) {
X kludge("You kick %s.", mon_nam(mon));
X sum = damageum(mon, &(uasmon->mattk[i]));
X if (sum == 2)
X (void)passive(mon, 1, 0, TRUE);
X else (void)passive(mon, sum, 1, TRUE);
X } else {
X missum(mon, &(uasmon->mattk[i]));
X (void)passive(mon, 0, 1, TRUE);
X }
X }
X }
X return;
X }
X#endif
X
X /* no need to check POLYSELF since only ghosts, which you can't turn */
X /* into, are noncorporeal */
X if(noncorporeal(mon->data)) {
X Your("kick passes through!");
X return;
X }
X
X if(Levitation && !rn2(3) && verysmall(mon->data) &&
X !is_flyer(mon->data)) {
X pline("Floating in the air, you miss wildly!");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X
X i = abs(inv_weight());
X j = weight_cap();
X
X if(i < (j*3)/10) {
X if(!rn2((i < j/10) ? 2 : (i < j/5) ? 3 : 4)) {
X if(martial() && !rn2(2)) goto doit;
X Your("clumsy kick does no damage.");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X if(i < j/10) clumsy = TRUE;
X else if(!rn2((i < j/5) ? 2 : 3)) clumsy = TRUE;
X }
X
X if(Fumbling) clumsy = TRUE;
X
X else if(uarm && objects[uarm->otyp].oc_bulky && ACURR(A_DEX) < rnd(25))
X clumsy = TRUE;
Xdoit:
X kludge("You kick %s.", mon_nam(mon));
X if(!rn2(clumsy ? 3 : 4) && (clumsy || !bigmonst(mon->data)) &&
X mon->mcansee && !mon->mtrapped && !thick_skinned(mon->data) &&
X mon->data->mlet != S_EEL && haseyes(mon->data) && mon->mcanmove &&
X !mon->mstun && !mon->mconf && !mon->msleep &&
X mon->data->mmove >= 12) {
X if(!nohands(mon->data) && !rn2(martial() ? 5 : 3)) {
X kludge("%s blocks your %skick.", Monnam(mon),
X clumsy ? "clumsy " : "");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X } else {
X mnexto(mon);
X if(mon->mx != x || mon->my != y) {
X pline("%s %s, %s evading your %skick.",
X Blind ? "It" : Monnam(mon),
X (can_teleport(mon->data) ? "teleports" :
X is_floater(mon->data) ? "floats" :
X is_flyer(mon->data) ? "flutters" :
X nolimbs(mon->data) ? "slides" :
X "jumps"),
X clumsy ? "easily" : "nimbly",
X clumsy ? "clumsy " : "");
X (void) passive(mon, FALSE, 1, TRUE);
X return;
X }
X }
X }
X kickdmg(mon, clumsy);
X}
X#endif /* KICK */
X
X/* return TRUE if caught, FALSE otherwise */
Xboolean
Xghitm(mtmp, amount)
Xregister struct monst *mtmp;
Xregister long amount;
X{
X if(!likes_gold(mtmp->data) && !mtmp->isshk
X#if defined(ALTARS) && defined(THEOLOGY)
X && !mtmp->ispriest
X#endif
X )
X wakeup(mtmp);
X else {
X mtmp->msleep = 0;
X mtmp->meating = 0;
X if(!rn2(4)) setmangry(mtmp); /* not always pleasing */
X
X /* greedy monsters catch gold */
X kludge("%s catches the gold.", Monnam(mtmp));
X mtmp->mgold += amount;
X if (mtmp->isshk) {
X long robbed = ESHK(mtmp)->robbed;
X
X if (robbed) {
X robbed -= amount;
X if (robbed < 0) robbed = 0;
X pline("The amount %scovers %s recent losses.",
X !robbed ? "" : "partially ",
X ESHK(mtmp)->ismale ? "his" : "her");
X ESHK(mtmp)->robbed = robbed;
X if(!robbed)
X make_happy_shk(mtmp);
X } else {
X if(mtmp->mpeaceful) {
X ESHK(mtmp)->credit += amount;
X You("have %ld zorkmid%s in credit.",
X ESHK(mtmp)->credit,
X plur(ESHK(mtmp)->credit));
X } else verbalize("Thanks, scum!");
X }
X }
X#if defined(ALTARS) && defined(THEOLOGY)
X else if(mtmp->ispriest) {
X if(mtmp->mpeaceful)
X verbalize("Thank you for your contribution.");
X else verbalize("Thanks, scum!");
X }
X#endif
X return(1);
X }
X return(0);
X
X}
X
Xboolean
Xbad_kick_throw_pos(x,y)
Xxchar x,y;
X{
X return(!accessible(x, y) || levl[x][y].typ == SDOOR);
X}
X
Xstruct monst *
Xghit(ddx, ddy, range)
Xregister int ddx, ddy, range;
X{
X register struct monst *mtmp = (struct monst *) 0;
X
X bhitpos.x = u.ux;
X bhitpos.y = u.uy;
X
X tmp_at(-1, GOLD_SYM); /* open call */
X tmp_at(-3, (int)AT_GLD);
X while(range-- > 0) {
X bhitpos.x += ddx;
X bhitpos.y += ddy;
X if(MON_AT(bhitpos.x, bhitpos.y)) {
X mtmp = m_at(bhitpos.x,bhitpos.y);
X tmp_at(-1, -1); /* close call */
X return(mtmp);
X }
X /* stop on a zorkmid */
X if(levl[bhitpos.x][bhitpos.y].gmask ||
X OBJ_AT(bhitpos.x, bhitpos.y)) {
X tmp_at(-1, -1); /* close call */
X return (struct monst *)0;
X }
X if(bad_kick_throw_pos(bhitpos.x,bhitpos.y)) {
X bhitpos.x -= ddx;
X bhitpos.y -= ddy;
X break;
X }
X tmp_at(bhitpos.x, bhitpos.y);
X }
X tmp_at(-1, -1);
X return(struct monst *)0;
X}
X
X#ifdef KICK
Xstatic int
Xkick_object(x, y)
Xint x, y;
X{
X int range, odx, ody, cnt = 0;
X register struct monst *mon;
X struct gold *gold;
X register struct obj *otmp;
X boolean costly = FALSE;
X
X /* if a pile, the "top" object gets kicked */
X for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere)
X if(!otmp->cobj) {
X cnt++;
X if(cnt == 1) kickobj = otmp;
X }
X
X /* range < 2 means the object will not move. */
X /* maybe dexterity should also figure here. */
X if(cnt) range = (int)((ACURR(A_STR) > 18 ? 20 :
X ACURR(A_STR))/2 - kickobj->owt/4);
X else range = rnd((int)ACURR(A_STR));
X
X if(martial()) range = range + rnd(3);
X if(range < 1) range = 1; /* safety... */
X
X /* see if the object has a place to move into */
X odx = x + u.dx;
X ody = y + u.dy;
X if(bad_kick_throw_pos(odx,ody))
X range = 1;
X
X if(Fumbling && !rn2(3)) {
X Your("clumsy kick missed.");
X return(1);
X }
X
X if(!cnt && levl[x][y].gmask) {
X long zm;
X gold = g_at(x, y);
X zm = gold->amount;
X if(IS_ROCK(levl[x][y].typ)) {
X if ((!martial() && rn2(20) > ACURR(A_DEX))
X#ifdef POLYSELF
X || IS_ROCK(levl[u.ux][u.uy].typ)
X#endif
X ) {
X pline("%s doesn't come loose.",
X Blind ? "It" : "The gold");
X return(!rn2(3) || martial());
X }
X pline("%s comes loose.", Blind ? "It" : "The gold");
X freegold(gold);
X newsym(x, y);
X mkgold(zm, u.ux, u.uy);
X if (Invisible
X#ifdef POLYSELF
X && !u.uundetected
X#endif
X ) newsym(u.ux, u.uy);
X return(1);
X }
X if(range < 2 || zm > 300L) /* arbitrary */
X return(0);
X freegold(gold);
X newsym(x, y);
X if(mon = ghit(u.dx, u.dy, range)) {
X setmangry(mon); /* not a means for payment to shk */
X if(ghitm(mon, zm)) /* was it caught? */
X return(1);
X }
X mkgold(zm, bhitpos.x, bhitpos.y);
X if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X return(1);
X }
X
X /* cnt should always be >= 1 here (meaning kickobj is set) due to
X * conditions of call */
X if(!cnt || kickobj->otyp == BOULDER
X || kickobj == uball || kickobj == uchain)
X return(0);
X
X /* a box gets a chance of breaking open here */
X if(Is_box(kickobj)) {
X boolean otrp = kickobj->otrapped;
X
X if (!kickobj->olocked && (!rn2(3) ||
X (martial() && !rn2(2)))) {
X pline("The lid slams open, then falls shut.");
X if(otrp) (void) chest_trap(kickobj, LEG);
X return(1);
X } else if (kickobj->olocked &&
X (!rn2(5) || (martial() && !rn2(2)))) {
X You("break open the lock!");
X kickobj->olocked = 0;
X if(otrp) (void) chest_trap(kickobj, LEG);
X return(1);
X }
X /* let it fall through to the next cases... */
X }
X
X if(Levitation && !rn2(3)) {
X You("miss."); /* do not identify the object */
X return(1);
X }
X
X /* fragile objects should not be kicked */
X if (breaks(kickobj, FALSE)) return(1);
X
X costly = costly_spot(x, y);
X
X /* potions get a chance of breaking here */
X if(kickobj->olet == POTION_SYM) {
X if(rn2(2)) {
X You("smash %s %s!",
X kickobj->quan==1 ? "the" : "a", xname(kickobj));
X potionbreathe(kickobj);
X useupf(kickobj);
X return(1);
X }
X }
X
X if(IS_ROCK(levl[x][y].typ)) {
X if ((!martial() && rn2(20) > ACURR(A_DEX))
X#ifdef POLYSELF
X || IS_ROCK(levl[u.ux][u.uy].typ)
X#endif
X ) {
X if (Blind) pline("It doesn't come loose.");
X else pline("The %s do%sn't come loose.",
X distant_name(kickobj, xname),
X (kickobj->quan==1) ? "es" : "");
X return(!rn2(3) || martial());
X }
X if (Blind) pline("It comes loose.");
X else pline("The %s come%s loose.", distant_name(kickobj, xname),
X (kickobj->quan==1) ? "s" : "");
X move_object(kickobj, u.ux, u.uy);
X newsym(x, y);
X stackobj(kickobj);
X if (Invisible
X#ifdef POLYSELF
X && !u.uundetected
X#endif
X ) newsym(u.ux, u.uy);
X if (costly && !costly_spot(u.ux, u.uy))
X addtobill(kickobj, FALSE);
X return(1);
X }
X
X /* too heavy to move. make sure not to call bhit */
X /* in this function when range < 2 (a display bug */
X /* results otherwise). */
X if(range <= 2) {
X if(Is_box(kickobj)) pline("THUD!");
X else pline("Thump!");
X if(!rn2(3) || martial()) return(1);
X return(0);
X }
X
X if (kickobj->quan > 1) (void) splitobj(kickobj, 1);
X
X /* Needed to fool bhit's display-cleanup to show immediately */
X /* the next object in the pile. We know here that the object */
X /* will move, so there is no need to worry about the location, */
X /* which merely needs to be something other than ox, oy. */
X move_object(kickobj, u.ux, u.uy);
X if(cnt == 1 && !MON_AT(x, y))
X newsym(x, y);
X
X mon = bhit(u.dx, u.dy, range, kickobj->olet,
X (int (*)()) 0, (int (*)()) 0, kickobj);
X freeobj(kickobj);
X if(mon) {
X# ifdef WORM
X if (mon->mx != bhitpos.x || mon->my != bhitpos.y)
X notonhead = TRUE;
X# endif
X /* awake monster if sleeping */
X wakeup(mon);
X if(thitmonst(mon, kickobj)) return(1);
X }
X if(costly && !costly_spot(bhitpos.x,bhitpos.y))
X addtobill(kickobj, FALSE);
X move_object(kickobj, bhitpos.x, bhitpos.y);
X kickobj->nobj = fobj;
X fobj = kickobj;
X stackobj(kickobj);
X if(!MON_AT(kickobj->ox, kickobj->oy))
X newsym(kickobj->ox, kickobj->oy);
X return(1);
X}
X
Xstatic char *
Xkickstr() {
X static char NEARDATA buf[BUFSIZ];
X
X if (kickobj) Sprintf(buf, "kicking %s", doname(kickobj));
X else if (IS_STWALL(maploc->typ)) Strcpy(buf, "kicking a wall");
X else if (IS_ROCK(maploc->typ)) Strcpy(buf, "kicking a rock");
X#ifdef THRONES
X else if (IS_THRONE(maploc->typ)) Strcpy(buf, "kicking a throne");
X#endif
X#ifdef SINKS
X else if (IS_SINK(maploc->typ)) Strcpy(buf, "kicking a sink");
X#endif
X#ifdef ALTARS
X else if (IS_ALTAR(maploc->typ)) Strcpy(buf, "kicking an altar");
X#endif
X#ifdef STRONGHOLD
X else if (IS_DRAWBRIDGE(maploc->typ))
X Strcpy(buf, "kicking the drawbridge");
X#endif
X else {
X switch (maploc->typ) {
X case STAIRS:
X Strcpy(buf, "kicking the stairs");
X break;
X#ifdef STRONGHOLD
X case LADDER:
X Strcpy(buf, "kicking a ladder");
X break;
X#endif
X }
X }
X
X return buf;
X}
X#endif /* KICK */
X
Xint
Xdokick() {
X register int x, y;
X register int avrg_attrib = (ACURR(A_STR)+ACURR(A_DEX)+ACURR(A_CON))/3;
X
X#ifdef POLYSELF
X if(nolimbs(uasmon)) {
X You("have no legs to kick with.");
X return(0);
X }
X if(verysmall(uasmon)) {
X You("are too small to do any kicking.");
X return(0);
X }
X#endif
X if(Wounded_legs) {
X Your("%s %s in no shape for kicking.",
X ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES)
X ? makeplural(body_part(LEG)) : body_part(LEG),
X ((Wounded_legs & BOTH_SIDES)==BOTH_SIDES) ? "are" : "is");
X return(0);
X }
X
X if(inv_weight() > 0) {
X Your("load is too heavy to balance yourself for a kick.");
X return(0);
X }
X
X if(u.utrap) {
X switch (u.utraptype) {
X case TT_PIT:
X pline("There's nothing to kick down here.");
X case TT_WEB:
X case TT_BEARTRAP:
X You("can't move your %s!", body_part(LEG));
X }
X return(0);
X }
X
X if(!getdir(1)) return(0);
X if(!u.dx && !u.dy) return(0);
X
X x = u.ux + u.dx;
X y = u.uy + u.dy;
X
X if(u.uswallow) {
X switch(rn2(3)) {
X case 0: You("can't move your %s!", body_part(LEG));
X break;
X case 1: if (is_animal(u.ustuck->data)) {
X pline("%s burps loudly.", Monnam(u.ustuck));
X break;
X }
X default: Your("feeble kick has no effect."); break;
X }
X return(1);
X }
X
X wake_nearby();
X u_wipe_engr(2);
X
X maploc = &levl[x][y];
X
X#ifdef KICK
X /* The next four main loops should stay in */
X /* their present order: monsters, objects, */
X /* non-doors, doors. */
X
X if(MON_AT(x, y)) {
X kick_monster(x, y);
X return(1);
X }
X
X kickobj = (struct obj *)0;
X if((OBJ_AT(x, y) || maploc->gmask) && !Levitation) {
X if(kick_object(x, y)) return(1);
X else goto ouch;
X }
X
X if(!IS_DOOR(maploc->typ)) {
X if(maploc->typ == SDOOR) {
X if(rn2(30) < avrg_attrib) {
X pline("Crash! You kick open a secret door!");
X maploc->typ = DOOR;
X if(maploc->doormask & D_TRAPPED) {
X b_trapped("door");
X maploc->doormask = D_NODOOR;
X } else
X maploc->doormask = D_ISOPEN;
X mnewsym(x,y);
X prl(x,y);
X return(1);
X } else goto ouch;
X }
X if(maploc->typ == SCORR) {
X if(rn2(30) < avrg_attrib) {
X pline("Crash! You kick open a secret passage!");
X maploc->typ = CORR;
X mnewsym(x,y);
X prl(x,y);
X return(1);
X } else goto ouch;
X }
X# ifdef THRONES
X if(IS_THRONE(maploc->typ)) {
X register int i;
X if((Luck < 0 || maploc->doormask) && !rn2(3)) {
X pline("CRASH! You destroy the throne.");
X maploc->typ = ROOM;
X maploc->doormask = 0; /* don't leave loose ends.. */
X mkgold((long)rnd(200), x, y);
X prl(x, y);
X return(1);
X } else if(Luck > 0 && !rn2(3) && !maploc->looted) {
X You("kick loose some ornamental coins and gems!");
X mkgold((300L+(long)rn2(201)), x, y);
X i = Luck + 1;
X if(i > 6) i = 6;
X while(i--) (void) mkobj_at(GEM_SYM, x, y, TRUE);
X prl(x, y);
X /* prevent endless milking */
X maploc->looted = T_LOOTED;
X return(1);
X } else if (!rn2(4)) {
X fall_through(FALSE);
X return(1);
X }
X goto ouch;
X }
X# endif
X# ifdef ALTARS
X if(IS_ALTAR(maploc->typ)) {
X You("kick the altar.");
X if(!rn2(3)) goto ouch;
X# ifdef THEOLOGY
X altar_wrath(x, y);
X# endif
X return(1);
X }
X# endif
X# ifdef SINKS
X if(IS_SINK(maploc->typ)) {
X if(rn2(5)) {
X if(flags.soundok)
X pline("Klunk! The pipes vibrate noisily.");
X else pline("Klunk!");
X return(1);
X } else if(!rn2(3) &&
X !(mons[PM_BLACK_PUDDING].geno & G_GENOD)) {
X pline("A %s ooze gushes up from the drain!",
X Hallucination ? hcolor() : black);
X pmon(makemon(&mons[PM_BLACK_PUDDING], x, y));
X return(1);
X# ifdef INFERNO
X } else if(!rn2(3) &&
X# ifndef POLYSELF
X poly_gender() != 2 &&
X# endif
X !(mons[poly_gender() == 1 ? PM_INCUBUS : PM_SUCCUBUS].geno & G_GENOD)) {
X /* can't resist... */
X pline("The dish washer returns!");
X pmon(makemon(&mons[poly_gender() == 1 ? PM_INCUBUS : PM_SUCCUBUS], x, y));
X return(1);
X# endif
X } else if(!rn2(3)) {
X pline("Flupp! Muddy waste pops up from the drain.");
X if(!maploc->looted) { /* only once per sink */
X if(!Blind)
X You("see a ring shining in its midst.");
X (void) mkobj_at(RING_SYM, x, y, TRUE);
X prl(x, y);
X maploc->looted = T_LOOTED;
X }
X return(1);
X }
X goto ouch;
X }
X# endif
X if(maploc->typ == STAIRS
X# ifdef STRONGHOLD
X || maploc->typ == LADDER
X# endif
X ) goto ouch;
X if(IS_STWALL(maploc->typ)) {
Xouch:
X pline("Ouch! That hurts!");
X if(!rn2(3)) set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X losehp(rnd(ACURR(A_CON) > 15 ? 3 : 5), kickstr(),
X KILLED_BY);
X return(1);
X }
X# ifdef STRONGHOLD
X if (is_drawbridge_wall(x,y) >= 0) {
X pline("The drawbridge is unaffected.");
X return(1);
X }
X# endif
X goto dumb;
X }
X#endif /* KICK */
X
X if(maploc->doormask == D_ISOPEN ||
X maploc->doormask == D_BROKEN ||
X maploc->doormask == D_NODOOR) {
X#ifdef KICK
Xdumb:
X#endif
X if (martial() || ACURR(A_DEX) >= 16 || rn2(3)) {
X You("kick at empty space.");
X } else {
X pline("Dumb move! You strain a muscle.");
X set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X }
X return(0);
X }
X
X /* door is known to be CLOSED or LOCKED */
X if(rnl(35) < avrg_attrib + (!martial() ? 0 : ACURR(A_DEX))) {
X /* break the door */
X if(maploc->doormask & D_TRAPPED) {
X pline("As you kick the door, it explodes!");
X b_trapped("door");
X maploc->doormask = D_NODOOR;
X } else if(ACURR(A_STR) > 18 && !rn2(5) && !in_shop(x, y)) {
X pline("As you kick the door, it shatters to pieces!");
X maploc->doormask = D_NODOOR;
X } else {
X pline("As you kick the door, it crashes open!");
X maploc->doormask = D_BROKEN;
X if(in_shop(x, y))
X pay_for_door(x, y, "break");
X }
X mnewsym(x,y);
X prl(x,y);
X } else pline("WHAMMM!!!");
X
X return(1);
X}
END_OF_FILE
if test 18914 -ne `wc -c <'src/dokick.c'`; then
echo shar: \"'src/dokick.c'\" unpacked with wrong size!
fi
# end of 'src/dokick.c'
fi
if test -f 'src/pray.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/pray.c'\"
else
echo shar: Extracting \"'src/pray.c'\" \(36355 characters\)
sed "s/^X//" >'src/pray.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)pray.c 3.0 89/11/20
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* Copyright (c) Benson I. Margulies, Mike Stephenson, Steve Linhart, 1989. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X#ifdef THEOLOGY
Xstatic int NDECL(in_trouble);
Xstatic void FDECL(fix_worst_trouble,(int));
Xstatic void NDECL(angrygods);
Xstatic void NDECL(pleased);
Xstatic void NDECL(gods_upset);
Xstatic void FDECL(consume_offering,(struct obj *));
X
X#define ALIGNLIM (5L + (moves/200L))
X
Xstruct ghods {
X char classlet;
X const char *law, *balance, *chaos;
X} gods[] = {
X
X'A', /* Central American */ "Quetzalcotl", "Camaxtli", "Huhetotl",
X'B', /* Celtic */ "Nuada", "Dagda", "Morrigan",
X'C', /* Babylonian */ "Anu", "Ishtar", "Anshar",
X'E', /* Elven */ "Solonor Thelandira",
X "Aerdrie Faenya", "Erevan Ilesere",
X'H', /* Greek */ "Athena", "Hermes", "Poseidon",
X'K', /* Celtic */ "Lugh", "Brigit", "Macannan Mac Lir",
X#ifdef NAMED_ITEMS
X/* It'd look funny if someone got a sword to steal souls for Arioch but Arioch
X * goes with the wrong character class...
X */
X'P', /* Hyborian */ "Mitra", "Crom", "Set",
X#else
X'P', /* Melnibonean */ "Donblas", "Grome", "Arioch",
X#endif
X'R', /* Nehwon */ "Votishal", "Death", "Rat God",
X'S', /* Japanese */ "Amaterasu Omikami", "Raiden", "Susanowo",
X'T', /* Chinese */ "Shan Lai Ching", "Chih Sung-tzu", "Huan Ti",
X'V', /* Norse */ "Tyr", "Balder", "Loki",
X'W', /* Egyptian */ "Ptah", "Thoth", "Anhur",
X0,0,0,0
X};
X
X#define TROUBLE_STONED 9
X#define TROUBLE_STRANGLED 8
X#define TROUBLE_SICK 7
X#define TROUBLE_STARVING 6
X#define TROUBLE_HIT 5
X#define TROUBLE_LYCANTHROPE 4
X#define TROUBLE_STUCK_IN_WALL 3
X#define TROUBLE_CURSED_BLINDFOLD 2
X#define TROUBLE_CURSED_LEVITATION 1
X
X#define TROUBLE_PUNISHED (-1)
X#define TROUBLE_CURSED_ITEMS (-2)
X#define TROUBLE_BLIND (-3)
X#define TROUBLE_HUNGRY (-4)
X#define TROUBLE_POISONED (-5)
X#define TROUBLE_WOUNDED_LEGS (-6)
X#define TROUBLE_STUNNED (-7)
X#define TROUBLE_CONFUSED (-8)
X#define TROUBLE_HALLUCINATION (-9)
X
X/* We could force rehumanize of polyselfed people, but we can't tell
X unintentional shape changes from the other kind. Oh well. */
X
X/* Return 0 if nothing particular seems wrong, positive numbers for
X serious trouble, and negative numbers for comparative annoyances. This
X returns the worst problem. There may be others, and the gods may fix
X more than one.
X
XThis could get as bizarre as noting surrounding opponents, (or hostile dogs),
Xbut that's really hard.
X */
X
X#define ugod_is_angry() (u.ualign < 0)
X#ifdef ALTARS
X#define on_altar() IS_ALTAR(levl[u.ux][u.uy].typ)
X#define on_shrine() ((levl[u.ux][u.uy].altarmask & A_SHRINE) != 0)
X#endif
X
Xstatic int
Xin_trouble()
X{
X register struct obj *otmp;
X int i, j, count=0;
X
X/* Borrowed from eat.c */
X
X#define SATIATED 0
X#define NOT_HUNGRY 1
X#define HUNGRY 2
X#define WEAK 3
X#define FAINTING 4
X#define FAINTED 5
X#define STARVED 6
X
X if(Stoned) return(TROUBLE_STONED);
X if(Strangled) return(TROUBLE_STRANGLED);
X if(Sick) return(TROUBLE_SICK);
X if(u.uhs >= WEAK) return(TROUBLE_STARVING);
X if(u.uhp < 5 || (u.uhp*7 < u.uhpmax)) return(TROUBLE_HIT);
X for (i= -1; i<=1; i++) for(j= -1; j<=1; j++) {
X if (!i && !j) continue;
X if (!isok(u.ux+i, u.uy+j) || IS_ROCK(levl[u.ux+i][u.uy+j].typ))
X count++;
X }
X#ifdef POLYSELF
X if(u.ulycn >= 0) return(TROUBLE_LYCANTHROPE);
X#endif
X if(count==8
X#ifdef POLYSELF
X && !passes_walls(uasmon)
X#endif
X ) return(TROUBLE_STUCK_IN_WALL);
X if((uarmf && uarmf->otyp==LEVITATION_BOOTS && uarmf->cursed) ||
X (uleft && uleft->otyp==RIN_LEVITATION && uleft->cursed) ||
X (uright && uright->otyp==RIN_LEVITATION && uright->cursed))
X return(TROUBLE_CURSED_LEVITATION);
X if(ublindf && ublindf->cursed) return(TROUBLE_CURSED_BLINDFOLD);
X
X if(Punished) return(TROUBLE_PUNISHED);
X for(otmp=invent; otmp; otmp=otmp->nobj)
X if((otmp->otyp==LOADSTONE || otmp->otyp==LUCKSTONE) &&
X otmp->cursed)
X return(TROUBLE_CURSED_ITEMS);
X if((uarmh && uarmh->cursed) || /* helmet */
X (uarms && uarms->cursed) || /* shield */
X (uarmg && uarmg->cursed) || /* gloves */
X (uarm && uarm->cursed) || /* armor */
X (uarmc && uarmc->cursed) || /* cloak */
X (uarmf && uarmf->cursed && uarmf->otyp != LEVITATION_BOOTS) ||
X /* boots */
X#ifdef SHIRT
X (uarmu && uarmu->cursed) || /* shirt */
X#endif
X (uwep && welded(uwep)) ||
X (uleft && uleft->cursed && uleft->otyp != RIN_LEVITATION) ||
X (uright && uright->cursed && uright->otyp != RIN_LEVITATION) ||
X (uamul && uamul->cursed))
X
X return(TROUBLE_CURSED_ITEMS);
X
X if(Blinded > 1) return(TROUBLE_BLIND);
X if(u.uhs >= HUNGRY) return(TROUBLE_HUNGRY);
X for(i=0; i<A_MAX; i++)
X if(ABASE(i) < AMAX(i)) return(TROUBLE_POISONED);
X if(Wounded_legs) return (TROUBLE_WOUNDED_LEGS);
X if(HStun) return (TROUBLE_STUNNED);
X if(HConfusion) return (TROUBLE_CONFUSED);
X if(Hallucination) return(TROUBLE_HALLUCINATION);
X
X return(0);
X}
X
Xconst char leftglow[] = "left ring softly glows";
Xconst char rightglow[] = "right ring softly glows";
X
Xstatic void
Xfix_worst_trouble(trouble)
Xregister int trouble;
X{
X int i;
X struct obj *otmp = (struct obj *)0;
X const char *what = NULL;
X
X u.ublesscnt += rnz(100);
X switch (trouble) {
X case TROUBLE_STONED:
X You("feel more limber.");
X Stoned = 0;
X break;
X case TROUBLE_STRANGLED:
X You("can breathe again.");
X Strangled = 0;
X break;
X case TROUBLE_HUNGRY:
X case TROUBLE_STARVING:
X Your("stomach feels content.");
X init_uhunger ();
X losestr(-1);
X flags.botl = 1;
X break;
X case TROUBLE_SICK:
X You("feel better.");
X make_sick(0L,FALSE);
X break;
X case TROUBLE_HIT:
X if (!Blind) {
X pline("%s glow surrounds you.",
X An(Hallucination ? hcolor() : golden));
X } else You("feel much better.");
X if (u.uhpmax < u.ulevel * 5 + 11)
X u.uhp = u.uhpmax += rnd(5);
X else
X u.uhp = u.uhpmax;
X flags.botl = 1;
X break;
X case TROUBLE_STUCK_IN_WALL:
X Your("surroundings change.");
X tele();
X break;
X case TROUBLE_CURSED_LEVITATION:
X if (uarmf && uarmf->otyp==LEVITATION_BOOTS
X && uarmf->cursed)
X otmp = uarmf;
X else if (uleft && uleft->otyp==RIN_LEVITATION
X && uleft->cursed) {
X otmp = uleft;
X what = leftglow;
X } else {
X otmp = uright;
X what = rightglow;
X }
X goto decurse;
X case TROUBLE_CURSED_BLINDFOLD:
X otmp = ublindf;
X goto decurse;
X case TROUBLE_PUNISHED:
X Your("chain disappears.");
X unpunish();
X break;
X#ifdef POLYSELF
X case TROUBLE_LYCANTHROPE:
X You("feel purified.");
X if(uasmon == &mons[u.ulycn] && !Polymorph_control)
X rehumanize();
X u.ulycn = -1; /* now remove the curse */
X break;
X#endif
X case TROUBLE_CURSED_ITEMS:
X if (uarmh && uarmh->cursed) /* helmet */
X otmp = uarmh;
X else if (uarms && uarms->cursed) /* shield */
X otmp = uarms;
X else if (uarmg && uarmg->cursed) /* gloves */
X otmp = uarmg;
X else if (uarm && uarm->cursed) /* armor */
X otmp = uarm;
X else if (uarmc && uarmc->cursed) /* cloak */
X otmp = uarmc;
X else if (uarmf && uarmf->cursed) /* boots */
X otmp = uarmf;
X#ifdef SHIRT
X else if (uarmu && uarmu->cursed) /* shirt */
X otmp = uarmu;
X#endif
X else if (uleft && uleft->cursed) {
X otmp = uleft;
X what = leftglow;
X } else if (uright && uright->cursed) {
X otmp = uright;
X what = rightglow;
X } else if (uamul && uamul->cursed) /* amulet */
X otmp = uamul;
X else if (welded(uwep)) otmp = uwep;
X else {
X for(otmp=invent; otmp; otmp=otmp->nobj)
X if ((otmp->otyp==LOADSTONE ||
X otmp->otyp==LUCKSTONE) && otmp->cursed)
X break;
X }
Xdecurse:
X otmp->cursed = 0;
X otmp->bknown = 1;
X if (!Blind)
X Your("%s %s.",
X what ? what : (const char *)aobjnam (otmp, "softly glow"),
X Hallucination ? hcolor() : amber);
X break;
X case TROUBLE_HALLUCINATION:
X pline ("Looks like you are back in Kansas.");
X make_hallucinated(0L,FALSE);
X break;
X case TROUBLE_BLIND:
X Your("%s feel better.", makeplural(body_part(EYE)));
X make_blinded(0L,FALSE);
X break;
X case TROUBLE_POISONED:
X if (Hallucination)
X pline("There's a tiger in your tank.");
X else
X You("feel in good health again.");
X for(i=0; i<A_MAX; i++) {
X if(ABASE(i) < AMAX(i)) {
X ABASE(i) = AMAX(i);
X flags.botl = 1;
X }
X }
X break;
X case TROUBLE_WOUNDED_LEGS:
X heal_legs();
X break;
X case TROUBLE_STUNNED:
X make_stunned(0L,TRUE);
X break;
X case TROUBLE_CONFUSED:
X make_confused(0L,TRUE);
X break;
X }
X}
X
Xstatic void
Xangrygods() {
X register int tmp;
X
X u.ublessed = 0;
X
X /* changed from tmp = u.ugangr + abs (u.uluck) -- rph */
X tmp = 3*u.ugangr +
X (Luck > 0 || u.ualign > 3 ? -Luck/3 : -Luck);
X if (tmp < 0) tmp = 0; /* possible if bad alignment but good luck */
X tmp = (tmp > 15 ? 15 : tmp); /* lets be a little reasonable */
X switch (tmp ? rn2(tmp): 0) {
X
X case 0:
X case 1: if (Hallucination)
X You("feel a%sholy dread.",
X u.ualigntyp == U_CHAOTIC ? "n un" : " ");
X else You("feel that %s is %s.",
X# ifdef ALTARS
X on_altar() ? a_gname() : u_gname(),
X# else
X u_gname(),
X# endif
X u.ualigntyp == U_NEUTRAL ? "offended" : "angry");
X break;
X case 2:
X case 3:
X pline("A voice thunders:");
X# ifdef POLYSELF
X pline("\"Thou %s, %s.\"",
X ugod_is_angry() ? "hast strayed from the path" :
X "art arrogant",
X u.usym == S_HUMAN ? "mortal" : "creature");
X# else
X pline("\"Thou %s, mortal.\"",
X ugod_is_angry() ? "hast strayed from the path" :
X "art arrogant");
X# endif
X verbalize("Thou must relearn thy lessons!");
X adjattrib(A_WIS, -1, FALSE);
X if (u.ulevel > 1) {
X losexp();
X if(u.uhp < 1) u.uhp = 1;
X if(u.uhpmax < 1) u.uhpmax = 1;
X } else {
X u.uexp = 0;
X flags.botl = 1;
X }
X break;
X case 6: if (!Punished) {
X punish((struct obj *)0);
X break;
X } /* else fall thru */
X case 4:
X case 5: if (!Blind)
X pline("%s glow surrounds you.",
X An(Hallucination ? hcolor() : black));
X rndcurse();
X break;
X case 7:
X case 8: pline("A voice booms out:");
X verbalize("Thou durst call upon me?");
X# ifdef POLYSELF
X pline("\"Then die, %s!\"",
X u.usym == S_HUMAN ? "mortal" : "creature");
X# else
X verbalize("Then die, mortal!");
X# endif
X (void) makemon(&mons[ndemon()], u.ux, u.uy);
X break;
X
X default: pline("Suddenly, a bolt of lightning strikes you!");
X if (Reflecting) {
X shieldeff(u.ux, u.uy);
X if (Blind)
X pline("For some reason you're unaffected.");
X else {
X if (Reflecting & W_AMUL) {
X pline("It reflects from your medallion.");
X makeknown(AMULET_OF_REFLECTION);
X } else {
X pline("It reflects from your shield.");
X makeknown(SHIELD_OF_REFLECTION);
X }
X }
X You("hear a cosmic sigh, and sense a decision being made.");
X pline("A wide-angle disintegration beam hits you!");
X goto ohno;
X } else if (Shock_resistance) {
X shieldeff(u.ux, u.uy);
X pline("It seems not to affect you.");
X pline("However, the ensuing disintegration beam does.");
Xohno:
X if (Disint_resistance) {
X You("bask in the disintegration beam for a minute...");
X pline("A voice rings out:");
X verbalize("I believe it not!");
X break;
X }
X }
X You("fry to a crisp.");
X killer_format = KILLED_BY_AN;
X killer = "holy wrath";
X done(DIED);
X break;
X }
X u.ublesscnt = rnz(300);
X return;
X}
X
Xstatic void
Xpleased() {
X int trouble = in_trouble (); /* what's your worst difficulty? */
X int pat_on_head = 0;
X
X You("feel that %s is pleased.",
X#ifndef ALTARS
X u_gname());
X#else
X on_altar() ? a_gname() : u_gname());
X
X /* not your deity */
X if (on_altar() &&
X (levl[u.ux][u.uy].altarmask & ~A_SHRINE) != u.ualigntyp + 1) {
X adjalign(-1);
X return;
X } else if (u.ualign < 2) adjalign(1);
X#endif
X
X
X /* depending on your luck, the gods will:
X - fix your worst problem if it's major.
X - fix all your major problems.
X - fix your worst problem if it's minor.
X - fix all of your problems.
X - do you a gratuitous favor.
X
X if you make it to the the last category, you roll randomly again
X to see what they do for you.
X
X If your luck is at least 0, then you are guaranteed rescued
X from your worst major problem. */
X
X if (!trouble) pat_on_head = 1;
X else {
X#ifdef ALTARS
X int action = rn1(on_altar() ? 3 + on_shrine() : 2, Luck+1);
X
X if (!on_altar()) action = max(action,2);
X#else
X int action = rn1(4,Luck+1);
X#endif
X
X switch(min(action,5)) {
X case 5: pat_on_head = 1;
X case 4: do fix_worst_trouble(trouble);
X while(trouble = in_trouble());
X break;
X
X case 3: fix_worst_trouble(trouble);
X case 2: while((trouble = in_trouble()) > 0)
X fix_worst_trouble(trouble);
X break;
X
X case 1: if (trouble > 0) fix_worst_trouble(trouble);
X }
X }
X
X if(pat_on_head)
X switch(rn2((Luck + 6)>>1)) {
X
X case 0: break;
X case 1:
X if(uwep && (uwep->olet == WEAPON_SYM || uwep->otyp
X == PICK_AXE) && (!uwep->blessed)) {
X if (uwep->cursed) {
X uwep->cursed = 0;
X uwep->bknown = 1;
X if (!Blind)
X Your("%s %s.",
X aobjnam(uwep, "softly glow"),
X Hallucination ? hcolor() : amber);
X } else if(uwep->otyp < BOW) {
X uwep->blessed = uwep->bknown = 1;
X if (!Blind) {
X Your("%s with %s aura.",
X aobjnam(uwep, "softly glow"),
X an(Hallucination ? hcolor() : light_blue));
X }
X }
X }
X break;
X case 3:
X#if defined(STRONGHOLD) && defined(MUSIC)
X /* takes 2 hints to get the music to enter the stronghold */
X if (flags.soundok) {
X if(music_heard < 1) {
X pline("A voice rings out:");
X# ifdef POLYSELF
X pline("\"Hark, %s!\"",
X u.usym == S_HUMAN ? "mortal" : "creature");
X# else
X verbalize("Hark, mortal!");
X# endif
X verbalize("To enter the castle, thou must play the right tune!");
X music_heard++;
X break;
X } else if (music_heard < 2) {
X You("hear a divine music...");
X pline("It sounds like: \"%s\".", tune);
X music_heard++;
X break;
X }
X }
X /* Otherwise, falls into next case */
X#endif
X case 2: if (!Blind)
X You("are surrounded by %s glow.",
X an(Hallucination ? hcolor() : golden));
X u.uhp = u.uhpmax += 5;
X ABASE(A_STR) = AMAX(A_STR);
X if (u.uhunger < 900) init_uhunger();
X if (u.uluck < 0) u.uluck = 0;
X make_blinded(0L,TRUE);
X flags.botl = 1;
X break;
X case 4:
X { register struct obj *otmp;
X
X if (Blind)
X You("feel the power of %s.", u_gname());
X else You("are surrounded by %s aura.",
X an(Hallucination ? hcolor() : light_blue));
X for(otmp=invent; otmp; otmp=otmp->nobj) {
X if (otmp->cursed) {
X otmp->cursed = 0;
X if (!Blind)
X Your("%s %s.",
X aobjnam(otmp, "softly glow"),
X Hallucination ? hcolor() : amber);
X }
X }
X break;
X }
X case 5:
X {
X const char *msg="\"and thus I grant thee the gift of %s!\"";
X pline("A voice booms out:");
X verbalize("Thou hast pleased me with thy progress,");
X if (!(HTelepat & INTRINSIC)) {
X HTelepat |= INTRINSIC;
X pline(msg, "Telepathy");
X } else if (!(Fast & INTRINSIC)) {
X Fast |= INTRINSIC;
X pline(msg, "Speed");
X } else if (!(Stealth & INTRINSIC)) {
X Stealth |= INTRINSIC;
X pline(msg, "Stealth");
X } else {
X if (!(Protection & INTRINSIC)) {
X Protection |= INTRINSIC;
X if (!u.ublessed) u.ublessed = rnd(3) + 1;
X } else u.ublessed++;
X pline(msg, "my protection");
X }
X verbalize("Use it wisely in my name!");
X break;
X }
X case 7:
X case 8:
X#ifdef ELBERETH
X if (u.ualign > 3 && !u.uhand_of_elbereth) {
X u.uhand_of_elbereth = TRUE;
X HSee_invisible |= INTRINSIC;
X HFire_resistance |= INTRINSIC;
X HCold_resistance |= INTRINSIC;
X HPoison_resistance |= INTRINSIC;
X pline("A voice booms out:");
X if (u.ualigntyp != U_CHAOTIC) {
X verbalize("I crown thee... The Hand of Elbereth!");
X#ifdef NAMED_ITEMS
X if(uwep && (uwep->otyp == LONG_SWORD)) {
X bless(uwep);
X uwep->bknown = 1;
X uwep->rustfree = 1;
X (void)oname(uwep, "Excalibur", 1);
X }
X#endif
X } else {
X register struct obj *obj;
X#ifdef NAMED_ITEMS
X const char *Stormbringer = "Stormbringer";
X
X /* This does the same damage as Excalibur.
X * Disadvantages: doesn't do bonuses to undead;
X * doesn't aid searching.
X * Advantages: part of that bonus is a level
X * drain.
X * Disadvantage: player cannot start with a
X * +5 weapon and turn it into a Stormbringer.
X * Advantage: they don't need to already have a
X * sword of the right type to get it...
X * However, if Stormbringer already exists in
X * the game, an ordinary good broadsword is
X * given and the messages are a bit different.
X */
X obj = mksobj(BROADSWORD, FALSE);
X if (exist_artifact(obj, Stormbringer))
X verbalize("Thou art chosen to take lives for Arioch!");
X else
X verbalize("Thou art chosen to steal souls for Arioch!");
X if (Blind)
X pline("Something appears at your %s.",
X makeplural(body_part(FOOT)));
X else
X pline("%s sword appears at your %s!",
X An(exist_artifact(obj, Stormbringer) ?
X (const char *)"wide" :
X Hallucination ? hcolor() : black),
X makeplural(body_part(FOOT)));
X obj->rustfree = 1;
X obj->cursed = 0;
X /* Why bless it? Why not. After all, chaotic gods
X * will bless regular weapons. And blessed really
X * means given sanctified to a deity, which is certainly
X * sensible even for Stormbringer and a chaotic deity...
X */
X obj->blessed = 1;
X
X /* if not "Stormbringer", make it a bit better otherwise */
X if (exist_artifact(obj, Stormbringer))
X obj->spe = 3;
X else
X obj->spe = 1;
X /* existence of "Stormbringer" is checked in oname() */
X obj = oname(obj, Stormbringer, 0);
X dropy(obj);
X#else
X verbalize("Thou shalt become the servant of Arioch!");
X#endif
X }
X break;
X }
X#endif
X
X case 6: pline ("An object appears at your %s!",
X makeplural(body_part(FOOT)));
X#ifdef SPELLS
X bless(mkobj_at(SPBOOK_SYM, u.ux, u.uy, TRUE));
X#else
X bless(mkobj_at(SCROLL_SYM, u.ux, u.uy, TRUE));
X#endif
X break;
X
X default: impossible("Confused deity!");
X break;
X }
X u.ublesscnt = rnz(350);
X#ifdef HARD
X# ifndef ELBERETH
X u.ublesscnt += (u.udemigod * rnz(1000));
X# else
X u.ublesscnt += ((u.udemigod + u.uhand_of_elbereth) * rnz(1000));
X# endif
X#endif
X return;
X}
X
Xstatic void
Xgods_upset()
X{
X#ifdef HARD
X u.ugangr++;
X angrygods();
X#else
X if (u.ugangr++) angrygods();
X else { /* exactly one warning */
X# ifdef ALTARS
X pline("The voice of %s booms out:",
X on_altar() ? a_gname() : u_gname());
X# else
X pline("A voice booms out:");
X# endif
X verbalize("Thou hast angered me.");
X verbalize("Disturb me again at thine own peril!");
X }
X#endif
X}
X
X#ifdef ENDGAME
Xstatic const char NEARDATA sacrifice_types[] = { FOOD_SYM, AMULET_SYM, 0 };
X#endif
X
Xstatic void
Xconsume_offering(otmp)
Xregister struct obj *otmp;
X{
X if (Hallucination)
X Your("sacrifice sprouts wings and a propeller and roars away!");
X else if (Blind && u.ualigntyp == U_LAWFUL)
X Your("sacrifice disappears!");
X else Your("sacrifice is consumed in a %s!",
X u.ualigntyp == U_LAWFUL ? "flash of light" : "burst of flame");
X if (carried(otmp)) useup(otmp);
X else useupf(otmp);
X}
X
Xint
Xdosacrifice()
X{
X register struct obj *otmp;
X int value = 0;
X#ifdef ALTARS
X /* Note: normal altar aligns are 0, 1, 2; this is -1, 0, 1 so it */
X /* can be compared with u.ualigntyp */
X int altaralign = (levl[u.ux][u.uy].altarmask & ~A_SHRINE) - 1;
X
X if (!on_altar()) {
X You("are not standing on an altar.");
X return 0;
X }
X#endif /* ALTARS /**/
X
X#ifdef ENDGAME
X if (dlevel == ENDLEVEL) {
X if (!(otmp = getobj(sacrifice_types, "sacrifice"))) return 0;
X } else
X if (!(otmp = floorfood("sacrifice", 0))) return 0;
X#else
X if (!(otmp = floorfood("sacrifice", 0))) return 0;
X#endif
X/*
X Was based on nutritional value and aging behavior (< 50 moves).
X Sacrificing a food ration got you max luck instantly, making the
X gods as easy to please as an angry dog!
X
X Now only accepts corpses, based on the games evaluation of their
X toughness. Human sacrifice, as well as sacrificing unicorns of
X your alignment, is strongly discouraged. (We can't tell whether
X a pet corpse was tame, so you can still sacrifice it.)
X */
X
X#define MAXVALUE 24 /* Highest corpse value (besides Wiz) */
X
X if (otmp->otyp == CORPSE) {
X register struct permonst *mtmp = &mons[otmp->corpsenm];
X extern int monstr[];
X
X if (otmp->corpsenm == PM_ACID_BLOB || (monstermoves <= otmp->age + 50))
X value = monstr[otmp->corpsenm] + 1;
X if (otmp->oeaten)
X value = eaten_stat(value, otmp);
X
X if (is_human(mtmp)) { /* Human sacrifice! */
X#ifdef POLYSELF
X if (is_demon(uasmon))
X You("find the idea very satisfying.");
X else
X#endif
X if (u.ualigntyp != U_CHAOTIC)
X pline("You'll regret this infamous offense!");
X#ifdef ALTARS
X if (altaralign != U_CHAOTIC) {
X /* curse the lawful/neutral altar */
X pline("The altar is stained with human blood.");
X levl[u.ux][u.uy].altarmask = A_CHAOS;
X angry_priest();
X } else {
X register struct monst *dmon;
X /* Human sacrifice on a chaotic altar is equivalent to demon summoning */
X# ifdef THEOLOGY
X if (altaralign == U_CHAOTIC)
X pline("The blood covers the altar!");
X else {
X# endif
X pline("The blood floods over the altar, which vanishes in %s cloud!",
X an(Hallucination ? hcolor() : black));
X levl[u.ux][u.uy].typ = ROOM;
X levl[u.ux][u.uy].altarmask = 0;
X# ifdef THEOLOGY
X }
X# endif
X change_luck(2);
X if(Invisible) newsym(u.ux, u.uy);
X if(dmon = makemon(&mons[dlord()], u.ux, u.uy)) {
X You("have summoned a demon lord!");
X if (u.ualigntyp == U_CHAOTIC)
X dmon->mpeaceful = 1;
X You("are terrified, and unable to move.");
X nomul(-3);
X } else pline("The cloud dissipates.");
X }
X#endif
X if (u.ualigntyp != U_CHAOTIC) {
X adjalign(-5);
X u.ugangr += 3;
X adjattrib(A_WIS, -1, TRUE);
X if (!Inhell) angrygods();
X change_luck(-5);
X } else adjalign(5);
X if (carried(otmp)) useup(otmp);
X else useupf(otmp);
X return(1);
X } else if (is_undead(mtmp)) { /* Not demons--no demon corpses */
X if (u.ualigntyp != U_CHAOTIC)
X value += 1;
X } else if (mtmp->mlet == S_UNICORN) {
X int unicalign;
X
X if (mtmp == &mons[PM_BLACK_UNICORN]) unicalign = -1;
X else if (mtmp == &mons[PM_GRAY_UNICORN]) unicalign = 0;
X else if (mtmp == &mons[PM_WHITE_UNICORN]) unicalign = 1;
X#ifdef __GNULINT__
X else { impossible("Bad unicorn type??"); unicalign = 0; }
X#endif
X#ifdef ALTARS
X /* If same as altar, always a very bad action. */
X if (unicalign == altaralign) {
X pline("Such an action is an insult to %s!", (unicalign== -1)
X ? "chaos" : unicalign ? "law" : "neutrality");
X adjattrib(A_WIS, -1, TRUE);
X value = -5;
X } else if (u.ualigntyp == altaralign) {
X /* If different from altar, and altar is same as yours, */
X /* get maximum alignment */
X if (u.ualign < ALIGNLIM)
X You("feel stridently %s!", (u.ualigntyp== U_CHAOTIC) ?
X "chaotic" : u.ualigntyp ? "lawful" : "neutral");
X else You("feel you are thoroughly on the right path.");
X u.ualign = ALIGNLIM;
X value += 3;
X } else
X /* If sacrificing unicorn of your alignment to altar not of */
X /* your alignment, your god gets angry and it's a conversion */
X#endif
X if (unicalign == u.ualigntyp) {
X u.ualign = -1;
X value = 1;
X } else value += 3;
X }
X }
X#ifdef ENDGAME
X if (otmp->otyp == AMULET_OF_YENDOR) {
X if (dlevel != ENDLEVEL) {
X if (otmp->spe == 0) {
X if (Hallucination)
X You("feel homesick.");
X else
X You("feel an urge to return to the surface.");
X return (1);
X }
X } else
X if (otmp->spe < 0) { /* fake! */
X if (flags.soundok)
X You("hear a nearby thunderclap.");
X if (!otmp->known) {
X You("realize you have made a %s.",
X Hallucination ? "boo-boo" : "mistake");
X otmp->known = 1;
X return (1);
X } else {
X /* don't you dare try to fool the gods */
X change_luck(-3);
X u.ugangr += 3;
X value = -3;
X }
X }
X else {
X /* The final Test. Did you win? */
X if(uamul == otmp) Amulet_off();
X if(carried(otmp)) useup(otmp); /* well, it's gone now */
X else useupf(otmp);
X You("offer the Amulet to %s...", a_gname());
X if (u.ualigntyp != altaralign) {
X /* And the opposing team picks him up and
X carries him off on their shoulders */
X pline("%s accepts your gift, and gains dominion over %s...",
X a_gname(), u_gname());
X pline("%s is enraged...", u_gname());
X pline("Fortunately, %s permits you to live...", a_gname());
X pline("A cloud of %s smoke surrounds you...",
X Hallucination ? hcolor() : (const char *)"orange");
X done(ESCAPED);
X } else { /* super big win */
X pline("An invisible choir sings, and you are bathed in radiance...");
X verbalize("Congratulations, mortal!");
X more();
Xverbalize("In return for thy service, I grant thee the gift of Immortality!");
X You("ascend to the status of Demigod...");
X done(ASCENDED);
X }
X }
X }
X#endif /* ENDGAME */
X
X#ifndef ALTARS /* No altars in shops */
X if (otmp->unpaid && u.ualigntyp != U_CHAOTIC) {
X You("realize sacrificing what is not yours is a very chaotic act.");
X value = -3;
X }
X#endif
X
X if (value == 0
X#ifndef ALTARS
X || Inhell
X#endif
X ) {
X pline(nothing_happens);
X return (1);
X }
X
X if (value < 0) /* I don't think the gods are gonna like this... */
X gods_upset();
X else {
X
X int saved_anger = u.ugangr;
X int saved_cnt = u.ublesscnt;
X int saved_luck = u.uluck;
X boolean consumed = FALSE;
X#ifdef ALTARS
X /* Sacrificing at an altar of a different alignment */
X if (u.ualigntyp != altaralign) {
X /* Is this a conversion ? */
X if(ugod_is_angry()) {
X if(u.ualignbase[0] == u.ualignbase[1]) {
X consume_offering(otmp);
X You("have a strong feeling that %s is angry...",
X u_gname());
X pline("%s accepts your allegiance.",a_gname());
X You("have a sudden sense of a new direction.");
X /* The player wears a helm of opposite alignment? */
X if (uarmh && uarmh->otyp == HELM_OF_OPPOSITE_ALIGNMENT)
X u.ualignbase[0] = altaralign;
X else
X u.ualigntyp = u.ualignbase[0] = altaralign;
X flags.botl = 1;
X /* Beware, Conversion is costly */
X change_luck(-3);
X u.ublesscnt += 300;
X adjalign((int)(u.ualignbase[1] * (ALIGNLIM / 2)));
X } else {
X pline("%s rejects your sacrifice!", a_gname());
X pline("The voice of %s booms:", u_gname());
X verbalize("Suffer, infidel!");
X adjalign(-5);
X u.ugangr += 3;
X adjattrib(A_WIS, -2, TRUE);
X if (!Inhell) angrygods();
X change_luck(-5);
X }
X return(1);
X } else {
X consume_offering(otmp);
X consumed = TRUE;
X You("sense a conflict between %s and %s.",
X u_gname(), a_gname());
X if (rn2(8 + (int)u.ulevel) > 5) {
X You("feel the power of %s increase.",
X u_gname());
X change_luck(1);
X /* Yes, this is supposed to be &=, not |= */
X levl[u.ux][u.uy].altarmask &= A_SHRINE;
X /* the following accommodates stupid compilers */
X levl[u.ux][u.uy].altarmask =
X levl[u.ux][u.uy].altarmask | (u.ualigntyp + 1);
X if (!Blind)
X pline("The newly consecrated altar glows %s.",
X Hallucination ? hcolor() :
X u.ualigntyp == U_LAWFUL ? white :
X u.ualigntyp ? black : (const char *)"gray");
X } else {
X pline("Unluckily, you feel the power of %s decrease.",
X u_gname());
X change_luck(-1);
X }
X return(1);
X }
X }
X#endif
X if(!consumed) consume_offering(otmp);
X /* OK, you get brownie points. */
X if(u.ugangr) {
X u.ugangr -= ((value * (u.ualigntyp == U_CHAOTIC ? 2 : 3)) / MAXVALUE);
X if(u.ugangr < 0) u.ugangr = 0;
X if(u.ugangr != saved_anger) {
X if (u.ugangr) {
X if(Hallucination)
X pline("The gods seem %s.", hcolor());
X else pline("The gods seem slightly mollified.");
X
X if ((int)u.uluck < 0) change_luck(1);
X } else {
X if (Hallucination)
X pline("The gods seem cosmic (not a new fact).");
X else pline ("The gods seem mollified.");
X
X if ((int)u.uluck < 0) u.uluck = 0;
X }
X } else { /* not satisfied yet */
X if (Hallucination)
X pline("The gods seem tall.");
X else You("have a feeling of inadequacy.");
X }
X }
X else if (u.ublesscnt > 0) {
X u.ublesscnt -= ((value * (u.ualigntyp == U_CHAOTIC ? 500 : 300))
X / MAXVALUE);
X if(u.ublesscnt < 0) u.ublesscnt = 0;
X if(u.ublesscnt != saved_cnt) {
X
X if (u.ublesscnt) {
X if (Hallucination)
X You("realize that the gods are not like you and I.");
X else
X You("have a hopeful feeling.");
X if ((int)u.uluck < 0) change_luck(1);
X } else {
X if (Hallucination)
X pline("Overall, there is a smell of fried onions.");
X else
X You("have a feeling of reconciliation.");
X if ((int)u.uluck < 0) u.uluck = 0;
X }
X }
X } else {
X /* you were already in pretty good standing */
X#if defined(ALTARS) && defined(NAMED_ITEMS)
X /* The player can gain an artifact */
X if(!rn2(10)) {
X otmp = mk_aligned_artifact((unsigned)(levl[u.ux][u.uy].altarmask & ~A_SHRINE));
X if(otmp) {
X if (otmp->spe < 0) otmp->spe = 0;
X if (otmp->cursed) otmp->cursed = 0;
X dropy(otmp);
X pline("An object appears at your %s!",
X makeplural(body_part(FOOT)));
X return(1);
X }
X }
X#endif
X change_luck((value * LUCKMAX) / (MAXVALUE * 2));
X if (u.uluck != saved_luck) {
X if (Blind)
X You("think something brushed your %s.",
X body_part(FOOT));
X else You(Hallucination ?
X "see crabgrass at your %s. A funny thing in a dungeon." :
X "glimpse a four-leaf clover at your %s.",
X makeplural(body_part(FOOT)));
X }
X }
X }
X return(1);
X}
X
Xint
Xdopray() { /* M. Stephenson (1.0.3b) */
X int trouble = in_trouble();
X#ifdef ALTARS
X int aligntyp =
X on_altar() ?
X (int)(levl[u.ux][u.uy].altarmask & ~A_SHRINE) - 1 :
X u.ualigntyp;
X int align;
X
X if (u.ualigntyp && u.ualigntyp == -aligntyp) align = -u.ualign;
X /* Opposite alignment altar */
X else if (u.ualigntyp != aligntyp) align = u.ualign / 2;
X /* Different (but non-opposite) alignment altar */
X else align = u.ualign;
X#else
X int aligntyp = u.ualigntyp;
X int align = u.ualign;
X#endif
X
X#ifdef POLYSELF
X if (is_undead(uasmon)) {
X if (aligntyp == 1 || (aligntyp == 0 && !rn2(10))) {
X verbalize(aligntyp == 1 ?
X "Vile creature, thou durst call upon me?" :
X "Walk no more, perversion of nature!");
X You("feel like you are falling apart.");
X rehumanize();
X losehp(rnd(20), "residual undead turning effect",
X KILLED_BY_AN);
X return(1);
X }
X }
X if (is_demon(uasmon) && (aligntyp != -1)) {
X pline("The very idea of praying to a %s god is repugnant to you.",
X u.ualigntyp ? "lawful" : "neutral");
X return(0);
X }
X#endif
X if (Inhell && u.ualigntyp != U_CHAOTIC) {
X pline("Since you are in hell, %s won't help you.",
X# ifdef ALTARS
X on_altar() ? a_gname() :
X# endif
X u_gname());
X aggravate();
X return(0);
X }
X
X#ifdef WIZARD
X if (wizard) {
X pline("Force the gods to be pleased? ");
X if (yn() == 'y') {
X u.ublesscnt = 0;
X if (u.uluck < 0) u.uluck = 0;
X u.ugangr = 0;
X if (align < 1) align = 1;
X }
X }
X#endif
X if ((!trouble && (u.ublesscnt > 0)) ||
X ((trouble < 0) && (u.ublesscnt > 100)) /* minor difficulties */ ||
X ((trouble > 0) && (u.ublesscnt > 200)) /* big trouble */
X ) {
X u.ublesscnt += rnz(250);
X change_luck(-3);
X gods_upset();
X } else if ((int)Luck < 0 || u.ugangr || align < 0)
X angrygods(); /* naughty */
X else if (align >= 0) pleased(); /* nice */
X nomovemsg = "You finish your prayer.";
X nomul(-3);
X return(1);
X}
X#endif /* THEOLOGY */
X
Xint
Xdoturn()
X{ /* Knights & Priest(esse)s only please */
X
X register struct monst *mtmp;
X register int xlev = 6;
X
X if((pl_character[0] != 'P') &&
X (pl_character[0] != 'K')) {
X#ifdef SPELLS
X /* Try to use turn undead spell. */
X if (objects[SPE_TURN_UNDEAD].oc_name_known) {
X register int sp_no;
X for (sp_no = 0; sp_no < MAXSPELL &&
X spl_book[sp_no].sp_id != NO_SPELL &&
X spl_book[sp_no].sp_id != SPE_TURN_UNDEAD; sp_no++);
X
X if (sp_no < MAXSPELL &&
X spl_book[sp_no].sp_id == SPE_TURN_UNDEAD)
X return spelleffects(++sp_no, TRUE);
X }
X#endif
X
X You("don't know how to turn undead!");
X return(0);
X }
X#if defined(POLYSELF) || defined(THEOLOGY)
X if (
X# ifdef POLYSELF
X (u.ualigntyp != U_CHAOTIC && (is_demon(uasmon) || is_undead(uasmon)))
X# endif
X# if defined(POLYSELF) && defined(THEOLOGY)
X ||
X# endif
X# ifdef THEOLOGY
X u.ugangr > 6 /* "Die, mortal!" */
X# endif
X ) {
X
X pline("For some reason, the gods seem to ignore you.");
X aggravate();
X return(0);
X }
X#endif
X if (Inhell && u.ualigntyp != U_CHAOTIC) {
X#ifdef THEOLOGY
X pline("Since you are in hell, %s won't help you.", u_gname());
X#else
X pline("Since you are in hell, the gods won't help you.");
X#endif
X aggravate();
X return(0);
X }
X#ifdef THEOLOGY
X pline("Calling upon %s, you chant an arcane formula.", u_gname());
X#else
X pline("Calling upon the gods, you chant an arcane formula.");
X#endif
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(cansee(mtmp->mx,mtmp->my)) {
X if(!mtmp->mtame && !mtmp->mpeaceful && (is_undead(mtmp->data) ||
X (is_demon(mtmp->data) && (u.ulevel > (MAXULEV/2))))) {
X
X if(Confusion) {
X pline("Unfortunately, your voice falters.");
X mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
X mtmp->mcanmove = 1;
X } else if (! resist(mtmp, '\0', 0, TELL))
X switch (mtmp->data->mlet) {
X /* this is intentional, lichs are tougher
X than zombies. */
X case S_LICH: xlev += 2;
X case S_GHOST: xlev += 2;
X case S_VAMPIRE: xlev += 2;
X case S_WRAITH: xlev += 2;
X case S_MUMMY: xlev += 2;
X case S_ZOMBIE:
X mtmp->mflee = 1; /* at least */
X if(u.ulevel >= xlev) {
X if(!resist(mtmp, '\0', 0, NOTELL)) {
X if(u.ualigntyp == U_CHAOTIC) {
X mtmp->mpeaceful = 1; /* make them friendly */
X } else { /* damn them */
X You("destroy %s!", mon_nam(mtmp));
X mondied(mtmp);
X }
X }
X }
X break;
X default: mtmp->mflee = 1;
X break;
X }
X }
X }
X nomul(-5);
X return(1);
X}
X
X#ifdef ALTARS
Xconst char *
Xa_gname()
X{
X return(a_gname_at(u.ux, u.uy));
X}
X
Xconst char *
Xa_gname_at(x,y) /* returns the name of an altar's deity */
Xxchar x, y;
X{
X register int align;
X
X if(!IS_ALTAR(levl[x][y].typ)) return((char *)0);
X
X align = levl[x][y].altarmask & ~A_SHRINE;
X# ifdef THEOLOGY
X {struct ghods *aghod;
X
X for(aghod=gods; aghod->classlet; aghod++)
X if(aghod->classlet == pl_character[0])
X switch(align) {
X case A_CHAOS: return(aghod->chaos);
X case A_NEUTRAL: return(aghod->balance);
X case A_LAW: return(aghod->law);
X default: impossible("unknown altar alignment.");
X return("Balance");
X }
X impossible("Altar to unknown character's god?");
X return("someone");
X }
X# else
X switch(align) {
X case A_CHAOS: return("Chaos");
X case A_NEUTRAL: return("Balance");
X case A_LAW: return("Law");
X default: impossible("unknown altar alignment.");
X return("Balance");
X }
X# endif /* THEOLOGY */
X}
X
X# ifdef THEOLOGY
Xvoid
Xaltar_wrath(x, y)
Xregister int x, y;
X{
X if(!strcmp(a_gname_at(x,y), u_gname())) {
X pline("The voice of %s booms:", a_gname_at(x,y));
X verbalize("How darest thou desecrate my altar!");
X adjattrib(A_WIS, -1, FALSE);
X } else {
X pline("A voice whispers in your ear:");
X verbalize("Thou shalt pay, infidel!");
X change_luck(-1);
X }
X}
X# endif /* THEOLOGY */
X#endif /* ALTARS */
X
X#ifdef THEOLOGY
Xconst char *
Xu_gname() { /* returns the name of the player's deity */
X register struct ghods *aghod;
X
X for(aghod=gods; aghod->classlet; aghod++)
X if(aghod->classlet == pl_character[0])
X switch(u.ualigntyp) {
X case 1: return(aghod->law);
X case 0: return(aghod->balance);
X case -1: return(aghod->chaos);
X default: impossible("unknown character alignment.");
X return("Balance");
X }
X impossible("atheist player?");
X return("someone");
X}
X#endif /* THEOLOGY */
END_OF_FILE
if test 36355 -ne `wc -c <'src/pray.c'`; then
echo shar: \"'src/pray.c'\" unpacked with wrong size!
fi
# end of 'src/pray.c'
fi
echo shar: End of archive 18 \(of 56\).
cp /dev/null ark18isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 56 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0