home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part41 < prev    next >
Encoding:
Internet Message Format  |  1993-01-31  |  57.2 KB

  1. Path: uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i049:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part41/108
  5. Message-ID: <4343@master.CNA.TEK.COM>
  6. Date: 30 Jan 93 01:12:57 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2314
  9. Approved: billr@saab.CNA.TEK.COM
  10. Xref: uunet comp.sources.games:1598
  11.  
  12. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  13. Posting-number: Volume 16, Issue 49
  14. Archive-name: nethack31/Part41
  15. Supersedes: nethack3p9: Volume 10, Issue 46-102
  16. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  17.  
  18.  
  19.  
  20. #! /bin/sh
  21. # This is a shell archive.  Remove anything before this line, then unpack
  22. # it by saving it into a file and typing "sh file".  To overwrite existing
  23. # files, type "sh file -c".  You can also feed this as standard input via
  24. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  25. # will see the following message at the end:
  26. #        "End of archive 41 (of 108)."
  27. # Contents:  src/do_wear.c src/spell.c
  28. # Wrapped by billr@saab on Fri Jan 29 17:06:47 1993
  29. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  30. if test -f 'src/do_wear.c' -a "${1}" != "-c" ; then 
  31.   echo shar: Will not clobber existing file \"'src/do_wear.c'\"
  32. else
  33. echo shar: Extracting \"'src/do_wear.c'\" \(37991 characters\)
  34. sed "s/^X//" >'src/do_wear.c' <<'END_OF_FILE'
  35. X/*    SCCS Id: @(#)do_wear.c    3.1    92/12/13    */
  36. X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  37. X/* NetHack may be freely redistributed.  See license for details. */
  38. X
  39. X#include "hack.h"
  40. X
  41. X#ifdef OVLB
  42. X
  43. Xstatic int NEARDATA todelay;
  44. X
  45. X#endif /*OVLB */
  46. X
  47. X#ifndef OVLB
  48. X
  49. XSTATIC_DCL long takeoff_mask, taking_off;
  50. X
  51. X#else /* OVLB */
  52. X
  53. XSTATIC_OVL long NEARDATA takeoff_mask = 0L, NEARDATA taking_off = 0L;
  54. X
  55. Xstatic const long NEARDATA takeoff_order[] = { WORN_BLINDF, 1L, /* weapon */
  56. X    WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK,
  57. X    WORN_HELMET, WORN_AMUL, WORN_ARMOR,
  58. X#ifdef TOURIST
  59. X    WORN_SHIRT,
  60. X#endif
  61. X    WORN_BOOTS, 0L };
  62. X
  63. Xstatic void FDECL(on_msg, (struct obj *));
  64. XSTATIC_PTR int NDECL(Armor_on);
  65. XSTATIC_PTR int NDECL(Boots_on);
  66. Xstatic int NDECL(Cloak_on);
  67. XSTATIC_PTR int NDECL(Helmet_on);
  68. XSTATIC_PTR int NDECL(Gloves_on);
  69. Xstatic void NDECL(Amulet_on);
  70. Xstatic void FDECL(Ring_off_or_gone, (struct obj *, BOOLEAN_P));
  71. XSTATIC_PTR int FDECL(select_off, (struct obj *));
  72. Xstatic struct obj *NDECL(do_takeoff);
  73. XSTATIC_PTR int NDECL(take_off);
  74. Xstatic void FDECL(already_wearing, (const char*));
  75. X
  76. Xvoid
  77. Xoff_msg(otmp) register struct obj *otmp; {
  78. X    if(flags.verbose)
  79. X        You("were wearing %s.", doname(otmp));
  80. X}
  81. X
  82. X/* for items that involve no delay */
  83. Xstatic void
  84. Xon_msg(otmp)
  85. Xregister struct obj *otmp;
  86. X{
  87. X    if(flags.verbose)
  88. X        You("are now wearing %s.",
  89. X        obj_is_pname(otmp) ? the(xname(otmp)) : an(xname(otmp)));
  90. X}
  91. X
  92. X#endif /* OVLB */
  93. X#ifdef OVL2
  94. X
  95. Xboolean
  96. Xis_boots(otmp) register struct obj *otmp; {
  97. X    return(otmp->otyp >= LOW_BOOTS &&
  98. X        otmp->otyp <= LEVITATION_BOOTS);
  99. X}
  100. X
  101. Xboolean
  102. Xis_helmet(otmp) register struct obj *otmp; {
  103. X    return(otmp->otyp >= ELVEN_LEATHER_HELM &&
  104. X        otmp->otyp <= HELM_OF_TELEPATHY);
  105. X}
  106. X
  107. X#endif /* OVLB */
  108. X#ifdef OVL2
  109. X
  110. Xboolean
  111. Xis_gloves(otmp) register struct obj *otmp; {
  112. X    return(otmp->otyp >= LEATHER_GLOVES &&
  113. X        otmp->otyp <= GAUNTLETS_OF_DEXTERITY);
  114. X}
  115. X
  116. X#endif /* OVL2 */
  117. X#ifdef OVLB
  118. X
  119. Xboolean
  120. Xis_cloak(otmp) register struct obj *otmp; {
  121. X    return(otmp->otyp >= MUMMY_WRAPPING &&
  122. X        otmp->otyp <= CLOAK_OF_DISPLACEMENT);
  123. X}
  124. X
  125. Xboolean
  126. Xis_shield(otmp) register struct obj *otmp; {
  127. X    return(otmp->otyp >= SMALL_SHIELD &&
  128. X        otmp->otyp <= SHIELD_OF_REFLECTION);
  129. X}
  130. X
  131. X/*
  132. X * The Type_on() functions should be called *after* setworn().
  133. X * The Type_off() functions call setworn() themselves.
  134. X */
  135. X
  136. XSTATIC_PTR
  137. Xint
  138. XBoots_on() {
  139. X    long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~WORN_BOOTS;
  140. X
  141. X    switch(uarmf->otyp) {
  142. X    case LOW_BOOTS:
  143. X    case IRON_SHOES:
  144. X    case HIGH_BOOTS:
  145. X    case JUMPING_BOOTS:
  146. X        break;
  147. X    case WATER_WALKING_BOOTS:
  148. X        if (u.uinwater) spoteffects();
  149. X        break;
  150. X    case SPEED_BOOTS:
  151. X        /* Speed boots are still better than intrinsic speed, */
  152. X        /* though not better than potion speed */
  153. X        if (!(oldprop & TIMEOUT)) {
  154. X            makeknown(uarmf->otyp);
  155. X            You("feel yourself speed up%s.",
  156. X                oldprop ? " a bit more" : "");
  157. X        }
  158. X        break;
  159. X    case ELVEN_BOOTS:
  160. X        if (!oldprop) {
  161. X            makeknown(uarmf->otyp);
  162. X            You("walk very quietly.");
  163. X        }
  164. X        break;
  165. X    case FUMBLE_BOOTS:
  166. X        if (!(oldprop & ~TIMEOUT))
  167. X            Fumbling += rnd(20);
  168. X        break;
  169. X    case LEVITATION_BOOTS:
  170. X        if (!oldprop) {
  171. X            makeknown(uarmf->otyp);
  172. X            float_up();
  173. X        }
  174. X        break;
  175. X    default: impossible("Unknown type of boots (%d)", uarmf->otyp);
  176. X    }
  177. X    return 0;
  178. X}
  179. X
  180. Xint
  181. XBoots_off() {
  182. X    register struct obj *obj = uarmf;
  183. X    /* For levitation, float_down() returns if Levitation, so we
  184. X     * must do a setworn() _before_ the levitation case.
  185. X     */
  186. X    long oldprop = u.uprops[objects[uarmf->otyp].oc_oprop].p_flgs & ~WORN_BOOTS;
  187. X
  188. X    setworn((struct obj *)0, W_ARMF);
  189. X    switch(obj->otyp) {
  190. X    case SPEED_BOOTS:
  191. X        if (!(oldprop & TIMEOUT)) {
  192. X            makeknown(obj->otyp);
  193. X            You("feel yourself slow down%s.",
  194. X                oldprop ? " a bit" : "");
  195. X        }
  196. X        break;
  197. X    case WATER_WALKING_BOOTS:
  198. X        if(is_pool(u.ux,u.uy) && !Levitation
  199. X#ifdef POLYSELF
  200. X            && !is_flyer(uasmon) && !is_clinger(uasmon)
  201. X#endif
  202. X            ) {
  203. X            makeknown(obj->otyp);
  204. X            /* make boots known in case you survive the drowning */
  205. X            spoteffects();
  206. X        }
  207. X        break;
  208. X    case ELVEN_BOOTS:
  209. X        if (!oldprop) {
  210. X            makeknown(obj->otyp);
  211. X            You("sure are noisy.");
  212. X        }
  213. X        break;
  214. X    case FUMBLE_BOOTS:
  215. X        if (!(oldprop & ~TIMEOUT))
  216. X            Fumbling = 0;
  217. X        break;
  218. X    case LEVITATION_BOOTS:
  219. X        if (!oldprop) {
  220. X            (void) float_down();
  221. X            makeknown(obj->otyp);
  222. X        }
  223. X        break;
  224. X    case LOW_BOOTS:
  225. X    case IRON_SHOES:
  226. X    case HIGH_BOOTS:
  227. X    case JUMPING_BOOTS:
  228. X        break;
  229. X    default: impossible("Unknown type of boots (%d)", obj->otyp);
  230. X    }
  231. X    return 0;
  232. X}
  233. X
  234. Xstatic int
  235. XCloak_on() {
  236. X    long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].p_flgs & ~WORN_CLOAK;
  237. X
  238. X    switch(uarmc->otyp) {
  239. X    case ELVEN_CLOAK:
  240. X    case CLOAK_OF_PROTECTION:
  241. X    case CLOAK_OF_DISPLACEMENT:
  242. X        makeknown(uarmc->otyp);
  243. X        break;
  244. X    case MUMMY_WRAPPING:
  245. X    case ORCISH_CLOAK:
  246. X    case DWARVISH_CLOAK:
  247. X    case CLOAK_OF_MAGIC_RESISTANCE:
  248. X        break;
  249. X    case CLOAK_OF_INVISIBILITY:
  250. X        if (!oldprop && !See_invisible && !Blind) {
  251. X            makeknown(uarmc->otyp);
  252. X            newsym(u.ux,u.uy);
  253. X            pline("Suddenly you cannot see yourself.");
  254. X        }
  255. X        break;
  256. X    case OILSKIN_CLOAK:
  257. X        pline("The %s fits very tightly.",xname(uarmc));
  258. X        break;
  259. X    default: impossible("Unknown type of cloak (%d)", uarmc->otyp);
  260. X    }
  261. X    return 0;
  262. X}
  263. X
  264. Xint
  265. XCloak_off() {
  266. X    long oldprop = u.uprops[objects[uarmc->otyp].oc_oprop].p_flgs & ~WORN_CLOAK;
  267. X
  268. X    switch(uarmc->otyp) {
  269. X    case MUMMY_WRAPPING:
  270. X    case ELVEN_CLOAK:
  271. X    case ORCISH_CLOAK:
  272. X    case DWARVISH_CLOAK:
  273. X    case CLOAK_OF_PROTECTION:
  274. X    case CLOAK_OF_MAGIC_RESISTANCE:
  275. X    case CLOAK_OF_DISPLACEMENT:
  276. X    case OILSKIN_CLOAK:
  277. X        break;
  278. X    case CLOAK_OF_INVISIBILITY:
  279. X        if (!oldprop && !See_invisible && !Blind) {
  280. X            makeknown(uarmc->otyp);
  281. X            setworn((struct obj *)0, W_ARMC);
  282. X            newsym(u.ux,u.uy);
  283. X            pline("Suddenly you can see yourself.");
  284. X            return 0;
  285. X        }
  286. X        break;
  287. X    default: impossible("Unknown type of cloak (%d)", uarmc->otyp);
  288. X    }
  289. X    setworn((struct obj *)0, W_ARMC);
  290. X    return 0;
  291. X}
  292. X
  293. XSTATIC_PTR
  294. Xint
  295. XHelmet_on()
  296. X{
  297. X    switch(uarmh->otyp) {
  298. X    case FEDORA:
  299. X    case HELMET:
  300. X    case DENTED_POT:
  301. X    case ELVEN_LEATHER_HELM:
  302. X    case DWARVISH_IRON_HELM:
  303. X    case ORCISH_HELM:
  304. X    case HELM_OF_TELEPATHY:
  305. X        break;
  306. X    case HELM_OF_BRILLIANCE:
  307. X        if (uarmh->spe) {
  308. X            ABON(A_INT) += uarmh->spe;
  309. X            ABON(A_WIS) += uarmh->spe;
  310. X            flags.botl = 1;
  311. X            makeknown(uarmh->otyp);
  312. X        }
  313. X        break;
  314. X    case HELM_OF_OPPOSITE_ALIGNMENT:
  315. X        if (u.ualign.type == A_NEUTRAL)
  316. X            u.ualign.type = rn2(2) ? A_CHAOTIC : A_LAWFUL;
  317. X        else u.ualign.type = -(u.ualign.type);
  318. X        makeknown(uarmh->otyp);
  319. X        flags.botl = 1;
  320. X        break;
  321. X    default: impossible("Unknown type of helm (%d)", uarmh->otyp);
  322. X    }
  323. X    return 0;
  324. X}
  325. X
  326. Xint
  327. XHelmet_off()
  328. X{
  329. X    switch(uarmh->otyp) {
  330. X    case FEDORA:
  331. X    case HELMET:
  332. X    case DENTED_POT:
  333. X    case ELVEN_LEATHER_HELM:
  334. X    case DWARVISH_IRON_HELM:
  335. X    case ORCISH_HELM:
  336. X        break;
  337. X    case HELM_OF_TELEPATHY:
  338. X        /* need to update ability before calling see_monsters() */
  339. X        setworn((struct obj *)0, W_ARMH);
  340. X        see_monsters();
  341. X        return 0;
  342. X    case HELM_OF_BRILLIANCE:
  343. X        if (uarmh->spe) {
  344. X            ABON(A_INT) -= uarmh->spe;
  345. X            ABON(A_WIS) -= uarmh->spe;
  346. X            flags.botl = 1;
  347. X        }
  348. X        break;
  349. X    case HELM_OF_OPPOSITE_ALIGNMENT:
  350. X        u.ualign.type = u.ualignbase[0];
  351. X        flags.botl = 1;
  352. X        break;
  353. X    default: impossible("Unknown type of helm (%d)", uarmh->otyp);
  354. X    }
  355. X    setworn((struct obj *)0, W_ARMH);
  356. X    return 0;
  357. X}
  358. X
  359. XSTATIC_PTR
  360. Xint
  361. XGloves_on() {
  362. X    long oldprop =
  363. X    u.uprops[objects[uarmg->otyp].oc_oprop].p_flgs & ~(WORN_GLOVES | TIMEOUT);
  364. X
  365. X    switch(uarmg->otyp) {
  366. X    case LEATHER_GLOVES:
  367. X        break;
  368. X    case GAUNTLETS_OF_FUMBLING:
  369. X        if (!oldprop)
  370. X            Fumbling += rnd(20);
  371. X        break;
  372. X    case GAUNTLETS_OF_POWER:
  373. X        makeknown(uarmg->otyp);
  374. X        flags.botl = 1; /* taken care of in attrib.c */
  375. X        break;
  376. X    case GAUNTLETS_OF_DEXTERITY:
  377. X        if (uarmg->spe) makeknown(uarmg->otyp);
  378. X        ABON(A_DEX) += uarmg->spe;
  379. X        flags.botl = 1;
  380. X        break;
  381. X    default: impossible("Unknown type of gloves (%d)", uarmg->otyp);
  382. X    }
  383. X    return 0;
  384. X}
  385. X
  386. Xint
  387. XGloves_off() {
  388. X    long oldprop =
  389. X    u.uprops[objects[uarmg->otyp].oc_oprop].p_flgs & ~(WORN_GLOVES | TIMEOUT);
  390. X
  391. X    switch(uarmg->otyp) {
  392. X    case LEATHER_GLOVES:
  393. X        break;
  394. X    case GAUNTLETS_OF_FUMBLING:
  395. X        if (!oldprop)
  396. X            Fumbling = 0;
  397. X        break;
  398. X    case GAUNTLETS_OF_POWER:
  399. X        makeknown(uarmg->otyp);
  400. X        flags.botl = 1; /* taken care of in attrib.c */
  401. X        break;
  402. X    case GAUNTLETS_OF_DEXTERITY:
  403. X        if (uarmg->spe) makeknown(uarmg->otyp);
  404. X        ABON(A_DEX) -= uarmg->spe;
  405. X        flags.botl = 1;
  406. X        break;
  407. X    default: impossible("Unknown type of gloves (%d)", uarmg->otyp);
  408. X    }
  409. X    setworn((struct obj *)0, W_ARMG);
  410. X    if (uwep && uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE
  411. X#ifdef POLYSELF
  412. X        && !(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
  413. X#endif
  414. X                            ) {
  415. X    /* Prevent wielding cockatrice when not wearing gloves */
  416. X    You("wield the cockatrice corpse in your bare %s.",
  417. X        makeplural(body_part(HAND)));
  418. X    You("turn to stone...");
  419. X    killer_format = KILLED_BY_AN;
  420. X    killer = "cockatrice corpse";
  421. X    done(STONING);
  422. X    }
  423. X    return 0;
  424. X}
  425. X
  426. X/*
  427. Xstatic int
  428. XShield_on() {
  429. X    switch(uarms->otyp) {
  430. X    case SMALL_SHIELD:
  431. X    case ELVEN_SHIELD:
  432. X    case URUK_HAI_SHIELD:
  433. X    case ORCISH_SHIELD:
  434. X    case DWARVISH_ROUNDSHIELD:
  435. X    case LARGE_SHIELD:
  436. X    case SHIELD_OF_REFLECTION:
  437. X        break;
  438. X    default: impossible("Unknown type of shield (%d)", uarms->otyp);
  439. X    }
  440. X    return 0;
  441. X}
  442. X*/
  443. X
  444. Xint
  445. XShield_off() {
  446. X/*
  447. X    switch(uarms->otyp) {
  448. X    case SMALL_SHIELD:
  449. X    case ELVEN_SHIELD:
  450. X    case URUK_HAI_SHIELD:
  451. X    case ORCISH_SHIELD:
  452. X    case DWARVISH_ROUNDSHIELD:
  453. X    case LARGE_SHIELD:
  454. X    case SHIELD_OF_REFLECTION:
  455. X        break;
  456. X    default: impossible("Unknown type of shield (%d)", uarms->otyp);
  457. X    }
  458. X*/
  459. X    setworn((struct obj *)0, W_ARMS);
  460. X    return 0;
  461. X}
  462. X
  463. X/* This must be done in worn.c, because one of the possible intrinsics conferred
  464. X * is fire resistance, and we have to immediately set HFire_resistance in worn.c
  465. X * since worn.c will check it before returning.
  466. X */
  467. XSTATIC_PTR
  468. Xint
  469. XArmor_on()
  470. X{
  471. X    return 0;
  472. X}
  473. X
  474. Xint
  475. XArmor_off()
  476. X{
  477. X    setworn((struct obj *)0, W_ARM);
  478. X    return 0;
  479. X}
  480. X
  481. X/* The gone functions differ from the off functions in that if you die from
  482. X * taking it off and have life saving, you still die.
  483. X */
  484. Xint
  485. XArmor_gone()
  486. X{
  487. X    setnotworn(uarm);
  488. X    return 0;
  489. X}
  490. X
  491. Xstatic void
  492. XAmulet_on()
  493. X{
  494. X    switch(uamul->otyp) {
  495. X    case AMULET_OF_ESP:
  496. X    case AMULET_OF_LIFE_SAVING:
  497. X    case AMULET_VERSUS_POISON:
  498. X    case AMULET_OF_REFLECTION:
  499. X    case AMULET_OF_MAGICAL_BREATHING:
  500. X    case FAKE_AMULET_OF_YENDOR:
  501. X        break;
  502. X    case AMULET_OF_CHANGE:
  503. X        makeknown(AMULET_OF_CHANGE);
  504. X        change_sex();
  505. X        /* Don't use same message as polymorph */
  506. X        You("are suddenly very %s!", flags.female ? "feminine"
  507. X            : "masculine");
  508. X        flags.botl = 1;
  509. X        pline("The amulet disintegrates!");
  510. X        useup(uamul);
  511. X        break;
  512. X    case AMULET_OF_STRANGULATION:
  513. X        makeknown(AMULET_OF_STRANGULATION);
  514. X        pline("It constricts your throat!");
  515. X        Strangled = 6;
  516. X        break;
  517. X    case AMULET_OF_RESTFUL_SLEEP:
  518. X        Sleeping = rnd(100);
  519. X        break;
  520. X    case AMULET_OF_YENDOR:
  521. X        break;
  522. X    }
  523. X}
  524. X
  525. Xvoid
  526. XAmulet_off()
  527. X{
  528. X    switch(uamul->otyp) {
  529. X    case AMULET_OF_ESP:
  530. X        /* need to update ability before calling see_monsters() */
  531. X        setworn((struct obj *)0, W_AMUL);
  532. X        see_monsters();
  533. X        return;
  534. X    case AMULET_OF_LIFE_SAVING:
  535. X    case AMULET_VERSUS_POISON:
  536. X    case AMULET_OF_REFLECTION:
  537. X    case FAKE_AMULET_OF_YENDOR:
  538. X        break;
  539. X    case AMULET_OF_MAGICAL_BREATHING:
  540. X        if (Underwater) {
  541. X            You("suddenly inhale an unhealthy amount of water!");
  542. X            /* Magical_breathing has to be set
  543. X               off before calling drown() */
  544. X            setworn((struct obj *)0, W_AMUL);
  545. X            (void) drown();
  546. X            return;
  547. X        }
  548. X        break;
  549. X    case AMULET_OF_CHANGE:
  550. X        impossible("Wearing an amulet of change?");
  551. X        break;
  552. X    case AMULET_OF_STRANGULATION:
  553. X        if (Strangled) {
  554. X            You("can breathe more easily!");
  555. X            Strangled = 0;
  556. X        }
  557. X        break;
  558. X    case AMULET_OF_RESTFUL_SLEEP:
  559. X        Sleeping = 0;
  560. X        break;
  561. X    case AMULET_OF_YENDOR:
  562. X        break;
  563. X    }
  564. X    setworn((struct obj *)0, W_AMUL);
  565. X}
  566. X
  567. Xvoid
  568. XRing_on(obj)
  569. Xregister struct obj *obj;
  570. X{
  571. X    long oldprop = u.uprops[objects[obj->otyp].oc_oprop].p_flgs & ~W_RING;
  572. X
  573. X    /* might put on two rings of the same type */
  574. X    if((u.uprops[objects[obj->otyp].oc_oprop].p_flgs & W_RING) == W_RING)
  575. X    oldprop = 1;
  576. X
  577. X    switch(obj->otyp){
  578. X    case RIN_TELEPORTATION:
  579. X    case RIN_REGENERATION:
  580. X    case RIN_SEARCHING:
  581. X    case RIN_STEALTH:
  582. X    case RIN_HUNGER:
  583. X    case RIN_AGGRAVATE_MONSTER:
  584. X    case RIN_POISON_RESISTANCE:
  585. X    case RIN_FIRE_RESISTANCE:
  586. X    case RIN_COLD_RESISTANCE:
  587. X    case RIN_SHOCK_RESISTANCE:
  588. X    case RIN_CONFLICT:
  589. X    case RIN_WARNING:
  590. X    case RIN_TELEPORT_CONTROL:
  591. X#ifdef POLYSELF
  592. X    case RIN_POLYMORPH:
  593. X    case RIN_POLYMORPH_CONTROL:
  594. X#endif
  595. X        break;
  596. X    case RIN_SEE_INVISIBLE:
  597. X        /* can now see invisible monsters */
  598. X        set_mimic_blocking(); /* do special mimic handling */
  599. X        see_monsters();
  600. X
  601. X        if (Invis && !oldprop
  602. X#ifdef POLYSELF
  603. X                && !perceives(uasmon)
  604. X#endif
  605. X                            && !Blind) {
  606. X            newsym(u.ux,u.uy);
  607. X            pline("Suddenly you can see yourself.");
  608. X            makeknown(RIN_SEE_INVISIBLE);
  609. X        }
  610. X        break;
  611. X    case RIN_INVISIBILITY:
  612. X        if (!oldprop && !See_invisible && !Blind) {
  613. X            makeknown(RIN_INVISIBILITY);
  614. X            newsym(u.ux,u.uy);
  615. X            Your("body takes on a %s transparency...",
  616. X                Hallucination ? "normal" : "strange");
  617. X        }
  618. X        break;
  619. X    case RIN_ADORNMENT:
  620. X        ABON(A_CHA) += obj->spe;
  621. X        flags.botl = 1;
  622. X        if (obj->spe || objects[RIN_ADORNMENT].oc_name_known) {
  623. X            makeknown(RIN_ADORNMENT);
  624. X            obj->known = TRUE;
  625. X        }
  626. X        break;
  627. X    case RIN_LEVITATION:
  628. X        if(!oldprop) {
  629. X            float_up();
  630. X            makeknown(RIN_LEVITATION);
  631. X            obj->known = TRUE;
  632. X        }
  633. X        break;
  634. X    case RIN_GAIN_STRENGTH:
  635. X        ABON(A_STR) += obj->spe;
  636. X        flags.botl = 1;
  637. X        if (obj->spe || objects[RIN_GAIN_STRENGTH].oc_name_known) {
  638. X            makeknown(RIN_GAIN_STRENGTH);
  639. X            obj->known = TRUE;
  640. X        }
  641. X        break;
  642. X    case RIN_INCREASE_DAMAGE:
  643. X        u.udaminc += obj->spe;
  644. X        break;
  645. X    case RIN_PROTECTION_FROM_SHAPE_CHAN:
  646. X        rescham();
  647. X        break;
  648. X    case RIN_PROTECTION:
  649. X        flags.botl = 1;
  650. X        if (obj->spe || objects[RIN_PROTECTION].oc_name_known) {
  651. X            makeknown(RIN_PROTECTION);
  652. X            obj->known = TRUE;
  653. X        }
  654. X        break;
  655. X    }
  656. X}
  657. X
  658. Xstatic void
  659. XRing_off_or_gone(obj,gone)
  660. Xregister struct obj *obj;
  661. Xboolean gone;
  662. X{
  663. X    register long mask = obj->owornmask & W_RING;
  664. X
  665. X    if(!(u.uprops[objects[obj->otyp].oc_oprop].p_flgs & mask))
  666. X    impossible("Strange... I didn't know you had that ring.");
  667. X    if(gone) setnotworn(obj);
  668. X    else setworn((struct obj *)0, obj->owornmask);
  669. X    switch(obj->otyp) {
  670. X    case RIN_TELEPORTATION:
  671. X    case RIN_REGENERATION:
  672. X    case RIN_SEARCHING:
  673. X    case RIN_STEALTH:
  674. X    case RIN_HUNGER:
  675. X    case RIN_AGGRAVATE_MONSTER:
  676. X    case RIN_POISON_RESISTANCE:
  677. X    case RIN_FIRE_RESISTANCE:
  678. X    case RIN_COLD_RESISTANCE:
  679. X    case RIN_SHOCK_RESISTANCE:
  680. X    case RIN_CONFLICT:
  681. X    case RIN_WARNING:
  682. X    case RIN_TELEPORT_CONTROL:
  683. X#ifdef POLYSELF
  684. X    case RIN_POLYMORPH:
  685. X    case RIN_POLYMORPH_CONTROL:
  686. X#endif
  687. X        break;
  688. X    case RIN_SEE_INVISIBLE:
  689. X        /* Make invisible monsters go away */
  690. X        if (!See_invisible) {
  691. X            set_mimic_blocking(); /* do special mimic handling */
  692. X            see_monsters();
  693. X        }
  694. X
  695. X        if (Invisible && !Blind) {
  696. X            newsym(u.ux,u.uy);
  697. X            pline("Suddenly you cannot see yourself.");
  698. X            makeknown(RIN_SEE_INVISIBLE);
  699. X        }
  700. X        break;
  701. X    case RIN_INVISIBILITY:
  702. X        if (!(Invisible & ~W_RING) && !See_invisible && !Blind) {
  703. X            newsym(u.ux,u.uy);
  704. X            Your("body seems to unfade...");
  705. X            makeknown(RIN_INVISIBILITY);
  706. X        }
  707. X        break;
  708. X    case RIN_ADORNMENT:
  709. X        ABON(A_CHA) -= obj->spe;
  710. X        flags.botl = 1;
  711. X        break;
  712. X    case RIN_LEVITATION:
  713. X        (void) float_down();
  714. X        if (!Levitation) makeknown(RIN_LEVITATION);
  715. X        break;
  716. X    case RIN_GAIN_STRENGTH:
  717. X        ABON(A_STR) -= obj->spe;
  718. X        flags.botl = 1;
  719. X        break;
  720. X    case RIN_INCREASE_DAMAGE:
  721. X        u.udaminc -= obj->spe;
  722. X        break;
  723. X    case RIN_PROTECTION_FROM_SHAPE_CHAN:
  724. X        /* If you're no longer protected, let the chameleons
  725. X         * change shape again -dgk
  726. X         */
  727. X        restartcham();
  728. X        break;
  729. X    }
  730. X}
  731. X
  732. Xvoid
  733. XRing_off(obj)
  734. Xstruct obj *obj;
  735. X{
  736. X    Ring_off_or_gone(obj,FALSE);
  737. X}
  738. X
  739. Xvoid
  740. XRing_gone(obj)
  741. Xstruct obj *obj;
  742. X{
  743. X    Ring_off_or_gone(obj,TRUE);
  744. X}
  745. X
  746. Xvoid
  747. XBlindf_on(otmp)
  748. Xregister struct obj *otmp;
  749. X{
  750. X    long already_blinded = Blinded;
  751. X    setworn(otmp, W_TOOL);
  752. X    if (otmp->otyp == TOWEL && flags.verbose)
  753. X        You("wrap %s around your %s.", an(xname(otmp)), body_part(HEAD));
  754. X    on_msg(otmp);
  755. X    if (!already_blinded) {
  756. X        if (Punished) set_bc(0);    /* Set ball&chain variables before */
  757. X                    /* the hero goes blind.           */
  758. X        if (Telepat) see_monsters();/* sense monsters */
  759. X        vision_full_recalc = 1;    /* recalc vision limits */
  760. X        flags.botl = 1;
  761. X    }
  762. X}
  763. X
  764. Xvoid
  765. XBlindf_off(otmp)
  766. Xregister struct obj *otmp;
  767. X{
  768. X    setworn((struct obj *)0, otmp->owornmask);
  769. X    off_msg(otmp);
  770. X    if (!Blinded) {
  771. X        if (Telepat) see_monsters();/* no longer sense monsters */
  772. X        vision_full_recalc = 1;    /* recalc vision limits */
  773. X        flags.botl = 1;
  774. X    } else
  775. X        You("still cannot see.");
  776. X}
  777. X
  778. X/* called in main to set intrinsics of worn start-up items */
  779. Xvoid
  780. Xset_wear() {
  781. X    if (uarm)  (void) Armor_on();
  782. X    if (uarmc) (void) Cloak_on();
  783. X    if (uarmf) (void) Boots_on();
  784. X    if (uarmg) (void) Gloves_on();
  785. X    if (uarmh) (void) Helmet_on();
  786. X/*    if (uarms) (void) Shield_on(); */
  787. X}
  788. X
  789. Xboolean
  790. Xdonning(otmp)
  791. Xregister struct obj *otmp;
  792. X{
  793. X    return (otmp == uarmf && (afternmv == Boots_on || afternmv == Boots_off))
  794. X    || (otmp == uarmh && (afternmv == Helmet_on || afternmv == Helmet_off))
  795. X    || (otmp == uarmg && (afternmv == Gloves_on || afternmv == Gloves_off))
  796. X    || (otmp == uarm && (afternmv == Armor_on || afternmv == Armor_off));
  797. X}
  798. X
  799. Xvoid
  800. Xcancel_don()
  801. X{
  802. X    /* the piece of armor we were donning/doffing has vanished, so stop
  803. X     * wasting time on it (and don't dereference it when donning would
  804. X     * otherwise finish)
  805. X     */
  806. X    afternmv = 0;
  807. X    nomovemsg = NULL;
  808. X    multi = 0;
  809. X}
  810. X
  811. Xstatic const char NEARDATA clothes[] = {ARMOR_CLASS, 0};
  812. Xstatic const char NEARDATA accessories[] = {RING_CLASS, AMULET_CLASS, TOOL_CLASS, 0};
  813. X
  814. Xint
  815. Xdotakeoff()
  816. X{
  817. X    register struct obj *otmp = (struct obj *)0;
  818. X    int armorpieces = 0;
  819. X
  820. X#define MOREARM(x) if (x) { armorpieces++; otmp = x; }
  821. X    MOREARM(uarmh);
  822. X    MOREARM(uarms);
  823. X    MOREARM(uarmg);
  824. X    MOREARM(uarmf);
  825. X    if (uarmc) {
  826. X        armorpieces++;
  827. X        otmp = uarmc;
  828. X    } else if (uarm) {
  829. X        armorpieces++;
  830. X        otmp = uarm;
  831. X#ifdef TOURIST
  832. X    } else if (uarmu) {
  833. X        armorpieces++;
  834. X        otmp = uarmu;
  835. X#endif
  836. X    }
  837. X    if (!armorpieces) {
  838. X#ifdef POLYSELF
  839. X        if (uskin)
  840. X            pline("The dragon scale mail is merged with your skin!");
  841. X        else
  842. X#endif
  843. X            pline("Not wearing any armor.");
  844. X        return 0;
  845. X    }
  846. X    if (armorpieces > 1)
  847. X        otmp = getobj(clothes, "take off");
  848. X    if (otmp == 0) return(0);
  849. X    if (!(otmp->owornmask & W_ARMOR)) {
  850. X        You("are not wearing that.");
  851. X        return(0);
  852. X    }
  853. X    if (((otmp == uarm) && (uarmc))
  854. X#ifdef TOURIST
  855. X                || ((otmp == uarmu) && (uarmc || uarm))
  856. X#endif
  857. X                                ) {
  858. X        You("can't take that off.");
  859. X        return(0);
  860. X    }
  861. X    if(otmp == uarmg && welded(uwep)) {
  862. X    You("seem unable to take off the gloves while holding your %s.",
  863. X      is_sword(uwep) ? "sword" : "weapon");
  864. X        uwep->bknown = TRUE;
  865. X        return(0);
  866. X    }
  867. X    if(otmp == uarmg && Glib) {
  868. X    You("can't remove the slippery gloves with your slippery fingers.");
  869. X        return(0);
  870. X    }
  871. X    if(otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP ||
  872. X                    u.utraptype == TT_INFLOOR)) { /* -3. */
  873. X        if(u.utraptype == TT_BEARTRAP)
  874. X        pline("The bear trap prevents you from pulling your %s out.",
  875. X              body_part(FOOT));
  876. X        else
  877. X        You("are stuck in the floor, and cannot pull your %s out.",
  878. X             makeplural(body_part(FOOT)));
  879. X        return(0);
  880. X    }
  881. X    reset_remarm();            /* since you may change ordering */
  882. X    (void) armoroff(otmp);
  883. X    return(1);
  884. X}
  885. X
  886. Xint
  887. Xdoremring() {
  888. X#ifdef GCC_WARN
  889. X    register struct obj *otmp = (struct obj *)0;
  890. X        /* suppress "may be used uninitialized" warning */
  891. X#else
  892. X    register struct obj *otmp;
  893. X#endif
  894. X    int Accessories = 0;
  895. X
  896. X#define MOREACC(x) if (x) { Accessories++; otmp = x; }
  897. X    MOREACC(uleft);
  898. X    MOREACC(uright);
  899. X    MOREACC(uamul);
  900. X    MOREACC(ublindf);
  901. X
  902. X    if(!Accessories) {
  903. X        pline("Not wearing any accessories.");
  904. X        return(0);
  905. X    }
  906. X    if (Accessories != 1) otmp = getobj(accessories, "take off");
  907. X    if(!otmp) return(0);
  908. X    if(!(otmp->owornmask & (W_RING | W_AMUL | W_TOOL))) {
  909. X        You("are not wearing that.");
  910. X        return(0);
  911. X    }
  912. X    if(cursed(otmp)) return(0);
  913. X    if(otmp->oclass == RING_CLASS) {
  914. X#ifdef POLYSELF
  915. X        if (nolimbs(uasmon)) {
  916. X            pline("It seems to be stuck.");
  917. X            return(0);
  918. X        }
  919. X#endif
  920. X        if (uarmg && uarmg->cursed) {
  921. X            uarmg->bknown = TRUE;
  922. XYou("seem unable to remove your ring without taking off your gloves.");
  923. X            return(0);
  924. X        }
  925. X        if (welded(uwep) && bimanual(uwep)) {
  926. X            uwep->bknown = TRUE;
  927. XYou("seem unable to remove the ring while your hands hold your %s.",
  928. X                is_sword(uwep) ? "sword" : "weapon");
  929. X            return(0);
  930. X        }
  931. X        if (welded(uwep) && otmp==uright) {
  932. X            uwep->bknown = TRUE;
  933. XYou("seem unable to remove the ring while your right hand holds your %s.",
  934. X                is_sword(uwep) ? "sword" : "weapon");
  935. X            return(0);
  936. X        }
  937. X        /* Sometimes we want to give the off_msg before removing and
  938. X         * sometimes after; for instance, "you were wearing a moonstone
  939. X         * ring (on right hand)" is desired but "you were wearing a
  940. X         * square amulet (being worn)" is not because of the redundant
  941. X         * "being worn".
  942. X         */
  943. X        off_msg(otmp);
  944. X        Ring_off(otmp);
  945. X    } else if(otmp->oclass == AMULET_CLASS) {
  946. X        Amulet_off();
  947. X        off_msg(otmp);
  948. X    } else Blindf_off(otmp); /* does its own off_msg */
  949. X    return(1);
  950. X}
  951. X
  952. Xint
  953. Xcursed(otmp) register struct obj *otmp; {
  954. X    /* Curses, like chickens, come home to roost. */
  955. X    if(otmp->cursed){
  956. X        You("can't.  %s to be cursed.",
  957. X            (is_boots(otmp) || is_gloves(otmp) || otmp->quan > 1L)
  958. X            ? "They seem" : "It seems");
  959. X        otmp->bknown = TRUE;
  960. X        return(1);
  961. X    }
  962. X    return(0);
  963. X}
  964. X
  965. Xint
  966. Xarmoroff(otmp) register struct obj *otmp; {
  967. X    register int delay = -objects[otmp->otyp].oc_delay;
  968. X
  969. X    if(cursed(otmp)) return(0);
  970. X    if(delay) {
  971. X        nomul(delay);
  972. X        if (is_helmet(otmp)) {
  973. X            nomovemsg = "You finish taking off your helmet.";
  974. X            afternmv = Helmet_off;
  975. X             }
  976. X        else if (is_gloves(otmp)) {
  977. X            nomovemsg = "You finish taking off your gloves.";
  978. X            afternmv = Gloves_off;
  979. X             }
  980. X        else if (is_boots(otmp)) {
  981. X            nomovemsg = "You finish taking off your boots.";
  982. X            afternmv = Boots_off;
  983. X             }
  984. X        else {
  985. X            nomovemsg = "You finish taking off your suit.";
  986. X            afternmv = Armor_off;
  987. X        }
  988. X    } else {
  989. X        /* Be warned!  We want off_msg after removing the item to
  990. X         * avoid "You were wearing ____ (being worn)."  However, an
  991. X         * item which grants fire resistance might cause some trouble
  992. X         * if removed in Hell and lifesaving puts it back on; in this
  993. X         * case the message will be printed at the wrong time (after
  994. X         * the messages saying you died and were lifesaved).  Luckily,
  995. X         * no cloak, shield, or fast-removable armor grants fire
  996. X         * resistance, so we can safely do the off_msg afterwards.
  997. X         * Rings do grant fire resistance, but for rings we want the
  998. X         * off_msg before removal anyway so there's no problem.  Take
  999. X         * care in adding armors granting fire resistance; this code
  1000. X         * might need modification.
  1001. X         */
  1002. X        if(is_cloak(otmp))
  1003. X            (void) Cloak_off();
  1004. X        else if(is_shield(otmp))
  1005. X            (void) Shield_off();
  1006. X        else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
  1007. X        off_msg(otmp);
  1008. X    }
  1009. X    takeoff_mask = taking_off = 0L;
  1010. X    return(1);
  1011. X}
  1012. X
  1013. Xstatic void
  1014. Xalready_wearing(cc)
  1015. Xconst char *cc;
  1016. X{
  1017. X    You("are already wearing %s", cc);
  1018. X}
  1019. X
  1020. Xint
  1021. Xdowear()
  1022. X{
  1023. X    register struct obj *otmp;
  1024. X    register int delay;
  1025. X    register int err = 0;
  1026. X    long mask = 0;
  1027. X
  1028. X#ifdef POLYSELF
  1029. X    /* cantweararm checks for suits of armor */
  1030. X    /* verysmall or nohands checks for shields, gloves, etc... */
  1031. X    if ((verysmall(uasmon) || nohands(uasmon))) {
  1032. X        pline("Don't even bother.");
  1033. X        return(0);
  1034. X    }
  1035. X#endif
  1036. X    otmp = getobj(clothes, "wear");
  1037. X    if(!otmp) return(0);
  1038. X#ifdef POLYSELF
  1039. X    if (cantweararm(uasmon) && !is_shield(otmp) &&
  1040. X            !is_helmet(otmp) && !is_gloves(otmp) &&
  1041. X            !is_boots(otmp)) {
  1042. X        pline("The %s will not fit on your body.",
  1043. X            is_cloak(otmp) ? "cloak" :
  1044. X# ifdef TOURIST
  1045. X            otmp->otyp == HAWAIIAN_SHIRT ? "shirt" :
  1046. X# endif
  1047. X            "suit");
  1048. X        return(0);
  1049. X    }
  1050. X#endif
  1051. X    if(otmp->owornmask & W_ARMOR) {
  1052. X        already_wearing("that!");
  1053. X        return(0);
  1054. X    }
  1055. X    if(is_helmet(otmp)) {
  1056. X        if(uarmh) {
  1057. X            already_wearing("a helmet.");
  1058. X            err++;
  1059. X        } else
  1060. X            mask = W_ARMH;
  1061. X    } else if(is_shield(otmp)){
  1062. X        if(uarms) {
  1063. X            already_wearing("a shield.");
  1064. X            err++;
  1065. X        }
  1066. X        if(uwep && bimanual(uwep)) {
  1067. X            You("cannot wear a shield while wielding a two-handed %s.",
  1068. X            is_sword(uwep) ? "sword" :
  1069. X                uwep->otyp == BATTLE_AXE ? "axe" : "weapon");
  1070. X            err++;
  1071. X        }
  1072. X        if(!err) mask = W_ARMS;
  1073. X    } else if(is_boots(otmp)) {
  1074. X           if(uarmf) {
  1075. X            already_wearing("boots.");
  1076. X            err++;
  1077. X           } if (u.utrap && (u.utraptype == TT_BEARTRAP ||
  1078. X                     u.utraptype == TT_INFLOOR)) {
  1079. X               if (u.utraptype == TT_BEARTRAP)
  1080. X               Your("%s is trapped!", body_part(FOOT));
  1081. X               else
  1082. X               Your("%s are stuck in the floor!",
  1083. X                makeplural(body_part(FOOT)));
  1084. X               err++;
  1085. X           } else
  1086. X            mask = W_ARMF;
  1087. X    } else if(is_gloves(otmp)) {
  1088. X        if(uarmg) {
  1089. X            already_wearing("gloves.");
  1090. X            err++;
  1091. X        } else
  1092. X        if (welded(uwep)) {
  1093. X            You("cannot wear gloves over your %s.",
  1094. X                  is_sword(uwep) ? "sword" : "weapon");
  1095. X            err++;
  1096. X        } else
  1097. X            mask = W_ARMG;
  1098. X#ifdef TOURIST
  1099. X    } else if( otmp->otyp == HAWAIIAN_SHIRT ) {
  1100. X        if (uarm || uarmc || uarmu) {
  1101. X            if(uarmu)
  1102. X               already_wearing("a shirt.");
  1103. X            else
  1104. X               You("can't wear that over your %s.",
  1105. X                 (uarm && !uarmc) ? "armor" : "cloak");
  1106. X            err++;
  1107. X        } else
  1108. X            mask = W_ARMU;
  1109. X#endif
  1110. X    } else if(is_cloak(otmp)) {
  1111. X        if(uarmc) {
  1112. X            already_wearing("a cloak.");
  1113. X            err++;
  1114. X        } else
  1115. X            mask = W_ARMC;
  1116. X    } else {
  1117. X        if(uarmc) {
  1118. X            You("cannot wear armor over a cloak.");
  1119. X            err++;
  1120. X        } else if(uarm) {
  1121. X            already_wearing("some armor.");
  1122. X            err++;
  1123. X        }
  1124. X        if(!err) mask = W_ARM;
  1125. X    }
  1126. X/* Unnecessary since now only weapons and special items like pick-axes get
  1127. X * welded to your hand, not armor
  1128. X    if(welded(otmp)) {
  1129. X        if(!err++)
  1130. X            weldmsg(otmp, FALSE);
  1131. X    }
  1132. X */
  1133. X    if(err) return(0);
  1134. X
  1135. X    otmp->known = TRUE;
  1136. X    if(otmp == uwep)
  1137. X        setuwep((struct obj *)0);
  1138. X    setworn(otmp, mask);
  1139. X    delay = -objects[otmp->otyp].oc_delay;
  1140. X    if(delay){
  1141. X        nomul(delay);
  1142. X        if(is_boots(otmp)) afternmv = Boots_on;
  1143. X        if(is_helmet(otmp)) afternmv = Helmet_on;
  1144. X        if(is_gloves(otmp)) afternmv = Gloves_on;
  1145. X        if(otmp == uarm) afternmv = Armor_on;
  1146. X        nomovemsg = "You finish your dressing maneuver.";
  1147. X    } else {
  1148. X        if(is_cloak(otmp)) (void) Cloak_on();
  1149. X/*        if(is_shield(otmp)) (void) Shield_on(); */
  1150. X        on_msg(otmp);
  1151. X    }
  1152. X    takeoff_mask = taking_off = 0L;
  1153. X    return(1);
  1154. X}
  1155. X
  1156. Xint
  1157. Xdoputon() {
  1158. X    register struct obj *otmp;
  1159. X    long mask = 0L;
  1160. X
  1161. X    if(uleft && uright && uamul && ublindf) {
  1162. X#ifdef POLYSELF
  1163. X        Your("%s%s are full, and you're already wearing an amulet and a blindfold.",
  1164. X            humanoid(uasmon) ? "ring-" : "",
  1165. X            makeplural(body_part(FINGER)));
  1166. X#else
  1167. X        Your("ring-fingers are full, and you're already wearing an amulet and a blindfold.");
  1168. X#endif
  1169. X        return(0);
  1170. X    }
  1171. X    otmp = getobj(accessories, "wear");
  1172. X    if(!otmp) return(0);
  1173. X    if(otmp->owornmask & (W_RING | W_AMUL | W_TOOL)) {
  1174. X        already_wearing("that!");
  1175. X        return(0);
  1176. X    }
  1177. X    if(welded(otmp)) {
  1178. X        weldmsg(otmp, TRUE);
  1179. X        return(0);
  1180. X    }
  1181. X    if(otmp == uwep)
  1182. X        setuwep((struct obj *)0);
  1183. X    if(otmp->oclass == RING_CLASS) {
  1184. X#ifdef POLYSELF
  1185. X        if(nolimbs(uasmon)) {
  1186. X            You("cannot make the ring stick to your body.");
  1187. X            return(0);
  1188. X        }
  1189. X#endif
  1190. X        if(uleft && uright){
  1191. X#ifdef POLYSELF
  1192. X            pline("There are no more %s%s to fill.",
  1193. X                humanoid(uasmon) ? "ring-" : "",
  1194. X                makeplural(body_part(FINGER)));
  1195. X#else
  1196. X            pline("There are no more ring-fingers to fill.");
  1197. X#endif
  1198. X            return(0);
  1199. X        }
  1200. X        if(uleft) mask = RIGHT_RING;
  1201. X        else if(uright) mask = LEFT_RING;
  1202. X        else do {
  1203. X            char qbuf[QBUFSZ];
  1204. X            char answer;
  1205. X
  1206. X#ifdef POLYSELF
  1207. X            Sprintf(qbuf, "What %s%s, Right or Left?",
  1208. X                humanoid(uasmon) ? "ring-" : "",
  1209. X                body_part(FINGER));
  1210. X#else
  1211. X            Strcpy(qbuf, "What ring-finger, Right or Left?");
  1212. X#endif
  1213. X            if(!(answer = yn_function(qbuf, "rl", '\0')))
  1214. X                return(0);
  1215. X            switch(answer){
  1216. X            case 'l':
  1217. X            case 'L':
  1218. X                mask = LEFT_RING;
  1219. X                break;
  1220. X            case 'r':
  1221. X            case 'R':
  1222. X                mask = RIGHT_RING;
  1223. X                break;
  1224. X            }
  1225. X        } while(!mask);
  1226. X        if (uarmg && uarmg->cursed) {
  1227. X            uarmg->bknown = TRUE;
  1228. X            You("cannot remove your gloves to put on the ring.");
  1229. X            return(0);
  1230. X        }
  1231. X        if (welded(uwep) && bimanual(uwep)) {
  1232. X            /* welded will set bknown */
  1233. X        You("cannot free your weapon hands to put on the ring.");
  1234. X            return(0);
  1235. X        }
  1236. X        if (welded(uwep) && mask==RIGHT_RING) {
  1237. X            /* welded will set bknown */
  1238. X        You("cannot free your weapon hand to put on the ring.");
  1239. X            return(0);
  1240. X        }
  1241. X        setworn(otmp, mask);
  1242. X        Ring_on(otmp);
  1243. X    } else if (otmp->oclass == AMULET_CLASS) {
  1244. X        if(uamul) {
  1245. X            already_wearing("an amulet.");
  1246. X            return(0);
  1247. X        }
  1248. X        setworn(otmp, W_AMUL);
  1249. X        if (otmp->otyp == AMULET_OF_CHANGE) {
  1250. X            Amulet_on();
  1251. X            /* Don't do a prinv() since the amulet is now gone */
  1252. X            return(1);
  1253. X        }
  1254. X        Amulet_on();
  1255. X    } else {    /* it's a blindfold */
  1256. X        if (ublindf) {
  1257. X            if (ublindf->otyp == TOWEL)
  1258. X                Your("%s is already covered by a towel.",
  1259. X                    body_part(FACE));
  1260. X            else
  1261. X                already_wearing("a blindfold.");
  1262. X            return(0);
  1263. X        }
  1264. X        if (otmp->otyp != BLINDFOLD && otmp->otyp != TOWEL) {
  1265. X            You("can't wear that!");
  1266. X            return(0);
  1267. X        }
  1268. X        Blindf_on(otmp);
  1269. X        return(1);
  1270. X    }
  1271. X    prinv(NULL, otmp, 0L);
  1272. X    return(1);
  1273. X}
  1274. X
  1275. X#endif /* OVLB */
  1276. X
  1277. X#ifdef OVL0
  1278. X
  1279. Xvoid
  1280. Xfind_ac() {
  1281. X    register int uac = 10;
  1282. X#ifdef POLYSELF
  1283. X    if (u.mtimedone) uac = mons[u.umonnum].ac;
  1284. X#endif
  1285. X    if(uarm) uac -= ARM_BONUS(uarm);
  1286. X    if(uarmc) uac -= ARM_BONUS(uarmc);
  1287. X    if(uarmh) uac -= ARM_BONUS(uarmh);
  1288. X    if(uarmf) uac -= ARM_BONUS(uarmf);
  1289. X    if(uarms) uac -= ARM_BONUS(uarms);
  1290. X    if(uarmg) uac -= ARM_BONUS(uarmg);
  1291. X#ifdef TOURIST
  1292. X    if(uarmu) uac -= ARM_BONUS(uarmu);
  1293. X#endif
  1294. X    if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
  1295. X    if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
  1296. X    if (Protection & INTRINSIC) uac -= u.ublessed;
  1297. X    if(uac != u.uac){
  1298. X        u.uac = uac;
  1299. X        flags.botl = 1;
  1300. X    }
  1301. X}
  1302. X
  1303. X#endif /* OVL0 */
  1304. X#ifdef OVLB
  1305. X
  1306. Xvoid
  1307. Xglibr()
  1308. X{
  1309. X    register struct obj *otmp;
  1310. X    int xfl = 0;
  1311. X    boolean leftfall, rightfall;
  1312. X
  1313. X    leftfall = (uleft && !uleft->cursed &&
  1314. X            (!uwep || !welded(uwep) || !bimanual(uwep)));
  1315. X    rightfall = (uright && !uright->cursed && (!welded(uwep)));
  1316. X    if(!uarmg) if(leftfall || rightfall)
  1317. X#ifdef POLYSELF
  1318. X                if(!nolimbs(uasmon))
  1319. X#endif
  1320. X                        {
  1321. X        /* changed so cursed rings don't fall off, GAN 10/30/86 */
  1322. X        Your("%s off your %s.",
  1323. X            (leftfall && rightfall) ? "rings slip" : "ring slips",
  1324. X            makeplural(body_part(FINGER)));
  1325. X        xfl++;
  1326. X        if(leftfall) {
  1327. X            otmp = uleft;
  1328. X            Ring_off(uleft);
  1329. X            dropx(otmp);
  1330. X        }
  1331. X        if(rightfall) {
  1332. X            otmp = uright;
  1333. X            Ring_off(uright);
  1334. X            dropx(otmp);
  1335. X        }
  1336. X    }
  1337. X    otmp = uwep;
  1338. X    if (otmp && !welded(otmp)) {
  1339. X        /* changed so cursed weapons don't fall, GAN 10/30/86 */
  1340. X        Your("%s %sslips from your %s.",
  1341. X            is_sword(otmp) ? "sword" :
  1342. X                makesingular(oclass_names[otmp->oclass]),
  1343. X            xfl ? "also " : "",
  1344. X            makeplural(body_part(HAND)));
  1345. X        setuwep((struct obj *)0);
  1346. X        dropx(otmp);
  1347. X    }
  1348. X}
  1349. X
  1350. Xstruct obj *
  1351. Xsome_armor(){
  1352. Xregister struct obj *otmph = (uarmc ? uarmc : uarm);
  1353. X    if(uarmh && (!otmph || !rn2(4))) otmph = uarmh;
  1354. X    if(uarmg && (!otmph || !rn2(4))) otmph = uarmg;
  1355. X    if(uarmf && (!otmph || !rn2(4))) otmph = uarmf;
  1356. X    if(uarms && (!otmph || !rn2(4))) otmph = uarms;
  1357. X#ifdef TOURIST
  1358. X    if(!uarm && !uarmc && uarmu && (!otmph || !rn2(4))) otmph = uarmu;
  1359. X#endif
  1360. X    return(otmph);
  1361. X}
  1362. X
  1363. Xvoid
  1364. Xerode_armor(acid_dmg)
  1365. Xboolean acid_dmg;
  1366. X{
  1367. Xregister struct obj *otmph = some_armor();
  1368. X
  1369. X    if (otmph && otmph != uarmf) {
  1370. X        if (otmph->greased) {
  1371. X        grease_protect(otmph,NULL,FALSE);
  1372. X        return;
  1373. X        }
  1374. X        if (otmph->oerodeproof ||
  1375. X        (acid_dmg ? !is_corrodeable(otmph) : !is_rustprone(otmph))) {
  1376. X        if (flags.verbose || !(otmph->oerodeproof && otmph->rknown))
  1377. X            Your("%s not affected.", aobjnam(otmph, "are"));
  1378. X        if (otmph->oerodeproof) otmph->rknown = TRUE;
  1379. X        return;
  1380. X        }
  1381. X        if (otmph->oeroded < MAX_ERODE) {
  1382. X        Your("%s%s!", aobjnam(otmph, acid_dmg ? "corrode" : "rust"),
  1383. X            otmph->oeroded+1 == MAX_ERODE ? " completely" :
  1384. X            otmph->oeroded ? " further" : "");
  1385. X        otmph->oeroded++;
  1386. X        return;
  1387. X        }
  1388. X        if (flags.verbose)
  1389. X        Your("%s completely %s.",
  1390. X             aobjnam(otmph, Blind ? "feel" : "look"),
  1391. X             acid_dmg ? "corroded" : "rusty");
  1392. X    }
  1393. X}
  1394. X
  1395. XSTATIC_PTR
  1396. Xint
  1397. Xselect_off(otmp)
  1398. Xregister struct obj *otmp;
  1399. X{
  1400. X    if(!otmp) return(0);
  1401. X    if(cursed(otmp)) return(0);
  1402. X#ifdef POLYSELF
  1403. X    if(otmp->oclass==RING_CLASS && nolimbs(uasmon)) return(0);
  1404. X#endif
  1405. X    if(welded(uwep) && (otmp==uarmg || otmp==uright || (otmp==uleft
  1406. X            && bimanual(uwep))))
  1407. X        return(0);
  1408. X    if(uarmg && uarmg->cursed && (otmp==uright || otmp==uleft)) {
  1409. X        uarmg->bknown = TRUE;
  1410. X        return(0);
  1411. X    }
  1412. X    if(otmp == uarmf && u.utrap && (u.utraptype == TT_BEARTRAP ||
  1413. X                    u.utraptype == TT_INFLOOR)) {
  1414. X        return (0);
  1415. X    }
  1416. X    if((otmp==uarm
  1417. X#ifdef TOURIST
  1418. X            || otmp==uarmu
  1419. X#endif
  1420. X                    ) && uarmc && uarmc->cursed) {
  1421. X        uarmc->bknown = TRUE;
  1422. X        return(0);
  1423. X    }
  1424. X#ifdef TOURIST
  1425. X    if(otmp==uarmu && uarm && uarm->cursed) {
  1426. X        uarm->bknown = TRUE;
  1427. X        return(0);
  1428. X    }
  1429. X#endif
  1430. X
  1431. X    if(otmp == uarm) takeoff_mask |= WORN_ARMOR;
  1432. X    else if(otmp == uarmc) takeoff_mask |= WORN_CLOAK;
  1433. X    else if(otmp == uarmf) takeoff_mask |= WORN_BOOTS;
  1434. X    else if(otmp == uarmg) takeoff_mask |= WORN_GLOVES;
  1435. X    else if(otmp == uarmh) takeoff_mask |= WORN_HELMET;
  1436. X    else if(otmp == uarms) takeoff_mask |= WORN_SHIELD;
  1437. X#ifdef TOURIST
  1438. X    else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
  1439. X#endif
  1440. X    else if(otmp == uleft) takeoff_mask |= LEFT_RING;
  1441. X    else if(otmp == uright) takeoff_mask |= RIGHT_RING;
  1442. X    else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
  1443. X    else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
  1444. X    else if(otmp == uwep) takeoff_mask |= 1L;    /* WIELDED_WEAPON */
  1445. X
  1446. X    else impossible("select_off: %s???", doname(otmp));
  1447. X
  1448. X    return(0);
  1449. X}
  1450. X
  1451. Xstatic struct obj *
  1452. Xdo_takeoff() {
  1453. X
  1454. X    register struct obj *otmp = (struct obj *)0;
  1455. X
  1456. X    if (taking_off == 1L) { /* weapon */
  1457. X      if(!cursed(uwep)) {
  1458. X        setuwep((struct obj *) 0);
  1459. X        You("are empty %s.", body_part(HANDED));
  1460. X      }
  1461. X    } else if (taking_off ==  WORN_ARMOR) {
  1462. X      otmp = uarm;
  1463. X      if(!cursed(otmp)) (void) Armor_off();
  1464. X    } else if (taking_off == WORN_CLOAK) {
  1465. X      otmp = uarmc;
  1466. X      if(!cursed(otmp)) (void) Cloak_off();
  1467. X    } else if (taking_off == WORN_BOOTS) {
  1468. X      otmp = uarmf;
  1469. X      if(!cursed(otmp)) (void) Boots_off();
  1470. X    } else if (taking_off == WORN_GLOVES) {
  1471. X      otmp = uarmg;
  1472. X      if(!cursed(otmp)) (void) Gloves_off();
  1473. X    } else if (taking_off == WORN_HELMET) {
  1474. X      otmp = uarmh;
  1475. X      if(!cursed(otmp)) (void) Helmet_off();
  1476. X    } else if (taking_off == WORN_SHIELD) {
  1477. X      otmp = uarms;
  1478. X      if(!cursed(otmp)) (void) Shield_off();
  1479. X#ifdef TOURIST
  1480. X    } else if (taking_off == WORN_SHIRT) {
  1481. X      otmp = uarmu;
  1482. X      if(!cursed(otmp))
  1483. X        setworn((struct obj *)0, uarmu->owornmask & W_ARMOR);
  1484. X#endif
  1485. X    } else if (taking_off == WORN_AMUL) {
  1486. X      otmp = uamul;
  1487. X      if(!cursed(otmp)) Amulet_off();
  1488. X    } else if (taking_off == LEFT_RING) {
  1489. X      otmp = uleft;
  1490. X      if(!cursed(otmp)) Ring_off(uleft);
  1491. X    } else if (taking_off == RIGHT_RING) {
  1492. X      otmp = uright;
  1493. X      if(!cursed(otmp)) Ring_off(uright);
  1494. X    } else if (taking_off == WORN_BLINDF) {
  1495. X      if(!cursed(ublindf)) {
  1496. X        setworn((struct obj *)0, ublindf->owornmask);
  1497. X        if(!Blinded) make_blinded(1L,FALSE); /* See on next move */
  1498. X        else     You("still cannot see.");
  1499. X      }
  1500. X    } else impossible("do_takeoff: taking off %lx", taking_off);
  1501. X
  1502. X    return(otmp);
  1503. X}
  1504. X
  1505. XSTATIC_PTR
  1506. Xint
  1507. Xtake_off() {
  1508. X
  1509. X    register int i;
  1510. X    register struct obj *otmp;
  1511. X
  1512. X    if(taking_off) {
  1513. X        if(todelay > 0) {
  1514. X
  1515. X        todelay--;
  1516. X        return(1);    /* still busy */
  1517. X        } else if((otmp = do_takeoff())) off_msg(otmp);
  1518. X
  1519. X        takeoff_mask &= ~taking_off;
  1520. X        taking_off = 0L;
  1521. X    }
  1522. X
  1523. X    for(i = 0; takeoff_order[i]; i++)
  1524. X        if(takeoff_mask & takeoff_order[i]) {
  1525. X
  1526. X        taking_off = takeoff_order[i];
  1527. X        break;
  1528. X        }
  1529. X
  1530. X    otmp = (struct obj *) 0;
  1531. X
  1532. X    if (taking_off == 0L) {
  1533. X      You("finish disrobing.");
  1534. X      return 0;
  1535. X    } else if (taking_off == 1L) {
  1536. X      todelay = 1;
  1537. X    } else if (taking_off == WORN_ARMOR) {
  1538. X      otmp = uarm;
  1539. X    } else if (taking_off == WORN_CLOAK) {
  1540. X      otmp = uarmc;
  1541. X    } else if (taking_off == WORN_BOOTS) {
  1542. X      otmp = uarmf;
  1543. X    } else if (taking_off == WORN_GLOVES) {
  1544. X      otmp = uarmg;
  1545. X    } else if (taking_off == WORN_HELMET) {
  1546. X      otmp = uarmh;
  1547. X    } else if (taking_off == WORN_SHIELD) {
  1548. X      otmp = uarms;
  1549. X#ifdef TOURIST
  1550. X    } else if (taking_off == WORN_SHIRT) {
  1551. X      otmp = uarmu;
  1552. X#endif
  1553. X    } else if (taking_off == WORN_AMUL) {
  1554. X      todelay = 1;
  1555. X    } else if (taking_off == LEFT_RING) {
  1556. X      todelay = 1;
  1557. X    } else if (taking_off == RIGHT_RING) {
  1558. X      todelay = 1;
  1559. X    } else if (taking_off == WORN_BLINDF) {
  1560. X      todelay = 2;
  1561. X    } else {
  1562. X      impossible("take_off: taking off %lx", taking_off);
  1563. X      return 0;    /* force done */
  1564. X    }
  1565. X
  1566. X    if(otmp) todelay = objects[otmp->otyp].oc_delay;
  1567. X    set_occupation(take_off, "disrobing", 0);
  1568. X    return(1);        /* get busy */
  1569. X}
  1570. X
  1571. X#endif /* OVLB */
  1572. X#ifdef OVL1
  1573. X
  1574. Xvoid
  1575. Xreset_remarm() { taking_off = takeoff_mask =0L; }
  1576. X
  1577. X#endif /* OVL1 */
  1578. X#ifdef OVLB
  1579. X
  1580. Xint
  1581. Xdoddoremarm() {
  1582. X
  1583. X    if(taking_off || takeoff_mask) {
  1584. X
  1585. X        You("continue disrobing.");
  1586. X        set_occupation(take_off, "disrobing", 0);
  1587. X        return(take_off());
  1588. X    }
  1589. X
  1590. X    (void) ggetobj("take off", select_off, 0);
  1591. X    if(takeoff_mask) return(take_off());
  1592. X    else         return(0);
  1593. X}
  1594. X
  1595. Xint
  1596. Xdestroy_arm(atmp)
  1597. Xregister struct obj *atmp;
  1598. X{
  1599. X    register struct obj *otmp;
  1600. X
  1601. X    if((otmp = uarmc) && (!atmp || atmp == uarmc)) {
  1602. X        Your("cloak crumbles and turns to dust!");
  1603. X        (void) Cloak_off();
  1604. X        useup(otmp);
  1605. X    } else if((otmp = uarm) && (!atmp || atmp == uarm)) {
  1606. X        /* may be disintegrated by spell or dragon breath... */
  1607. X        if (donning(otmp)) cancel_don();
  1608. X        Your("armor turns to dust and falls to the floor!");
  1609. X        (void) Armor_gone();
  1610. X        useup(otmp);
  1611. X#ifdef TOURIST
  1612. X    } else if((otmp = uarmu) && (!atmp || atmp == uarmu)) {
  1613. X        Your("shirt crumbles into tiny threads and falls apart!");
  1614. X        useup(otmp);
  1615. X#endif
  1616. X    } else if((otmp = uarmh) && (!atmp || atmp == uarmh)) {
  1617. X        if (donning(otmp)) cancel_don();
  1618. X        Your("helmet turns to dust and is blown away!");
  1619. X        (void) Helmet_off();
  1620. X        useup(otmp);
  1621. X    } else if((otmp = uarmg) && (!atmp || atmp == uarmg)) {
  1622. X        if (donning(otmp)) cancel_don();
  1623. X        Your("gloves vanish!");
  1624. X        (void) Gloves_off();
  1625. X        useup(otmp);
  1626. X        selftouch("You");
  1627. X    } else if((otmp = uarmf) && (!atmp || atmp == uarmf)) {
  1628. X        if (donning(otmp)) cancel_don();
  1629. X        Your("boots disintegrate!");
  1630. X        (void) Boots_off();
  1631. X        useup(otmp);
  1632. X    } else if((otmp =uarms) && (!atmp || atmp == uarms)) {
  1633. X        Your("shield crumbles away!");
  1634. X        (void) Shield_off();
  1635. X        useup(otmp);
  1636. X    } else    return(0);        /* could not destroy anything */
  1637. X
  1638. X    return(1);
  1639. X}
  1640. X
  1641. Xvoid
  1642. Xadj_abon(otmp, delta)
  1643. Xregister struct obj *otmp;
  1644. Xregister schar delta;
  1645. X{
  1646. X    if (uarmg && otmp->otyp == GAUNTLETS_OF_DEXTERITY) {
  1647. X        ABON(A_DEX) += (delta);
  1648. X        flags.botl = 1;
  1649. X    }
  1650. X    if (uarmh && otmp->otyp == HELM_OF_BRILLIANCE) {
  1651. X        ABON(A_INT) += (delta);
  1652. X        ABON(A_WIS) += (delta);
  1653. X        flags.botl = 1;
  1654. X    }
  1655. X}
  1656. X
  1657. X#endif /* OVLB */
  1658. X
  1659. X/*do_wear.c*/
  1660. END_OF_FILE
  1661. if test 37991 -ne `wc -c <'src/do_wear.c'`; then
  1662.     echo shar: \"'src/do_wear.c'\" unpacked with wrong size!
  1663. fi
  1664. # end of 'src/do_wear.c'
  1665. fi
  1666. if test -f 'src/spell.c' -a "${1}" != "-c" ; then 
  1667.   echo shar: Will not clobber existing file \"'src/spell.c'\"
  1668. else
  1669. echo shar: Extracting \"'src/spell.c'\" \(15639 characters\)
  1670. sed "s/^X//" >'src/spell.c' <<'END_OF_FILE'
  1671. X/*    SCCS Id: @(#)spell.c    3.1    92/12/10
  1672. X/*    Copyright (c) M. Stephenson 1988              */
  1673. X/* NetHack may be freely redistributed.  See license for details. */
  1674. X
  1675. X#include "hack.h"
  1676. X
  1677. Xstatic schar NEARDATA delay;        /* moves left for this spell */
  1678. Xstatic struct obj NEARDATA *book;    /* last/current book being xscribed */
  1679. X
  1680. X#define spelluses(spell)    spl_book[spell-1].sp_uses
  1681. X#define decrnuses(spell)    spl_book[spell-1].sp_uses--
  1682. X#define spellev(spell)        spl_book[spell-1].sp_lev
  1683. X#define spellname(spell)    OBJ_NAME(objects[spl_book[spell-1].sp_id])
  1684. X#define spellid(spell)        spl_book[spell-1].sp_id
  1685. X
  1686. Xstatic void FDECL(cursed_book, (int));
  1687. Xstatic void FDECL(deadbook, (struct obj *));
  1688. XSTATIC_PTR int NDECL(learn);
  1689. Xstatic int NDECL(getspell);
  1690. Xstatic char FDECL(spellet, (int));
  1691. Xstatic char NDECL(dospellmenu);
  1692. X
  1693. Xstatic void
  1694. Xcursed_book(lev)
  1695. X    register int    lev;
  1696. X{
  1697. X    switch(rn2(lev)) {
  1698. X    case 0:
  1699. X        You("feel a wrenching sensation.");
  1700. X        tele();        /* teleport him */
  1701. X        break;
  1702. X    case 1:
  1703. X        You("feel threatened.");
  1704. X        aggravate();
  1705. X        break;
  1706. X    case 2:
  1707. X        make_blinded(Blinded + rn1(100,250),TRUE);
  1708. X        break;
  1709. X    case 3:
  1710. X        take_gold();
  1711. X        break;
  1712. X    case 4:
  1713. X        pline("These runes were just too much to comprehend.");
  1714. X        make_confused(HConfusion + rn1(7,16),FALSE);
  1715. X        break;
  1716. X    case 5:
  1717. X        pline("The book was coated with contact poison!");
  1718. X        if (uarmg) {
  1719. X            /* Note: at this writing, there are no corrodeable
  1720. X             * gloves in the game.  If no one plans on adding
  1721. X             * copper gauntlets, most of this could be removed. -3.
  1722. X             */
  1723. X            if (uarmg->oerodeproof || !is_corrodeable(uarmg)) {
  1724. X            Your("gloves seem unaffected.");
  1725. X            } else if (uarmg->oeroded < MAX_ERODE) {
  1726. X            Your("gloves corrode%s!",
  1727. X                 uarmg->oeroded+1 == MAX_ERODE ? " completely" :
  1728. X                 uarmg->oeroded ? " further" : "");
  1729. X            uarmg->oeroded++;
  1730. X            } else
  1731. X            Your("gloves %s completely corroded.",
  1732. X                 Blind ? "feel" : "look");
  1733. X            break;
  1734. X        }
  1735. X        if(Poison_resistance) {
  1736. X            losestr(rn1(1,2));
  1737. X            losehp(rnd(6), "contact-poisoned spellbook", KILLED_BY_AN);
  1738. X        } else {
  1739. X            losestr(rn1(4,3));
  1740. X            losehp(rnd(10), "contact-poisoned spellbook", KILLED_BY_AN);
  1741. X        }
  1742. X        break;
  1743. X    case 6:
  1744. X        if(Antimagic) {
  1745. X            shieldeff(u.ux, u.uy);
  1746. X            pline("The book explodes, but you are unharmed!");
  1747. X        } else {
  1748. X            pline("As you read the book, it explodes in your %s!",
  1749. X            body_part(FACE));
  1750. X            losehp (2*rnd(10)+5, "exploding rune", KILLED_BY_AN);
  1751. X        }
  1752. X        break;
  1753. X    default:
  1754. X        rndcurse();
  1755. X        break;
  1756. X    }
  1757. X    return;
  1758. X}
  1759. X
  1760. X/* special effects for The Book of the Dead */
  1761. Xstatic void
  1762. Xdeadbook(book2)
  1763. Xstruct obj *book2;
  1764. X{
  1765. X    if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) {
  1766. X    register struct obj *otmp;
  1767. X    register boolean arti1_primed = FALSE, arti2_primed = FALSE,
  1768. X             arti_cursed = FALSE;
  1769. X
  1770. X    if(book2->cursed) {
  1771. X        pline("The runes appear scrambled.  You can't read them!");
  1772. X        return;
  1773. X    }
  1774. X
  1775. X    if(!u.uhave.bell || !u.uhave.menorah) {
  1776. X        pline("A chill runs down your spine.");
  1777. X        if(!u.uhave.bell) You("hear a faint chime...");
  1778. X        if(!u.uhave.menorah) pline("Vlad's doppelganger is amused.");
  1779. X        return;
  1780. X    }
  1781. X
  1782. X    for(otmp = invent; otmp; otmp = otmp->nobj) {
  1783. X        if(otmp->otyp == CANDELABRUM_OF_INVOCATION &&
  1784. X           otmp->spe == 7 && otmp->lamplit) {
  1785. X        if(!otmp->cursed) arti1_primed = TRUE;
  1786. X        else arti_cursed = TRUE;
  1787. X        }
  1788. X        if(otmp->otyp == BELL_OF_OPENING &&
  1789. X           (moves - otmp->age) < 5L) { /* you rang it recently */
  1790. X        if(!otmp->cursed) arti2_primed = TRUE;
  1791. X        else arti_cursed = TRUE;
  1792. X        }
  1793. X    }
  1794. X
  1795. X    if(arti_cursed) {
  1796. X        pline("The invocation fails!");
  1797. X        pline("At least one of your artifacts is cursed...");
  1798. X    } else if(arti1_primed && arti2_primed) {
  1799. X        mkinvokearea();
  1800. X        u.uevent.invoked = 1;
  1801. X    } else {    /* at least one artifact not prepared properly */
  1802. X        You("have a feeling that something is amiss...");
  1803. X        goto raise_dead;
  1804. X    }
  1805. X    return;
  1806. X    }
  1807. X
  1808. X    /* when not an invocation situation */
  1809. X    if(book2->cursed)
  1810. Xraise_dead:
  1811. X    {
  1812. X    register struct monst *mtmp;
  1813. X    coord mm;
  1814. X
  1815. X    You("raised the dead!");
  1816. X    mm.x = u.ux;
  1817. X    mm.y = u.uy;
  1818. X    mkundead(&mm);
  1819. X    if(!rn2(4))
  1820. X        if(mtmp = makemon(&mons[PM_MASTER_LICH],u.ux,u.uy)) {
  1821. X        mtmp->mpeaceful = 0;
  1822. X        set_malign(mtmp);
  1823. X        }
  1824. X    } else if(book2->blessed) {
  1825. X    register struct monst *mtmp, *mtmp2;
  1826. X
  1827. X    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
  1828. X        mtmp2 = mtmp->nmon;        /* tamedog() changes chain */
  1829. X        if(is_undead(mtmp->data) && cansee(mtmp->mx, mtmp->my)) {
  1830. X        mtmp->mpeaceful = TRUE;
  1831. X        if(sgn(mtmp->data->maligntyp) == sgn(u.ualign.type)
  1832. X           && distu(mtmp->mx, mtmp->my) < 4)
  1833. X            if (mtmp->mtame)
  1834. X            mtmp->mtame++;
  1835. X            else
  1836. X            (void) tamedog(mtmp, (struct obj *)0);
  1837. X        else mtmp->mflee = TRUE;
  1838. X        }
  1839. X    }
  1840. X    } else {
  1841. X    switch(rn2(3)) {
  1842. X    case 0: 
  1843. X        Your("ancestors are annoyed with you!"); 
  1844. X        break;
  1845. X    case 1: 
  1846. X        pline("The headstones in the cemetery begin to move!");
  1847. X        break;
  1848. X    default:
  1849. X        pline("Oh my!  Your name appears in the book!");
  1850. X    }
  1851. X    }
  1852. X    return;
  1853. X}
  1854. X
  1855. XSTATIC_PTR
  1856. Xint
  1857. Xlearn()
  1858. X{
  1859. X    register int    i;
  1860. X    register unsigned booktype;
  1861. X
  1862. X    if (delay) {    /* not if (delay++), so at end delay == 0 */
  1863. X        delay++;
  1864. X        return(1); /* still busy */
  1865. X    }
  1866. X    exercise(A_WIS, TRUE);        /* you're studying. */
  1867. X    booktype = book->otyp;
  1868. X    if(booktype == SPE_BOOK_OF_THE_DEAD) {
  1869. X        deadbook(book);
  1870. X        return(0);
  1871. X    }
  1872. X
  1873. X    for (i = 0; i < MAXSPELL; i++)  {
  1874. X        if (spl_book[i].sp_id == booktype)  {
  1875. X            if (book->spestudied >= rn1(1,8-spl_book[i].sp_lev)) {
  1876. X                pline("This spellbook is too faint to be read anymore.");
  1877. X                book->otyp = booktype = SPE_BLANK_PAPER;
  1878. X                makeknown((int)booktype);
  1879. X            }
  1880. X            else if (spl_book[i].sp_uses < 11-spl_book[i].sp_lev) {
  1881. X                Your("knowledge of that spell is keener.");
  1882. X                spl_book[i].sp_uses += rn1(1,9-spl_book[i].sp_lev);
  1883. X                book->spestudied++;
  1884. X                exercise(A_WIS, TRUE);    /* extra study */
  1885. X            } else
  1886. X                You("know that spell quite well already.");
  1887. X            break;
  1888. X        } else if (spl_book[i].sp_id == NO_SPELL)  {
  1889. X            spl_book[i].sp_id = booktype;
  1890. X            spl_book[i].sp_lev = objects[booktype].oc_level;
  1891. X            /* spells have 1 .. 9-level uses. */
  1892. X            /* ie 1 or 2 uses w/ most potent */
  1893. X            spl_book[i].sp_uses = rn1(1,9-spl_book[i].sp_lev);
  1894. X            book->spestudied++;
  1895. X            You("add the spell to your repertoire.");
  1896. X            makeknown((int)booktype);
  1897. X            break;
  1898. X        }
  1899. X    }
  1900. X    if (i == MAXSPELL) impossible("Too many spells memorized!");
  1901. X
  1902. X    if (book->cursed) {    /* maybe a demon cursed it */
  1903. X        cursed_book(objects[booktype].oc_level);
  1904. X    }
  1905. X        check_unpaid(book);
  1906. X    book = 0;
  1907. X    return(0);
  1908. X}
  1909. X
  1910. Xint
  1911. Xstudy_book(spellbook)
  1912. Xregister struct obj *spellbook;
  1913. X{
  1914. X    register int     booktype = spellbook->otyp;
  1915. X    register boolean confused = (Confusion != 0);
  1916. X
  1917. X    if (delay && spellbook == book)
  1918. X        You("continue your efforts to memorize the spell.");
  1919. X    else {
  1920. X        switch(booktype)  {
  1921. X
  1922. X/* blank spellbook */
  1923. X    case SPE_BLANK_PAPER:
  1924. X        pline("This spellbook is all blank.");
  1925. X        makeknown(SPE_BLANK_PAPER);
  1926. X        return(1);
  1927. X/* level 1 spells */
  1928. X    case SPE_HEALING:
  1929. X    case SPE_DETECT_MONSTERS:
  1930. X    case SPE_FORCE_BOLT:
  1931. X    case SPE_LIGHT:
  1932. X    case SPE_SLEEP:
  1933. X    case SPE_KNOCK:
  1934. X/* level 2 spells */
  1935. X    case SPE_MAGIC_MISSILE:
  1936. X    case SPE_CONFUSE_MONSTER:
  1937. X    case SPE_SLOW_MONSTER:
  1938. X    case SPE_CURE_BLINDNESS:
  1939. X    case SPE_CREATE_MONSTER:
  1940. X    case SPE_DETECT_FOOD:
  1941. X    case SPE_WIZARD_LOCK:
  1942. X        delay = -objects[booktype].oc_delay;
  1943. X        break;
  1944. X/* level 3 spells */
  1945. X    case SPE_HASTE_SELF:
  1946. X    case SPE_CAUSE_FEAR:
  1947. X    case SPE_CURE_SICKNESS:
  1948. X    case SPE_DETECT_UNSEEN:
  1949. X    case SPE_EXTRA_HEALING:
  1950. X    case SPE_CHARM_MONSTER:
  1951. X    case SPE_CLAIRVOYANCE:
  1952. X/* level 4 spells */
  1953. X    case SPE_LEVITATION:
  1954. X    case SPE_RESTORE_ABILITY:
  1955. X    case SPE_INVISIBILITY:
  1956. X    case SPE_FIREBALL:
  1957. X    case SPE_DETECT_TREASURE:
  1958. X        delay = -(objects[booktype].oc_level - 1) * objects[booktype].oc_delay;
  1959. X        break;
  1960. X/* level 5 spells */
  1961. X    case SPE_REMOVE_CURSE:
  1962. X    case SPE_MAGIC_MAPPING:
  1963. X    case SPE_CONE_OF_COLD:
  1964. X    case SPE_IDENTIFY:
  1965. X    case SPE_DIG:
  1966. X/* level 6 spells */
  1967. X    case SPE_TURN_UNDEAD:
  1968. X    case SPE_POLYMORPH:
  1969. X    case SPE_CREATE_FAMILIAR:
  1970. X    case SPE_TELEPORT_AWAY:
  1971. X        delay = -objects[booktype].oc_level * objects[booktype].oc_delay;
  1972. X        break;
  1973. X/* level 7 spells */
  1974. X    case SPE_CANCELLATION:
  1975. X    case SPE_FINGER_OF_DEATH:
  1976. X    case SPE_BOOK_OF_THE_DEAD:
  1977. X        delay = -8 * objects[booktype].oc_delay;
  1978. X        break;
  1979. X/* impossible */
  1980. X    default:
  1981. X        impossible("Unknown spellbook, %d;", booktype);
  1982. X        return(0);
  1983. X    }
  1984. X
  1985. X        /* Books are often wiser than their readers (Rus.) */
  1986. X        if(!spellbook->blessed &&
  1987. X                spellbook->otyp != SPE_BOOK_OF_THE_DEAD &&
  1988. X            (spellbook->cursed ||
  1989. X                rn2(20) > (ACURR(A_INT) + 4 + (int)(u.ulevel/2)
  1990. X                    - 2*objects[booktype].oc_level))) {
  1991. X            cursed_book(objects[booktype].oc_level);
  1992. X            nomul(delay);            /* study time */
  1993. X            delay = 0;
  1994. X            if(!rn2(3)) {
  1995. X                useup(spellbook);
  1996. X                pline("The spellbook crumbles to dust!");
  1997. X            }
  1998. X            return(1);
  1999. X        }
  2000. X        else if(confused) {
  2001. X            if(!rn2(3) && 
  2002. X                spellbook->otyp != SPE_BOOK_OF_THE_DEAD) {
  2003. X                useup(spellbook);
  2004. X                pline("Being confused you have difficulties in controlling your actions.");
  2005. X                display_nhwindow(WIN_MESSAGE, FALSE);
  2006. X                You("accidentally tear the spellbook to pieces.");
  2007. X            }
  2008. X            else
  2009. X                You("find yourself reading the first line over and over again.");
  2010. X            nomul(delay);
  2011. X            delay = 0;
  2012. X            return(1);
  2013. X        }
  2014. X
  2015. X        You("begin to %s the runes.",
  2016. X            spellbook->otyp == SPE_BOOK_OF_THE_DEAD ? "recite" :
  2017. X            "memorize");
  2018. X    }
  2019. X
  2020. X    book = spellbook;
  2021. X    set_occupation(learn, "studying", 0);
  2022. X    return(1);
  2023. X}
  2024. X
  2025. Xstatic int
  2026. Xgetspell()
  2027. X{
  2028. X    register int    maxs, ilet, i;
  2029. X    char     lets[BUFSZ], buf[BUFSZ], qbuf[QBUFSZ];
  2030. X
  2031. X    if (spl_book[0].sp_id == NO_SPELL)  {
  2032. X
  2033. X        You("don't know any spells right now.");
  2034. X        return(0);
  2035. X    } else  {
  2036. X
  2037. X        for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
  2038. X        if (maxs >= MAXSPELL)  {
  2039. X
  2040. X        impossible("Too many spells memorized.");
  2041. X        return(0);
  2042. X        }
  2043. X
  2044. X        for(i = 0; (i < maxs) && (i < 26); buf[++i] = 0)  buf[i] = 'a' + i;
  2045. X        for(i = 26; (i < maxs) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26;
  2046. X
  2047. X        if (maxs == 1)  Strcpy(lets, "a");
  2048. X        else if (maxs < 27)  Sprintf(lets, "a-%c", 'a' + maxs - 1);
  2049. X        else if (maxs == 27)  Sprintf(lets, "a-z A");
  2050. X        else Sprintf(lets, "a-z A-%c", 'A' + maxs - 27);
  2051. X        for(;;)  {
  2052. X
  2053. X        Sprintf(qbuf, "Cast which spell? [%s ?]", lets);
  2054. X        if ((ilet = yn_function(qbuf, NULL, '\0')) == '?') {
  2055. X            ilet = dospellmenu();
  2056. X            if(!ilet)
  2057. X                continue;
  2058. X        }
  2059. X        if (index(quitchars, ilet))
  2060. X            return(0);
  2061. X        else for(i = 0; buf[i] != 0; i++)
  2062. X            if(ilet == buf[i])  return(++i);
  2063. X        You("don't know that spell.");
  2064. X        }
  2065. X    }
  2066. X}
  2067. X
  2068. Xint
  2069. Xdocast()
  2070. X{
  2071. X    register int     spell;
  2072. X
  2073. X    spell = getspell();
  2074. X    if (!spell) return(0);
  2075. X
  2076. X    return(spelleffects(spell,FALSE));
  2077. X}
  2078. X
  2079. Xint
  2080. Xspelleffects(spell,atme)
  2081. Xregister int spell;
  2082. Xboolean atme;
  2083. X{
  2084. X    register int energy, damage;
  2085. X    boolean confused = (Confusion != 0);
  2086. X    struct obj *pseudo;
  2087. X
  2088. X    /* note that trying to cast it decrements the # of uses,    */
  2089. X    /* even if the mage does not have enough food/energy to use */
  2090. X    /* the spell */
  2091. X    switch (spelluses(spell)) {
  2092. X        case 0:
  2093. X            pline ("Curdled magical energy twists through you...");
  2094. X            pline ("...you have overloaded and burned out this spell.");
  2095. X            make_confused((long)spellev(spell) * 3, FALSE);
  2096. X            return(0);
  2097. X        case 1:
  2098. X            Your("nerves tingle warningly.");
  2099. X            break;
  2100. X        case 2:
  2101. X            pline ("This spell is starting to be over-used.");
  2102. X            break;
  2103. X        default:
  2104. X            break;
  2105. X    }
  2106. X    decrnuses(spell);
  2107. X    energy = spellev(spell) * 7 / 2 - 2;    /* 1 <= energy <= 22 */
  2108. X    if (u.uhunger <= 100 && spell != SPE_DETECT_FOOD) {
  2109. X        You("are too hungry to cast that spell.");
  2110. X        return(0);
  2111. X    } else if (ACURR(A_STR) < 6)  {
  2112. X        You("lack the strength to cast spells.");
  2113. X        return(0);
  2114. X    } else if(check_capacity(
  2115. X        "Your concentration falters while carrying so much stuff.")) {
  2116. X        return (1);
  2117. X    }
  2118. X
  2119. X    if (u.uhave.amulet) {
  2120. X        You("feel the amulet draining your energy away.");
  2121. X        energy *= rnd(3);
  2122. X    }
  2123. X    if(energy > u.uen)  {
  2124. X        You("don't have enough energy to cast that spell.");
  2125. X        return(0);
  2126. X    } else {
  2127. X        if (spell != SPE_DETECT_FOOD)
  2128. X            morehungry(energy * 10);
  2129. X        u.uen -= energy;
  2130. X    }
  2131. X    flags.botl = 1;
  2132. X
  2133. X    if (confused ||
  2134. X        ((int)(ACURR(A_INT) + Luck) - 3 * spellev(spell)) < 0) {
  2135. X
  2136. X        if (Hallucination)
  2137. X            pline("Far out... a light show!");
  2138. X        else    pline("The air around you crackles as you goof up.");
  2139. X        return(0);
  2140. X    }
  2141. X    exercise(A_WIS, TRUE);
  2142. X/*    pseudo is a temporary "false" object containing the spell stats. */
  2143. X    pseudo = mksobj(spellid(spell), FALSE, FALSE);
  2144. X    pseudo->blessed = pseudo->cursed = 0;
  2145. X    pseudo->quan = 20L;            /* do not let useup get it */
  2146. X    switch(pseudo->otyp)  {
  2147. X
  2148. X/* These spells are all duplicates of wand effects */
  2149. X    case SPE_FORCE_BOLT:
  2150. X    case SPE_SLEEP:
  2151. X    case SPE_MAGIC_MISSILE:
  2152. X    case SPE_KNOCK:
  2153. X    case SPE_SLOW_MONSTER:
  2154. X    case SPE_WIZARD_LOCK:
  2155. X    case SPE_FIREBALL:
  2156. X    case SPE_CONE_OF_COLD:
  2157. X    case SPE_DIG:
  2158. X    case SPE_TURN_UNDEAD:
  2159. X    case SPE_POLYMORPH:
  2160. X    case SPE_TELEPORT_AWAY:
  2161. X    case SPE_CANCELLATION:
  2162. X    case SPE_FINGER_OF_DEATH:
  2163. X    case SPE_LIGHT:
  2164. X    case SPE_DETECT_UNSEEN:
  2165. X        if (!(objects[pseudo->otyp].oc_dir == NODIR)) {
  2166. X            if (atme) u.dx = u.dy = u.dz = 0;
  2167. X            else (void) getdir(NULL);
  2168. X            if(!u.dx && !u.dy && !u.dz) {
  2169. X                if((damage = zapyourself(pseudo)))
  2170. X                losehp(damage, 
  2171. X        self_pronoun("zapped %sself with a spell", "him"),
  2172. X                    NO_KILLER_PREFIX);
  2173. X            } else    weffects(pseudo);
  2174. X        } else weffects(pseudo);
  2175. X        break;
  2176. X/* These are all duplicates of scroll effects */
  2177. X    case SPE_CONFUSE_MONSTER:
  2178. X    case SPE_DETECT_FOOD:
  2179. X    case SPE_CAUSE_FEAR:
  2180. X    case SPE_CHARM_MONSTER:
  2181. X    case SPE_REMOVE_CURSE:
  2182. X    case SPE_MAGIC_MAPPING:
  2183. X    case SPE_CREATE_MONSTER:
  2184. X    case SPE_IDENTIFY:
  2185. X        (void) seffects(pseudo);
  2186. X        break;
  2187. X    case SPE_HASTE_SELF:
  2188. X    case SPE_DETECT_TREASURE:
  2189. X    case SPE_DETECT_MONSTERS:
  2190. X    case SPE_LEVITATION:
  2191. X    case SPE_RESTORE_ABILITY:
  2192. X    case SPE_INVISIBILITY:
  2193. X        (void) peffects(pseudo);
  2194. X        break;
  2195. X    case SPE_HEALING:
  2196. X        You("feel a bit better.");
  2197. X        healup(rnd(8), 0, FALSE, FALSE);
  2198. X        break;
  2199. X    case SPE_CURE_BLINDNESS:
  2200. X        healup(0, 0, FALSE, TRUE);
  2201. X        break;
  2202. X    case SPE_CURE_SICKNESS:
  2203. X        if (Sick) You("are no longer ill.");
  2204. X        healup(0, 0, TRUE, FALSE);
  2205. X        break;
  2206. X    case SPE_EXTRA_HEALING:
  2207. X        You("feel a fair bit better.");
  2208. X        healup(d(2,8)+2, 0, FALSE, FALSE);
  2209. X        break;
  2210. X    case SPE_CREATE_FAMILIAR:
  2211. X        make_familiar((struct obj *)0, u.ux, u.uy);
  2212. X        break;
  2213. X    case SPE_CLAIRVOYANCE:
  2214. X        do_vicinity_map();
  2215. X        break;
  2216. X    default:
  2217. X        impossible("Unknown spell %d attempted.", spell);
  2218. X        obfree(pseudo, (struct obj *)0);
  2219. X        return(0);
  2220. X    }
  2221. X    obfree(pseudo, (struct obj *)0);    /* now, get rid of it */
  2222. X    return(1);
  2223. X}
  2224. X
  2225. Xvoid
  2226. Xlosespells() {
  2227. X    register boolean confused = (Confusion != 0);
  2228. X    register int     n, nzap, i;
  2229. X
  2230. X    book = 0;
  2231. X    for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++);
  2232. X    if (!n) return;
  2233. X    if (n < MAXSPELL) {
  2234. X        nzap = rnd(n);
  2235. X        if (nzap < n) nzap += confused;
  2236. X        for (i = 0; i < nzap; i++) {
  2237. X            spl_book[n-i-1].sp_id = NO_SPELL;
  2238. X            exercise(A_WIS, FALSE);    /* ouch! */
  2239. X        }
  2240. X    } else impossible("Too many spells memorized!");
  2241. X    return;
  2242. X}
  2243. X
  2244. Xstatic char
  2245. Xspellet(spl)
  2246. Xint spl;
  2247. X{
  2248. X    return (spl < 27) ? ('a' + spl - 1) : ('A' + spl - 27);
  2249. X}
  2250. X
  2251. Xint
  2252. Xdovspell()
  2253. X{
  2254. X    (void) dospellmenu();
  2255. X    return 0;
  2256. X}
  2257. X
  2258. Xstatic char
  2259. Xdospellmenu()
  2260. X{
  2261. X    winid tmpwin;
  2262. X    register int maxs, i;
  2263. X    char rval;
  2264. X    char     buf[BUFSZ];
  2265. X
  2266. X    if (spl_book[0].sp_id == NO_SPELL)  {
  2267. X
  2268. X        You("don't know any spells right now.");
  2269. X        return 0;
  2270. X    }
  2271. X
  2272. X    for(maxs = 1; (maxs < MAXSPELL) && (spl_book[maxs].sp_id != NO_SPELL); maxs++);
  2273. X    if (maxs >= MAXSPELL)  {
  2274. X
  2275. X        impossible("Too many spells memorized.");
  2276. X        return 0;
  2277. X    }
  2278. X    tmpwin = create_nhwindow(NHW_MENU);
  2279. X    start_menu(tmpwin);
  2280. X    add_menu(tmpwin, 0, 0, "Currently known spells:");
  2281. X    add_menu(tmpwin, 0, 0, "");
  2282. X
  2283. X    for(i = 1; i <= maxs; i++) {
  2284. X        Sprintf(buf, "%c %c %s (%d)",
  2285. X            spellet(i), (spelluses(i)) ? '-' : '*',
  2286. X            spellname(i), spellev(i));
  2287. X        add_menu(tmpwin, spellet(i), 0, buf);
  2288. X      }
  2289. X    end_menu(tmpwin, '\0', "\033 ", NULL);
  2290. X    rval = select_menu(tmpwin);
  2291. X    destroy_nhwindow(tmpwin);
  2292. X
  2293. X    return rval;
  2294. X}
  2295. X
  2296. X/*spell.c*/
  2297. END_OF_FILE
  2298. if test 15639 -ne `wc -c <'src/spell.c'`; then
  2299.     echo shar: \"'src/spell.c'\" unpacked with wrong size!
  2300. fi
  2301. # end of 'src/spell.c'
  2302. fi
  2303. echo shar: End of archive 41 \(of 108\).
  2304. cp /dev/null ark41isdone
  2305. MISSING=""
  2306. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  2307. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  2308. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  2309. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  2310. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  2311. 101 102 103 104 105 106 107 108 ; do
  2312.     if test ! -f ark${I}isdone ; then
  2313.     MISSING="${MISSING} ${I}"
  2314.     fi
  2315. done
  2316. if test "${MISSING}" = "" ; then
  2317.     echo You have unpacked all 108 archives.
  2318.     echo "Now execute 'rebuild.sh'"
  2319.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  2320. else
  2321.     echo You still need to unpack the following archives:
  2322.     echo "        " ${MISSING}
  2323. fi
  2324. ##  End of shell archive.
  2325. exit 0
  2326.