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