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