billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 48
Archive-name: nethack3p9/Part03
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 3 (of 56)."
# Contents: others/pcunix.c src/zap.c
# Wrapped by billr@saab on Wed Jul 11 17:10:52 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'others/pcunix.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'others/pcunix.c'\"
else
echo shar: Extracting \"'others/pcunix.c'\" \(4479 characters\)
sed "s/^X//" >'others/pcunix.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)pcunix.c 3.0 89/12/29
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X/* This file collects some Unix dependencies; pager.c contains some more */
X
X/*
X * The time is used for:
X * - seed for rand()
X * - year on tombstone and yymmdd in record file
X * - phase of the moon (various monsters react to NEW_MOON or FULL_MOON)
X * - night and midnight (the undead are dangerous at midnight)
X * - determination of what files are "very old"
X */
X
X#include "hack.h" /* mainly for index() which depends on BSD */
X
X#ifndef MACOS
X#include <sys/types.h>
X#include <sys/stat.h>
X#endif
X
Xstatic struct tm * NDECL(getlt);
X
X#ifdef OVLB
X
X#ifndef MACOS
Xstatic struct stat buf;
X# ifdef WANT_GETHDATE
Xstatic struct stat hbuf;
X# endif
X#endif
X
Xvoid
Xsetrandom()
X{
X (void) Srand((int) time ((time_t *) 0));
X}
X
Xstatic struct tm *
Xgetlt()
X{
X time_t date;
X
X (void) time(&date);
X return(localtime(&date));
X}
X
Xint
Xgetyear()
X{
X return(1900 + getlt()->tm_year);
X}
X
Xchar *
Xgetdate()
X{
X static char datestr[7];
X register struct tm *lt = getlt();
X
X Sprintf(datestr, "%2d%2d%2d",
X lt->tm_year, lt->tm_mon + 1, lt->tm_mday);
X if(datestr[2] == ' ') datestr[2] = '0';
X if(datestr[4] == ' ') datestr[4] = '0';
X return(datestr);
X}
X
Xint
Xphase_of_the_moon() /* 0-7, with 0: new, 4: full */
X{ /* moon period: 29.5306 days */
X /* year: 365.2422 days */
X register struct tm *lt = getlt();
X register int epact, diy, golden;
X
X diy = lt->tm_yday;
X golden = (lt->tm_year % 19) + 1;
X epact = (11 * golden + 18) % 30;
X if ((epact == 25 && golden > 11) || epact == 24)
X epact++;
X
X return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 );
X}
X
Xint
Xnight()
X{
X register int hour = getlt()->tm_hour;
X
X return(hour < 6 || hour > 21);
X}
X
Xint
Xmidnight()
X{
X return(getlt()->tm_hour == 0);
X}
X
X#ifndef MACOS
Xvoid
Xgethdate(name)
Xchar *name;
X{
X# ifdef WANT_GETHDATE
X/* old version - for people short of space */
X/*
X/* register char *np;
X/* if(stat(name, &hbuf))
X/* error("Cannot get status of %s.",
X/* (np = rindex(name, '/')) ? np+1 : name);
X/*
X/* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */
X
X/*
X * The problem with #include <sys/param.h> is that this include file
X * does not exist on all systems, and moreover, that it sometimes includes
X * <sys/types.h> again, so that the compiler sees these typedefs twice.
X */
X#define MAXPATHLEN 1024
X
X register char *np, *path;
X char filename[MAXPATHLEN+1], *getenv();
X
X if (index(name, '/') != NULL || (path = getenv("PATH")) == NULL)
X path = "";
X
X for (;;) {
X if ((np = index(path, ':')) == NULL)
X np = path + strlen(path); /* point to end str */
X if (np - path <= 1) /* %% */
X Strcpy(filename, name);
X else {
X (void) strncpy(filename, path, np - path);
X filename[np - path] = '/';
X Strcpy(filename + (np - path) + 1, name);
X }
X if (stat(filename, &hbuf) == 0)
X return;
X if (*np == '\0')
X path = "";
X path = np + 1;
X }
X error("Cannot get status of %s.", (np = rindex(name, '/')) ? np+1 : name);
X# endif /* WANT_GETHDATE */
X}
X
Xint
Xuptodate(fd)
Xint fd;
X{
X# ifdef WANT_GETHDATE
X if(fstat(fd, &buf)) {
X pline("Cannot get status of saved level? ");
X return(0);
X }
X if(buf.st_mtime < hbuf.st_mtime) {
X pline("Saved level is out of date. ");
X return(0);
X }
X# else
X# if defined(MSDOS) && !defined(NO_FSTAT)
X if(fstat(fd, &buf)) {
X if(moves > 1) pline("Cannot get status of saved level? ");
X else pline("Cannot get status of saved game");
X return(0);
X }
X if(comp_times(buf.st_mtime)) {
X if(moves > 1) pline("Saved level is out of date");
X else pline("Saved game is out of date. ");
X return(0);
X }
X# endif /* MSDOS /* */
X# endif /* WANT_GETHDATE */
X return(1);
X}
X#endif /* MACOS /* */
X
Xvoid
Xregularize(s)
X/*
X * normalize file name - we don't like .'s, /'s, :'s [Mac], or spaces,
X * and in msdos / OS/2 we really get picky
X */
Xregister char *s;
X{
X register char *lp;
X
X#ifdef MSDOS
X for (lp = s; *lp; lp++)
X if (*lp <= ' ' || *lp == '"' || (*lp >= '*' && *lp <= ',') ||
X *lp == '.' || *lp == '/' || (*lp >= ':' && *lp <= '?') ||
X# ifdef OS2
X *lp == '&' || *lp == '(' || *lp == ')' ||
X# endif
X *lp == '|' || *lp >= 127 || (*lp >= '[' && *lp <= ']'))
X *lp = '_';
X#else
X while((lp=index(s, '.')) || (lp=index(s, '/')) || (lp=index(s,' '))
X# ifdef MACOS
X || (lp=index(s, ':'))
X# endif
X ) *lp = '_';
X#endif
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 4479 -ne `wc -c <'others/pcunix.c'`; then
echo shar: \"'others/pcunix.c'\" unpacked with wrong size!
fi
# end of 'others/pcunix.c'
fi
if test -f 'src/zap.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/zap.c'\"
else
echo shar: Extracting \"'src/zap.c'\" \(50988 characters\)
sed "s/^X//" >'src/zap.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)zap.c 3.0 89/11/08
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X#if defined(ALTARS) && defined(THEOLOGY)
Xstatic boolean NEARDATA priesthit = FALSE;
X#endif
X
Xstatic int FDECL(burn_floor_paper,(int,int));
XSTATIC_PTR int FDECL(bhitm,(struct monst *,struct obj *));
Xstatic void FDECL(cancel_item,(struct obj *));
Xstatic int FDECL(bhitgold,(struct gold *,struct obj *));
XSTATIC_PTR int FDECL(bhito,(struct obj *,struct obj *));
Xstatic void FDECL(backfire,(struct obj *));
Xstatic uchar FDECL(dirlet,(int,int));
Xstatic int FDECL(zhit,(struct monst *,int,int));
X
Xconst char *fl[]= {
X "magic missile", /* Wands must be 0-9 */
X "bolt of fire",
X "sleep ray",
X "bolt of cold",
X "death ray",
X "bolt of lightning",
X "",
X "",
X "",
X "",
X
X "magic missile", /* Spell equivalents must be 10-19 */
X "fireball",
X "sleep ray",
X "cone of cold",
X "finger of death",
X "bolt of lightning",
X "",
X "",
X "",
X "",
X
X "blast of missiles", /* Dragon breath equivalents 20-29*/
X "blast of fire",
X "blast of sleep gas",
X "blast of frost",
X "blast of disintegration",
X "blast of lightning",
X "blast of poison gas",
X "blast of acid",
X "",
X ""
X};
X
X#ifdef TEXTCOLOR
Xstatic const int zapcolor[10] = {
X AT_ZAP, RED|BRIGHT, AT_ZAP, WHITE|BRIGHT, AT_ZAP, WHITE|BRIGHT,
X AT_ZAP, AT_ZAP, AT_ZAP, AT_ZAP
X};
X#endif
X
X/* Routines for IMMEDIATE wands and spells. */
X/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
XSTATIC_PTR
Xint
Xbhitm(mtmp, otmp)
Xregister struct monst *mtmp;
Xregister struct obj *otmp;
X{
X wakeup(mtmp);
X switch(otmp->otyp) {
X case WAN_STRIKING:
X#ifdef SPELLS
X case SPE_FORCE_BOLT:
X#endif
X if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
X register int tmp = d(2,12);
X hit((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp, exclam(tmp));
X (void) resist(mtmp, otmp->olet, tmp, TELL);
X } else miss((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp);
X break;
X case WAN_SLOW_MONSTER:
X#ifdef SPELLS
X case SPE_SLOW_MONSTER:
X#endif
X if(! resist(mtmp, otmp->olet, 0, NOTELL)) {
X if (mtmp->mspeed == MFAST) mtmp->mspeed = 0;
X else mtmp->mspeed = MSLOW;
X if (u.uswallow && (mtmp == u.ustuck) &&
X is_whirly(mtmp->data)) {
X You("disrupt %s!", mon_nam(mtmp));
X pline("A huge hole opens up...");
X expels(mtmp, mtmp->data, TRUE);
X }
X }
X break;
X case WAN_SPEED_MONSTER:
X if (!resist(mtmp, otmp->olet, 0, NOTELL))
X if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
X else mtmp->mspeed = MFAST;
X break;
X case WAN_UNDEAD_TURNING:
X#ifdef SPELLS
X case SPE_TURN_UNDEAD:
X#endif
X if(is_undead(mtmp->data)) {
X
X if(!resist(mtmp, otmp->olet, rnd(8), NOTELL))
X mtmp->mflee = 1;
X }
X break;
X case WAN_POLYMORPH:
X#ifdef SPELLS
X case SPE_POLYMORPH:
X#endif
X if(!resist(mtmp, otmp->olet, 0, NOTELL))
X if( newcham(mtmp, (struct permonst *)0) )
X if (!Hallucination)
X makeknown(otmp->otyp);
X break;
X case WAN_CANCELLATION:
X#ifdef SPELLS
X case SPE_CANCELLATION:
X#endif
X if(!resist(mtmp, otmp->olet, 0, NOTELL)) {
X if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
X were_change(mtmp);
X#ifdef GOLEMS
X if (mtmp->data == &mons[PM_CLAY_GOLEM]) {
X if (!Blind)
X pline("Some writing vanishes from %s's head!",
X mon_nam(mtmp));
X killed(mtmp);
X }
X else
X#endif /* GOLEMS */
X mtmp->mcan = 1;
X }
X break;
X case WAN_TELEPORTATION:
X#ifdef SPELLS
X case SPE_TELEPORT_AWAY:
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
X if(mtmp->ispriest && in_temple(mtmp->mx, mtmp->my)) {
X kludge("%s resists your magic!", Monnam(mtmp));
X wakeup(mtmp);
X break;
X }
X#endif
X rloc(mtmp);
X break;
X case WAN_MAKE_INVISIBLE:
X mtmp->minvis = 1;
X break;
X case WAN_NOTHING:
X break;
X#ifdef PROBING
X case WAN_PROBING:
X makeknown(otmp->otyp);
X mstatusline(mtmp);
X break;
X#endif
X case WAN_OPENING:
X if(u.uswallow && mtmp == u.ustuck) {
X if (is_animal(mtmp->data)) {
X if (Blind) pline("Its mouth opens!");
X else pline("%s opens its mouth!", Monnam(mtmp));
X }
X expels(mtmp, mtmp->data, TRUE);
X break;
X }
X case WAN_LOCKING:
X#ifdef SPELLS
X case SPE_KNOCK:
X case SPE_WIZARD_LOCK:
X#endif
X break;
X default:
X impossible("What an interesting effect (%u)", otmp->otyp);
X }
X return 0;
X}
X
Xstruct monst *
Xrevive(obj,ininv)
Xregister struct obj *obj;
Xboolean ininv;
X{
X register struct monst *mtmp = (struct monst *)0;
X
X if(obj->otyp == CORPSE) {
X int montype = obj->corpsenm;
X int x = ininv ? u.ux : obj->ox;
X int y = ininv ? u.uy : obj->oy;
X
X if (cant_create(&montype)) { /* will make zombie instead */
X mtmp = makemon(&mons[PM_HUMAN_ZOMBIE], x, y);
X if (mtmp) {
X mtmp->mhp = mtmp->mhpmax = 100;
X mtmp->mspeed = MFAST;
X }
X } else {
X struct obj *otmp;
X#ifdef ARMY
X if (is_mercenary(&mons[montype]))
X montype = PM_UNARMORED_SOLDIER;
X#endif
X mtmp = makemon(&mons[montype], x, y);
X if (mtmp) {
X /* Monster retains its name */
X if (obj->onamelth)
X mtmp = christen_monst(mtmp, ONAME(obj));
X /* No inventory for newly revived monsters */
X while(otmp = (mtmp->minvent)) {
X mtmp->minvent = otmp->nobj;
X free((genericptr_t)otmp);
X }
X }
X }
X if (mtmp && obj->oeaten)
X mtmp->mhp = eaten_stat(mtmp->mhp, obj);
X if (ininv) useup(obj);
X else {
X /* not useupf(), which charges */
X if (obj->quan > 1) obj->quan--;
X else delobj(obj);
X }
X if (x != u.ux || y != u.uy || Invisible)
X newsym(x, y);
X }
X return mtmp;
X}
X
Xstatic const char NEARDATA charged_objs[] = { WAND_SYM, WEAPON_SYM, ARMOR_SYM, 0 };
X
Xstatic void
Xcancel_item(obj)
Xregister struct obj *obj;
X{
X switch(obj->otyp) {
X case RIN_GAIN_STRENGTH:
X if(obj->owornmask & W_RING) {
X ABON(A_STR) -= obj->spe;
X flags.botl = 1;
X }
X break;
X case RIN_ADORNMENT:
X if(obj->owornmask & W_RING) {
X ABON(A_CHA) -= obj->spe;
X flags.botl = 1;
X }
X break;
X case RIN_INCREASE_DAMAGE:
X if(obj->owornmask & W_RING)
X u.udaminc -= obj->spe;
X break;
X case GAUNTLETS_OF_DEXTERITY:
X if(obj->owornmask & W_ARMG) {
X ABON(A_DEX) -= obj->spe;
X flags.botl = 1;
X }
X break;
X case HELM_OF_BRILLIANCE:
X if(obj->owornmask & W_ARMH) {
X ABON(A_INT) -= obj->spe;
X ABON(A_WIS) -= obj->spe;
X flags.botl = 1;
X }
X break;
X /* case RIN_PROTECTION: /* not needed */
X }
X if(obj->spe &&
X !(obj->otyp == AMULET_OF_YENDOR ||
X obj->otyp == WAN_CANCELLATION || /* can't cancel cancellation */
X obj->otyp == TIN || obj->otyp == EGG ||
X obj->otyp == STATUE ||
X#ifdef MAIL
X obj->otyp == SCR_MAIL ||
X#endif
X#ifdef TUTTI_FRUTTI
X obj->otyp == SLIME_MOLD ||
X#endif
X obj->otyp == KEY || obj->otyp == SKELETON_KEY ||
X obj->otyp == LARGE_BOX || obj->otyp == CHEST))
X obj->spe = (obj->olet == WAND_SYM) ? -1 : 0;
X
X if (obj->olet == SCROLL_SYM
X#ifdef MAIL
X && obj->otyp != SCR_MAIL
X#endif
X )
X obj->otyp = SCR_BLANK_PAPER;
X
X if (obj->olet == POTION_SYM && obj->otyp > POT_BOOZE)
X obj->otyp = (obj->otyp==POT_SICKNESS || obj->otyp==POT_SEE_INVISIBLE) ? POT_FRUIT_JUICE : POT_WATER;
X /* sickness is "biologically contaminated" fruit juice; cancel it
X * and it just becomes fruit juice... whereas see invisible
X * tastes like "enchanted" fruit juice, it similarly cancels.
X */
X obj->blessed = obj->cursed = FALSE;
X}
X
Xstatic int
Xbhitgold(gold, otmp)
Xregister struct gold *gold;
Xregister struct obj *otmp;
X{
X switch(otmp->otyp) {
X case WAN_TELEPORTATION:
X#ifdef SPELLS
X case SPE_TELEPORT_AWAY:
X#endif
X rlocgold(gold);
X break;
X }
X return 1;
X}
X
XSTATIC_PTR
Xint
Xbhito(obj, otmp) /* object obj was hit by the effect of wand otmp */
Xregister struct obj *obj, *otmp; /* returns TRUE if sth was done */
X{
X register int res = 1;
X struct obj *otmp2;
X
X if(obj == uball || obj == uchain)
X res = 0;
X else
X switch(otmp->otyp) {
X case WAN_POLYMORPH:
X#ifdef SPELLS
X case SPE_POLYMORPH:
X#endif
X /* avoid unicorn/tool abuse */
X if (obj->otyp == UNICORN_HORN) obj->olet = WEAPON_SYM;
X
X /* preserve symbol and quantity */
X otmp2 = mkobj_at(obj->olet, obj->ox, obj->oy, FALSE);
X otmp2->quan = obj->quan;
X#ifdef MAIL
X /* You can't send yourself 100 mail messages and then
X * polymorph them into useful scrolls
X */
X if (obj->otyp == SCR_MAIL) {
X otmp2->otyp = SCR_MAIL;
X otmp2->spe = 1;
X }
X#endif
X /* keep special fields (including charges on wands) */
X if (index(charged_objs, otmp2->olet)) otmp2->spe = obj->spe;
X
X /* Amulet gets cheap stewr 870807 */
X if (obj->otyp == AMULET_OF_YENDOR) otmp2->spe = -1;
X
X otmp2->cursed = obj->cursed;
X otmp2->blessed = obj->blessed;
X otmp2->rustfree = obj->rustfree;
X
X /* Keep chest/box traps and poisoned ammo if we may */
X if (obj->otrapped && Is_box(otmp2))
X otmp2->otrapped = 1;
X if (obj->opoisoned &&
X (otmp2->olet == WEAPON_SYM && otmp2->otyp <= SHURIKEN))
X otmp2->opoisoned = 1;
X
X if (obj->otyp == CORPSE){
X /* Turn dragon corpses into dragon armors */
X if (obj->corpsenm >= PM_GRAY_DRAGON
X && obj->corpsenm <= PM_YELLOW_DRAGON) {
X if (!rn2(10)) { /* Random failure */
X otmp2->otyp = TIN;
X otmp2->known = otmp2->dknown = 1;
X } else {
X otmp2->otyp = DRAGON_SCALE_MAIL;
X otmp2->olet = ARMOR_SYM;
X otmp2->spe = 0;
X otmp2->rustfree = 1;
X otmp2->quan = 1;
X otmp2->cursed = 0;
X }
X otmp2->corpsenm = obj->corpsenm;
X /* and croc corpses into shoes */
X } else if (obj->corpsenm == PM_CROCODILE) {
X otmp2->otyp = LOW_BOOTS;
X otmp2->olet = ARMOR_SYM;
X otmp2->spe = 0;
X otmp2->rustfree = 1;
X otmp2->quan = 1;
X otmp2->cursed = 0;
X }
X }
X
X /* no box contents --KAA */
X if (Is_container(otmp2)) delete_contents(otmp2);
X
X if(otmp2->otyp == MAGIC_LAMP) otmp2->otyp = LAMP;
X
X if(otmp2->otyp == WAN_WISHING)
X while(otmp2->otyp == WAN_WISHING ||
X otmp2->otyp == WAN_POLYMORPH)
X otmp2->otyp = rnd_class(WAN_LIGHT, WAN_LIGHTNING);
X
X /* update the weight */
X otmp2->owt = weight(otmp2);
X delobj(obj);
X break;
X case WAN_STRIKING:
X#ifdef SPELLS
X case SPE_FORCE_BOLT:
X#endif
X if(obj->otyp == BOULDER)
X fracture_rock(obj);
X else if(obj->otyp == STATUE)
X (void) break_statue(obj);
X else
X res = 0;
X break;
X case WAN_CANCELLATION:
X#ifdef SPELLS
X case SPE_CANCELLATION:
X#endif
X cancel_item(obj);
X break;
X case WAN_TELEPORTATION:
X#ifdef SPELLS
X case SPE_TELEPORT_AWAY:
X#endif
X rloco(obj);
X break;
X case WAN_MAKE_INVISIBLE:
X obj->oinvis = 1;
X break;
X case WAN_UNDEAD_TURNING:
X#ifdef SPELLS
X case SPE_TURN_UNDEAD:
X#endif
X res = !!revive(obj,FALSE);
X break;
X case WAN_OPENING:
X case WAN_LOCKING:
X#ifdef SPELLS
X case SPE_KNOCK:
X case SPE_WIZARD_LOCK:
X#endif
X if(Is_box(obj))
X res = boxlock(obj, otmp);
X else
X res = 0;
X if (res /* && obj->olet == WAND_SYM */)
X makeknown(obj->otyp);
X break;
X case WAN_SLOW_MONSTER: /* no effect on objects */
X#ifdef SPELLS
X case SPE_SLOW_MONSTER:
X#endif
X case WAN_SPEED_MONSTER:
X case WAN_NOTHING:
X#ifdef PROBING
X case WAN_PROBING:
X#endif
X res = 0;
X break;
X default:
X impossible("What an interesting effect (%u)", otmp->otyp);
X }
X return(res);
X}
X
X/*
X * zappable - returns 1 if zap is available, 0 otherwise.
X * it removes a charge from the wand if zappable.
X * added by GAN 11/03/86
X */
Xint
Xzappable(wand)
Xregister struct obj *wand;
X{
X if(wand->spe < 0 || (wand->spe == 0 && rn2(121)))
X return 0;
X if(wand->spe == 0)
X You("wrest one more spell from the worn-out wand.");
X wand->spe--;
X return 1;
X}
X
X/*
X * zapnodir - zaps an NODIR wand.
X * added by GAN 11/03/86
X */
Xvoid
Xzapnodir(wand)
Xregister struct obj *wand;
X{
X switch(wand->otyp){
X case WAN_LIGHT:
X litroom(TRUE);
X break;
X case WAN_SECRET_DOOR_DETECTION:
X if(!findit()) return;
X break;
X case WAN_CREATE_MONSTER:
X { register int cnt = 1;
X if(!rn2(23)) cnt += rn2(7) + 1;
X while(cnt--)
X (void) makemon((struct permonst *) 0, u.ux, u.uy);
X }
X break;
X case WAN_WISHING:
X if(Luck + rn2(5) < 0) {
X pline("Unfortunately, nothing happens.");
X break;
X }
X makewish();
X break;
X }
X if(!objects[wand->otyp].oc_name_known) {
X makeknown(wand->otyp);
X more_experienced(0,10);
X }
X}
X
Xstatic void
Xbackfire(otmp)
X
X register struct obj * otmp;
X{
X pline("The %s suddenly explodes!", xname(otmp));
X losehp(d(otmp->spe+2,6), "exploding wand", KILLED_BY_AN);
X useup(otmp);
X}
X
Xstatic const char NEARDATA zap_syms[] = { WAND_SYM, 0 };
X
Xint
Xdozap()
X{
X register struct obj *obj;
X int damage;
X
X obj = getobj(zap_syms, "zap");
X if(!obj) return(0);
X
X check_unpaid(obj);
X
X /* zappable addition done by GAN 11/03/86 */
X if(!zappable(obj)) pline(nothing_happens);
X else if(obj->cursed && !rn2(100)) {
X backfire(obj); /* the wand blows up in your face! */
X return(1);
X } else if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) {
X if (!Blind)
X pline("The %s glows and fades.", xname(obj));
X /* make him pay for knowing !NODIR */
X } else if(!u.dx && !u.dy && !u.dz && !(objects[obj->otyp].bits & NODIR)) {
X if((damage = zapyourself(obj)))
X losehp(damage, self_pronoun("zapped %sself with a wand", "him"),
X NO_KILLER_PREFIX);
X }
X else {
X weffects(obj);
X#if defined(ALTARS) && defined(THEOLOGY)
X if(priesthit) ghod_hitsu();
X priesthit = FALSE;
X#endif
X }
X if (obj->spe < 0) {
X pline ("The %s %sturns to dust.",
X xname(obj), Blind ? "" : "glows violently, then ");
X useup(obj);
X }
X return(1);
X}
X
Xint
Xzapyourself(obj)
X register struct obj *obj;
X{
X struct obj *otmp;
X int damage = 0;
X
X switch(obj->otyp) {
X case WAN_STRIKING:
X#ifdef SPELLS
X case SPE_FORCE_BOLT:
X#endif
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X pline("Boing!");
X } else {
X You("magically bash yourself!");
X damage=d(8,6);
X }
X break;
X case WAN_LIGHTNING:
X makeknown(WAN_LIGHTNING);
X if (!Shock_resistance) {
X pline("Idiot! You've shocked yourself!");
X damage = d(12,6);
X } else {
X shieldeff(u.ux, u.uy);
X You("zap yourself, but seem unharmed.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_ELEC, d(12,6));
X#endif /* GOLEMS */
X#endif
X }
X destroy_item(WAND_SYM, AD_ELEC);
X destroy_item(RING_SYM, AD_ELEC);
X if(!Blind) {
X You("are blinded by the flash!");
X make_blinded((long)rnd(100),FALSE);
X }
X break;
X case WAN_FIRE:
X makeknown(WAN_FIRE);
X#ifdef SPELLS
X case SPE_FIREBALL:
X#endif
X#ifdef MUSIC
X case FIRE_HORN:
X#endif
X pline("You've set light to yourself!");
X if (Fire_resistance) {
X shieldeff(u.ux, u.uy);
X You("feel mildly hot.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_FIRE, d(12,6));
X#endif /* GOLEMS */
X#endif
X } else
X damage = d(12,6);
X destroy_item(SCROLL_SYM, AD_FIRE);
X destroy_item(POTION_SYM, AD_FIRE);
X#ifdef SPELLS
X destroy_item(SPBOOK_SYM, AD_FIRE);
X#endif
X break;
X case WAN_COLD:
X makeknown(WAN_COLD);
X#ifdef SPELLS
X case SPE_CONE_OF_COLD:
X#endif
X#ifdef MUSIC
X case FROST_HORN:
X#endif
X if (Cold_resistance) {
X shieldeff(u.ux, u.uy);
X You("feel mildly chilly.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_COLD, d(12,6));
X#endif /* GOLEMS */
X#endif
X } else {
X You("imitate a popsicle!");
X damage = d(12,6);
X }
X destroy_item(POTION_SYM, AD_COLD);
X break;
X case WAN_MAGIC_MISSILE:
X makeknown(WAN_MAGIC_MISSILE);
X#ifdef SPELLS
X case SPE_MAGIC_MISSILE:
X#endif
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X pline("The missiles bounce!");
X } else {
X damage = d(4,6);
X pline("Idiot! You've shot yourself!");
X }
X break;
X case WAN_POLYMORPH:
X#ifdef POLYSELF
X makeknown(WAN_POLYMORPH);
X#endif
X#ifdef SPELLS
X case SPE_POLYMORPH:
X#endif
X#ifdef POLYSELF
X polyself();
X#else
X newman();
X#endif
X break;
X case WAN_CANCELLATION:
X#ifdef SPELLS
X case SPE_CANCELLATION:
X#endif
X#ifdef POLYSELF
X#ifdef GOLEMS
X if (u.umonnum == PM_CLAY_GOLEM) {
X if (!Blind)
X pline("Some writing vanishes from your head!");
X rehumanize();
X break;
X }
X#endif /* GOLEMS */
X#endif
X for(otmp = invent; otmp; otmp = otmp->nobj)
X cancel_item(otmp);
X#ifdef POLYSELF
X if(u.mtimedone) rehumanize();
X#endif
X flags.botl = 1; /* because of potential AC change */
X find_ac();
X break;
X case WAN_MAKE_INVISIBLE:
X if (!Invis && !See_invisible)
X makeknown(WAN_MAKE_INVISIBLE);
X HInvis |= INTRINSIC;
X if (!See_invisible) newsym(u.ux, u.uy);
X break;
X case WAN_SPEED_MONSTER:
X if (!(Fast & INTRINSIC)) {
X Fast |= INTRINSIC;
X You("seem to be moving faster.");
X makeknown(WAN_SPEED_MONSTER);
X }
X break;
X case WAN_SLEEP:
X makeknown(WAN_SLEEP);
X#ifdef SPELLS
X case SPE_SLEEP:
X#endif
X if(Sleep_resistance) {
X shieldeff(u.ux, u.uy);
X You("don't feel sleepy!");
X } else {
X pline("The sleep ray hits you!");
X nomul(-rn2(50));
X }
X break;
X case WAN_SLOW_MONSTER:
X#ifdef SPELLS
X case SPE_SLOW_MONSTER:
X#endif
X if(Fast & (TIMEOUT | INTRINSIC)) {
X Fast &= ~(TIMEOUT | INTRINSIC);
X You("seem to be moving slower.");
X }
X break;
X case WAN_TELEPORTATION:
X#ifdef SPELLS
X case SPE_TELEPORT_AWAY:
X#endif
X tele();
X break;
X case WAN_DEATH:
X#ifdef SPELLS
X case SPE_FINGER_OF_DEATH:
X#endif
X#ifdef POLYSELF
X if (is_undead(uasmon)) {
X pline((obj->otyp == WAN_DEATH) ?
X "The wand shoots an apparently harmless beam at you."
X : "You seem no deader than before.");
X break;
X }
X#endif
X killer_format = NO_KILLER_PREFIX;
X killer = self_pronoun("shot %sself with a death ray","him");
X You("irradiate yourself with pure energy!");
X You("die.");
X makeknown(WAN_DEATH);
X /* They might survive with an amulet of life saving */
X done(DIED);
X break;
X#ifdef SPELLS
X case SPE_TURN_UNDEAD:
X#endif
X case WAN_UNDEAD_TURNING:
X#ifdef POLYSELF
X if (is_undead(uasmon)) {
X You("feel frightened and %sstunned.",
X Stunned ? "even more " : "");
X make_stunned(HStun + rnd(30), FALSE);
X }
X#endif
X break;
X#ifdef SPELLS
X case SPE_DIG:
X case SPE_DETECT_UNSEEN:
X#endif
X case WAN_DIGGING:
X case WAN_NOTHING:
X case WAN_OPENING:
X case WAN_LOCKING:
X#ifdef SPELLS
X case SPE_KNOCK:
X case SPE_WIZARD_LOCK:
X#endif
X break;
X#ifdef PROBING
X case WAN_PROBING:
X makeknown(WAN_PROBING);
X ustatusline();
X break;
X#endif
X default: impossible("object %d used?",obj->otyp);
X }
X return(damage);
X}
X
X/* called for various wand and spell effects - M. Stephenson */
Xvoid
Xweffects(obj)
Xregister struct obj *obj;
X{
X xchar zx,zy;
X
X if(objects[obj->otyp].bits & IMMEDIATE) {
X if(u.uswallow) (void)bhitm(u.ustuck, obj);
X else if(u.dz) {
X if(u.dz > 0) {
X#ifdef STRONGHOLD
X if(levl[u.ux][u.uy].typ == DRAWBRIDGE_DOWN &&
X (obj->otyp == WAN_LOCKING
X# ifdef SPELLS
X || obj->otyp == SPE_WIZARD_LOCK
X# endif
X ))
X (void)close_drawbridge(u.ux, u.uy);
X else
X#endif
X {
X register struct obj *otmp, *otmp2 = (struct obj *)0;
X
X if(levl[u.ux][u.uy].gmask)
X (void) bhitgold(g_at(u.ux, u.uy), obj);
X /* pre-reverse the polymorph pile, -dave- 3/90 */
X if (obj->otyp == WAN_POLYMORPH
X#ifdef SPELLS
X || obj->otyp == SPE_POLYMORPH
X#endif
X ) {
X otmp = level.objects[u.ux][u.uy];
X level.objects[u.ux][u.uy] = otmp2;
X while(otmp) {
X otmp2 = otmp->nexthere;
X otmp->nexthere = level.objects[u.ux][u.uy];
X level.objects[u.ux][u.uy] = otmp;
X otmp = otmp2;
X }
X }
X for(otmp = level.objects[u.ux][u.uy];
X otmp; otmp = otmp2) {
X /* changed by GAN to hit all objects there */
X otmp2 = otmp->nexthere;
X /* save pointer as bhito may destroy otmp */
X (void) bhito(otmp, obj);
X }
X }
X }
X } else (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
X } else {
X switch(obj->otyp){
X case WAN_LIGHT:
X#ifdef SPELLS
X case SPE_LIGHT:
X#endif
X litroom(TRUE);
X break;
X case WAN_SECRET_DOOR_DETECTION:
X#ifdef SPELLS
X case SPE_DETECT_UNSEEN:
X#endif
X if(!findit()) return;
X break;
X case WAN_CREATE_MONSTER:
X { register int cnt = 1;
X if(!rn2(23)) cnt += rn2(7) + 1;
X while(cnt--)
X (void) makemon((struct permonst *) 0, u.ux, u.uy);
X }
X break;
X case WAN_WISHING:
X if(Luck + rn2(5) < 0) {
X pline("Unfortunately, nothing happens.");
X break;
X }
X makewish();
X break;
X case WAN_DIGGING:
X#ifdef SPELLS
X case SPE_DIG:
X#endif
X /* Original effect (approximately):
X * from CORR: dig until we pierce a wall
X * from ROOM: piece wall and dig until we reach
X * an ACCESSIBLE place.
X * Currently: dig for digdepth positions;
X * also down on request of Lennart Augustsson.
X */
X { register struct rm *room;
X register int digdepth,dlx,dly;
X register boolean shopdoor = FALSE;
X#ifdef __GNULINT__
X dlx = dly = 0;
X#endif
X if(u.uswallow) {
X register struct monst *mtmp = u.ustuck;
X
X if (!is_whirly(mtmp->data)) {
X if (is_animal(mtmp->data))
X if (Blind)
X You("pierce its stomach wall!");
X else
X You("pierce %s's stomach wall!",
X mon_nam(mtmp));
X mtmp->mhp = 1; /* almost dead */
X expels(mtmp, mtmp->data,
X !is_animal(mtmp->data));
X }
X break;
X }
X if(u.dz) {
X if(u.dz < 0) {
X You("loosen a rock from the ceiling.");
X pline("It falls on your %s!",
X body_part(HEAD));
X losehp(1, "falling rock", KILLED_BY_AN);
X (void) mksobj_at((int)ROCK, u.ux, u.uy);
X fobj->quan = 1;
X stackobj(fobj);
X if(Invisible) newsym(u.ux, u.uy);
X } else {
X#ifdef MACOS
X segments |= SEG_ZAP;
X#endif
X dighole();
X }
X break;
X }
X zx = u.ux+u.dx;
X zy = u.uy+u.dy;
X digdepth = 8 + rn2(18);
X Tmp_at2(-1, '*'); /* open call */
X while(--digdepth >= 0) {
X if(!isok(zx,zy)) break;
X room = &levl[zx][zy];
X Tmp_at2(zx,zy);
X if(is_maze_lev) {
X if(IS_WALL(room->typ)) {
X if(room->diggable == W_DIGGABLE)
X room->typ = ROOM;
X else if(!Blind)
X pline("The wall glows then fades.");
X break;
X }
X if(room->typ == STONE) {
X if(room->diggable == W_DIGGABLE)
X room->typ = CORR;
X else if (!Blind)
X pline("The rock glows then fades.");
X break;
X }
X } else
X if(IS_ROCK(room->typ))
X if(may_dig(zx,zy))
X if(IS_WALL(room->typ) ||
X room->typ == SDOOR) {
X room->typ = DOOR;
X room->doormask = D_NODOOR;
X mnewsym(zx, zy);
X if (cansee(zx,zy)) prl(zx, zy);
X digdepth -= 2;
X } else {
X room->typ = CORR;
X digdepth--;
X }
X else
X break;
X else if(closed_door(zx, zy)) {
X room->doormask = D_NODOOR;
X mnewsym(zx, zy);
X if (cansee(zx,zy)) prl(zx, zy);
X if(in_shop(zx,zy)) {
X shopdoor = TRUE;
X dlx = zx;
X dly = zy;
X }
X digdepth -= 2;
X }
X mnewsym(zx,zy);
X zx += u.dx;
X zy += u.dy;
X }
X mnewsym(zx,zy); /* not always necessary */
X Tmp_at2(-1,-1); /* closing call */
X if(!Blind) prl(u.ux+u.dx, u.uy+u.dy);
X if(shopdoor)
X pay_for_door(dlx, dly, "destroy");
X break;
X }
X default:
X#ifdef SPELLS
X if((int) obj->otyp >= SPE_MAGIC_MISSILE) {
X
X buzz((int) obj->otyp - SPE_MAGIC_MISSILE + 10,
X (int)u.ulevel / 2 + 1, u.ux, u.uy, u.dx, u.dy);
X } else
X#endif
X
X buzz((int) obj->otyp - WAN_MAGIC_MISSILE, 6,
X u.ux, u.uy, u.dx, u.dy);
X break;
X }
X if(!objects[obj->otyp].oc_name_known) {
X makeknown(obj->otyp);
X more_experienced(0,10);
X }
X }
X return;
X}
X
Xconst char *
Xexclam(force)
Xregister int force;
X{
X /* force == 0 occurs e.g. with sleep ray */
X /* note that large force is usual with wands so that !! would
X require information about hand/weapon/wand */
X return (const char *)((force < 0) ? "?" : (force <= 4) ? "." : "!");
X}
X
Xvoid
Xhit(str,mtmp,force)
Xregister const char *str;
Xregister struct monst *mtmp;
Xregister const char *force; /* usually either "." or "!" */
X{
X if(!cansee(mtmp->mx,mtmp->my) || !flags.verbose) pline("The %s hits it.", str);
X else pline("The %s hits %s%s", str, mon_nam(mtmp), force);
X}
X
Xvoid
Xmiss(str,mtmp)
Xregister const char *str;
Xregister struct monst *mtmp;
X{
X pline("The %s misses %s.", str,
X (cansee(mtmp->mx,mtmp->my) && flags.verbose) ? mon_nam(mtmp) : "it");
X}
X
X/* bhit: called when a weapon is thrown (sym = obj->olet) or when an
X IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of
X range or when a monster is hit; the monster is returned, and bhitpos
X is set to the final position of the weapon thrown; the ray of a wand
X may affect several objects and monsters on its path - for each of
X these an argument function is called. */
X/* check !u.uswallow before calling bhit() */
X
Xstruct monst *
Xbhit(ddx,ddy,range,sym,fhitm,fhito,obj)
Xregister int ddx,ddy,range; /* direction and range */
Xchar sym; /* symbol displayed on path */
Xint FDECL((*fhitm), (struct monst *, struct obj *)),
X FDECL((*fhito), (struct obj *, struct obj *)); /* fns called when mon/obj hit */
Xstruct obj *obj; /* 2nd arg to fhitm/fhito */
X{
X register struct monst *mtmp;
X register struct obj *otmp;
X register uchar typ;
X boolean shopdoor = FALSE;
X#ifdef __GNULINT__
X xchar dlx=0, dly=0;
X#else
X xchar dlx, dly;
X#endif
X
X bhitpos.x = u.ux;
X bhitpos.y = u.uy;
X
X if(sym) {
X tmp_at(-1, sym); /* open call */
X#ifdef TEXTCOLOR
X tmp_at(-3, (int)objects[obj->otyp].oc_color);
X#else
X tmp_at(-3, (int)AT_OBJ);
X#endif
X }
X while(range-- > 0) {
X#ifdef STRONGHOLD
X int x,y;
X#endif
X bhitpos.x += ddx;
X bhitpos.y += ddy;
X#ifdef STRONGHOLD
X x = bhitpos.x; y = bhitpos.y;
X if (find_drawbridge(&x,&y) && !sym)
X switch (obj->otyp) {
X case WAN_OPENING:
X# ifdef SPELLS
X case SPE_KNOCK:
X# endif
X if (is_db_wall(bhitpos.x, bhitpos.y))
X (void) open_drawbridge(x,y);
X break;
X case WAN_LOCKING:
X# ifdef SPELLS
X case SPE_WIZARD_LOCK:
X# endif
X (void) close_drawbridge(x,y);
X break;
X case WAN_STRIKING:
X# ifdef SPELLS
X case SPE_FORCE_BOLT:
X# endif
X if (levl[bhitpos.x][bhitpos.y].typ !=
X DRAWBRIDGE_UP)
X destroy_drawbridge(x,y);
X }
X#endif /* STRONGHOLD /**/
X if(MON_AT(bhitpos.x, bhitpos.y)){
X mtmp = m_at(bhitpos.x,bhitpos.y);
X if(sym) {
X tmp_at(-1, -1); /* close call */
X return(mtmp);
X }
X (*fhitm)(mtmp, obj);
X range -= 3;
X }
X /* modified by GAN to hit all objects */
X if(fhito){
X int hitanything = 0;
X register struct obj *next_obj = (struct obj *)0;
X
X if((fhito == bhito) && levl[bhitpos.x][bhitpos.y].gmask)
X hitanything += bhitgold(g_at(bhitpos.x,bhitpos.y),obj);
X /* pre-reverse the polymorph pile, -dave- 3/90 */
X if (obj->otyp == WAN_POLYMORPH
X#ifdef SPELLS
X || obj->otyp == SPE_POLYMORPH
X#endif
X ) {
X otmp = level.objects[bhitpos.x][bhitpos.y];
X level.objects[bhitpos.x][bhitpos.y] = next_obj;
X while(otmp) {
X next_obj = otmp->nexthere;
X otmp->nexthere = level.objects[bhitpos.x][bhitpos.y];
X level.objects[bhitpos.x][bhitpos.y] = otmp;
X otmp = next_obj;
X }
X }
X for(otmp = level.objects[bhitpos.x][bhitpos.y];
X otmp; otmp = next_obj) {
X /* Fix for polymorph bug, Tim Wright */
X next_obj = otmp->nexthere;
X hitanything += (*fhito)(otmp, obj);
X }
X if(hitanything) range--;
X }
X typ = levl[bhitpos.x][bhitpos.y].typ;
X if((IS_DOOR(typ) || typ == SDOOR) && !sym) {
X switch (obj->otyp) {
X case WAN_OPENING:
X case WAN_LOCKING:
X case WAN_STRIKING:
X#ifdef SPELLS
X case SPE_KNOCK:
X case SPE_WIZARD_LOCK:
X case SPE_FORCE_BOLT:
X#endif
X if (doorlock(obj, bhitpos.x, bhitpos.y)) {
X makeknown(obj->otyp);
X if (levl[bhitpos.x][bhitpos.y].doormask == D_BROKEN
X && in_shop(bhitpos.x, bhitpos.y)) {
X shopdoor = TRUE;
X dlx = bhitpos.x; dly = bhitpos.y;
X }
X }
X break;
X }
X }
X if(!ZAP_POS(typ) || closed_door(bhitpos.x, bhitpos.y)) {
X bhitpos.x -= ddx;
X bhitpos.y -= ddy;
X break;
X }
X if(sym) tmp_at(bhitpos.x, bhitpos.y);
X#ifdef SINKS
X if(sym && IS_SINK(typ))
X break; /* physical objects fall onto sink */
X#endif
X }
X
X /* leave last symbol unless in a pool */
X if(sym)
X tmp_at(-1, is_pool(bhitpos.x,bhitpos.y) ? -1 : 0);
X
X if(shopdoor)
X pay_for_door(dlx, dly, "destroy");
X
X return (struct monst *)0;
X}
X
Xstruct monst *
Xboomhit(dx, dy)
Xint dx, dy;
X{
X register int i, ct;
X char sym = ')';
X
X bhitpos.x = u.ux;
X bhitpos.y = u.uy;
X
X for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
X tmp_at(-1, sym); /* open call */
X#ifndef TEXTCOLOR
X tmp_at(-3, (int)AT_OBJ);
X#else
X tmp_at(-3, HI_METAL);
X#endif
X for(ct=0; ct<10; ct++) {
X if(i == 8) i = 0;
X sym = ')' + '(' - sym;
X tmp_at(-2, sym); /* change let call */
X dx = xdir[i];
X dy = ydir[i];
X bhitpos.x += dx;
X bhitpos.y += dy;
X if(MON_AT(bhitpos.x, bhitpos.y)){
X tmp_at(-1,-1);
X return(m_at(bhitpos.x,bhitpos.y));
X }
X if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
X bhitpos.x -= dx;
X bhitpos.y -= dy;
X break;
X }
X if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
X if(Fumbling || rn2(20) >= ACURR(A_DEX)){
X /* we hit ourselves */
X (void) thitu(10, rnd(10), (struct obj *)0,
X "boomerang");
X break;
X } else { /* we catch it */
X tmp_at(-1,-1);
X pline("Skillfully, you catch the boomerang.");
X return(&youmonst);
X }
X }
X tmp_at(bhitpos.x, bhitpos.y);
X if(ct % 5 != 0) i++;
X#ifdef SINKS
X if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ))
X break; /* boomerang falls on sink */
X#endif
X }
X tmp_at(-1, -1); /* do not leave last symbol */
X return (struct monst *)0;
X}
X
Xstatic uchar
Xdirlet(dx, dy)
Xregister int dx, dy;
X{
X return
X (dx == dy) ? LSLANT_SYM :
X (dx && dy) ? RSLANT_SYM :
X dx ? HBEAM_SYM : VBEAM_SYM;
X}
X
Xstatic int
Xzhit(mon, type, nd) /* returns damage to mon */
Xregister struct monst *mon;
Xregister int type, nd;
X{
X register int tmp = 0;
X register int abstype = abs(type) % 10;
X
X switch(abstype) {
X case 0: /* magic missile */
X tmp = d(nd,6);
X break;
X case 1: /* fire */
X if(resists_fire(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = d(nd,6);
X if(resists_cold(mon->data)) tmp += 7;
X break;
X case 2: /* sleep */
X tmp = 0;
X if(resists_sleep(mon->data) ||
X resist(mon, (type == 2) ? WAND_SYM : '\0', 0, NOTELL))
X shieldeff(mon->mx, mon->my);
X else if (mon->mcanmove) {
X int tmp2 = d(nd,25);
X mon->mcanmove = 0;
X if (mon->mfrozen + tmp2 > 127) mon->mfrozen = 127;
X else mon->mfrozen += tmp2;
X }
X break;
X case 3: /* cold */
X if(resists_cold(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = d(nd,6);
X if(resists_fire(mon->data)) tmp += d(nd, 3);
X break;
X case 4: /* death/disintegration */
X if(abs(type) != 24) { /* death */
X if(is_undead(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X type = -1; /* so they don't get saving throws */
X } else if (resists_disint(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = mon->mhp+1;
X break;
X case 5: /* lightning */
X if(resists_elec(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = d(nd,6);
X {
X register unsigned rnd_tmp = rnd(50);
X mon->mcansee = 0;
X if((mon->mblinded + rnd_tmp) > 127)
X mon->mblinded = 127;
X else mon->mblinded += rnd_tmp;
X }
X break;
X case 6: /* poison */
X if(resists_poison(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = d(nd,6);
X break;
X case 7: /* acid */
X if(resists_acid(mon->data)) {
X shieldeff(mon->mx, mon->my);
X break;
X }
X tmp = d(nd,6);
X break;
X }
X if (type >= 0)
X if (resist(mon, (type < 10) ? WAND_SYM : '\0', 0, NOTELL)) tmp /= 2;
X mon->mhp -= tmp;
X return(tmp);
X}
X
X/*
X * burn scrolls and spell books on floor at position x,y
X * return the number of scrolls and spell books burned
X */
Xstatic int
Xburn_floor_paper(x, y)
Xint x, y;
X{
X register struct obj *obj, *obj2;
X register int scrquan, i, cnt = 0;
X
X for(obj = level.objects[x][y]; obj; obj = obj2) {
X obj2 = obj->nexthere;
X /* Bug fix - KAA */
X#ifdef SPELLS
X if((obj->olet == SCROLL_SYM || obj->olet == SPBOOK_SYM)) {
X#else
X if(obj->olet == SCROLL_SYM) {
X#endif
X if (obj->otyp == SCR_FIRE
X#ifdef SPELLS
X || obj->otyp == SPE_FIREBALL
X#endif
X )
X continue;
X scrquan = obj->quan;
X for(i = 1; i <= scrquan ; i++)
X if(!rn2(3)) {
X cnt++;
X /* not useupf(), which charges */
X if (obj->quan > 1) obj->quan--;
X else delobj(obj);
X }
X }
X }
X return(cnt);
X}
X
X/* type == 0 to 9 : you shooting a wand */
X/* type == 10 to 19 : you casting a spell */
X/* type == 20 to 29 : you breathing as a monster */
X/* type == -10 to -19 : monster casting spell */
X/* type == -20 to -29 : monster breathing at you */
X/* called with dx = dy = 0 with vertical bolts */
Xvoid
Xbuzz(type,nd,sx,sy,dx,dy)
Xregister int type, nd;
Xregister xchar sx,sy;
Xregister int dx,dy;
X{
X int abstype = abs(type) % 10;
X register const char *fltxt = fl[abs(type)];
X struct rm *lev;
X register xchar lsx, lsy;
X#ifdef __GNULINT__
X xchar range, olx=0, oly=0;
X#else
X xchar range, olx, oly;
X#endif
X struct monst *mon;
X register boolean bodyhit = FALSE;
X register boolean shopdoor = FALSE;
X
X if(u.uswallow) {
X register int tmp;
X
X if(type < 0) return;
X tmp = zhit(u.ustuck, type, nd);
X if(!u.ustuck) u.uswallow = 0;
X else pline("The %s rips into %s%s",
X fltxt, mon_nam(u.ustuck), exclam(tmp));
X if (u.ustuck->mhp < 1)
X killed(u.ustuck);
X return;
X }
X if(type < 0) pru();
X range = rn1(7,7);
X Tmp_at2(-1, (int) dirlet(dx,dy)); /* open call */
X#ifdef TEXTCOLOR
X Tmp_at2(-3, zapcolor[abstype]);
X#endif
X while(range-- > 0) {
X lsx = sx; sx += dx;
X lsy = sy; sy += dy;
X if((lev = &levl[sx][sy])->typ) {
X if((cansee(lsx,lsy) && cansee(sx,sy)) ||
X (!cansee(lsx,lsy) && cansee(sx,sy) &&
X (IS_DOOR(lev->typ) || IS_ROOM(lev->typ))))
X Tmp_at2(sx,sy);
X } else {
X int bounce = 0;
X if(cansee(sx-dx,sy-dy))
X pline("The %s bounces!", fltxt);
X if(ZAP_POS(levl[sx][sy-dy].typ))
X bounce = 1;
X if(ZAP_POS(levl[sx-dx][sy].typ)) {
X if(!bounce || rn2(2)) bounce = 2;
X }
X switch(bounce){
X case 0:
X dx = -dx;
X dy = -dy;
X continue;
X case 1:
X dy = -dy;
X sx -= dx;
X break;
X case 2:
X dx = -dx;
X sy -= dy;
X break;
X }
X Tmp_at2(-2,(int) dirlet(dx,dy));
X continue;
X }
X if(abstype == 1 /* fire */ &&
X (is_pool(sx,sy) || (lev->typ == ROOM && lev->icedpool))) {
X if(lev->typ == ROOM) {
X#ifdef STUPID
X if (lev->icedpool == ICED_POOL)
X lev->typ = POOL;
X else
X lev->typ = MOAT;
X#else
X lev->typ = (lev->icedpool == ICED_POOL ? POOL : MOAT);
X#endif
X lev->icedpool = 0;
X pline("The ice crackles and melts.");
X mnewsym(sx,sy);
X } else {
X#ifdef STRONGHOLD
X if(lev->typ != POOL) { /* MOAT or DRAWBRIDGE_UP */
X if(cansee(sx,sy))
X pline("Some water evaporates.");
X else if(flags.soundok)
X You("hear a hissing sound.");
X } else {
X#endif
X register struct trap *ttmp;
X
X range -= 3;
X lev->typ = ROOM;
X mnewsym(sx,sy);
X if(cansee(sx,sy)) pline("The water evaporates.");
X else if(flags.soundok)
X You("hear a hissing sound.");
X ttmp = maketrap(sx, sy, PIT);
X ttmp->tseen = 1;
X#ifdef STRONGHOLD
X }
X#endif
X }
X }
X if(abstype == 3 /* cold */ && is_pool(sx,sy)) {
X boolean moat = (lev->typ != POOL);
X
X range -= 3;
X#ifdef STRONGHOLD
X if(lev->typ == DRAWBRIDGE_UP) {
X lev->drawbridgemask |= DB_ICE;
X } else {
X#endif
X lev->typ = ROOM;
X lev->icedpool = (moat ? ICED_MOAT : ICED_POOL);
X#ifdef STRONGHOLD
X }
X#endif
X mnewsym(sx,sy);
X if(cansee(sx,sy)) {
X if(moat)
X pline("The moat is bridged with ice!");
X else pline("The water freezes.");
X } else if(flags.soundok)
X You("hear a crackling sound.");
X }
X if(closed_door(sx, sy)) {
X range = 0;
X switch(abstype) {
X case 1:
X lev->doormask = D_NODOOR;
X mnewsym(sx,sy);
X if(cansee(sx,sy)) {
X pline("The door is consumed in flames!");
X prl(sx,sy);
X }
X else You("smell smoke.");
X if(type >= 0 && in_shop(sx, sy)) {
X shopdoor = TRUE;
X olx = sx;
X oly = sy;
X }
X break;
X case 3:
X lev->doormask = D_NODOOR;
X mnewsym(sx,sy);
X if(cansee(sx,sy)) {
X pline("The door freezes and shatters!");
X prl(sx,sy);
X }
X else You("feel cold.");
X if(type >= 0 && in_shop(sx, sy)) {
X shopdoor = TRUE;
X olx = sx;
X oly = sy;
X }
X break;
X case 4:
X lev->doormask = D_NODOOR;
X mnewsym(sx,sy);
X if(cansee(sx,sy)) {
X pline("The door disintegrates!");
X prl(sx,sy);
X }
X else if(flags.soundok)
X You("hear a crashing sound.");
X if(type >= 0 && in_shop(sx, sy)) {
X shopdoor = TRUE;
X olx = sx;
X oly = sy;
X }
X break;
X case 5:
X lev->doormask = D_BROKEN;
X mnewsym(sx,sy);
X if(cansee(sx,sy)) {
X pline("The door splinters!");
X prl(sx,sy);
X }
X else if(flags.soundok)
X You("hear a crackling sound.");
X if(type >= 0 && in_shop(sx, sy)) {
X shopdoor = TRUE;
X olx = sx;
X oly = sy;
X }
X break;
X default:
X if(cansee(sx,sy)) {
X if (type >= 0 && type <= 9)
X pline("The door absorbs your bolt!");
X else if (type >= 10 && type <= 19)
X pline("The door absorbs your spell!");
X#ifdef POLYSELF
X else if (type >= 20 && type <= 29)
X pline("The door absorbs your blast!");
X#endif
X else if (type >= -19 && type <= -10)
X pline("The door absorbs the spell!");
X else
X pline("The door absorbs the blast!");
X } else You("feel vibrations.");
X break;
X }
X }
X if(OBJ_AT(sx, sy) && abstype == 1)
X if(burn_floor_paper(sx,sy) && cansee(sx,sy)) {
X mnewsym(sx,sy);
X if(!Blind)
X You("see a puff of smoke.");
X }
X if(MON_AT(sx, sy)){
X mon = m_at(sx,sy);
X /* Cannot use wakeup() which also angers the monster */
X mon->msleep = 0;
X if(mon->mimic) seemimic(mon);
X if(type >= 0) {
X setmangry(mon);
X#if defined(ALTARS) && defined(THEOLOGY)
X if(mon->ispriest && in_temple(mon->mx, mon->my))
X priesthit = TRUE;
X#endif
X }
X if(rnd(20) < 18 + mon->data->ac) {
X register int tmp = zhit(mon, type, nd);
X if(mon->mhp < 1) {
X if(type < 0) {
X if(cansee(mon->mx,mon->my))
X pline("%s is killed by the %s!",
X Monnam(mon), fltxt);
X mondied(mon);
X } else
X killed(mon);
X } else
X hit(fltxt, mon, exclam(tmp));
X range -= 2;
X } else
X miss(fltxt,mon);
X } else if(sx == u.ux && sy == u.uy) {
X nomul(0);
X if(rnd(20) < 18+u.uac) {
X register int dam = 0;
X range -= 2;
X pline("The %s hits you!",fltxt);
X if (Reflecting) {
X if (!Blind) {
X if(Reflecting & WORN_AMUL)
X makeknown(AMULET_OF_REFLECTION);
X else
X makeknown(SHIELD_OF_REFLECTION);
X pline("But it reflects from your %s!",
X (Reflecting & W_AMUL) ? "amulet" : "shield");
X } else
X pline("For some reason you are not affected!");
X if (dx) dx = -dx;
X if (dy) dy = -dy;
X shieldeff(sx, sy);
X }
X else switch(abstype) {
X case 0: /* magic missile */
X if(Antimagic) {
X shieldeff(sx, sy);
X pline("The missiles bounce off!");
X } else dam = d(nd,6);
X break;
X case 1: /* fire */
X if(Fire_resistance) {
X shieldeff(sx, sy);
X You("don't feel hot!");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_FIRE, d(nd, 6));
X#endif /* GOLEMS */
X#endif
X } else dam = d(nd, 6);
X while (1) {
X switch(rn2(5)) {
X case 0:
X if (!rust_dmg(uarmh, "leather helmet", 0, FALSE)) continue;
X break;
X case 1:
X bodyhit = TRUE;
X if (uarmc) break;
X if (uarm) (void)(rust_dmg(uarm, xname(uarm), 0, FALSE));
X break;
X case 2:
X if (!rust_dmg(uarms, "wooden shield", 0, FALSE)) continue;
X break;
X case 3:
X if (!rust_dmg(uarmg, "gloves", 0, FALSE)) continue;
X break;
X case 4:
X if (!rust_dmg(uarmf, "boots", 0, FALSE)) continue;
X break;
X }
X break; /* Out of while loop */
X }
X if(!rn2(3) && bodyhit)
X destroy_item(POTION_SYM, AD_FIRE);
X if(!rn2(3) && bodyhit)
X destroy_item(SCROLL_SYM, AD_FIRE);
X#ifdef SPELLS
X if(!rn2(5) && bodyhit)
X destroy_item(SPBOOK_SYM, AD_FIRE);
X#endif
X break;
X case 2: /* sleep */
X if(Sleep_resistance) {
X shieldeff(u.ux, u.uy);
X You("don't feel sleepy.");
X } else nomul(-d(nd,25)); /* sleep ray */
X break;
X case 3: /* cold */
X if(Cold_resistance) {
X shieldeff(sx, sy);
X You("don't feel cold.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_COLD, d(nd, 6));
X#endif /* GOLEMS */
X#endif
X } else
X dam = d(nd, 6);
X if(!rn2(3))
X destroy_item(POTION_SYM, AD_COLD);
X break;
X case 4: /* death */
X if(type == -24
X#ifdef POLYSELF
X || type == 24
X#endif
X ) { /* disintegration */
X if (Disint_resistance) {
X You("are not disintegrated.");
X break;
X } else if(uarms) {
X (void) destroy_arm(uarms);
X break;
X } else if (uarm) {
X (void) destroy_arm(uarm);
X break;
X }
X }
X#ifdef POLYSELF
X else if(is_undead(uasmon)) {
X shieldeff(sx, sy);
X You("seem unaffected.");
X break;
X }
X#endif
X u.uhp = -1;
X break;
X case 5: /* lightning */
X if (Shock_resistance) {
X shieldeff(sx, sy);
X You("aren't affected.");
X#ifdef POLYSELF
X#ifdef GOLEMS
X ugolemeffects(AD_ELEC, d(nd, 6));
X#endif /* GOLEMS */
X#endif
X } else
X dam = d(nd, 6);
X if(!rn2(3))
X destroy_item(WAND_SYM, AD_ELEC);
X if(!rn2(3))
X destroy_item(RING_SYM, AD_ELEC);
X break;
X case 6: /* poison */
X poisoned("blast", A_DEX, "poisoned blast", 15);
X break;
X case 7: /* acid */
X pline("The acid burns!");
X dam = d(nd,6);
X if(!rn2(6)) corrode_weapon();
X if(!rn2(6)) corrode_armor();
X break;
X }
X losehp(dam,fltxt, KILLED_BY_AN);
X } else pline("The %s whizzes by you!",fltxt);
X if (abstype == 5 && !Blind) { /* LIGHTNING */
X You("are blinded by the flash!");
X make_blinded((long)d(nd,50),FALSE);
X seeoff(0);
X }
X stop_occupation();
X }
X if(!ZAP_POS(lev->typ)) {
X int bounce = 0;
X uchar rmn;
X if(cansee(sx,sy)) pline("The %s bounces!", fltxt);
X range--;
X if(!dx || !dy || !rn2(20)){
X dx = -dx;
X dy = -dy;
X } else {
X if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
X (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
X bounce = 1;
X if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
X (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
X if(!bounce || rn2(2))
X bounce = 2;
X
X switch(bounce){
X case 0:
X dy = -dy;
X dx = -dx;
X break;
X case 1:
X dy = -dy;
X break;
X case 2:
X dx = -dx;
X break;
X }
X Tmp_at2(-2, (int) dirlet(dx,dy));
X }
X }
X }
X Tmp_at2(-1,-1);
X if(shopdoor) pay_for_door(olx, oly, abstype == 1 ? "burn away" :
X abstype == 3 ? "shatter" :
X abstype == 4 ? "disintegrate" :
X "destroy");
X}
X
Xvoid
Xrlocgold(gold)
Xregister struct gold *gold;
X{
X register int tx, ty, otx, oty;
X long val = gold->amount;
X
X otx = gold->gx;
X oty = gold->gy;
X do {
X tx = rn1(COLNO-3,2);
X ty = rn2(ROWNO);
X } while(!goodpos(tx,ty,(struct permonst *)0));
X freegold(g_at(otx,oty));
X mkgold(val, tx, ty);
X if(cansee(otx,oty))
X newsym(otx,oty);
X if(cansee(tx,ty))
X newsym(tx,ty);
X}
X
Xvoid
Xrloco(obj)
Xregister struct obj *obj;
X{
X register int tx, ty, otx, oty;
X
X otx = obj->ox;
X oty = obj->oy;
X do {
X tx = rn1(COLNO-3,2);
X ty = rn2(ROWNO);
X } while(!goodpos(tx,ty,(struct permonst *)0));
X move_object(obj, tx, ty);
X mnewsym(otx, oty);
X if(cansee(otx,oty) && !vism_at(otx,oty) && !Blind &&
X (Invisible || u.ux != otx || u.uy != oty))
X newsym(otx,oty);
X mnewsym(tx, ty);
X if(cansee(tx,ty) && !vism_at(tx,ty) && !Blind &&
X (Invisible || u.ux != tx || u.uy != ty))
X newsym(tx,ty);
X}
X
Xvoid
Xfracture_rock(obj) /* fractured by pick-axe or wand of striking */
Xregister struct obj *obj; /* no texts here! */
X{
X /* unpobj(obj); */
X obj->otyp = ROCK;
X obj->quan = 7 + rn2(60);
X obj->owt = weight(obj);
X obj->olet = GEM_SYM;
X obj->known = FALSE;
X obj->onamelth = 0; /* no names */
X if(cansee(obj->ox,obj->oy))
X prl(obj->ox,obj->oy);
X}
X
Xboolean
Xbreak_statue(obj)
Xregister struct obj *obj;
X{
X struct trap *trap;
X
X if(trap = t_at(obj->ox,obj->oy))
X if(obj->corpsenm == trap->pm)
X if(makemon(&mons[trap->pm], obj->ox, obj->oy)) {
X pline("Instead of shattering, the statue suddenly comes alive!");
X delobj(obj);
X deltrap(trap);
X return FALSE;
X }
X if (obj->spe) {
X struct obj *magazine;
X#ifdef SPELLS
X magazine = mkobj_at(SPBOOK_SYM, obj->ox, obj->oy, TRUE);
X#else
X magazine = mkobj_at(SCROLL_SYM, obj->ox, obj->oy, TRUE);
X#endif
X magazine->blessed = obj->blessed;
X magazine->cursed = obj->cursed;
X }
X fracture_rock(obj);
X return TRUE;
X}
X
Xconst char *destroy_strings[] = {
X "freezes and shatters", "freeze and shatter", "shattered potion",
X "boils and explodes", "boil and explode", "boiling potion",
X "catches fire and burns", "catch fire and burn", "burning scroll",
X "catches fire and burns", "catch fire and burn", "burning book",
X "turns to dust and vanishes", "turn to dust and vanish", "",
X "breaks apart and explodes", "break apart and explode", "exploding wand"
X};
X
Xvoid
Xdestroy_item(osym, dmgtyp)
Xregister int osym, dmgtyp;
X{
X register struct obj *obj, *obj2;
X register int quan, i, cnt, dmg, xresist, skip;
X register int dindx;
X const char *mult;
X
X for(obj = invent; obj; obj = obj2) {
X
X obj2 = obj->nobj;
X if(obj->olet != osym) continue; /* test only objs of type osym */
X xresist = skip = 0;
X#ifdef __GNULINT__
X quan = dmg = dindx = 0;
X#endif
X switch(dmgtyp) {
X case AD_COLD:
X if(osym == POTION_SYM) {
X quan = obj->quan;
X dindx = 0;
X dmg = rnd(4);
X } else skip++;
X break;
X case AD_FIRE:
X xresist = (Fire_resistance && obj->olet != POTION_SYM);
X
X if (obj->otyp == SCR_FIRE
X#ifdef SPELLS
X || obj->otyp == SPE_FIREBALL
X#endif
X )
X skip++;
X quan = obj->quan;
X switch(osym) {
X case POTION_SYM:
X dindx = 1;
X dmg = rnd(6);
X break;
X case SCROLL_SYM:
X dindx = 2;
X dmg = 1;
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X dindx = 3;
X dmg = 1;
X break;
X#endif
X default:
X skip++;
X break;
X }
X break;
X case AD_ELEC:
X xresist = (Shock_resistance && obj->olet != RING_SYM);
X quan = obj->quan;
X switch(osym) {
X case RING_SYM:
X if(obj->otyp == RIN_SHOCK_RESISTANCE)
X { skip++; break; }
X dindx = 4;
X dmg = 0;
X break;
X case WAND_SYM:
X if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
X dindx = 5;
X dmg = rnd(10);
X break;
X default:
X skip++;
X break;
X }
X break;
X default:
X skip++;
X break;
X }
X if(!skip) {
X for(i = cnt = 0; i < quan; i++)
X if(!rn2(3)) cnt++;
X
X if(!cnt) continue;
X if(cnt == quan) mult = "Your";
X else mult = (cnt == 1) ? "One of your" : "Some of your";
X pline("%s %s %s!", mult, xname(obj),
X (cnt > 1) ? destroy_strings[dindx*3 + 1]
X : destroy_strings[dindx*3]);
X if(osym == POTION_SYM && dmgtyp != AD_COLD)
X potionbreathe(obj);
X for(i = 0; i < cnt; i++) {
X if (obj->owornmask) setnotworn(obj);
X useup(obj);
X }
X if(dmg) {
X if(xresist) You("aren't hurt!");
X else losehp(dmg,
X (cnt==1) ? destroy_strings[dindx*3 + 2] :
X (const char *)makeplural(destroy_strings[dindx*3 + 2]),
X (cnt==1) ? KILLED_BY_AN : KILLED_BY);
X }
X }
X }
X return;
X}
X
Xint
Xdestroy_mitem(mtmp, osym, dmgtyp)
Xregister struct monst *mtmp;
Xregister int osym, dmgtyp;
X{
X register struct obj *obj, *obj2;
X register int quan, i, cnt, skip, tmp = 0;
X register int dindx;
X
X for(obj = mtmp->minvent; obj; obj = obj2) {
X
X obj2 = obj->nobj;
X if(obj->olet != osym) continue; /* test only objs of type osym */
X skip = 0;
X#ifdef __GNULINT__
X quan = dindx = 0;
X#endif
X switch(dmgtyp) {
X case AD_COLD:
X if(osym == POTION_SYM) {
X quan = obj->quan;
X dindx = 0;
X tmp++;
X } else skip++;
X break;
X case AD_FIRE:
X if (obj->otyp == SCR_FIRE
X#ifdef SPELLS
X || obj->otyp == SPE_FIREBALL
X#endif
X )
X skip++;
X quan = obj->quan;
X switch(osym) {
X case POTION_SYM:
X dindx = 1;
X tmp++;
X break;
X case SCROLL_SYM:
X dindx = 2;
X tmp++;
X break;
X#ifdef SPELLS
X case SPBOOK_SYM:
X dindx = 3;
X tmp++;
X break;
X#endif
X default:
X skip++;
X break;
X }
X break;
X case AD_ELEC:
X quan = obj->quan;
X switch(osym) {
X case RING_SYM:
X if(obj->otyp == RIN_SHOCK_RESISTANCE)
X { skip++; break; }
X dindx = 4;
X break;
X case WAND_SYM:
X if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
X dindx = 5;
X tmp++;
X break;
X default:
X skip++;
X break;
X }
X break;
X default:
X skip++;
X break;
X }
X if(!skip) {
X for(i = cnt = 0; i < quan; i++)
X if(!rn2(3)) cnt++;
X
X if(!cnt) continue;
X pline("%s's %s %s!", Monnam(mtmp), xname(obj),
X (cnt > 1) ? destroy_strings[dindx*3 + 1]
X : destroy_strings[dindx*3]);
X for(i = 0; i < cnt; i++) m_useup(mtmp, obj);
X }
X }
X return(tmp);
X}
X
X/*ARGSUSED*/
Xint
Xresist(mtmp, olet, damage, tell)
Xregister struct monst *mtmp;
Xregister char olet;
Xregister int damage, tell;
X{
X register int resisted = 0;
X#ifdef HARD
X register int lev;
X
X switch(olet) {
X
X case WAND_SYM:
X lev = 8;
X break;
X
X case SCROLL_SYM:
X lev = 6;
X break;
X
X case POTION_SYM:
X lev = 5;
X break;
X
X default: lev = u.ulevel;
X break;
X }
X
X resisted = (rn2(100) - mtmp->m_lev + lev) < mtmp->data->mr;
X if(resisted) {
X
X if(tell) {
X shieldeff(mtmp->mx, mtmp->my);
X pline("%s resists!", canseemon(mtmp) ? Monnam(mtmp) : "It");
X }
X mtmp->mhp -= damage/2;
X } else
X#endif
X mtmp->mhp -= damage;
X
X if(mtmp->mhp < 1) killed(mtmp);
X return(resisted);
X}
X
Xvoid
Xmakewish()
X{
X char buf[BUFSZ];
X register struct obj *otmp;
X unsigned wishquan, mergquan;
X int tries = 0;
X
Xretry:
X You("may wish for an object. What do you want? ");
X getlin(buf);
X if(buf[0] == '\033') buf[0] = 0;
X/* Note: if they wished for and got a non-object successfully, such as gold,
X * otmp = &zeroobj
X */
X otmp = readobjnam(buf);
X if (!otmp) {
X pline("Nothing fitting that description exists in the game.");
X if (++tries < 5) goto retry;
X pline(thats_enough_tries);
X if (!(otmp = readobjnam((char *)0)))
X return; /* for safety; should never happen */
X }
X if (otmp != &zeroobj) {
X if (!Blind) otmp->dknown = 1; /* needed for merge to work */
X wishquan = otmp->quan;
X otmp = addinv(otmp);
X if(inv_cnt() > 52) {
X pline("Oops! The %s to the floor!", aobjnam(otmp, "drop"));
X dropx(otmp);
X } else {
X mergquan = otmp->quan;
X otmp->quan = wishquan; /* to fool prinv() */
X prinv(otmp);
X otmp->quan = mergquan;
X }
X#ifdef THEOLOGY
X u.ublesscnt += rn1(100,50); /* the gods take notice */
X#endif
X }
X}
END_OF_FILE
if test 50988 -ne `wc -c <'src/zap.c'`; then
echo shar: \"'src/zap.c'\" unpacked with wrong size!
fi
# end of 'src/zap.c'
fi
echo shar: End of archive 3 \(of 56\).
cp /dev/null ark3isdone
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