home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume7 / nethack3 / part02 < prev    next >
Internet Message Format  |  1989-07-31  |  56KB

  1. Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v07i057:  NetHack3 -  display oriented dungeons & dragons (Ver. 3.0), Part02/38
  5. Message-ID: <4331@tekred.CNA.TEK.COM>
  6. Date: 24 Jul 89 19:00:56 GMT
  7. Sender: nobody@tekred.CNA.TEK.COM
  8. Lines: 2269
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
  12. Posting-number: Volume 7, Issue 57
  13. Archive-name: NetHack3/Part02
  14.  
  15.  
  16.  
  17. #! /bin/sh
  18. # This is a shell archive.  Remove anything before this line, then unpack
  19. # it by saving it into a file and typing "sh file".  To overwrite existing
  20. # files, type "sh file -c".  You can also feed this as standard input via
  21. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  22. # will see the following message at the end:
  23. #        "End of archive 2 (of 38)."
  24. # Contents:  src/o_init.c src/zap.c
  25. # Wrapped by billr@saab on Sun Jul 23 21:32:46 1989
  26. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  27. if test -f 'src/o_init.c' -a "${1}" != "-c" ; then 
  28.   echo shar: Will not clobber existing file \"'src/o_init.c'\"
  29. else
  30. echo shar: Extracting \"'src/o_init.c'\" \(7223 characters\)
  31. sed "s/^X//" >'src/o_init.c' <<'END_OF_FILE'
  32. X/*    SCCS Id: @(#)o_init.c    3.0    88/07/06
  33. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  34. X/* NetHack may be freely redistributed.  See license for details. */
  35. X
  36. X#include    "hack.h"        /* for typedefs */
  37. X
  38. X/* note that NROFOBJECTS is the number of legal objects, which does not count
  39. X * the strange object and null object that take up positions 0 and NROFOBJECTS+1
  40. X * in the objects array
  41. X */
  42. X#define TOTAL_OBJS    (NROFOBJECTS+2)
  43. X
  44. Xconst char obj_symbols[] = {
  45. X    ILLOBJ_SYM, AMULET_SYM, FOOD_SYM, WEAPON_SYM, TOOL_SYM,
  46. X    BALL_SYM, CHAIN_SYM, ROCK_SYM, ARMOR_SYM,
  47. X    POTION_SYM, SCROLL_SYM, WAND_SYM,
  48. X#ifdef SPELLS
  49. X    SPBOOK_SYM,
  50. X#endif
  51. X    RING_SYM, GEM_SYM, 0 };
  52. X
  53. Xint bases[sizeof(obj_symbols)] = DUMMY;
  54. Xstatic int disco[TOTAL_OBJS] = DUMMY;
  55. X
  56. Xint
  57. Xletindex(let) register char let; {
  58. Xregister int i = 0;
  59. Xregister char ch;
  60. X    while((ch = obj_symbols[i++]) != 0)
  61. X        if(ch == let) return(i);
  62. X    return(0);
  63. X}
  64. X
  65. Xstatic void
  66. Xsetgemprobs()
  67. X{
  68. X    register int j,first;
  69. X#ifdef STRONGHOLD
  70. X    int level = (dlevel > MAXLEVEL) ? MAXLEVEL : dlevel;
  71. X#endif
  72. X
  73. X    first = bases[letindex(GEM_SYM)];
  74. X
  75. X#ifdef STRONGHOLD
  76. X    for(j = 0; j < 9-level/3; j++)
  77. X#else
  78. X    for(j = 0; j < 9-dlevel/3; j++)
  79. X#endif
  80. X        objects[first+j].oc_prob = 0;
  81. X    first += j;
  82. X    if(first >= LAST_GEM || first > NROFOBJECTS ||
  83. X        objects[first].oc_olet != GEM_SYM ||
  84. X        objects[first].oc_name == NULL)
  85. X        Printf("Not enough gems? - first=%d j=%d LAST_GEM=%d\n",
  86. X            first, j, LAST_GEM);
  87. X    for(j = first; j < LAST_GEM; j++)
  88. X        objects[j].oc_prob = (180+j-first)/(LAST_GEM-first);
  89. X}
  90. X
  91. X/* shuffle descriptions on objects o_low to o_high */
  92. Xstatic void
  93. Xshuffle(o_low, o_high, domaterial)
  94. X
  95. X    register int o_low, o_high;
  96. X    register boolean domaterial;
  97. X{
  98. X    register int i, j;
  99. X    char *desc;
  100. X    int tmp;
  101. X
  102. X    for(j=o_low; j <= o_high; j++) {
  103. X        i = o_low + rn2(j+1-o_low);
  104. X        desc = objects[j].oc_descr;
  105. X        objects[j].oc_descr = objects[i].oc_descr;
  106. X        objects[i].oc_descr = desc;
  107. X        /* shuffle discovery list */
  108. X        tmp = disco[j];
  109. X        disco[j] = disco[i];
  110. X        disco[i] = tmp;
  111. X        /* shuffle material */
  112. X        if(domaterial) {
  113. X            tmp = objects[j].oc_material;
  114. X            objects[j].oc_material = objects[i].oc_material;
  115. X            objects[i].oc_material = tmp;
  116. X        }
  117. X    }
  118. X}
  119. X
  120. Xvoid
  121. Xinit_objects(){
  122. Xregister int i, j, first, last, sum, end;
  123. Xregister char let;
  124. X
  125. X    /* bug fix to prevent "initialization error" abort on Intel Xenix.
  126. X     * reported by mikew@semike
  127. X     */
  128. X    for(i = 0; i != sizeof(obj_symbols); i++)
  129. X        bases[i] = 0;
  130. X    for(i = 0; i != TOTAL_OBJS; i++)
  131. X        disco[i] = i;
  132. X
  133. X    /* init base; if probs given check that they add up to 1000,
  134. X       otherwise compute probs; shuffle descriptions */
  135. X    end = TOTAL_OBJS;
  136. X    first = 0;
  137. X    while( first < end ) {
  138. X        let = objects[first].oc_olet;
  139. X        last = first+1;
  140. X        while(last < end && objects[last].oc_olet == let
  141. X                 && objects[last].oc_name != NULL) last++;
  142. X        i = letindex(let);
  143. X        if((!i && let != ILLOBJ_SYM && let != '.') || bases[i] != 0)
  144. X            error("initialization error for %c", let);
  145. X        bases[i] = first;
  146. X
  147. X        if(let == GEM_SYM) setgemprobs();
  148. X    check:
  149. X        sum = 0;
  150. X        for(j = first; j < last; j++) sum += objects[j].oc_prob;
  151. X        if(sum == 0) {
  152. X            for(j = first; j < last; j++)
  153. X                objects[j].oc_prob = (1000+j-first)/(last-first);
  154. X            goto check;
  155. X        }
  156. X        if(sum != 1000)
  157. X            error("init-prob error for %c (%d%%)", let, sum);
  158. X
  159. X        if(objects[first].oc_descr != NULL &&
  160. X           let != TOOL_SYM && let != WEAPON_SYM && let != ARMOR_SYM) {
  161. X
  162. X            /* shuffle, also some additional descriptions */
  163. X            while(last < end && objects[last].oc_olet == let)
  164. X                last++;
  165. X            j = last;
  166. X            if (let == GEM_SYM) {
  167. X                while(--j > first)
  168. X                /* NOTE:  longest color name must be default */
  169. X                if(!strcmp(objects[j].oc_name,"turquoise")) {
  170. X                    if(rn2(2)) /* change from green? */
  171. X                    Strcpy(objects[j].oc_descr, blue);
  172. X                } else if (!strcmp(objects[j].oc_name,"aquamarine")) {
  173. X                    if(rn2(2)) /* change from green? */
  174. X                    Strcpy(objects[j].oc_descr, blue);
  175. X                } else if (!strcmp(objects[j].oc_name,"fluorite")) {
  176. X                    switch (rn2(4)) { /* change from violet? */
  177. X                    case 0:  break;
  178. X                    case 1:
  179. X                        Strcpy(objects[j].oc_descr, blue);
  180. X                        break;
  181. X                    case 2:
  182. X                        Strcpy(objects[j].oc_descr, white);
  183. X                        break;
  184. X                    case 3:
  185. X                        Strcpy(objects[j].oc_descr, green);
  186. X                        break;
  187. X                    }
  188. X                }
  189. X            } else {
  190. X                if (let == AMULET_SYM || let == POTION_SYM)
  191. X                j--;  /* THE amulet doesn't have description */
  192. X                /* and water is always "clear" - 3. */
  193. X                shuffle(first, --j, TRUE);
  194. X            }
  195. X        }
  196. X        first = last;
  197. X    }
  198. X
  199. X    /* shuffle the helmets */
  200. X    shuffle(HELMET, HELM_OF_TELEPATHY, FALSE);
  201. X
  202. X    /* shuffle the gloves */
  203. X    shuffle(LEATHER_GLOVES, GAUNTLETS_OF_DEXTERITY, FALSE);
  204. X
  205. X    /* shuffle the cloaks */
  206. X    shuffle(CLOAK_OF_PROTECTION, CLOAK_OF_DISPLACEMENT, FALSE);
  207. X
  208. X    /* shuffle the boots */
  209. X    shuffle(SPEED_BOOTS, LEVITATION_BOOTS, FALSE);
  210. X}
  211. X
  212. Xvoid
  213. Xoinit()            /* level dependent initialization */
  214. X{
  215. X    setgemprobs();
  216. X}
  217. X
  218. Xvoid
  219. Xsavenames(fd)
  220. Xregister int fd;
  221. X{
  222. X    register int i;
  223. X    unsigned int len;
  224. X    struct objclass *now = &objects[0];
  225. X    bwrite(fd, (genericptr_t)&now, sizeof now);
  226. X    bwrite(fd, (genericptr_t)bases, sizeof bases);
  227. X    bwrite(fd, (genericptr_t)disco, sizeof disco);
  228. X    bwrite(fd, (genericptr_t)objects, sizeof(struct objclass) * TOTAL_OBJS);
  229. X    /* as long as we use only one version of Hack we
  230. X       need not save oc_name and oc_descr, but we must save
  231. X       oc_uname for all objects */
  232. X    for(i=0; i < TOTAL_OBJS; i++) {
  233. X        if(objects[i].oc_uname) {
  234. X            len = strlen(objects[i].oc_uname)+1;
  235. X            bwrite(fd, (genericptr_t)&len, sizeof len);
  236. X            bwrite(fd, (genericptr_t)objects[i].oc_uname, len);
  237. X        }
  238. X    }
  239. X}
  240. X
  241. Xvoid
  242. Xrestnames(fd)
  243. Xregister int fd;
  244. X{
  245. X    register int i;
  246. X    unsigned int len;
  247. X    struct objclass *then;
  248. X    long differ;
  249. X    mread(fd, (genericptr_t) &then, sizeof then);
  250. X    mread(fd, (genericptr_t) bases, sizeof bases);
  251. X    mread(fd, (genericptr_t) disco, sizeof disco);
  252. X    mread(fd, (genericptr_t) objects, sizeof(struct objclass) * TOTAL_OBJS);
  253. X#ifndef MSDOS
  254. X    differ = (genericptr_t)&objects[0] - (genericptr_t)then;
  255. X#else
  256. X    differ = (long)&objects[0] - (long)then;
  257. X#endif
  258. X    for(i=0; i < TOTAL_OBJS; i++) {
  259. X        if (objects[i].oc_name) {
  260. X#ifndef MSDOS
  261. X            objects[i].oc_name += differ;
  262. X#else
  263. X            objects[i].oc_name =
  264. X                (char *)((long)(objects[i].oc_name) + differ);
  265. X#endif
  266. X        }
  267. X        if (objects[i].oc_descr) {
  268. X#ifndef MSDOS
  269. X            objects[i].oc_descr += differ;
  270. X#else
  271. X            objects[i].oc_descr =
  272. X                (char *)((long)(objects[i].oc_descr) + differ);
  273. X#endif
  274. X        }
  275. X        if (objects[i].oc_uname) {
  276. X            mread(fd, (genericptr_t) &len, sizeof len);
  277. X            objects[i].oc_uname = (char *) alloc(len);
  278. X            mread(fd, (genericptr_t)objects[i].oc_uname, len);
  279. X        }
  280. X    }
  281. X}
  282. X
  283. Xstatic boolean
  284. Xinteresting_to_discover(i)
  285. Xregister int i;
  286. X{
  287. X    return objects[i].oc_uname != NULL ||
  288. X        (objects[i].oc_name_known && objects[i].oc_descr != NULL);
  289. X}
  290. X
  291. Xint
  292. Xdodiscovered()                /* free after Robert Viduya */
  293. X{
  294. X    register int i, dis;
  295. X    int    ct = 0;
  296. X    char class = -1;
  297. X
  298. X    cornline(0, "Discoveries");
  299. X
  300. X    for (i = 0; i <= NROFOBJECTS; i++) {
  301. X    if (interesting_to_discover(dis = disco[i])) {
  302. X        ct++;
  303. X        if (objects[dis].oc_olet != class) {
  304. X        class = objects[dis].oc_olet;
  305. X        cornline(1, let_to_name(class));
  306. X        }
  307. X        cornline(1, typename(dis));
  308. X    }
  309. X    }
  310. X    if (ct == 0) {
  311. X    You("haven't discovered anything yet...");
  312. X    cornline(3, NULL);
  313. X    } else
  314. X    cornline(2, NULL);
  315. X
  316. X    return 0;
  317. X}
  318. END_OF_FILE
  319. if test 7223 -ne `wc -c <'src/o_init.c'`; then
  320.     echo shar: \"'src/o_init.c'\" unpacked with wrong size!
  321. fi
  322. # end of 'src/o_init.c'
  323. fi
  324. if test -f 'src/zap.c' -a "${1}" != "-c" ; then 
  325.   echo shar: Will not clobber existing file \"'src/zap.c'\"
  326. else
  327. echo shar: Extracting \"'src/zap.c'\" \(44087 characters\)
  328. sed "s/^X//" >'src/zap.c' <<'END_OF_FILE'
  329. X/*    SCCS Id: @(#)zap.c    3.0    88/10/25
  330. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  331. X/* NetHack may be freely redistributed.  See license for details. */
  332. X
  333. X#include "hack.h"
  334. X
  335. X#if defined(ALTARS) && defined(THEOLOGY)
  336. Xstatic boolean priesthit = FALSE;
  337. X#endif
  338. X
  339. Xconst char *fl[]= {
  340. X    "magic missile",    /* Wands must be 0-9 */
  341. X    "bolt of fire",
  342. X    "sleep ray",
  343. X    "bolt of cold",
  344. X    "death ray",
  345. X    "bolt of lightning",
  346. X    "",
  347. X    "",
  348. X    "",
  349. X    "",
  350. X
  351. X    "magic missile",    /* Spell equivalents must be 10-19 */
  352. X    "fireball",
  353. X    "sleep ray",
  354. X    "cone of cold",
  355. X    "finger of death",
  356. X    "bolt of lightning",
  357. X    "",
  358. X    "",
  359. X    "",
  360. X    "",
  361. X
  362. X    "blast of missiles",    /* Dragon breath equivalents 20-29*/
  363. X    "blast of fire",
  364. X    "blast of sleeping gas",
  365. X    "blast of frost",
  366. X    "blast of disintegration",
  367. X    "blast of lightning",
  368. X    "blast of poison gas",
  369. X    "blast of acid",
  370. X    "",
  371. X    ""
  372. X};
  373. X
  374. X/* Routines for IMMEDIATE wands and spells. */
  375. X/* bhitm: monster mtmp was hit by the effect of wand or spell otmp */
  376. Xstatic int
  377. Xbhitm(mtmp, otmp)
  378. Xregister struct monst *mtmp;
  379. Xregister struct obj *otmp;
  380. X{
  381. X    wakeup(mtmp);
  382. X    switch(otmp->otyp) {
  383. X    case WAN_STRIKING:
  384. X#ifdef SPELLS
  385. X    case SPE_FORCE_BOLT:
  386. X#endif
  387. X        if(u.uswallow || rnd(20) < 10+mtmp->data->ac) {
  388. X            register int tmp = d(2,12);
  389. X            hit((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp, exclam(tmp));
  390. X            (void) resist(mtmp, otmp->olet, tmp, TELL);
  391. X        } else miss((otmp->otyp == WAN_STRIKING) ? "wand" : "spell", mtmp);
  392. X        break;
  393. X    case WAN_SLOW_MONSTER:
  394. X#ifdef SPELLS
  395. X    case SPE_SLOW_MONSTER:
  396. X#endif
  397. X        if(! resist(mtmp, otmp->olet, 0, NOTELL))
  398. X            if (mtmp->mspeed == MFAST) mtmp->mspeed = 0;
  399. X            else mtmp->mspeed = MSLOW;
  400. X        break;
  401. X    case WAN_SPEED_MONSTER:
  402. X        if (!resist(mtmp, otmp->olet, 0, NOTELL))
  403. X            if (mtmp->mspeed == MSLOW) mtmp->mspeed = 0;
  404. X            else mtmp->mspeed = MFAST;
  405. X        break;
  406. X    case WAN_UNDEAD_TURNING:
  407. X#ifdef SPELLS
  408. X    case SPE_TURN_UNDEAD:
  409. X#endif
  410. X        if(is_undead(mtmp->data)) {
  411. X
  412. X            if(!resist(mtmp, otmp->olet, rnd(8), NOTELL))
  413. X                mtmp->mflee = 1;
  414. X        }
  415. X        break;
  416. X    case WAN_POLYMORPH:
  417. X#ifdef SPELLS
  418. X    case SPE_POLYMORPH:
  419. X#endif
  420. X        if(!resist(mtmp, otmp->olet, 0, NOTELL))
  421. X            if( newcham(mtmp, (struct permonst *)0) )
  422. X            if (!Hallucination)
  423. X                makeknown(otmp->otyp);
  424. X        break;
  425. X    case WAN_CANCELLATION:
  426. X#ifdef SPELLS
  427. X    case SPE_CANCELLATION:
  428. X#endif
  429. X        if(!resist(mtmp, otmp->olet, 0, NOTELL)) {
  430. X          if (is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN)
  431. X            were_change(mtmp);
  432. X#ifdef GOLEMS
  433. X          if (mtmp->data == &mons[PM_CLAY_GOLEM]) {
  434. X            if (!Blind)
  435. X              pline("Some writing vanishes from %s's head!",
  436. X            mon_nam(mtmp));
  437. X            killed(mtmp);
  438. X          }
  439. X          else
  440. X#endif /* GOLEMS */
  441. X            mtmp->mcan = 1;
  442. X        }
  443. X        break;
  444. X    case WAN_TELEPORTATION:
  445. X#ifdef SPELLS
  446. X    case SPE_TELEPORT_AWAY:
  447. X#endif
  448. X#if defined(ALTARS) && defined(THEOLOGY)
  449. X        if(mtmp->ispriest && in_temple(mtmp->mx, mtmp->my)) {
  450. X            kludge("%s resists your magic!", Monnam(mtmp));
  451. X            wakeup(mtmp);
  452. X            break;
  453. X        }
  454. X#endif
  455. X        rloc(mtmp);
  456. X        break;
  457. X    case WAN_MAKE_INVISIBLE:
  458. X        mtmp->minvis = 1;
  459. X        break;
  460. X    case WAN_NOTHING:
  461. X        break;
  462. X#ifdef PROBING
  463. X    case WAN_PROBING:
  464. X        makeknown(otmp->otyp);
  465. X        mstatusline(mtmp);
  466. X        break;
  467. X#endif
  468. X    case WAN_OPENING:
  469. X    case WAN_LOCKING:
  470. X#ifdef SPELLS
  471. X    case SPE_KNOCK:
  472. X    case SPE_WIZARD_LOCK:
  473. X#endif
  474. X        break;
  475. X    default:
  476. X        impossible("What an interesting effect (%u)", otmp->otyp);
  477. X    }
  478. X    return 0;
  479. X}
  480. X
  481. Xstruct monst *
  482. Xrevive(obj,ininv)
  483. Xregister struct obj *obj;
  484. Xboolean ininv;
  485. X{
  486. X    register struct monst *mtmp;
  487. X
  488. X    if(obj->otyp == CORPSE) {
  489. X        int montype,x,y,nl;
  490. X        char buf[BUFSZ];
  491. X
  492. X        if (nl = obj->onamelth) Strcpy(buf, ONAME(obj));
  493. X        montype = obj->corpsenm;
  494. X        if (ininv) {
  495. X            x = u.ux; y = u.uy;
  496. X            useup(obj);
  497. X        } else {
  498. X            x = obj->ox; y = obj->oy;
  499. X            useupf(obj);
  500. X        }
  501. X        if (cant_create(&montype)) { /* will make zombie instead */
  502. X            mtmp = makemon(&mons[PM_HUMAN_ZOMBIE], x, y);
  503. X            if (mtmp) {
  504. X                mtmp->mhp = mtmp->mhpmax = 100;
  505. X                mtmp->mspeed = MFAST;
  506. X            }
  507. X        } else {
  508. X#ifdef ARMY
  509. X            if (is_mercenary(&mons[montype]))
  510. X                montype = PM_UNARMORED_SOLDIER;
  511. X#endif
  512. X            mons[montype].pxlth += nl;
  513. X            mtmp = mkmon_at(mons[montype].mname, x, y);
  514. X            mons[montype].pxlth -= nl;
  515. X            if (mtmp) {
  516. X                /* Monster retains its name */
  517. X                mtmp->mnamelth = nl;
  518. X                if (nl) Strcpy(NAME(mtmp), buf);
  519. X                /* No inventory for newly revived monsters */
  520. X                while(obj = (mtmp->minvent)) {
  521. X                    mtmp->minvent = obj->nobj;
  522. X                    free((genericptr_t)obj);
  523. X                }
  524. X            }
  525. X        }
  526. X    }
  527. X    return mtmp;
  528. X}
  529. X
  530. Xstatic const char charged_objs[] = { WAND_SYM, WEAPON_SYM, ARMOR_SYM, 0 };
  531. X
  532. Xstatic void
  533. Xcancel_item(obj)
  534. Xregister struct obj *obj;
  535. X{
  536. X    if(obj->spe &&
  537. X      !(obj->otyp == AMULET_OF_YENDOR ||
  538. X        obj->otyp == WAN_CANCELLATION || /* can't cancel cancellation */
  539. X        obj->otyp == TIN || obj->otyp == EGG ||
  540. X        obj->otyp == STATUE ||
  541. X#ifdef MAIL
  542. X        obj->otyp == SCR_MAIL ||
  543. X#endif
  544. X        obj->otyp == KEY || obj->otyp == SKELETON_KEY ||
  545. X        obj->otyp == LARGE_BOX || obj->otyp == CHEST))
  546. X        obj->spe = (obj->olet == WAND_SYM) ? -1 : 0;
  547. X    if (obj->olet == SCROLL_SYM
  548. X#ifdef MAIL
  549. X        && obj->otyp != SCR_MAIL
  550. X#endif
  551. X       )
  552. X        obj->otyp = SCR_BLANK_PAPER;
  553. X    if (obj->olet == POTION_SYM && obj->otyp > POT_BOOZE)
  554. X        obj->otyp = (obj->otyp==POT_SICKNESS) ? POT_FRUIT_JUICE : POT_WATER;
  555. X        /* sickness is "biologically contaminated" fruit juice; cancel it
  556. X         * and it just becomes fruit juice...
  557. X         */
  558. X    obj->blessed = obj->cursed = FALSE;
  559. X}
  560. X
  561. Xstatic int
  562. Xbhito(obj, otmp)    /* object obj was hit by the effect of wand otmp */
  563. Xregister struct obj *obj, *otmp;    /* returns TRUE if sth was done */
  564. X{
  565. X    register int res = 1;
  566. X    struct obj *otmp2;
  567. X
  568. X    if(obj == uball || obj == uchain)
  569. X        res = 0;
  570. X    else
  571. X    switch(otmp->otyp) {
  572. X    case WAN_POLYMORPH:
  573. X#ifdef SPELLS
  574. X    case SPE_POLYMORPH:
  575. X#endif
  576. X#ifdef MAIL
  577. X        /* You can't send yourself 100 mail messages and then
  578. X         * polymorph them into useful scrolls
  579. X         */
  580. X        if (obj->otyp == SCR_MAIL) obj->spe = 1;
  581. X#endif
  582. X        /* preserve symbol and quantity */
  583. X        otmp2 = mkobj_at(obj->olet, obj->ox, obj->oy);
  584. X        otmp2->quan = obj->quan;
  585. X
  586. X        /* keep special fields (including charges on wands) */
  587. X        if (index(charged_objs, otmp2->olet)) otmp2->spe = obj->spe;
  588. X
  589. X        /* Amulet gets cheap   stewr 870807 */
  590. X        if (obj->otyp == AMULET_OF_YENDOR) otmp2->spe = -1;
  591. X
  592. X        /* Wands of wishing max 3 stewr 870808 */
  593. X        if ((otmp2->otyp == WAN_WISHING)
  594. X            && (obj->spe > 3)) otmp2->spe = 3;
  595. X
  596. X        otmp2->cursed = obj->cursed;
  597. X        otmp2->blessed = obj->blessed;
  598. X        otmp2->rustfree = obj->rustfree;
  599. X
  600. X        /* Keep chest/box traps and poisoned ammo if we may */
  601. X        if (obj->otrapped && Is_box(otmp2))
  602. X            otmp2->otrapped = 1;
  603. X        if (obj->opoisoned && 
  604. X            (otmp2->olet == WEAPON_SYM && otmp2->otyp <= SHURIKEN))
  605. X            otmp2->opoisoned = 1;
  606. X
  607. X        /* Turn dragon corpses into dragon armors */
  608. X        if (obj->otyp == CORPSE && obj->corpsenm >= PM_GREY_DRAGON
  609. X                && obj->corpsenm <= PM_YELLOW_DRAGON) {
  610. X            if (!rn2(10)) { /* Random failure */
  611. X                otmp2->otyp = TIN;
  612. X                otmp2->known = otmp2->dknown = 1;
  613. X            } else {
  614. X                otmp2->otyp = DRAGON_SCALE_MAIL;
  615. X                otmp2->olet = ARMOR_SYM;
  616. X                otmp2->spe = 0;
  617. X                otmp2->rustfree = 1;
  618. X                otmp2->quan = 1;
  619. X                otmp2->cursed = 0;
  620. X            }
  621. X            otmp2->corpsenm = obj->corpsenm;
  622. X        }
  623. X
  624. X        /* update the weight */
  625. X        otmp2->owt = weight(otmp2);
  626. X        delobj(obj);
  627. X        break;
  628. X    case WAN_STRIKING:
  629. X#ifdef SPELLS
  630. X    case SPE_FORCE_BOLT:
  631. X#endif
  632. X        if(obj->otyp == BOULDER)
  633. X            fracture_rock(obj);
  634. X        else if(obj->otyp == STATUE)
  635. X            (void) break_statue(obj);
  636. X        else
  637. X            res = 0;
  638. X        break;
  639. X    case WAN_CANCELLATION:
  640. X#ifdef SPELLS
  641. X    case SPE_CANCELLATION:
  642. X#endif
  643. X        cancel_item(obj);
  644. X        break;
  645. X    case WAN_TELEPORTATION:
  646. X#ifdef SPELLS
  647. X    case SPE_TELEPORT_AWAY:
  648. X#endif
  649. X        rloco(obj);
  650. X        break;
  651. X    case WAN_MAKE_INVISIBLE:
  652. X        obj->oinvis = 1;
  653. X        break;
  654. X    case WAN_UNDEAD_TURNING:
  655. X#ifdef SPELLS
  656. X    case SPE_TURN_UNDEAD:
  657. X#endif
  658. X        res = !!revive(obj,FALSE);
  659. X        break;
  660. X    case WAN_OPENING:
  661. X    case WAN_LOCKING:
  662. X#ifdef SPELLS
  663. X    case SPE_KNOCK:
  664. X    case SPE_WIZARD_LOCK:
  665. X#endif
  666. X        if(Is_box(obj))
  667. X            res = boxlock(obj, otmp);
  668. X        else
  669. X            res = 0;
  670. X        if (res /* && obj->olet == WAND_SYM */)
  671. X            makeknown(obj->otyp);
  672. X        break;
  673. X    case WAN_SLOW_MONSTER:        /* no effect on objects */
  674. X#ifdef SPELLS
  675. X    case SPE_SLOW_MONSTER:
  676. X#endif
  677. X    case WAN_SPEED_MONSTER:
  678. X    case WAN_NOTHING:
  679. X#ifdef PROBING
  680. X    case WAN_PROBING:
  681. X#endif
  682. X        res = 0;
  683. X        break;
  684. X    default:
  685. X        impossible("What an interesting effect (%u)", otmp->otyp);
  686. X    }
  687. X    return(res);
  688. X}
  689. X
  690. X/*
  691. X * zappable - returns 1 if zap is available, 0 otherwise.
  692. X *          it removes a charge from the wand if zappable.
  693. X * added by GAN 11/03/86
  694. X */
  695. Xint
  696. Xzappable(wand)
  697. Xregister struct obj *wand;
  698. X{
  699. X    if(wand->spe < 0 || (wand->spe == 0 && rn2(121)))
  700. X        return 0;
  701. X    if(wand->spe == 0)
  702. X        You("wrest one more spell from the worn-out wand.");
  703. X    wand->spe--;
  704. X    return 1;
  705. X}
  706. X
  707. X/*
  708. X * zapnodir - zaps an NODIR wand.
  709. X * added by GAN 11/03/86
  710. X */
  711. Xvoid
  712. Xzapnodir(wand)
  713. Xregister struct obj *wand;
  714. X{
  715. X    switch(wand->otyp){
  716. X        case WAN_LIGHT:
  717. X            litroom(TRUE);
  718. X            break;
  719. X        case WAN_SECRET_DOOR_DETECTION:
  720. X            if(!findit()) return;
  721. X            break;
  722. X        case WAN_CREATE_MONSTER:
  723. X            { register int cnt = 1;
  724. X            if(!rn2(23)) cnt += rn2(7) + 1;
  725. X            while(cnt--)
  726. X                (void) makemon((struct permonst *) 0, u.ux, u.uy);
  727. X            }
  728. X            break;
  729. X        case WAN_WISHING:
  730. X
  731. X            if(u.uluck + rn2(5) < 0) {
  732. X                pline("Unfortunately, nothing happens.");
  733. X                break;
  734. X            }
  735. X            makewish();
  736. X            break;
  737. X    }
  738. X    if(!objects[wand->otyp].oc_name_known) {
  739. X            makeknown(wand->otyp);
  740. X            more_experienced(0,10);
  741. X    }
  742. X}
  743. X
  744. Xstatic void
  745. Xbackfire(otmp)
  746. X
  747. X    register struct obj * otmp;
  748. X{
  749. X    pline("The %s suddenly explodes!", xname(otmp));
  750. X    losehp(d(otmp->spe+2,6), "exploding wand");
  751. X    useup(otmp);
  752. X}
  753. X
  754. Xstatic const char zap_syms[] = { WAND_SYM, 0 };
  755. X
  756. Xint
  757. Xdozap()
  758. X{
  759. X    register struct obj *obj;
  760. X    int    damage;
  761. X
  762. X    obj = getobj(zap_syms, "zap");
  763. X    if(!obj) return(0);
  764. X
  765. X    check_unpaid(obj);
  766. X
  767. X    /* zappable addition done by GAN 11/03/86 */
  768. X    if(!zappable(obj)) pline(nothing_happens);
  769. X    else if(obj->cursed && !rn2(100)) {
  770. X        backfire(obj);    /* the wand blows up in your face! */
  771. X        return(1);
  772. X    } else if(!(objects[obj->otyp].bits & NODIR) && !getdir(1)) {
  773. X        if (!Blind)
  774. X            pline("The %s glows and fades.", xname(obj));
  775. X        /* make him pay for knowing !NODIR */
  776. X    } else if(!u.dx && !u.dy && !u.dz && !(objects[obj->otyp].bits & NODIR)) {
  777. X        if((damage = zapyourself(obj)))
  778. X        losehp(damage,"self-inflicted injury");
  779. X    }
  780. X    else {
  781. X        weffects(obj);
  782. X#if defined(ALTARS) && defined(THEOLOGY)
  783. X        if(priesthit) ghod_hitsu();
  784. X        priesthit = FALSE;
  785. X#endif
  786. X    }
  787. X    if (obj->spe < 0) {
  788. X        pline ("The %s %sturns to dust.",
  789. X           xname(obj), Blind ? "" : "glows violently, then ");
  790. X        useup(obj);
  791. X    }
  792. X    return(1);
  793. X}
  794. X
  795. Xint
  796. Xzapyourself(obj)
  797. X    register struct obj    *obj;
  798. X{
  799. X    struct obj    *otmp;
  800. X    int    damage = 0;
  801. X
  802. X    switch(obj->otyp) {
  803. X        case WAN_STRIKING:
  804. X#ifdef SPELLS
  805. X        case SPE_FORCE_BOLT:
  806. X#endif
  807. X            if(Antimagic) {
  808. X            shieldeff(u.ux, u.uy);
  809. X            pline("Boing!");
  810. X            } else {
  811. X            You("magically bash yourself!");
  812. X            damage=d(8,6);
  813. X            }
  814. X            break;
  815. X        case WAN_LIGHTNING:
  816. X            makeknown(WAN_LIGHTNING);
  817. X            if (!Shock_resistance) {
  818. X            pline("Idiot!  You've shocked yourself!");
  819. X            damage = d(12,6);
  820. X            } else {
  821. X            shieldeff(u.ux, u.uy);
  822. X            You("zap yourself, but seem unharmed.");
  823. X#ifdef POLYSELF
  824. X#ifdef GOLEMS
  825. X            ugolemeffects(AD_ELEC, d(12,6));
  826. X#endif /* GOLEMS */
  827. X#endif
  828. X            }
  829. X            if(!Blind) {
  830. X                You("are blinded by the flash!");
  831. X                make_blinded((long)rnd(100),FALSE);
  832. X            }
  833. X            break;
  834. X        case WAN_FIRE:
  835. X            makeknown(WAN_FIRE);
  836. X#ifdef SPELLS
  837. X        case SPE_FIREBALL:
  838. X#endif
  839. X#ifdef MUSIC
  840. X        case FIRE_HORN:
  841. X#endif
  842. X            pline("You've set light to yourself!");
  843. X            if (Fire_resistance) {
  844. X            shieldeff(u.ux, u.uy);
  845. X            You("feel mildly hot.");
  846. X#ifdef POLYSELF
  847. X#ifdef GOLEMS
  848. X            ugolemeffects(AD_FIRE, d(12,6));
  849. X#endif /* GOLEMS */
  850. X#endif
  851. X            } else
  852. X            damage = d(12,6);
  853. X            destroy_item(SCROLL_SYM, AD_FIRE);
  854. X            destroy_item(POTION_SYM, AD_FIRE);
  855. X#ifdef SPELLS
  856. X            destroy_item(SPBOOK_SYM, AD_FIRE);
  857. X#endif
  858. X            break;
  859. X        case WAN_COLD:
  860. X            makeknown(WAN_COLD);
  861. X#ifdef SPELLS
  862. X        case SPE_CONE_OF_COLD:
  863. X#endif
  864. X#ifdef MUSIC
  865. X        case FROST_HORN:
  866. X#endif
  867. X            if (Cold_resistance) {
  868. X            shieldeff(u.ux, u.uy);
  869. X            You("feel mildly chilly.");
  870. X#ifdef POLYSELF
  871. X#ifdef GOLEMS
  872. X            ugolemeffects(AD_COLD, d(12,6));
  873. X#endif /* GOLEMS */
  874. X#endif
  875. X            } else {
  876. X            You("imitate a popsicle!");
  877. X            damage = d(12,6);
  878. X            }
  879. X            destroy_item(POTION_SYM, AD_COLD);
  880. X            break;
  881. X        case WAN_MAGIC_MISSILE:
  882. X            makeknown(WAN_MAGIC_MISSILE);
  883. X#ifdef SPELLS
  884. X        case SPE_MAGIC_MISSILE:
  885. X#endif
  886. X            if(Antimagic) {
  887. X            shieldeff(u.ux, u.uy);
  888. X            pline("The missiles bounce!");
  889. X            } else {
  890. X            damage = d(4,6);
  891. X            pline("Idiot!  You've shot yourself!");
  892. X            }
  893. X            break;
  894. X        case WAN_POLYMORPH:
  895. X#ifdef POLYSELF
  896. X            makeknown(WAN_POLYMORPH);
  897. X#endif
  898. X#ifdef SPELLS
  899. X        case SPE_POLYMORPH:
  900. X#endif
  901. X#ifdef POLYSELF
  902. X            polyself();
  903. X#else
  904. X            You("shudder for a moment.");
  905. X#endif
  906. X            break;
  907. X        case WAN_CANCELLATION:
  908. X#ifdef SPELLS
  909. X        case SPE_CANCELLATION:
  910. X#endif
  911. X#ifdef POLYSELF
  912. X#ifdef GOLEMS
  913. X            if (u.umonnum == PM_CLAY_GOLEM) {
  914. X            if (!Blind)
  915. X                pline("Some writing vanishes from your head!");
  916. X            rehumanize();
  917. X            break;
  918. X            }
  919. X#endif /* GOLEMS */
  920. X#endif
  921. X            for(otmp = invent; otmp; otmp = otmp->nobj)
  922. X            cancel_item(otmp);
  923. X#ifdef POLYSELF
  924. X            if(u.mtimedone) rehumanize();
  925. X#endif
  926. X            flags.botl = 1;  /* because of potential AC change */
  927. X            find_ac();
  928. X            break;
  929. X           case WAN_MAKE_INVISIBLE:
  930. X            if (!Invisible) makeknown(WAN_MAKE_INVISIBLE);
  931. X            HInvis |= INTRINSIC;
  932. X            if (!See_invisible) newsym(u.ux, u.uy);
  933. X            break;
  934. X           case WAN_SPEED_MONSTER:
  935. X            if (!(Fast & INTRINSIC)) {
  936. X            Fast |= INTRINSIC;
  937. X            You("seem to be moving faster.");
  938. X            makeknown(WAN_SPEED_MONSTER);
  939. X            }
  940. X            break;
  941. X           case WAN_SLEEP:
  942. X            makeknown(WAN_SLEEP);
  943. X#ifdef SPELLS
  944. X        case SPE_SLEEP:
  945. X#endif
  946. X            if(Sleep_resistance) {
  947. X            shieldeff(u.ux, u.uy);
  948. X            You("don't feel sleepy!");
  949. X            } else {
  950. X            pline("The sleep ray hits you!");
  951. X            nomul(-rn2(50));
  952. X            }
  953. X            break;
  954. X        case WAN_SLOW_MONSTER:
  955. X#ifdef SPELLS
  956. X        case SPE_SLOW_MONSTER:
  957. X#endif
  958. X            if(Fast & (TIMEOUT | INTRINSIC)) {
  959. X            Fast &= ~(TIMEOUT | INTRINSIC);
  960. X            You("seem to be moving slower.");
  961. X            }
  962. X            break;
  963. X        case WAN_TELEPORTATION:
  964. X#ifdef SPELLS
  965. X        case SPE_TELEPORT_AWAY:
  966. X#endif
  967. X            tele();
  968. X            break;
  969. X        case WAN_DEATH:
  970. X#ifdef SPELLS
  971. X        case SPE_FINGER_OF_DEATH:
  972. X#endif
  973. X#ifdef POLYSELF
  974. X            if (is_undead(uasmon)) {
  975. X            pline((obj->otyp == WAN_DEATH) ?
  976. X              "The wand shoots an apparently harmless beam at you."
  977. X              : "You seem no deader than before.");
  978. X            break;
  979. X            }
  980. X#endif
  981. X            killer = "death ray";
  982. X            You("irradiate yourself with pure energy!");
  983. X            You("die.");
  984. X            makeknown(WAN_DEATH);
  985. X            /* They might survive with an amulet of life saving */
  986. X            done("died");
  987. X            break;
  988. X#ifdef SPELLS
  989. X        case SPE_TURN_UNDEAD:
  990. X#endif
  991. X        case WAN_UNDEAD_TURNING:
  992. X#ifdef POLYSELF
  993. X            if (is_undead(uasmon)) {
  994. X            Printf("You feel frightened and %sstunned.",
  995. X                 Stunned ? "even more " : "");
  996. X            make_stunned(HStun + rnd(30), FALSE);
  997. X            }
  998. X#endif
  999. X            break;
  1000. X#ifdef SPELLS
  1001. X        case SPE_DIG:
  1002. X        case SPE_DETECT_UNSEEN:
  1003. X#endif
  1004. X        case WAN_DIGGING:
  1005. X        case WAN_NOTHING:
  1006. X        case WAN_OPENING:
  1007. X        case WAN_LOCKING:
  1008. X#ifdef SPELLS
  1009. X        case SPE_KNOCK:
  1010. X        case SPE_WIZARD_LOCK:
  1011. X#endif
  1012. X            break;
  1013. X#ifdef PROBING
  1014. X        case WAN_PROBING:
  1015. X            makeknown(WAN_PROBING);
  1016. X            ustatusline();
  1017. X            break;
  1018. X#endif
  1019. X        default: impossible("object %d used?",obj->otyp);
  1020. X    }
  1021. X    return(damage);
  1022. X}
  1023. X
  1024. X/* called for various wand and spell effects - M. Stephenson */
  1025. Xvoid
  1026. Xweffects(obj)
  1027. Xregister struct    obj    *obj;
  1028. X{
  1029. X    xchar zx,zy;
  1030. X
  1031. X    if(objects[obj->otyp].bits & IMMEDIATE) {
  1032. X        if(u.uswallow)    (void)bhitm(u.ustuck, obj);
  1033. X        else if(u.dz) {
  1034. X        if(u.dz > 0 && levl[u.ux][u.uy].omask) {
  1035. X            register struct obj *otmp,*otmp2;
  1036. X
  1037. X            /* changed by GAN to hit all objects there */
  1038. X            for(otmp = fobj; otmp ; otmp = otmp2) {
  1039. X            otmp2 = otmp->nobj;
  1040. X            /* save pointer as bhito may destroy otmp */
  1041. X            if(otmp->ox == u.ux && otmp->oy == u.uy)
  1042. X                (void) bhito(otmp, obj);
  1043. X            }
  1044. X        }
  1045. X        } else if((obj->otyp == WAN_OPENING) ||
  1046. X#ifdef SPELLS
  1047. X              (obj->otyp == SPE_KNOCK) ||
  1048. X              (obj->otyp == SPE_WIZARD_LOCK) ||
  1049. X#endif
  1050. X              (obj->otyp == WAN_LOCKING)) {
  1051. X            (void)bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  1052. X#ifdef STRONGHOLD
  1053. X        } else if(obj->otyp == WAN_STRIKING
  1054. X#ifdef SPELLS
  1055. X              || obj->otyp == SPE_FORCE_BOLT
  1056. X#endif /* SPELLS /**/
  1057. X              ) {
  1058. X            int x,y;
  1059. X            x = u.ux + u.dx;
  1060. X            y = u.uy + u.dy;
  1061. X            if (find_drawbridge(&x,&y))
  1062. X            destroy_drawbridge(x,y);
  1063. X
  1064. X            else (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  1065. X#endif /* STRONGHOLD /**/
  1066. X        } else  (void) bhit(u.dx,u.dy,rn1(8,6),0,bhitm,bhito,obj);
  1067. X    } else {
  1068. X        switch(obj->otyp){
  1069. X        case WAN_LIGHT:
  1070. X#ifdef SPELLS
  1071. X        case SPE_LIGHT:
  1072. X#endif
  1073. X            litroom(TRUE);
  1074. X            break;
  1075. X        case WAN_SECRET_DOOR_DETECTION:
  1076. X#ifdef SPELLS
  1077. X        case SPE_DETECT_UNSEEN:
  1078. X#endif
  1079. X            if(!findit()) return;
  1080. X            break;
  1081. X        case WAN_CREATE_MONSTER:
  1082. X            { register int cnt = 1;
  1083. X            if(!rn2(23)) cnt += rn2(7) + 1;
  1084. X            while(cnt--)
  1085. X                (void) makemon((struct permonst *) 0, u.ux, u.uy);
  1086. X            }
  1087. X            break;
  1088. X        case WAN_WISHING:
  1089. X            if(u.uluck + rn2(5) < 0) {
  1090. X                pline("Unfortunately, nothing happens.");
  1091. X                break;
  1092. X            }
  1093. X            makewish();
  1094. X            break;
  1095. X        case WAN_DIGGING:
  1096. X#ifdef SPELLS
  1097. X        case SPE_DIG:
  1098. X#endif
  1099. X            /* Original effect (approximately):
  1100. X             * from CORR: dig until we pierce a wall
  1101. X             * from ROOM: piece wall and dig until we reach
  1102. X             * an ACCESSIBLE place.
  1103. X             * Currently: dig for digdepth positions;
  1104. X             * also down on request of Lennart Augustsson.
  1105. X             */
  1106. X            { register struct rm *room;
  1107. X              register int digdepth,dlx,dly;
  1108. X              register boolean shopdoor = FALSE;
  1109. X            if(u.uswallow) {
  1110. X                register struct monst *mtmp = u.ustuck;
  1111. X
  1112. X                You("pierce %s's stomach wall!",
  1113. X                    mon_nam(mtmp));
  1114. X                mtmp->mhp = 1;    /* almost dead */
  1115. X                unstuck(mtmp);
  1116. X                mnexto(mtmp);
  1117. X                break;
  1118. X            }
  1119. X            if(u.dz) {
  1120. X                if(u.dz < 0) {
  1121. X                You("loosen a rock from the ceiling.");
  1122. X                pline("It falls on your %s!",
  1123. X                    body_part(HEAD));
  1124. X                losehp(1, "falling rock");
  1125. X                (void) mksobj_at((int)ROCK, u.ux, u.uy);
  1126. X                fobj->quan = 1;
  1127. X                stackobj(fobj);
  1128. X                if(Invisible) newsym(u.ux, u.uy);
  1129. X                } else {
  1130. X                dighole();
  1131. X                }
  1132. X                break;
  1133. X            }
  1134. X            zx = u.ux+u.dx;
  1135. X            zy = u.uy+u.dy;
  1136. X            digdepth = 8 + rn2(18);
  1137. X            Tmp_at2(-1, '*');    /* open call */
  1138. X            while(--digdepth >= 0) {
  1139. X                if(!isok(zx,zy)) break;
  1140. X                room = &levl[zx][zy];
  1141. X                Tmp_at2(zx,zy);
  1142. X                if(is_maze_lev) {
  1143. X                if(IS_WALL(room->typ)) {
  1144. X                    if(room->diggable == W_DIGGABLE)
  1145. X                    room->typ = ROOM;
  1146. X                    else if(!Blind)
  1147. X                    pline("The wall glows then fades.");
  1148. X                    break;
  1149. X                }
  1150. X                if(room->typ == STONE) {
  1151. X                    if(room->diggable == W_DIGGABLE)
  1152. X                    room->typ = CORR;
  1153. X                    else if (!Blind)
  1154. X                    pline("The rock glows then fades.");
  1155. X                    break;
  1156. X                }
  1157. X                } else
  1158. X                if(IS_ROCK(room->typ))
  1159. X                    if(may_dig(zx,zy))
  1160. X                    if(IS_WALL(room->typ) ||
  1161. X                        room->typ == SDOOR) {
  1162. X                        room->typ = DOOR;
  1163. X                        room->doormask = D_NODOOR;
  1164. X                        if(in_shop(zx,zy)) {
  1165. X                        shopdoor = TRUE;
  1166. X                        dlx = zx;
  1167. X                        dly = zy;
  1168. X                        }
  1169. X                        digdepth -= 2;
  1170. X                    } else {
  1171. X                        room->typ = CORR;
  1172. X                        digdepth--;
  1173. X                    }
  1174. X                    else
  1175. X                    break;
  1176. X                else if(room->typ == DOOR &&
  1177. X                    (room->doormask & (D_LOCKED | D_CLOSED))) {
  1178. X                    room->doormask = D_NODOOR;
  1179. X                    if(in_shop(zx,zy)) {
  1180. X                    shopdoor = TRUE;
  1181. X                    dlx = zx;
  1182. X                    dly = zy;
  1183. X                    }
  1184. X                    digdepth -= 2;
  1185. X                }
  1186. X                mnewsym(zx,zy);
  1187. X                zx += u.dx;
  1188. X                zy += u.dy;
  1189. X            }
  1190. X            mnewsym(zx,zy);    /* not always necessary */
  1191. X            Tmp_at2(-1,-1);    /* closing call */
  1192. X            if(shopdoor && !in_shop(u.ux, u.uy))
  1193. X                pay_for_door(dlx, dly, "destroy");
  1194. X            break;
  1195. X            }
  1196. X        default:
  1197. X#ifdef SPELLS
  1198. X            if((int) obj->otyp >= SPE_MAGIC_MISSILE) {
  1199. X
  1200. X                buzz((int) obj->otyp - SPE_MAGIC_MISSILE + 10,
  1201. X                 (int)u.ulevel / 2 + 1, u.ux, u.uy, u.dx, u.dy);
  1202. X            } else
  1203. X#endif
  1204. X
  1205. X                buzz((int) obj->otyp - WAN_MAGIC_MISSILE, 6,
  1206. X                 u.ux, u.uy, u.dx, u.dy);
  1207. X            break;
  1208. X        }
  1209. X        if(!objects[obj->otyp].oc_name_known) {
  1210. X            makeknown(obj->otyp);
  1211. X            more_experienced(0,10);
  1212. X        }
  1213. X    }
  1214. X    return;
  1215. X}
  1216. X
  1217. Xchar *
  1218. Xexclam(force)
  1219. Xregister int force;
  1220. X{
  1221. X    /* force == 0 occurs e.g. with sleep ray */
  1222. X    /* note that large force is usual with wands so that !! would
  1223. X        require information about hand/weapon/wand */
  1224. X    return( (force < 0) ? "?" : (force <= 4) ? "." : "!" );
  1225. X}
  1226. X
  1227. Xvoid
  1228. Xhit(str,mtmp,force)
  1229. Xregister char *str;
  1230. Xregister struct monst *mtmp;
  1231. Xregister char *force;        /* usually either "." or "!" */
  1232. X{
  1233. X    if(!cansee(mtmp->mx,mtmp->my) || !flags.verbose) pline("The %s hits it.", str);
  1234. X    else pline("The %s hits %s%s", str, mon_nam(mtmp), force);
  1235. X}
  1236. X
  1237. Xvoid
  1238. Xmiss(str,mtmp)
  1239. Xregister char *str;
  1240. Xregister struct monst *mtmp;
  1241. X{
  1242. X    pline("The %s misses %s.", str,
  1243. X          (cansee(mtmp->mx,mtmp->my) && flags.verbose) ? mon_nam(mtmp) : "it");
  1244. X}
  1245. X
  1246. X/* bhit: called when a weapon is thrown (sym = obj->olet) or when an
  1247. X   IMMEDIATE wand is zapped (sym = 0); the weapon falls down at end of
  1248. X   range or when a monster is hit; the monster is returned, and bhitpos
  1249. X   is set to the final position of the weapon thrown; the ray of a wand
  1250. X   may affect several objects and monsters on its path - for each of
  1251. X   these an argument function is called. */
  1252. X/* check !u.uswallow before calling bhit() */
  1253. X
  1254. Xstruct monst *
  1255. Xbhit(ddx,ddy,range,sym,fhitm,fhito,obj)
  1256. Xregister int ddx,ddy,range;        /* direction and range */
  1257. Xchar sym;                /* symbol displayed on path */
  1258. Xint (*fhitm)(), (*fhito)();        /* fns called when mon/obj hit */
  1259. Xstruct obj *obj;            /* 2nd arg to fhitm/fhito */
  1260. X{
  1261. X    register struct monst *mtmp;
  1262. X    register struct obj *otmp;
  1263. X    register int typ;
  1264. X
  1265. X    bhitpos.x = u.ux;
  1266. X    bhitpos.y = u.uy;
  1267. X
  1268. X    if(sym) {
  1269. X        tmp_at(-1, sym);    /* open call */
  1270. X        tmp_at(-3, (int)AT_OBJ);
  1271. X    }
  1272. X    while(range-- > 0) {
  1273. X        bhitpos.x += ddx;
  1274. X        bhitpos.y += ddy;
  1275. X        typ = levl[bhitpos.x][bhitpos.y].typ;
  1276. X#ifdef STRONGHOLD
  1277. X        if(IS_DRAWBRIDGE(typ))
  1278. X            switch (obj->otyp) {
  1279. X            case WAN_OPENING:
  1280. X# ifdef SPELLS
  1281. X            case SPE_KNOCK:
  1282. X# endif
  1283. X                (void) open_drawbridge(bhitpos.x,bhitpos.y);
  1284. X                break;
  1285. X            case WAN_LOCKING:
  1286. X# ifdef SPELLS
  1287. X            case SPE_WIZARD_LOCK:
  1288. X# endif
  1289. X                (void) close_drawbridge(bhitpos.x,bhitpos.y);
  1290. X            }
  1291. X#endif /* STRONGHOLD /**/
  1292. X        if(levl[bhitpos.x][bhitpos.y].mmask){
  1293. X            mtmp = m_at(bhitpos.x,bhitpos.y);
  1294. X            if(sym) {
  1295. X                tmp_at(-1, -1);    /* close call */
  1296. X                return(mtmp);
  1297. X            }
  1298. X            (*fhitm)(mtmp, obj);
  1299. X            range -= 3;
  1300. X        }
  1301. X        /* modified by GAN to hit all objects */
  1302. X        if(fhito && levl[bhitpos.x][bhitpos.y].omask){
  1303. X            int hitanything = 0;
  1304. X            otmp = fobj;
  1305. X            /* Fix for polymorph bug, Tim Wright */
  1306. X            while(otmp) { /* was a "for" loop.  */
  1307. X            register struct obj *next_obj;
  1308. X
  1309. X            next_obj = otmp->nobj;
  1310. X            if(otmp->ox == bhitpos.x && otmp->oy == bhitpos.y)
  1311. X                hitanything += (*fhito)(otmp, obj);
  1312. X            otmp = next_obj;
  1313. X            }
  1314. X            if(hitanything)    range--;
  1315. X        }
  1316. X        if(IS_DOOR(typ) || typ == SDOOR) {
  1317. X            switch (obj->otyp) {
  1318. X            case WAN_OPENING:
  1319. X            case WAN_LOCKING:
  1320. X#ifdef SPELLS
  1321. X            case SPE_KNOCK:
  1322. X            case SPE_WIZARD_LOCK:
  1323. X#endif
  1324. X                if (doorlock(obj,bhitpos.x,bhitpos.y))
  1325. X                    makeknown(obj->otyp);
  1326. X                break;
  1327. X            }
  1328. X        }
  1329. X        if(!ZAP_POS(typ) || (IS_DOOR(typ) &&
  1330. X           (levl[bhitpos.x][bhitpos.y].doormask & (D_LOCKED | D_CLOSED)))
  1331. X          ) {
  1332. X            bhitpos.x -= ddx;
  1333. X            bhitpos.y -= ddy;
  1334. X            break;
  1335. X        }
  1336. X        if(sym) tmp_at(bhitpos.x, bhitpos.y);
  1337. X#ifdef SINKS
  1338. X        if(sym && IS_SINK(typ))
  1339. X            break;    /* physical objects fall onto sink */
  1340. X#endif
  1341. X    }
  1342. X
  1343. X    /* leave last symbol unless in a pool */
  1344. X    if(sym)
  1345. X       tmp_at(-1, is_pool(bhitpos.x,bhitpos.y) ? -1 : 0);
  1346. X    return (struct monst *)0;
  1347. X}
  1348. X
  1349. Xstruct monst *
  1350. Xboomhit(dx, dy)
  1351. Xint dx, dy;
  1352. X{
  1353. X    register int i, ct;
  1354. X    char sym = ')';
  1355. X
  1356. X    bhitpos.x = u.ux;
  1357. X    bhitpos.y = u.uy;
  1358. X
  1359. X    for(i=0; i<8; i++) if(xdir[i] == dx && ydir[i] == dy) break;
  1360. X    tmp_at(-1, sym);    /* open call */
  1361. X    tmp_at(-3, (int)AT_OBJ);
  1362. X    for(ct=0; ct<10; ct++) {
  1363. X        if(i == 8) i = 0;
  1364. X        sym = ')' + '(' - sym;
  1365. X        tmp_at(-2, sym);    /* change let call */
  1366. X        dx = xdir[i];
  1367. X        dy = ydir[i];
  1368. X        bhitpos.x += dx;
  1369. X        bhitpos.y += dy;
  1370. X        if(levl[bhitpos.x][bhitpos.y].mmask){
  1371. X            tmp_at(-1,-1);
  1372. X            return(m_at(bhitpos.x,bhitpos.y));
  1373. X        }
  1374. X        if(!ZAP_POS(levl[bhitpos.x][bhitpos.y].typ)) {
  1375. X            bhitpos.x -= dx;
  1376. X            bhitpos.y -= dy;
  1377. X            break;
  1378. X        }
  1379. X        if(bhitpos.x == u.ux && bhitpos.y == u.uy) { /* ct == 9 */
  1380. X            if(rn2(20) >= ACURR(A_DEX)){ /* we hit ourselves */
  1381. X                (void) thitu(10, rnd(10), "boomerang");
  1382. X                break;
  1383. X            } else {    /* we catch it */
  1384. X                tmp_at(-1,-1);
  1385. X                pline("Skillfully, you catch the boomerang.");
  1386. X                return(&youmonst);
  1387. X            }
  1388. X        }
  1389. X        tmp_at(bhitpos.x, bhitpos.y);
  1390. X        if(ct % 5 != 0) i++;
  1391. X#ifdef SINKS
  1392. X        if(IS_SINK(levl[bhitpos.x][bhitpos.y].typ))
  1393. X            break;    /* boomerang falls on sink */
  1394. X#endif
  1395. X    }
  1396. X    tmp_at(-1, -1);    /* do not leave last symbol */
  1397. X    return (struct monst *)0;
  1398. X}
  1399. X
  1400. Xstatic uchar
  1401. Xdirlet(dx, dy)
  1402. Xregister int dx, dy;
  1403. X{
  1404. X    return
  1405. X        (dx == dy) ? LSLANT_SYM :
  1406. X        (dx && dy) ? RSLANT_SYM :
  1407. X        dx ? HBEAM_SYM : VBEAM_SYM;
  1408. X}
  1409. X
  1410. Xstatic int
  1411. Xzhit(mon, type, nd)            /* returns damage to mon */
  1412. Xregister struct monst *mon;
  1413. Xregister int type, nd;
  1414. X{
  1415. X    register int tmp = 0;
  1416. X    register int abstype = abs(type) % 10;
  1417. X
  1418. X    switch(abstype) {
  1419. X    case 0:            /* magic missile */
  1420. X        tmp = d(nd,6);
  1421. X        break;
  1422. X    case 1:            /* fire */
  1423. X        if(resists_fire(mon->data)) {
  1424. X            shieldeff(mon->mx, mon->my);
  1425. X            break;
  1426. X        }
  1427. X        tmp = d(nd,6);
  1428. X        if(resists_cold(mon->data)) tmp += 7;
  1429. X        break;
  1430. X    case 2:            /* sleep */
  1431. X        tmp = 0;
  1432. X        if(resists_sleep(mon->data) ||
  1433. X           resist(mon, (type == 2) ? WAND_SYM : '\0', 0, NOTELL))
  1434. X            shieldeff(mon->mx, mon->my);
  1435. X        else    mon->mfroz = 1;
  1436. X        break;
  1437. X    case 3:            /* cold */
  1438. X        if(resists_cold(mon->data)) {
  1439. X            shieldeff(mon->mx, mon->my);
  1440. X            break;
  1441. X        }
  1442. X        tmp = d(nd,6);
  1443. X        if(resists_fire(mon->data)) tmp += d(nd, 3);
  1444. X        break;
  1445. X    case 4:            /* death/disintegration */
  1446. X        if(abs(type) != 24) {    /* death */
  1447. X            if(is_undead(mon->data)) {
  1448. X            shieldeff(mon->mx, mon->my);
  1449. X            break;
  1450. X            }
  1451. X            type = 0; /* so they don't get saving throws */
  1452. X        }
  1453. X        tmp = mon->mhp+1;
  1454. X        break;
  1455. X    case 5:            /* lightning */
  1456. X        if(resists_elec(mon->data)) {
  1457. X            shieldeff(mon->mx, mon->my);
  1458. X            break;
  1459. X        }
  1460. X        tmp = d(nd,6);
  1461. X        {
  1462. X            register unsigned rnd_tmp = rnd(50);
  1463. X            mon->mcansee = 0;
  1464. X            if((mon->mblinded + rnd_tmp) > 127)
  1465. X                mon->mblinded = 127;
  1466. X            else mon->mblinded += rnd_tmp;
  1467. X        }
  1468. X        break;
  1469. X    case 6:            /* poison */
  1470. X        if(resists_poison(mon->data)) {
  1471. X            shieldeff(mon->mx, mon->my);
  1472. X            break;
  1473. X        }
  1474. X        tmp = d(nd,6);
  1475. X        break;
  1476. X    case 7:            /* acid */
  1477. X        if(resists_acid(mon->data)) {
  1478. X            shieldeff(mon->mx, mon->my);
  1479. X            break;
  1480. X        }
  1481. X        tmp = d(nd,6);
  1482. X        break;
  1483. X    }
  1484. X    if (type >= 0)
  1485. X        if (resist(mon, (type < 10) ? WAND_SYM : '\0', 0, NOTELL)) tmp /= 2;
  1486. X    mon->mhp -= tmp;
  1487. X    return(tmp);
  1488. X}
  1489. X
  1490. X/*
  1491. X * burn scrolls on floor at position x,y
  1492. X * return the number of scrolls burned
  1493. X */
  1494. Xstatic int
  1495. Xburn_floor_scrolls(x, y)
  1496. Xint x, y;
  1497. X{
  1498. X    register struct obj *obj, *obj2;
  1499. X    register int scrquan, i, cnt = 0;
  1500. X
  1501. X    if(levl[x][y].omask)
  1502. X    for(obj = fobj; obj; obj = obj2) {
  1503. X        obj2 = obj->nobj;
  1504. X        /* Bug fix - KAA */
  1505. X        if(obj->ox == x && obj->oy == y && obj->olet == SCROLL_SYM) {
  1506. X        scrquan = obj->quan;
  1507. X        for(i = 1; i <= scrquan ; i++)
  1508. X            if(!rn2(3))  {
  1509. X            cnt++;
  1510. X            if(in_shop(u.ux, u.uy))
  1511. X                addtobill(obj, FALSE);
  1512. X            useupf(obj);
  1513. X            }
  1514. X        }
  1515. X    }
  1516. X    return(cnt);
  1517. X}
  1518. X
  1519. X/* type == 0 to 9     : you shooting a wand */
  1520. X/* type == 10 to 19   : you casting a spell */
  1521. X/* type == 20 to 29   : you breathing as a monster */
  1522. X/* type == -10 to -19   : monster casting spell */
  1523. X/* type == -20 to -29 : monster breathing at you */
  1524. X/* called with dx = dy = 0 with vertical bolts */
  1525. Xvoid
  1526. Xbuzz(type,nd,sx,sy,dx,dy)
  1527. Xregister int type, nd;
  1528. Xregister xchar sx,sy;
  1529. Xregister int dx,dy;
  1530. X{
  1531. X    int abstype = abs(type) % 10;
  1532. X    register char *fltxt = fl[abs(type)];
  1533. X    struct rm *lev;
  1534. X    xchar range, olx, oly;
  1535. X    struct monst *mon;
  1536. X    register boolean bodyhit = FALSE;
  1537. X    register boolean shopdoor = FALSE;
  1538. X
  1539. X    if(u.uswallow) {
  1540. X        register int tmp;
  1541. X
  1542. X        if(type < 0) return;
  1543. X        tmp = zhit(u.ustuck, type, nd);
  1544. X        if(!u.ustuck)    u.uswallow = 0;
  1545. X        else    pline("The %s rips into %s%s",
  1546. X                fltxt, mon_nam(u.ustuck), exclam(tmp));
  1547. X        if (u.ustuck->mhp < 1)
  1548. X            killed(u.ustuck);
  1549. X        return;
  1550. X    }
  1551. X    if(type < 0) pru();
  1552. X    range = rn1(7,7);
  1553. X    Tmp_at2(-1, (int) dirlet(dx,dy));    /* open call */
  1554. X#ifdef MSDOSCOLOR
  1555. X    Tmp_at2(-3, (int)(abstype == 1 ? AT_RED :    /* fire */
  1556. X              abstype == 3 || abstype == 5 ? AT_WHITE :    /* cold/elec */
  1557. X              AT_ZAP);
  1558. X#endif
  1559. X    while(range-- > 0) {
  1560. X        sx += dx;
  1561. X        sy += dy;
  1562. X        if((lev = &levl[sx][sy])->typ) Tmp_at2(sx,sy);
  1563. X        else {
  1564. X            int bounce = 0;
  1565. X            if(cansee(sx-dx,sy-dy))
  1566. X                pline("The %s bounces!", fltxt);
  1567. X            if(ZAP_POS(levl[sx][sy-dy].typ))
  1568. X                bounce = 1;
  1569. X            if(ZAP_POS(levl[sx-dx][sy].typ)) {
  1570. X                if(!bounce || rn2(2)) bounce = 2;
  1571. X            }
  1572. X            switch(bounce){
  1573. X            case 0:
  1574. X                dx = -dx;
  1575. X                dy = -dy;
  1576. X                continue;
  1577. X            case 1:
  1578. X                dy = -dy;
  1579. X                sx -= dx;
  1580. X                break;
  1581. X            case 2:
  1582. X                dx = -dx;
  1583. X                sy -= dy;
  1584. X                break;
  1585. X            }
  1586. X            Tmp_at2(-2,(int) dirlet(dx,dy));
  1587. X            continue;
  1588. X        }
  1589. X        if(is_pool(sx,sy) && abstype == 1 /* fire */) {
  1590. X#ifdef STRONGHOLD
  1591. X            if(lev->typ != POOL) {    /* MOAT or DRAWBRIDGE_UP */
  1592. X                if(cansee(sx,sy))
  1593. X                pline("Some water evaporates.");
  1594. X                else if(flags.soundok)
  1595. X                You("hear a hissing sound.");
  1596. X            } else {
  1597. X#endif
  1598. X                register struct trap *ttmp;
  1599. X
  1600. X                range -= 3;
  1601. X                lev->typ = ROOM;
  1602. X                mnewsym(sx,sy);
  1603. X                if(cansee(sx,sy)) pline("The water evaporates.");
  1604. X                else if(flags.soundok)
  1605. X                You("hear a hissing sound.");
  1606. X                ttmp = maketrap(sx, sy, PIT);
  1607. X                ttmp->tseen = 1;
  1608. X#ifdef STRONGHOLD
  1609. X            }
  1610. X#endif
  1611. X        }
  1612. X        if(is_pool(sx,sy) && abstype == 3 /* cold */) {
  1613. X            boolean moat = (lev->typ != POOL);
  1614. X
  1615. X            range -= 3;
  1616. X#ifdef STRONGHOLD
  1617. X            if(lev->typ == DRAWBRIDGE_UP)
  1618. X                lev->drawbridgemask |= DB_FLOOR;
  1619. X            else
  1620. X#endif
  1621. X                lev->typ = ROOM;
  1622. X            mnewsym(sx,sy);
  1623. X            if(cansee(sx,sy)) {
  1624. X                if(moat)
  1625. X                    pline("The moat is bridged with ice!");
  1626. X                else     pline("The water freezes.");
  1627. X            } else if(flags.soundok)
  1628. X                You("hear a crackling sound.");
  1629. X        }
  1630. X        if(IS_DOOR(lev->typ) && (lev->doormask & (D_LOCKED | D_CLOSED))) {
  1631. X            range = 0;
  1632. X            switch(abstype) {
  1633. X            case 1:
  1634. X               lev->doormask = D_NODOOR;
  1635. X               if(cansee(sx,sy))
  1636. X                pline("The door is consumed in flames!");
  1637. X               else You("smell smoke.");
  1638. X               if(type >= 0 && in_shop(sx, sy)) {
  1639. X                shopdoor = TRUE;
  1640. X                olx = sx;
  1641. X                oly = sy;
  1642. X               }
  1643. X               break;
  1644. X            case 3:
  1645. X               lev->doormask = D_NODOOR;
  1646. X               if(cansee(sx,sy))
  1647. X                pline("The door freezes and shatters!");
  1648. X               else You("feel cold.");
  1649. X               if(type >= 0 && in_shop(sx, sy)) {
  1650. X                shopdoor = TRUE;
  1651. X                olx = sx;
  1652. X                oly = sy;
  1653. X               }
  1654. X               break;
  1655. X            case 4:
  1656. X               lev->doormask = D_NODOOR;
  1657. X               if(cansee(sx,sy))
  1658. X                pline("The door disintegrates!");
  1659. X               else if(flags.soundok)
  1660. X                You("hear a crashing sound.");
  1661. X               if(type >= 0 && in_shop(sx, sy)) {
  1662. X                shopdoor = TRUE;
  1663. X                olx = sx;
  1664. X                oly = sy;
  1665. X               }
  1666. X               break;
  1667. X            case 5:
  1668. X               lev->doormask = D_BROKEN;
  1669. X               if(cansee(sx,sy))
  1670. X                pline("The door splinters!");
  1671. X               else if(flags.soundok)
  1672. X                You("hear a crackling sound.");
  1673. X               if(type >= 0 && in_shop(sx, sy)) {
  1674. X                shopdoor = TRUE;
  1675. X                olx = sx;
  1676. X                oly = sy;
  1677. X               }
  1678. X               break;
  1679. X            default:
  1680. X               if(cansee(sx,sy)) {
  1681. X                   if (type >= 0 && type <= 9)
  1682. X                   pline("The door absorbs your bolt!");
  1683. X                   else if (type >= 10 && type <= 19)
  1684. X                   pline("The door absorbs your spell!");
  1685. X#ifdef POLYSELF
  1686. X                   else if (type >= 20 && type <= 29)
  1687. X                   pline("The door absorbs your blast!");
  1688. X#endif
  1689. X                   else if (type >= -19 && type <= -10)
  1690. X                   pline("The door absorbs the spell!");
  1691. X                   else
  1692. X                   pline("The door absorbs the blast!");
  1693. X               } else You("feel vibrations.");
  1694. X               break;
  1695. X            }
  1696. X        }
  1697. X        if(levl[sx][sy].omask && abstype == 1)
  1698. X            if(burn_floor_scrolls(sx,sy) && cansee(sx,sy))  {
  1699. X                mnewsym(sx,sy);
  1700. X                if(!Blind)
  1701. X                You("see a puff of smoke.");
  1702. X            }
  1703. X        if(levl[sx][sy].mmask){
  1704. X            mon = m_at(sx,sy);
  1705. X            /* Cannot use wakeup() which also angers the monster */
  1706. X            mon->msleep = 0;
  1707. X            if(mon->mimic) seemimic(mon);
  1708. X            if(type >= 0) {
  1709. X                setmangry(mon);
  1710. X#if defined(ALTARS) && defined(THEOLOGY)
  1711. X                if(mon->ispriest && in_temple(mon->mx, mon->my))
  1712. X                priesthit = TRUE;
  1713. X#endif
  1714. X            }
  1715. X            if(rnd(20) < 18 + mon->data->ac) {
  1716. X                register int tmp = zhit(mon, type, nd);
  1717. X                if(mon->mhp < 1) {
  1718. X                if(type < 0) {
  1719. X                    if(cansee(mon->mx,mon->my))
  1720. X                      pline("%s is killed by the %s!",
  1721. X                        Monnam(mon), fltxt);
  1722. X                    mondied(mon);
  1723. X                } else
  1724. X                    killed(mon);
  1725. X                 } else
  1726. X                hit(fltxt, mon, exclam(tmp));
  1727. X                range -= 2;
  1728. X            } else
  1729. X                miss(fltxt,mon);
  1730. X        } else if(sx == u.ux && sy == u.uy) {
  1731. X            nomul(0);
  1732. X            if(rnd(20) < 18+u.uac) {
  1733. X                register int dam = 0;
  1734. X                range -= 2;
  1735. X                pline("The %s hits you!",fltxt);
  1736. X                if (Reflecting) {
  1737. X                    if (!Blind) {
  1738. X                    if(Reflecting & WORN_AMUL)
  1739. X                        makeknown(AMULET_OF_REFLECTION);
  1740. X                    else
  1741. X                        makeknown(SHIELD_OF_REFLECTION);
  1742. X            pline("But it reflects from your %s!",
  1743. X                (Reflecting & W_AMUL) ? "amulet" : "shield");
  1744. X                    } else
  1745. X            pline("For some reason you are not affected!");
  1746. X                    if (dx) dx = -dx;
  1747. X                    if (dy) dy = -dy;
  1748. X                    shieldeff(sx, sy);
  1749. X                }
  1750. X                else switch(abstype) {
  1751. X                case 0:        /* magic missile */
  1752. X                    if(Antimagic) {
  1753. X                    shieldeff(sx, sy);
  1754. X                    pline("The missiles bounce off!");
  1755. X                    } else dam = d(nd,6);
  1756. X                    break;
  1757. X                case 1:        /* fire */
  1758. X                    if(Fire_resistance) {
  1759. X                    shieldeff(sx, sy);
  1760. X                    You("don't feel hot!");
  1761. X#ifdef POLYSELF
  1762. X#ifdef GOLEMS
  1763. X                    ugolemeffects(AD_FIRE, d(nd, 6));
  1764. X#endif /* GOLEMS */
  1765. X#endif
  1766. X                    } else dam = d(nd, 6);
  1767. X                    while (1) {
  1768. X                    switch(rn2(5)) {
  1769. X                    case 0:
  1770. X        if (!rust_dmg(uarmh, "leather helmet", 0, FALSE)) continue;
  1771. X                        break;
  1772. X                    case 1:
  1773. X                        bodyhit = TRUE;
  1774. X                        if (uarmc) break;
  1775. X        (void)(rust_dmg(uarm, "leather armor", 0, FALSE));
  1776. X                        break;
  1777. X                    case 2:
  1778. X        if (!rust_dmg(uarms, "wooden shield", 0, FALSE)) continue;
  1779. X                        break;
  1780. X                    case 3:
  1781. X        if (!rust_dmg(uarmg, "gloves", 0, FALSE)) continue;
  1782. X                        break;
  1783. X                    case 4:
  1784. X        if (!rust_dmg(uarmf, "boots", 0, FALSE)) continue;
  1785. X                        break;
  1786. X                    }
  1787. X                    break; /* Out of while loop */
  1788. X                        }
  1789. X                    if(!rn2(3) && bodyhit)
  1790. X                    destroy_item(POTION_SYM, AD_FIRE);
  1791. X                    if(!rn2(3) && bodyhit)
  1792. X                    destroy_item(SCROLL_SYM, AD_FIRE);
  1793. X#ifdef SPELLS
  1794. X                    if(!rn2(5) && bodyhit)
  1795. X                    destroy_item(SPBOOK_SYM, AD_FIRE);
  1796. X#endif
  1797. X                    break;
  1798. X                case 2:        /* sleep */
  1799. X                    if(Sleep_resistance) {
  1800. X                    shieldeff(u.ux, u.uy);
  1801. X                    You("don't feel sleepy.");
  1802. X                    } else nomul(-d(nd,25)); /* sleep ray */
  1803. X                    break;
  1804. X                case 3:        /* cold */
  1805. X                    if(Cold_resistance) {
  1806. X                    shieldeff(sx, sy);
  1807. X                    You("don't feel cold.");
  1808. X#ifdef POLYSELF
  1809. X#ifdef GOLEMS
  1810. X                    ugolemeffects(AD_COLD, d(nd, 6));
  1811. X#endif /* GOLEMS */
  1812. X#endif
  1813. X                    } else
  1814. X                    dam = d(nd, 6);
  1815. X                    if(!rn2(3))
  1816. X                    destroy_item(POTION_SYM, AD_COLD);
  1817. X                    break;
  1818. X                case 4:        /* death */
  1819. X                    if(type == -24) { /* disintegration */
  1820. X                    if(uarms) {
  1821. X                        (void) destroy_arm(uarms);
  1822. X                    } else if (uarm) {
  1823. X                if (Disint_resistance & WORN_ARMOR)
  1824. X                    Your("armor absorbs the blast!");
  1825. X                else (void) destroy_arm(uarm);
  1826. X                    }
  1827. X                    break;
  1828. X                    }
  1829. X#ifdef POLYSELF
  1830. X                    else if(is_undead(uasmon)) {
  1831. X                    shieldeff(sx, sy);
  1832. X                    You("seem unaffected.");
  1833. X                    break;
  1834. X                    }
  1835. X#endif
  1836. X                    u.uhp = -1;
  1837. X                    break;
  1838. X                case 5:        /* lightning */
  1839. X                    if (Shock_resistance) {
  1840. X                    shieldeff(sx, sy);
  1841. X                    You("aren't affected.");
  1842. X#ifdef POLYSELF
  1843. X#ifdef GOLEMS
  1844. X                    ugolemeffects(AD_ELEC, d(nd, 6));
  1845. X#endif /* GOLEMS */
  1846. X#endif
  1847. X                    } else
  1848. X                    dam = d(nd, 6);
  1849. X                    break;
  1850. X                case 6:        /* poison */
  1851. X                    poisoned("blast", A_DEX, "poisoned blast");
  1852. X                    break;
  1853. X                case 7:        /* acid */
  1854. X                    pline("The acid burns!");
  1855. X                    dam = d(nd,6);
  1856. X                    if(!rn2(6)) corrode_weapon();
  1857. X                    if(!rn2(6)) corrode_armor();
  1858. X                    break;
  1859. X                }
  1860. X                losehp(dam,fltxt);
  1861. X            } else pline("The %s whizzes by you!",fltxt);
  1862. X            if (abstype == 5 && !Blind) { /* LIGHTNING */
  1863. X                    You("are blinded by the flash!");
  1864. X                make_blinded((long)d(nd,50),FALSE);
  1865. X                seeoff(0);
  1866. X            }
  1867. X            stop_occupation();
  1868. X        }
  1869. X        if(!ZAP_POS(lev->typ)) {
  1870. X            int bounce = 0, rmn;
  1871. X            if(cansee(sx,sy)) pline("The %s bounces!", fltxt);
  1872. X            range--;
  1873. X            if(!dx || !dy || !rn2(20)){
  1874. X                dx = -dx;
  1875. X                dy = -dy;
  1876. X            } else {
  1877. X              if(ZAP_POS(rmn = levl[sx][sy-dy].typ) &&
  1878. X                (IS_ROOM(rmn) || ZAP_POS(levl[sx+dx][sy-dy].typ)))
  1879. X                bounce = 1;
  1880. X              if(ZAP_POS(rmn = levl[sx-dx][sy].typ) &&
  1881. X                (IS_ROOM(rmn) || ZAP_POS(levl[sx-dx][sy+dy].typ)))
  1882. X                if(!bounce || rn2(2))
  1883. X                    bounce = 2;
  1884. X
  1885. X              switch(bounce){
  1886. X              case 0:
  1887. X                dy = -dy;
  1888. X                dx = -dx;
  1889. X                break;
  1890. X              case 1:
  1891. X                dy = -dy;
  1892. X                break;
  1893. X              case 2:
  1894. X                dx = -dx;
  1895. X                break;
  1896. X              }
  1897. X              Tmp_at2(-2, (int) dirlet(dx,dy));
  1898. X            }
  1899. X        }
  1900. X    }
  1901. X    Tmp_at2(-1,-1);
  1902. X    if(shopdoor && !in_shop(u.ux, u.uy))
  1903. X        pay_for_door(olx, oly, abstype == 1 ? "burn away" :
  1904. X                       abstype == 3 ? "shatter" :
  1905. X                       abstype == 4 ? "disintegrate" :
  1906. X                       "destroy");
  1907. X}
  1908. X
  1909. Xvoid
  1910. Xrloco(obj)
  1911. Xregister struct obj *obj;
  1912. X{
  1913. X    register int tx, ty, otx, oty;
  1914. X
  1915. X    otx = obj->ox;
  1916. X    oty = obj->oy;
  1917. X    do {
  1918. X        tx = rn1(COLNO-3,2);
  1919. X        ty = rn2(ROWNO);
  1920. X    } while(!goodpos(tx,ty));
  1921. X    obj->ox = tx;
  1922. X    obj->oy = ty;
  1923. X    set_omask(otx,oty);
  1924. X    if(cansee(otx,oty))
  1925. X        newsym(otx,oty);
  1926. X    levl[tx][ty].omask = 1;
  1927. X    if(cansee(tx,ty))
  1928. X        newsym(tx,ty);
  1929. X}
  1930. X
  1931. Xvoid
  1932. Xfracture_rock(obj)    /* fractured by pick-axe or wand of striking */
  1933. Xregister struct obj *obj;           /* no texts here! */
  1934. X{
  1935. X    /* unpobj(obj); */
  1936. X    obj->otyp = ROCK;
  1937. X    obj->blessed = FALSE;
  1938. X    obj->quan = 7 + rn2(60);
  1939. X    obj->owt = weight(obj);
  1940. X    obj->olet = GEM_SYM;
  1941. X    obj->known = FALSE;
  1942. X    if(cansee(obj->ox,obj->oy))
  1943. X        prl(obj->ox,obj->oy);
  1944. X}
  1945. X
  1946. Xboolean
  1947. Xbreak_statue(obj)
  1948. Xregister struct obj *obj;
  1949. X{
  1950. X    struct trap *trap;
  1951. X
  1952. X    if(trap = t_at(obj->ox,obj->oy))
  1953. X        if(obj->corpsenm == trap->pm)
  1954. X        if(makemon(&mons[trap->pm], obj->ox, obj->oy)) {
  1955. X            pline("Instead of shattering, the statue suddenly comes alive!");
  1956. X            delobj(obj);
  1957. X            deltrap(trap);
  1958. X            return FALSE;
  1959. X        }
  1960. X    if (obj->spe) {
  1961. X        struct obj *magazine;
  1962. X#ifdef SPELLS
  1963. X        magazine = mkobj_at(SPBOOK_SYM, obj->ox, obj->oy);
  1964. X#else
  1965. X        magazine = mkobj_at(SCROLL_SYM, obj->ox, obj->oy);
  1966. X#endif
  1967. X        magazine->blessed = obj->blessed;
  1968. X        magazine->cursed = obj->cursed;
  1969. X    }
  1970. X    fracture_rock(obj);
  1971. X    return TRUE;
  1972. X}
  1973. X
  1974. Xconst char *destroy_strings[] = {
  1975. X    "freezes and shatters", "freeze and shatter", "shattered potion",
  1976. X    "boils and explodes", "boil and explode", "boiling potion",
  1977. X    "catches fire and burns", "catch fire and burn", "burning scroll",
  1978. X    "catches fire and burns", "catch fire and burn", "burning book",
  1979. X    "turns to dust and vanishes", "turn to dust and vanish", "",
  1980. X    "breaks apart and explodes", "break apart and explode", "exploding wand"
  1981. X};
  1982. X
  1983. Xvoid
  1984. Xdestroy_item(osym, dmgtyp)
  1985. Xregister int osym, dmgtyp;
  1986. X{
  1987. X    register struct obj *obj, *obj2;
  1988. X    register int quan, i, cnt, dmg, xresist, skip;
  1989. X    register int dindx;
  1990. X    char *mult;
  1991. X
  1992. X    for(obj = invent; obj; obj = obj2) {
  1993. X
  1994. X        obj2 = obj->nobj;
  1995. X        if(obj->olet != osym) continue; /* test only objs of type osym */
  1996. X        xresist = skip = 0;
  1997. X
  1998. X        switch(dmgtyp) {
  1999. X        case AD_COLD:
  2000. X            if(osym == POTION_SYM) {
  2001. X            quan = obj->quan;
  2002. X            dindx = 0;
  2003. X            dmg = rnd(4);
  2004. X            } else skip++;
  2005. X                break;
  2006. X        case AD_FIRE:
  2007. X            xresist = (Fire_resistance && obj->olet != POTION_SYM);
  2008. X
  2009. X            /* Let's say scrolls of fire are fire resistant */
  2010. X
  2011. X            if (obj->otyp == SCR_FIRE)
  2012. X              skip++;
  2013. X            quan = obj->quan;
  2014. X            switch(osym) {
  2015. X            case POTION_SYM:
  2016. X                dindx = 1;
  2017. X                dmg = rnd(6);
  2018. X                break;
  2019. X            case SCROLL_SYM:
  2020. X                dindx = 2;
  2021. X                dmg = 1;
  2022. X                break;
  2023. X#ifdef SPELLS
  2024. X            case SPBOOK_SYM:
  2025. X                dindx = 3;
  2026. X                dmg = 1;
  2027. X                break;
  2028. X#endif
  2029. X            default:
  2030. X                skip++;
  2031. X                break;
  2032. X            }
  2033. X            break;
  2034. X        case AD_ELEC:
  2035. X            xresist = (Shock_resistance && obj->olet != RING_SYM);
  2036. X            quan = obj->quan;
  2037. X            switch(osym) {
  2038. X            case RING_SYM:
  2039. X                if(obj->otyp == RIN_SHOCK_RESISTANCE)
  2040. X                    { skip++; break; }
  2041. X                dindx = 4;
  2042. X                dmg = 0;
  2043. X                break;
  2044. X            case WAND_SYM:
  2045. X                if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
  2046. X                dindx = 5;
  2047. X                dmg = rnd(10);
  2048. X                break;
  2049. X            default:
  2050. X                skip++;
  2051. X                break;
  2052. X            }
  2053. X            break;
  2054. X        default:
  2055. X            skip++;
  2056. X            break;
  2057. X        }
  2058. X        if(!skip) {
  2059. X        for(i = cnt = 0; i < quan; i++)
  2060. X            if(!rn2(3)) cnt++;
  2061. X
  2062. X        if(!cnt) continue;
  2063. X        if(cnt == quan)    mult = "Your";
  2064. X        else    mult = (cnt == 1) ? "One of your" : "Some of your";
  2065. X        pline("%s %s %s!", mult, xname(obj),
  2066. X            (cnt > 1) ? destroy_strings[dindx*3 + 1]
  2067. X                  : destroy_strings[dindx*3]);
  2068. X        if(osym == POTION_SYM && dmgtyp != AD_COLD)
  2069. X            potionbreathe(obj);
  2070. X        for(i = 0; i < cnt; i++) useup(obj);
  2071. X        if(dmg) {
  2072. X            if(xresist)    You("aren't hurt!");
  2073. X            else    losehp(dmg, destroy_strings[dindx*3 + 2]);
  2074. X        }
  2075. X        }
  2076. X    }
  2077. X    return;
  2078. X}
  2079. X
  2080. Xint
  2081. Xdestroy_mitem(mtmp, osym, dmgtyp)
  2082. Xregister struct monst *mtmp;
  2083. Xregister int osym, dmgtyp;
  2084. X{
  2085. X    register struct obj *obj, *obj2;
  2086. X    register int quan, i, cnt, skip, tmp = 0;
  2087. X    register int dindx;
  2088. X
  2089. X    for(obj = mtmp->minvent; obj; obj = obj2) {
  2090. X
  2091. X        obj2 = obj->nobj;
  2092. X        if(obj->olet != osym) continue; /* test only objs of type osym */
  2093. X        skip = 0;
  2094. X
  2095. X        switch(dmgtyp) {
  2096. X        case AD_COLD:
  2097. X            if(osym == POTION_SYM) {
  2098. X            quan = obj->quan;
  2099. X            dindx = 0;
  2100. X            tmp++;
  2101. X            } else skip++;
  2102. X                break;
  2103. X        case AD_FIRE:
  2104. X            /* Let's say scrolls of fire are fire resistant */
  2105. X
  2106. X            if (obj->otyp == SCR_FIRE)
  2107. X              skip++;
  2108. X            quan = obj->quan;
  2109. X            switch(osym) {
  2110. X            case POTION_SYM:
  2111. X                dindx = 1;
  2112. X                tmp++;
  2113. X                break;
  2114. X            case SCROLL_SYM:
  2115. X                dindx = 2;
  2116. X                tmp++;
  2117. X                break;
  2118. X#ifdef SPELLS
  2119. X            case SPBOOK_SYM:
  2120. X                dindx = 3;
  2121. X                tmp++;
  2122. X                break;
  2123. X#endif
  2124. X            default:
  2125. X                skip++;
  2126. X                break;
  2127. X            }
  2128. X            break;
  2129. X        case AD_ELEC:
  2130. X            quan = obj->quan;
  2131. X            switch(osym) {
  2132. X            case RING_SYM:
  2133. X                if(obj->otyp == RIN_SHOCK_RESISTANCE)
  2134. X                    { skip++; break; }
  2135. X                dindx = 4;
  2136. X                break;
  2137. X            case WAND_SYM:
  2138. X                if(obj->otyp == WAN_LIGHTNING) { skip++; break; }
  2139. X                dindx = 5;
  2140. X                tmp++;
  2141. X                break;
  2142. X            default:
  2143. X                skip++;
  2144. X                break;
  2145. X            }
  2146. X            break;
  2147. X        default:
  2148. X            skip++;
  2149. X            break;
  2150. X        }
  2151. X        if(!skip) {
  2152. X        for(i = cnt = 0; i < quan; i++)
  2153. X            if(!rn2(3)) cnt++;
  2154. X
  2155. X        if(!cnt) continue;
  2156. X        pline("%s's %s %s!", Monnam(mtmp), xname(obj),
  2157. X            (cnt > 1) ? destroy_strings[dindx*3 + 1]
  2158. X                  : destroy_strings[dindx*3]);
  2159. X        for(i = 0; i < cnt; i++) m_useup(mtmp, obj);
  2160. X        }
  2161. X    }
  2162. X    return(tmp);
  2163. X}
  2164. X
  2165. X/*ARGSUSED*/
  2166. Xint
  2167. Xresist(mtmp, olet, damage, tell)
  2168. Xregister struct monst    *mtmp;
  2169. Xregister char    olet;
  2170. Xregister int    damage, tell;
  2171. X{
  2172. X    register int    resisted = 0;
  2173. X#ifdef HARD
  2174. X    register int    level;
  2175. X
  2176. X    switch(olet)  {
  2177. X
  2178. X        case WAND_SYM:
  2179. X            level = 8;
  2180. X            break;
  2181. X
  2182. X        case SCROLL_SYM:
  2183. X            level = 6;
  2184. X            break;
  2185. X
  2186. X        case POTION_SYM:
  2187. X            level = 5;
  2188. X            break;
  2189. X
  2190. X        default:    level = u.ulevel;
  2191. X            break;
  2192. X    }
  2193. X
  2194. X    resisted = (rn2(100) - mtmp->m_lev + level) < mtmp->data->mr;
  2195. X    if(resisted) {
  2196. X
  2197. X        if(tell) {
  2198. X            shieldeff(mtmp->mx, mtmp->my);
  2199. X            pline("%s resists!", canseemon(mtmp) ? Monnam(mtmp) : "It");
  2200. X        }
  2201. X        mtmp->mhp -= damage/2;
  2202. X    } else
  2203. X#endif
  2204. X        mtmp->mhp -= damage;
  2205. X
  2206. X    if(mtmp->mhp < 1) killed(mtmp);
  2207. X    return(resisted);
  2208. X}
  2209. X
  2210. Xvoid
  2211. Xmakewish()
  2212. X{
  2213. X    char buf[BUFSZ];
  2214. X    register struct obj *otmp;
  2215. X    int wishquan, mergquan;
  2216. X    register boolean dropit = (inv_cnt() >= 52);
  2217. X    int tries = 0;
  2218. X
  2219. Xretry:
  2220. X    You("may wish for an object.  What do you want? ");
  2221. X    getlin(buf);
  2222. X    if(buf[0] == '\033') buf[0] = 0;
  2223. X/* Note: if they wished for and got a non-object successfully, such as gold,
  2224. X * otmp = &zeroobj
  2225. X */
  2226. X    otmp = readobjnam(buf);
  2227. X    if (!otmp) {
  2228. X        pline("Nothing fitting that description exists in the game.");
  2229. X        if (++tries < 5) goto retry;
  2230. X        pline(thats_enough_tries);
  2231. X        if (!(otmp = readobjnam((char *)0)))
  2232. X        return; /* for safety; should never happen */
  2233. X    }
  2234. X    if (otmp != &zeroobj) {
  2235. X        if(dropit) {
  2236. X        pline("Oops!  The %s drop%s to the floor!", xname(otmp),
  2237. X            otmp->quan > 1 ? "" : "s");
  2238. X        dropy(otmp);
  2239. X        } else {
  2240. X            wishquan = otmp->quan;
  2241. X            otmp = addinv(otmp);
  2242. X            mergquan = otmp->quan;
  2243. X            otmp->quan = wishquan; /* to fool prinv() */
  2244. X            prinv(otmp);
  2245. X            otmp->quan = mergquan;
  2246. X        }
  2247. X#ifdef WIZARD
  2248. X     if (!wizard)
  2249. X#endif
  2250. X        if(otmp->otyp == WAN_WISHING) otmp->recharged = 1;
  2251. X
  2252. X#ifdef THEOLOGY
  2253. X        u.ublesscnt += rn1(100,50);  /* the gods take notice */
  2254. X#endif
  2255. X    }
  2256. X}
  2257. END_OF_FILE
  2258. if test 44087 -ne `wc -c <'src/zap.c'`; then
  2259.     echo shar: \"'src/zap.c'\" unpacked with wrong size!
  2260. fi
  2261. # end of 'src/zap.c'
  2262. fi
  2263. echo shar: End of archive 2 \(of 38\).
  2264. cp /dev/null ark2isdone
  2265. MISSING=""
  2266. 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
  2267.     if test ! -f ark${I}isdone ; then
  2268.     MISSING="${MISSING} ${I}"
  2269.     fi
  2270. done
  2271. if test "${MISSING}" = "" ; then
  2272.     echo You have unpacked all 38 archives.
  2273.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2274. else
  2275.     echo You still need to unpack the following archives:
  2276.     echo "        " ${MISSING}
  2277. fi
  2278. ##  End of shell archive.
  2279. exit 0
  2280.