billr@saab.CNA.TEK.COM (Bill Randle) (07/25/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 7, Issue 57 Archive-name: NetHack3/Part02 #! /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 2 (of 38)." # Contents: src/o_init.c src/zap.c # Wrapped by billr@saab on Sun Jul 23 21:32:46 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'src/o_init.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/o_init.c'\" else echo shar: Extracting \"'src/o_init.c'\" \(7223 characters\) sed "s/^X//" >'src/o_init.c' <<'END_OF_FILE' X/* SCCS Id: @(#)o_init.c 3.0 88/07/06 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" /* for typedefs */ X X/* note that NROFOBJECTS is the number of legal objects, which does not count X * the strange object and null object that take up positions 0 and NROFOBJECTS+1 X * in the objects array X */ X#define TOTAL_OBJS (NROFOBJECTS+2) X Xconst char obj_symbols[] = { X ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM, X BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM, X POTION_SYM, SCROLL_SYM, WAND_SYM, X#ifdef SPELLS X SPBOOK_SYM, X#endif X RING_SYM, GEM_SYM, 0 }; X Xint bases[sizeof(obj_symbols)] = DUMMY; Xstatic int disco[TOTAL_OBJS] = DUMMY; X Xint Xletindex(let) register char let; { Xregister int i = 0; Xregister char ch; X while((ch = obj_symbols[i++]) != 0) X if(ch == let) return(i); X return(0); X} X Xstatic void Xsetgemprobs() X{ X register int j,first; X#ifdef STRONGHOLD X int level = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel; X#endif X X first = bases[letindex(GEM_SYM)]; X X#ifdef STRONGHOLD X for(j = 0; j < 9-level/3; j++) X#else X for(j = 0; j < 9-dlevel/3; j++) X#endif X objects[first+j].oc_prob = 0; X first += j; X if(first >= LAST_GEM || first > NROFOBJECTS || X objects[first].oc_olet != GEM_SYM || X objects[first].oc_name == NULL) X Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n", X first, j, LAST_GEM); X for(j = first; j < LAST_GEM; j++) X objects[j].oc_prob = (180+j-first)/(LAST_GEM-first); X} X X/* shuffle descriptions on objects o_low to o_high */ Xstatic void Xshuffle(o_low, o_high, domaterial) X X register int o_low, o_high; X register boolean domaterial; X{ X register int i, j; X char *desc; X int tmp; X X for(j=o_low; j <= o_high; j++) { X i = o_low + rn2(j+1-o_low); X desc = objects[j].oc_descr; X objects[j].oc_descr = objects[i].oc_descr; X objects[i].oc_descr = desc; X /* shuffle discovery list */ X tmp = disco[j]; X disco[j] = disco[i]; X disco[i] = tmp; X /* shuffle material */ X if(domaterial) { X tmp = objects[j].oc_material; X objects[j].oc_material = objects[i].oc_material; X objects[i].oc_material = tmp; X } X } X} X Xvoid Xinit_objects(){ Xregister int i, j, first, last, sum, end; Xregister char let; X X /* bug fix to prevent "initialization error" abort on Intel Xenix. X * reported by mikew@semike X */ X for(i = 0; i != sizeof(obj_symbols); i++) X bases[i] = 0; X for(i = 0; i != TOTAL_OBJS; i++) X disco[i] = i; X X /* init base; if probs given check that they add up to 1000, X otherwise compute probs; shuffle descriptions */ X end = TOTAL_OBJS; X first = 0; X while( first < end ) { X let = objects[first].oc_olet; X last = first+1; X while(last < end && objects[last].oc_olet == let X && objects[last].oc_name != NULL) last++; X i = letindex(let); X if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0) X error("initialization error for %c", let); X bases[i] = first; X X if(let == GEM_SYM) setgemprobs(); X check: X sum = 0; X for(j = first; j < last; j++) sum += objects[j].oc_prob; X if(sum == 0) { X for(j = first; j < last; j++) X objects[j].oc_prob = (1000+j-first)/(last-first); X goto check; X } X if(sum != 1000) X error("init-prob error for %c (%d%%)", let, sum); X X if(objects[first].oc_descr != NULL && X let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) { X X /* shuffle, also some additional descriptions */ X while(last < end && objects[last].oc_olet == let) X last++; X j = last; X if (let == GEM_SYM) { X while(--j > first) X /* NOTE: longest color name must be default */ X if(!strcmp(objects[j].oc_name,"turquoise")) { X if(rn2(2)) /* change from green? */ X Strcpy(objects[j].oc_descr, blue); X } else if (!strcmp(objects[j].oc_name,"aquamarine")) { X if(rn2(2)) /* change from green? */ X Strcpy(objects[j].oc_descr, blue); X } else if (!strcmp(objects[j].oc_name,"fluorite")) { X switch (rn2(4)) { /* change from violet? */ X case 0: break; X case 1: X Strcpy(objects[j].oc_descr, blue); X break; X case 2: X Strcpy(objects[j].oc_descr, white); X break; X case 3: X Strcpy(objects[j].oc_descr, green); X break; X } X } X } else { X if (let == AMULET_SYM || let == POTION_SYM) X j--; /* THE amulet doesn't have description */ X /* and water is always "clear" - 3. */ X shuffle(first, --j, TRUE); X } X } X first = last; X } X X /* shuffle the helmets */ X shuffle(HELMET, HELM_OF_TELEPATHY, FALSE); X X /* shuffle the gloves */ X shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE); X X /* shuffle the cloaks */ X shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE); X X /* shuffle the boots */ X shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE); X} X Xvoid Xoinit() /* level dependent initialization */ X{ X setgemprobs(); X} X Xvoid Xsavenames(fd) Xregister int fd; X{ X register int i; X unsigned int len; X struct objclass *now = &objects[0]; X bwrite(fd, (genericptr_t)&now, sizeof now); X bwrite(fd, (genericptr_t)bases, sizeof bases); X bwrite(fd, (genericptr_t)disco, sizeof disco); X bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS); X /* as long as we use only one version of Hack we X need not save oc_name and oc_descr, but we must save X oc_uname for all objects */ X for(i=0; i < TOTAL_OBJS; i++) { X if(objects[i].oc_uname) { X len = strlen(objects[i].oc_uname)+1; X bwrite(fd, (genericptr_t)&len, sizeof len); X bwrite(fd, (genericptr_t)objects[i].oc_uname, len); X } X } X} X Xvoid Xrestnames(fd) Xregister int fd; X{ X register int i; X unsigned int len; X struct objclass *then; X long differ; X mread(fd, (genericptr_t) &then, sizeof then); X mread(fd, (genericptr_t) bases, sizeof bases); X mread(fd, (genericptr_t) disco, sizeof disco); X mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS); X#ifndef MSDOS X differ = (genericptr_t)&objects[0] - (genericptr_t)then; X#else X differ = (long)&objects[0] - (long)then; X#endif X for(i=0; i < TOTAL_OBJS; i++) { X if (objects[i].oc_name) { X#ifndef MSDOS X objects[i].oc_name += differ; X#else X objects[i].oc_name = X (char *)((long)(objects[i].oc_name) + differ); X#endif X } X if (objects[i].oc_descr) { X#ifndef MSDOS X objects[i].oc_descr += differ; X#else X objects[i].oc_descr = X (char *)((long)(objects[i].oc_descr) + differ); X#endif X } X if (objects[i].oc_uname) { X mread(fd, (genericptr_t) &len, sizeof len); X objects[i].oc_uname = (char *) alloc(len); X mread(fd, (genericptr_t)objects[i].oc_uname, len); X } X } X} X Xstatic boolean Xinteresting_to_discover(i) Xregister int i; X{ X return objects[i].oc_uname != NULL || X (objects[i].oc_name_known && objects[i].oc_descr != NULL); X} X Xint Xdodiscovered() /* free after Robert Viduya */ X{ X register int i, dis; X int ct = 0; X char class = -1; X X cornline(0, "Discoveries"); X X for (i = 0; i <= NROFOBJECTS; i++) { X if (interesting_to_discover(dis = disco[i])) { X ct++; X if (objects[dis].oc_olet != class) { X class = objects[dis].oc_olet; X cornline(1, let_to_name(class)); X } X cornline(1, typename(dis)); X } X } X if (ct == 0) { X You("haven't discovered anything yet..."); X cornline(3, NULL); X } else X cornline(2, NULL); X X return 0; X} END_OF_FILE if test 7223 -ne `wc -c <'src/o_init.c'`; then echo shar: \"'src/o_init.c'\" unpacked with wrong size! fi # end of 'src/o_init.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'\" \(44087 characters\) sed "s/^X//" >'src/zap.c' <<'END_OF_FILE' X/* SCCS Id: @(#)zap.c 3.0 88/10/25 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 priesthit = FALSE; X#endif 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 sleeping 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/* Routines for IMMEDIATE wands and spells. */ X/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */ Xstatic int 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 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 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; X X if(obj->otyp == CORPSE) { X int montype,x,y,nl; X char buf[BUFSZ]; X X if (nl = obj->onamelth) Strcpy(buf, ONAME(obj)); X montype = obj->corpsenm; X if (ininv) { X x = u.ux; y = u.uy; X useup(obj); X } else { X x = obj->ox; y = obj->oy; X useupf(obj); 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#ifdef ARMY X if (is_mercenary(&mons[montype])) X montype = PM_UNARMORED_SOLDIER; X#endif X mons[montype].pxlth += nl; X mtmp = mkmon_at(mons[montype].mname, x, y); X mons[montype].pxlth -= nl; X if (mtmp) { X /* Monster retains its name */ X mtmp->mnamelth = nl; X if (nl) Strcpy(NAME(mtmp), buf); X /* No inventory for newly revived monsters */ X while(obj = (mtmp->minvent)) { X mtmp->minvent = obj->nobj; X free((genericptr_t)obj); X } X } X } X } X return mtmp; X} X Xstatic const char charged_objs[] = { WAND_SYM, WEAPON_SYM, ARMOR_SYM, 0 }; X Xstatic void Xcancel_item(obj) Xregister struct obj *obj; 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 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 if (obj->olet == SCROLL_SYM X#ifdef MAIL X && obj->otyp != SCR_MAIL X#endif X ) X obj->otyp = SCR_BLANK_PAPER; X if (obj->olet == POTION_SYM && obj->otyp > POT_BOOZE) X obj->otyp = (obj->otyp==POT_SICKNESS) ? POT_FRUIT_JUICE : POT_WATER; X /* sickness is "biologically contaminated" fruit juice; cancel it X * and it just becomes fruit juice... X */ X obj->blessed = obj->cursed = FALSE; X} X Xstatic int 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#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) obj->spe = 1; X#endif X /* preserve symbol and quantity */ X otmp2 = mkobj_at(obj->olet, obj->ox, obj->oy); X otmp2->quan = obj->quan; X 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 /* Wands of wishing max 3 stewr 870808 */ X if ((otmp2->otyp == WAN_WISHING) X && (obj->spe > 3)) otmp2->spe = 3; 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 /* Turn dragon corpses into dragon armors */ X if (obj->otyp == CORPSE && obj->corpsenm >= PM_GREY_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 } 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 X if(u.uluck + 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"); X useup(otmp); X} X Xstatic const char 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-inflicted injury"); 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 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 You("shudder for a moment."); 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 (!Invisible) 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 = "death ray"; 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 Printf("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 && levl[u.ux][u.uy].omask) { X register struct obj *otmp,*otmp2; X X /* changed by GAN to hit all objects there */ X for(otmp = fobj; otmp ; otmp = otmp2) { X otmp2 = otmp->nobj; X /* save pointer as bhito may destroy otmp */ X if(otmp->ox == u.ux && otmp->oy == u.uy) X (void) bhito(otmp, obj); X } X } X } else if((obj->otyp == WAN_OPENING) || X#ifdef SPELLS X (obj->otyp == SPE_KNOCK) || X (obj->otyp == SPE_WIZARD_LOCK) || X#endif X (obj->otyp == WAN_LOCKING)) { X (void)bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj); X#ifdef STRONGHOLD X } else if(obj->otyp == WAN_STRIKING X#ifdef SPELLS X || obj->otyp == SPE_FORCE_BOLT X#endif /* SPELLS /**/ X ) { X int x,y; X x = u.ux + u.dx; X y = u.uy + u.dy; X if (find_drawbridge(&x,&y)) X destroy_drawbridge(x,y); X X else (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj); X#endif /* STRONGHOLD /**/ 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(u.uluck + 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 if(u.uswallow) { X register struct monst *mtmp = u.ustuck; X X You("pierce %s's stomach wall!", X mon_nam(mtmp)); X mtmp->mhp = 1; /* almost dead */ X unstuck(mtmp); X mnexto(mtmp); 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"); 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 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 if(in_shop(zx,zy)) { X shopdoor = TRUE; X dlx = zx; X dly = zy; X } X digdepth -= 2; X } else { X room->typ = CORR; X digdepth--; X } X else X break; X else if(room->typ == DOOR && X (room->doormask & (D_LOCKED | D_CLOSED))) { X room->doormask = D_NODOOR; 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(shopdoor && !in_shop(u.ux, u.uy)) 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 Xchar * 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( (force < 0) ? "?" : (force <= 4) ? "." : "!" ); X} X Xvoid Xhit(str,mtmp,force) Xregister char *str; Xregister struct monst *mtmp; Xregister 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 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 (*fhitm)(), (*fhito)(); /* 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 int typ; X X bhitpos.x = u.ux; X bhitpos.y = u.uy; X X if(sym) { X tmp_at(-1, sym); /* open call */ X tmp_at(-3, (int)AT_OBJ); X } X while(range-- > 0) { X bhitpos.x += ddx; X bhitpos.y += ddy; X typ = levl[bhitpos.x][bhitpos.y].typ; X#ifdef STRONGHOLD X if(IS_DRAWBRIDGE(typ)) X switch (obj->otyp) { X case WAN_OPENING: X# ifdef SPELLS X case SPE_KNOCK: X# endif X (void) open_drawbridge(bhitpos.x,bhitpos.y); X break; X case WAN_LOCKING: X# ifdef SPELLS X case SPE_WIZARD_LOCK: X# endif X (void) close_drawbridge(bhitpos.x,bhitpos.y); X } X#endif /* STRONGHOLD /**/ X if(levl[bhitpos.x][bhitpos.y].mmask){ 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 && levl[bhitpos.x][bhitpos.y].omask){ X int hitanything = 0; X otmp = fobj; X /* Fix for polymorph bug, Tim Wright */ X while(otmp) { /* was a "for" loop. */ X register struct obj *next_obj; X X next_obj = otmp->nobj; X if(otmp->ox == bhitpos.x && otmp->oy == bhitpos.y) X hitanything += (*fhito)(otmp, obj); X otmp = next_obj; X } X if(hitanything) range--; X } X if(IS_DOOR(typ) || typ == SDOOR) { X switch (obj->otyp) { X case WAN_OPENING: X case WAN_LOCKING: X#ifdef SPELLS X case SPE_KNOCK: X case SPE_WIZARD_LOCK: X#endif X if (doorlock(obj,bhitpos.x,bhitpos.y)) X makeknown(obj->otyp); X break; X } X } X if(!ZAP_POS(typ) || (IS_DOOR(typ) && X (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED))) X ) { 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 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 tmp_at(-3, (int)AT_OBJ); 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(levl[bhitpos.x][bhitpos.y].mmask){ 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(rn2(20) >= ACURR(A_DEX)){ /* we hit ourselves */ X (void) thitu(10, rnd(10), "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 mon->mfroz = 1; 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 = 0; /* so they don't get saving throws */ 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 on floor at position x,y X * return the number of scrolls burned X */ Xstatic int Xburn_floor_scrolls(x, y) Xint x, y; X{ X register struct obj *obj, *obj2; X register int scrquan, i, cnt = 0; X X if(levl[x][y].omask) X for(obj = fobj; obj; obj = obj2) { X obj2 = obj->nobj; X /* Bug fix - KAA */ X if(obj->ox == x && obj->oy == y && obj->olet == SCROLL_SYM) { X scrquan = obj->quan; X for(i = 1; i <= scrquan ; i++) X if(!rn2(3)) { X cnt++; X if(in_shop(u.ux, u.uy)) X addtobill(obj, FALSE); X useupf(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 char *fltxt = fl[abs(type)]; X struct rm *lev; X xchar range, olx, oly; 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 MSDOSCOLOR X Tmp_at2(-3, (int)(abstype == 1 ? AT_RED : /* fire */ X abstype == 3 || abstype == 5 ? AT_WHITE : /* cold/elec */ X AT_ZAP); X#endif X while(range-- > 0) { X sx += dx; X sy += dy; X if((lev = &levl[sx][sy])->typ) 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(is_pool(sx,sy) && abstype == 1 /* fire */) { 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 if(is_pool(sx,sy) && abstype == 3 /* cold */) { X boolean moat = (lev->typ != POOL); X X range -= 3; X#ifdef STRONGHOLD X if(lev->typ == DRAWBRIDGE_UP) X lev->drawbridgemask |= DB_FLOOR; X else X#endif X lev->typ = ROOM; 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(IS_DOOR(lev->typ) && (lev->doormask & (D_LOCKED | D_CLOSED))) { X range = 0; X switch(abstype) { X case 1: X lev->doormask = D_NODOOR; X if(cansee(sx,sy)) X pline("The door is consumed in flames!"); 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 if(cansee(sx,sy)) X pline("The door freezes and shatters!"); 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 if(cansee(sx,sy)) X pline("The door disintegrates!"); 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 if(cansee(sx,sy)) X pline("The door splinters!"); 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(levl[sx][sy].omask && abstype == 1) X if(burn_floor_scrolls(sx,sy) && cansee(sx,sy)) { X mnewsym(sx,sy); X if(!Blind) X You("see a puff of smoke."); X } X if(levl[sx][sy].mmask){ 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 (void)(rust_dmg(uarm, "leather armor", 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) { /* disintegration */ X if(uarms) { X (void) destroy_arm(uarms); X } else if (uarm) { X if (Disint_resistance & WORN_ARMOR) X Your("armor absorbs the blast!"); X else (void) destroy_arm(uarm); X } X break; 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 break; X case 6: /* poison */ X poisoned("blast", A_DEX, "poisoned blast"); 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); 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, 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 && !in_shop(u.ux, u.uy)) X pay_for_door(olx, oly, abstype == 1 ? "burn away" : X abstype == 3 ? "shatter" : X abstype == 4 ? "disintegrate" : X "destroy"); 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)); X obj->ox = tx; X obj->oy = ty; X set_omask(otx,oty); X if(cansee(otx,oty)) X newsym(otx,oty); X levl[tx][ty].omask = 1; X if(cansee(tx,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->blessed = FALSE; X obj->quan = 7 + rn2(60); X obj->owt = weight(obj); X obj->olet = GEM_SYM; X obj->known = FALSE; 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); X#else X magazine = mkobj_at(SCROLL_SYM, obj->ox, obj->oy); 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 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 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 /* Let's say scrolls of fire are fire resistant */ X X if (obj->otyp == SCR_FIRE) 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++) useup(obj); X if(dmg) { X if(xresist) You("aren't hurt!"); X else losehp(dmg, destroy_strings[dindx*3 + 2]); 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 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 /* Let's say scrolls of fire are fire resistant */ X X if (obj->otyp == SCR_FIRE) 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 level; X X switch(olet) { X X case WAND_SYM: X level = 8; X break; X X case SCROLL_SYM: X level = 6; X break; X X case POTION_SYM: X level = 5; X break; X X default: level = u.ulevel; X break; X } X X resisted = (rn2(100) - mtmp->m_lev + level) < 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 int wishquan, mergquan; X register boolean dropit = (inv_cnt() >= 52); 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(dropit) { X pline("Oops! The %s drop%s to the floor!", xname(otmp), X otmp->quan > 1 ? "" : "s"); X dropy(otmp); X } else { X wishquan = otmp->quan; X otmp = addinv(otmp); X mergquan = otmp->quan; X otmp->quan = wishquan; /* to fool prinv() */ X prinv(otmp); X otmp->quan = mergquan; X } X#ifdef WIZARD X if (!wizard) X#endif X if(otmp->otyp == WAN_WISHING) otmp->recharged = 1; X X#ifdef THEOLOGY X u.ublesscnt += rn1(100,50); /* the gods take notice */ X#endif X } X} END_OF_FILE if test 44087 -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 2 \(of 38\). cp /dev/null ark2isdone 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 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 38 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