home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume14 / umoria4 / part07 < prev    next >
Internet Message Format  |  1992-08-31  |  57KB

  1. Path: uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v14i039:  umoria4 - single player dungeon simulation (ver. 5.5), Part07/39
  5. Message-ID: <3397@master.CNA.TEK.COM>
  6. Date: 20 Aug 92 18:02:59 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2254
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: grabiner@math.harvard.edu (David Grabiner)
  12. Posting-number: Volume 14, Issue 39
  13. Archive-name: umoria4/Part07
  14. Supersedes: umoria3: Volume 9, Issue 55-97; Volume 10, Issue 15-17
  15. Environment: Curses, Unix, Mac, MS-DOS, Atari-ST, Amiga, VMS
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 7 (of 39)."
  26. # Contents:  source/moria1.c util/mc/mon.inf
  27. # Wrapped by billr@saab on Thu Aug 20 09:11:27 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'source/moria1.c' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'source/moria1.c'\"
  31. else
  32. echo shar: Extracting \"'source/moria1.c'\" \(45054 characters\)
  33. sed "s/^X//" >'source/moria1.c' <<'END_OF_FILE'
  34. X/* source/moria1.c: misc code, mainly handles player movement, inventory, etc
  35. X
  36. X   Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  37. X
  38. X   This software may be copied and distributed for educational, research, and
  39. X   not for profit purposes provided that this copyright and statement are
  40. X   included in all such copies. */
  41. X
  42. X#ifdef __TURBOC__
  43. X#include    <stdlib.h>
  44. X#endif
  45. X
  46. X#include <stdio.h>
  47. X#include <ctype.h>
  48. X
  49. X#include "config.h"
  50. X#include "constant.h"
  51. X#include "types.h"
  52. X#include "externs.h"
  53. X
  54. X#ifdef USG
  55. X#ifndef ATARIST_MWC
  56. X#include <string.h>
  57. X#else
  58. Xchar *strcat();
  59. Xint strlen();
  60. X#endif
  61. X#else
  62. X#include <strings.h>
  63. X#endif
  64. X
  65. X#if defined(LINT_ARGS)
  66. Xstatic void inven_screen(int);
  67. Xstatic char map_roguedir(char);
  68. Xstatic void sub1_move_light(int, int, int, int);
  69. Xstatic void sub3_move_light(int, int, int, int);
  70. X#endif
  71. X
  72. X#ifdef ATARIST_TC
  73. X/* Include this to get prototypes for standard library functions.  */
  74. X#include <stdlib.h>
  75. X#endif
  76. X
  77. X/* Changes speed of monsters relative to player        -RAK-    */
  78. X/* Note: When the player is sped up or slowed down, I simply     */
  79. X/*     change the speed of all the monsters.    This greatly     */
  80. X/*     simplified the logic.                       */
  81. Xvoid change_speed(num)
  82. Xregister int num;
  83. X{
  84. X  register int i;
  85. X#ifdef ATARIST_MWC
  86. X  int32u holder;
  87. X#endif
  88. X
  89. X  py.flags.speed += num;
  90. X#ifdef ATARIST_MWC
  91. X  py.flags.status |= (holder = PY_SPEED);
  92. X#else
  93. X  py.flags.status |= PY_SPEED;
  94. X#endif
  95. X  for (i = mfptr - 1; i >= MIN_MONIX; i--)
  96. X      m_list[i].cspeed += num;
  97. X}
  98. X
  99. X
  100. X/* Player bonuses                    -RAK-    */
  101. X/* When an item is worn or taken off, this re-adjusts the player */
  102. X/* bonuses.  Factor=1 : wear; Factor=-1 : removed         */
  103. X/* Only calculates properties with cumulative effect.  Properties that
  104. X   depend on everything being worn are recalculated by calc_bonuses() -CJS- */
  105. Xvoid py_bonuses(t_ptr, factor)
  106. Xregister inven_type *t_ptr;
  107. Xregister int factor;
  108. X{
  109. X  register int i, amount;
  110. X#ifdef ATARIST_MWC
  111. X  int32u holder;
  112. X#endif
  113. X
  114. X  amount = t_ptr->p1 * factor;
  115. X  if (t_ptr->flags & TR_STATS)
  116. X    {
  117. X      for(i = 0; i < 6; i++)
  118. X    if ((1 << i) & t_ptr->flags)
  119. X      bst_stat(i, amount);
  120. X    }
  121. X  if (TR_SEARCH & t_ptr->flags)
  122. X    {
  123. X      py.misc.srh += amount;
  124. X      py.misc.fos -= amount;
  125. X    }
  126. X  if (TR_STEALTH & t_ptr->flags)
  127. X    py.misc.stl += amount;
  128. X  if (TR_SPEED & t_ptr->flags)
  129. X    change_speed(-amount);
  130. X#ifdef ATARIST_MWC
  131. X  if (((holder = TR_BLIND) & t_ptr->flags) && (factor > 0))
  132. X    py.flags.blind += 1000;
  133. X  if (((holder = TR_TIMID) & t_ptr->flags) && (factor > 0))
  134. X    py.flags.afraid += 50;
  135. X  if ((holder = TR_INFRA) & t_ptr->flags)
  136. X    py.flags.see_infra += amount;
  137. X#else
  138. X  if ((TR_BLIND & t_ptr->flags) && (factor > 0))
  139. X    py.flags.blind += 1000;
  140. X  if ((TR_TIMID & t_ptr->flags) && (factor > 0))
  141. X    py.flags.afraid += 50;
  142. X  if (TR_INFRA & t_ptr->flags)
  143. X    py.flags.see_infra += amount;
  144. X#endif
  145. X}
  146. X
  147. X/* Recalculate the effect of all the stuff we use.          -CJS- */
  148. Xvoid calc_bonuses()
  149. X{
  150. X  register int32u item_flags;
  151. X#if defined(ATARIST_MWC)
  152. X  int32u holder;        /* to avoid a compiler bug */
  153. X#endif
  154. X  int old_dis_ac;
  155. X  register struct flags *p_ptr;
  156. X  register struct misc *m_ptr;
  157. X  register inven_type *i_ptr;
  158. X  register int i;
  159. X
  160. X  p_ptr = &py.flags;
  161. X  m_ptr = &py.misc;
  162. X  if (p_ptr->slow_digest)
  163. X    p_ptr->food_digested++;
  164. X  if (p_ptr->regenerate)
  165. X    p_ptr->food_digested -= 3;
  166. X  p_ptr->see_inv     = FALSE;
  167. X  p_ptr->teleport    = FALSE;
  168. X  p_ptr->free_act    = FALSE;
  169. X  p_ptr->slow_digest = FALSE;
  170. X  p_ptr->aggravate   = FALSE;
  171. X  p_ptr->sustain_str = FALSE;
  172. X  p_ptr->sustain_int = FALSE;
  173. X  p_ptr->sustain_wis = FALSE;
  174. X  p_ptr->sustain_con = FALSE;
  175. X  p_ptr->sustain_dex = FALSE;
  176. X  p_ptr->sustain_chr = FALSE;
  177. X  p_ptr->fire_resist = FALSE;
  178. X  p_ptr->acid_resist = FALSE;
  179. X  p_ptr->cold_resist = FALSE;
  180. X  p_ptr->regenerate  = FALSE;
  181. X  p_ptr->lght_resist = FALSE;
  182. X  p_ptr->ffall         = FALSE;
  183. X
  184. X  old_dis_ac = m_ptr->dis_ac;
  185. X  m_ptr->ptohit     = tohit_adj();          /* Real To Hit   */
  186. X  m_ptr->ptodam     = todam_adj();          /* Real To Dam   */
  187. X  m_ptr->ptoac     = toac_adj();          /* Real To AC    */
  188. X  m_ptr->pac     = 0;            /* Real AC         */
  189. X  m_ptr->dis_th     = m_ptr->ptohit;  /* Display To Hit        */
  190. X  m_ptr->dis_td     = m_ptr->ptodam;  /* Display To Dam        */
  191. X  m_ptr->dis_ac     = 0;        /* Display AC         */
  192. X  m_ptr->dis_tac = m_ptr->ptoac;   /* Display To AC        */
  193. X  for (i = INVEN_WIELD; i < INVEN_LIGHT; i++)
  194. X    {
  195. X      i_ptr = &inventory[i];
  196. X      if (i_ptr->tval != TV_NOTHING)
  197. X    {
  198. X      m_ptr->ptohit += i_ptr->tohit;
  199. X      if (i_ptr->tval != TV_BOW)        /* Bows can't damage. -CJS- */
  200. X        m_ptr->ptodam += i_ptr->todam;
  201. X      m_ptr->ptoac    += i_ptr->toac;
  202. X      m_ptr->pac += i_ptr->ac;
  203. X      if (known2_p(i_ptr))
  204. X        {
  205. X          m_ptr->dis_th  += i_ptr->tohit;
  206. X          if (i_ptr->tval != TV_BOW)
  207. X        m_ptr->dis_td  += i_ptr->todam;    /* Bows can't damage. -CJS- */
  208. X          m_ptr->dis_tac += i_ptr->toac;
  209. X          m_ptr->dis_ac += i_ptr->ac;
  210. X        }
  211. X      else if (! (TR_CURSED & i_ptr->flags))
  212. X        /* Base AC values should always be visible, as long as the item
  213. X           is not cursed.  */
  214. X        m_ptr->dis_ac += i_ptr->ac;
  215. X    }
  216. X    }
  217. X  m_ptr->dis_ac += m_ptr->dis_tac;
  218. X
  219. X  if (weapon_heavy)
  220. X    m_ptr->dis_th += (py.stats.use_stat[A_STR] * 15 -
  221. X              inventory[INVEN_WIELD].weight);
  222. X
  223. X  /* Add in temporary spell increases    */
  224. X  if (p_ptr->invuln > 0)
  225. X    {
  226. X      m_ptr->pac += 100;
  227. X      m_ptr->dis_ac += 100;
  228. X    }
  229. X  if (p_ptr->blessed > 0)
  230. X    {
  231. X      m_ptr->pac    += 2;
  232. X      m_ptr->dis_ac += 2;
  233. X    }
  234. X  if (p_ptr->detect_inv > 0)
  235. X    p_ptr->see_inv = TRUE;
  236. X
  237. X  /* can't print AC here because might be in a store */
  238. X  if (old_dis_ac != m_ptr->dis_ac)
  239. X#ifdef ATARIST_MWC
  240. X    p_ptr->status |= (holder = PY_ARMOR);
  241. X#else
  242. X    p_ptr->status |= PY_ARMOR;
  243. X#endif
  244. X
  245. X  item_flags = 0;
  246. X  i_ptr = &inventory[INVEN_WIELD];
  247. X  for (i = INVEN_WIELD; i < INVEN_LIGHT; i++)
  248. X    {
  249. X      item_flags |= i_ptr->flags;
  250. X      i_ptr++;
  251. X    }
  252. X#if !defined(ATARIST_MWC)
  253. X  if (TR_SLOW_DIGEST & item_flags)
  254. X    p_ptr->slow_digest = TRUE;
  255. X  if (TR_AGGRAVATE & item_flags)
  256. X    p_ptr->aggravate = TRUE;
  257. X  if (TR_TELEPORT & item_flags)
  258. X    p_ptr->teleport = TRUE;
  259. X  if (TR_REGEN & item_flags)
  260. X    p_ptr->regenerate = TRUE;
  261. X  if (TR_RES_FIRE & item_flags)
  262. X    p_ptr->fire_resist = TRUE;
  263. X  if (TR_RES_ACID & item_flags)
  264. X    p_ptr->acid_resist = TRUE;
  265. X  if (TR_RES_COLD & item_flags)
  266. X    p_ptr->cold_resist = TRUE;
  267. X  if (TR_FREE_ACT & item_flags)
  268. X    p_ptr->free_act = TRUE;
  269. X  if (TR_SEE_INVIS & item_flags)
  270. X    p_ptr->see_inv = TRUE;
  271. X  if (TR_RES_LIGHT & item_flags)
  272. X    p_ptr->lght_resist = TRUE;
  273. X  if (TR_FFALL & item_flags)
  274. X    p_ptr->ffall = TRUE;
  275. X#else
  276. X  /* this avoids a bug in the Mark Williams C compiler for the Atari ST */
  277. X  holder = TR_SLOW_DIGEST;
  278. X  if (holder & item_flags)
  279. X    p_ptr->slow_digest = TRUE;
  280. X  holder = TR_AGGRAVATE;
  281. X  if (holder & item_flags)
  282. X    p_ptr->aggravate = TRUE;
  283. X  holder = TR_TELEPORT;
  284. X  if (holder & item_flags)
  285. X    p_ptr->teleport = TRUE;
  286. X  holder = TR_REGEN;
  287. X  if (holder & item_flags)
  288. X    p_ptr->regenerate = TRUE;
  289. X  holder = TR_RES_FIRE;
  290. X  if (holder & item_flags)
  291. X    p_ptr->fire_resist = TRUE;
  292. X  holder = TR_RES_ACID;
  293. X  if (holder & item_flags)
  294. X    p_ptr->acid_resist = TRUE;
  295. X  holder = TR_RES_COLD;
  296. X  if (holder & item_flags)
  297. X    p_ptr->cold_resist = TRUE;
  298. X  holder = TR_FREE_ACT;
  299. X  if (holder & item_flags)
  300. X    p_ptr->free_act = TRUE;
  301. X  holder = TR_SEE_INVIS;
  302. X  if (holder & item_flags)
  303. X    p_ptr->see_inv = TRUE;
  304. X  holder = TR_RES_LIGHT;
  305. X  if (holder & item_flags)
  306. X    p_ptr->lght_resist = TRUE;
  307. X  holder = TR_FFALL;
  308. X  if (holder & item_flags)
  309. X    p_ptr->ffall = TRUE;
  310. X#endif
  311. X
  312. X  i_ptr = &inventory[INVEN_WIELD];
  313. X  for (i = INVEN_WIELD; i < INVEN_LIGHT; i++)
  314. X    {
  315. X#ifdef ATARIST_MWC
  316. X      if ((holder = TR_SUST_STAT) & i_ptr->flags)
  317. X#else
  318. X      if (TR_SUST_STAT & i_ptr->flags)
  319. X#endif
  320. X    switch(i_ptr->p1)
  321. X      {
  322. X      case 1: p_ptr->sustain_str = TRUE; break;
  323. X      case 2: p_ptr->sustain_int = TRUE; break;
  324. X      case 3: p_ptr->sustain_wis = TRUE; break;
  325. X      case 4: p_ptr->sustain_con = TRUE; break;
  326. X      case 5: p_ptr->sustain_dex = TRUE; break;
  327. X      case 6: p_ptr->sustain_chr = TRUE; break;
  328. X      default: break;
  329. X      }
  330. X      i_ptr++;
  331. X    }
  332. X
  333. X  if (p_ptr->slow_digest)
  334. X    p_ptr->food_digested--;
  335. X  if (p_ptr->regenerate)
  336. X    p_ptr->food_digested += 3;
  337. X}
  338. X
  339. X
  340. X/* Displays inventory items from r1 to r2    -RAK-    */
  341. X/* Designed to keep the display as far to the right as possible.  The  -CJS-
  342. X   parameter col gives a column at which to start, but if the display does
  343. X   not fit, it may be moved left.  The return value is the left edge used. */
  344. X/* If mask is non-zero, then only display those items which have a non-zero
  345. X   entry in the mask array.  */
  346. Xint show_inven(r1, r2, weight, col, mask)
  347. Xregister int r1, r2;
  348. Xint weight, col;
  349. Xchar *mask;
  350. X{
  351. X  register int i;
  352. X  int total_weight, len, l, lim, current_line;
  353. X  bigvtype tmp_val;
  354. X  vtype out_val[23];
  355. X
  356. X  len = 79 - col;
  357. X  if (weight)
  358. X    lim = 68;
  359. X  else
  360. X    lim = 76;
  361. X
  362. X  for (i = r1; i <= r2; i++)         /* Print the items      */
  363. X    {
  364. X      if (mask == CNIL || mask[i])
  365. X    {
  366. X      objdes(tmp_val, &inventory[i], TRUE);
  367. X      tmp_val[lim] = 0;     /* Truncate if too long. */
  368. X      (void) sprintf(out_val[i], "  %c) %s", 'a'+i, tmp_val);
  369. X      l = strlen(out_val[i]);
  370. X      if (weight)
  371. X        l += 9;
  372. X      if (l > len)
  373. X        len = l;
  374. X    }
  375. X    }
  376. X
  377. X  col = 79 - len;
  378. X  if (col < 0)
  379. X    col = 0;
  380. X
  381. X  current_line = 1;
  382. X  for (i = r1; i <= r2; i++)
  383. X    {
  384. X      if (mask == CNIL || mask[i])
  385. X    {
  386. X      /* don't need first two spaces if in first column */
  387. X      if (col == 0)
  388. X        prt(&out_val[i][2], current_line, col);
  389. X      else
  390. X        prt(out_val[i], current_line, col);
  391. X      if (weight)
  392. X        {
  393. X          total_weight = inventory[i].weight*inventory[i].number;
  394. X          (void) sprintf (tmp_val, "%3d.%d lb",
  395. X                  (total_weight) / 10, (total_weight) % 10);
  396. X          prt (tmp_val, current_line, 71);
  397. X        }
  398. X      current_line++;
  399. X    }
  400. X    }
  401. X  return col;
  402. X}
  403. X
  404. X
  405. X/* Return a string describing how a given equipment item is carried. -CJS- */
  406. Xchar *describe_use(i)
  407. Xregister int i;
  408. X{
  409. X  register char *p;
  410. X
  411. X  switch(i)
  412. X    {
  413. X    case INVEN_WIELD:
  414. X      p = "wielding"; break;
  415. X    case INVEN_HEAD:
  416. X      p = "wearing on your head"; break;
  417. X    case INVEN_NECK:
  418. X      p = "wearing around your neck"; break;
  419. X    case INVEN_BODY:
  420. X      p = "wearing on your body"; break;
  421. X    case INVEN_ARM:
  422. X      p = "wearing on your arm"; break;
  423. X    case INVEN_HANDS:
  424. X      p = "wearing on your hands"; break;
  425. X    case INVEN_RIGHT:
  426. X      p = "wearing on your right hand"; break;
  427. X    case INVEN_LEFT:
  428. X      p = "wearing on your left hand"; break;
  429. X    case INVEN_FEET:
  430. X      p = "wearing on your feet"; break;
  431. X    case INVEN_OUTER:
  432. X      p = "wearing about your body"; break;
  433. X    case INVEN_LIGHT:
  434. X      p = "using to light the way"; break;
  435. X    case INVEN_AUX:
  436. X      p = "holding ready by your side"; break;
  437. X    default:
  438. X      p = "carrying in your pack"; break;
  439. X    }
  440. X  return p;
  441. X}
  442. X
  443. X
  444. X/* Displays equipment items from r1 to end    -RAK-    */
  445. X/* Keep display as far right as possible. -CJS- */
  446. Xint show_equip(weight, col)
  447. Xint weight, col;
  448. X{
  449. X  register int i, line;
  450. X  int total_weight, l, len, lim;
  451. X  register char *prt1;
  452. X  bigvtype prt2;
  453. X  vtype out_val[INVEN_ARRAY_SIZE-INVEN_WIELD];
  454. X  register inven_type *i_ptr;
  455. X
  456. X  line = 0;
  457. X  len = 79 - col;
  458. X  if (weight)
  459. X    lim = 52;
  460. X  else
  461. X    lim = 60;
  462. X  for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) /* Range of equipment */
  463. X    {
  464. X      i_ptr = &inventory[i];
  465. X      if (i_ptr->tval != TV_NOTHING)
  466. X    {
  467. X      switch(i)         /* Get position          */
  468. X        {
  469. X        case INVEN_WIELD:
  470. X          if (py.stats.use_stat[A_STR]*15 < i_ptr->weight)
  471. X        prt1 = "Just lifting";
  472. X          else
  473. X        prt1 = "Wielding";
  474. X          break;
  475. X        case INVEN_HEAD:
  476. X          prt1 = "On head"; break;
  477. X        case INVEN_NECK:
  478. X          prt1 = "Around neck"; break;
  479. X        case INVEN_BODY:
  480. X          prt1 = "On body"; break;
  481. X        case INVEN_ARM:
  482. X          prt1 = "On arm"; break;
  483. X        case INVEN_HANDS:
  484. X          prt1 = "On hands"; break;
  485. X        case INVEN_RIGHT:
  486. X          prt1 = "On right hand"; break;
  487. X        case INVEN_LEFT:
  488. X          prt1 = "On left hand"; break;
  489. X        case INVEN_FEET:
  490. X          prt1 = "On feet"; break;
  491. X        case INVEN_OUTER:
  492. X          prt1 = "About body"; break;
  493. X        case INVEN_LIGHT:
  494. X          prt1 = "Light source"; break;
  495. X        case INVEN_AUX:
  496. X          prt1 = "Spare weapon"; break;
  497. X        default:
  498. X          prt1 = "Unknown value"; break;
  499. X        }
  500. X      objdes(prt2, &inventory[i], TRUE);
  501. X      prt2[lim] = 0; /* Truncate if necessary */
  502. X      (void) sprintf(out_val[line], "  %c) %-14s: %s", line+'a',
  503. X             prt1, prt2);
  504. X      l = strlen(out_val[line]);
  505. X      if (weight)
  506. X        l += 9;
  507. X      if (l > len)
  508. X        len = l;
  509. X      line++;
  510. X    }
  511. X    }
  512. X  col = 79 - len;
  513. X  if (col < 0)
  514. X    col = 0;
  515. X
  516. X  line = 0;
  517. X  for (i = INVEN_WIELD; i < INVEN_ARRAY_SIZE; i++) /* Range of equipment */
  518. X    {
  519. X      i_ptr = &inventory[i];
  520. X      if (i_ptr->tval != TV_NOTHING)
  521. X    {
  522. X      /* don't need first two spaces when using whole screen */
  523. X      if (col == 0)
  524. X        prt(&out_val[line][2], line+1, col);
  525. X      else
  526. X        prt(out_val[line], line+1, col);
  527. X      if (weight)
  528. X        {
  529. X          total_weight = i_ptr->weight*i_ptr->number;
  530. X          (void) sprintf(prt2, "%3d.%d lb",
  531. X                 (total_weight) / 10, (total_weight) % 10);
  532. X          prt(prt2, line+1, 71);
  533. X        }
  534. X      line++;
  535. X    }
  536. X    }
  537. X  erase_line(line+1, col);
  538. X  return col;
  539. X}
  540. X
  541. X/* Remove item from equipment list        -RAK-    */
  542. Xvoid takeoff(item_val, posn)
  543. Xint item_val, posn;
  544. X{
  545. X  register char *p;
  546. X  bigvtype out_val, prt2;
  547. X  register inven_type *t_ptr;
  548. X#ifdef ATARIST_MWC
  549. X  int32u holder;
  550. X#endif
  551. X
  552. X  equip_ctr--;
  553. X  t_ptr = &inventory[item_val];
  554. X  inven_weight -= t_ptr->weight*t_ptr->number;
  555. X#ifdef ATARIST_MWC
  556. X  py.flags.status |= (holder = PY_STR_WGT);
  557. X#else
  558. X  py.flags.status |= PY_STR_WGT;
  559. X#endif
  560. X
  561. X  if (item_val == INVEN_WIELD || item_val == INVEN_AUX)
  562. X    p = "Was wielding ";
  563. X  else if (item_val == INVEN_LIGHT)
  564. X    p = "Light source was ";
  565. X  else
  566. X    p = "Was wearing ";
  567. X
  568. X  objdes(prt2, t_ptr, TRUE);
  569. X  if (posn >= 0)
  570. X    (void) sprintf(out_val, "%s%s (%c)", p, prt2, 'a'+posn);
  571. X  else
  572. X    (void) sprintf(out_val, "%s%s", p, prt2);
  573. X  msg_print(out_val);
  574. X  if (item_val != INVEN_AUX)      /* For secondary weapon  */
  575. X    py_bonuses(t_ptr, -1);
  576. X  invcopy(t_ptr, OBJ_NOTHING);
  577. X}
  578. X
  579. X
  580. X/* Used to verify if this really is the item we wish to     -CJS-
  581. X   wear or read. */
  582. Xint verify(prompt, item)
  583. Xchar *prompt;
  584. Xint item;
  585. X{
  586. X  bigvtype out_str, object;
  587. X
  588. X  objdes(object, &inventory[item], TRUE);
  589. X  object[strlen(object)-1] = '?'; /* change the period to a question mark */
  590. X  (void) sprintf(out_str, "%s %s", prompt, object);
  591. X  return get_check(out_str);
  592. X}
  593. X
  594. X
  595. X/* All inventory commands (wear, exchange, take off, drop, inventory and
  596. X   equipment) are handled in an alternative command input mode, which accepts
  597. X   any of the inventory commands.
  598. X
  599. X   It is intended that this function be called several times in succession,
  600. X   as some commands take up a turn, and the rest of moria must proceed in the
  601. X   interim. A global variable is provided, doing_inven, which is normally
  602. X   zero; however if on return from inven_command it is expected that
  603. X   inven_command should be called *again*, (being still in inventory command
  604. X   input mode), then doing_inven is set to the inventory command character
  605. X   which should be used in the next call to inven_command.
  606. X
  607. X   On return, the screen is restored, but not flushed. Provided no flush of
  608. X   the screen takes place before the next call to inven_command, the inventory
  609. X   command screen is silently redisplayed, and no actual output takes place at
  610. X   all. If the screen is flushed before a subsequent call, then the player is
  611. X   prompted to see if we should continue. This allows the player to see any
  612. X   changes that take place on the screen during inventory command input.
  613. X
  614. X  The global variable, screen_change, is cleared by inven_command, and set
  615. X  when the screen is flushed. This is the means by which inven_command tell
  616. X  if the screen has been flushed.
  617. X
  618. X  The display of inventory items is kept to the right of the screen to
  619. X  minimize the work done to restore the screen afterwards.        -CJS-*/
  620. X
  621. X/* Inventory command screen states. */
  622. X#define BLANK_SCR    0
  623. X#define EQUIP_SCR    1
  624. X#define INVEN_SCR    2
  625. X#define WEAR_SCR    3
  626. X#define HELP_SCR    4
  627. X#define WRONG_SCR    5
  628. X
  629. X/* Keep track of the state of the inventory screen. */
  630. Xstatic int scr_state, scr_left, scr_base;
  631. Xstatic int wear_low, wear_high;
  632. X
  633. X/* Draw the inventory screen. */
  634. Xstatic void inven_screen(new_scr)
  635. Xint new_scr;
  636. X{
  637. X  register int line;
  638. X
  639. X  if (new_scr != scr_state)
  640. X    {
  641. X      scr_state = new_scr;
  642. X      switch(new_scr)
  643. X    {
  644. X    case BLANK_SCR:
  645. X      line = 0;
  646. X      break;
  647. X    case HELP_SCR:
  648. X      if (scr_left > 52)
  649. X        scr_left = 52;
  650. X      prt("  ESC: exit", 1, scr_left);
  651. X      prt("  w  : wear or wield object", 2, scr_left);
  652. X      prt("  t  : take off item", 3, scr_left);
  653. X      prt("  d  : drop object", 4, scr_left);
  654. X      prt("  x  : exchange weapons", 5, scr_left);
  655. X      prt("  i  : inventory of pack", 6, scr_left);
  656. X      prt("  e  : list used equipment", 7, scr_left);
  657. X      line = 7;
  658. X      break;
  659. X    case INVEN_SCR:
  660. X      scr_left = show_inven(0, inven_ctr - 1, show_weight_flag, scr_left,
  661. X                CNIL);
  662. X      line = inven_ctr;
  663. X      break;
  664. X    case WEAR_SCR:
  665. X      scr_left = show_inven(wear_low, wear_high, show_weight_flag,
  666. X                scr_left, CNIL);
  667. X      line = wear_high - wear_low + 1;
  668. X      break;
  669. X    case EQUIP_SCR:
  670. X      scr_left = show_equip(show_weight_flag, scr_left);
  671. X      line = equip_ctr;
  672. X      break;
  673. X    }
  674. X      if (line >= scr_base)
  675. X    {
  676. X      scr_base = line + 1;
  677. X      erase_line(scr_base, scr_left);
  678. X    }
  679. X      else
  680. X    {
  681. X      while (++line <= scr_base)
  682. X        erase_line(line, scr_left);
  683. X    }
  684. X    }
  685. X}
  686. X
  687. X/* This does all the work. */
  688. Xvoid inven_command(command)
  689. Xchar command;
  690. X{
  691. X  register int slot, item;
  692. X  int tmp, tmp2, selecting, from, to;
  693. X  char *prompt, *swap, *disp, *string;
  694. X  char which, query;
  695. X  bigvtype prt1, prt2;
  696. X  register inven_type *i_ptr;
  697. X  inven_type tmp_obj;
  698. X#ifdef ATARIST_MWC
  699. X  int32u holder;
  700. X#endif
  701. X
  702. X  free_turn_flag = TRUE;
  703. X  save_screen();
  704. X  /* Take up where we left off after a previous inventory command. -CJS- */
  705. X  if (doing_inven)
  706. X    {
  707. X      /* If the screen has been flushed, we need to redraw. If the command is
  708. X     a simple ' ' to recover the screen, just quit. Otherwise, check and
  709. X     see what the user wants. */
  710. X      if (screen_change)
  711. X    {
  712. X      if (command == ' ' || !get_check("Continuing with inventory command?"))
  713. X        {
  714. X          doing_inven = FALSE;
  715. X          return;
  716. X        }
  717. X      scr_left = 50;
  718. X      scr_base = 0;
  719. X    }
  720. X      tmp = scr_state;
  721. X      scr_state = WRONG_SCR;
  722. X      inven_screen(tmp);
  723. X    }
  724. X  else
  725. X    {
  726. X      scr_left = 50;
  727. X      scr_base = 0;
  728. X      /* this forces exit of inven_command() if selecting is not set true */
  729. X      scr_state = BLANK_SCR;
  730. X    }
  731. X  do
  732. X    {
  733. X      if (isupper((int)command))
  734. X    command = tolower((int)command);
  735. X
  736. X      /* Simple command getting and screen selection. */
  737. X      selecting = FALSE;
  738. X      switch(command)
  739. X    {
  740. X    case 'i':       /* Inventory        */
  741. X      if (inven_ctr == 0)
  742. X        msg_print("You are not carrying anything.");
  743. X      else
  744. X        inven_screen(INVEN_SCR);
  745. X      break;
  746. X    case 'e':      /* Equipment       */
  747. X      if (equip_ctr == 0)
  748. X        msg_print("You are not using any equipment.");
  749. X      else
  750. X        inven_screen(EQUIP_SCR);
  751. X      break;
  752. X    case 't':      /* Take off       */
  753. X      if (equip_ctr == 0)
  754. X        msg_print("You are not using any equipment.");
  755. X      /* don't print message restarting inven command after taking off
  756. X         something, it is confusing */
  757. X      else if (inven_ctr >= INVEN_WIELD && !doing_inven)
  758. X        msg_print("You will have to drop something first.");
  759. X      else
  760. X        {
  761. X          if (scr_state != BLANK_SCR)
  762. X        inven_screen(EQUIP_SCR);
  763. X          selecting = TRUE;
  764. X        }
  765. X      break;
  766. X    case 'd':        /* Drop */
  767. X      if (inven_ctr == 0 && equip_ctr == 0)
  768. X        msg_print("But you're not carrying anything.");
  769. X      else if (cave[char_row][char_col].tptr != 0)
  770. X        msg_print("There's no room to drop anything here.");
  771. X      else
  772. X        {
  773. X          selecting = TRUE;
  774. X          if ((scr_state == EQUIP_SCR && equip_ctr > 0) || inven_ctr == 0)
  775. X        {
  776. X          if (scr_state != BLANK_SCR)
  777. X            inven_screen(EQUIP_SCR);
  778. X          command = 'r';    /* Remove - or take off and drop. */
  779. X        }
  780. X          else if (scr_state != BLANK_SCR)
  781. X        inven_screen(INVEN_SCR);
  782. X        }
  783. X      break;
  784. X    case 'w':      /* Wear/wield       */
  785. X      for (wear_low = 0;
  786. X           wear_low < inven_ctr && inventory[wear_low].tval > TV_MAX_WEAR;
  787. X           wear_low++)
  788. X        ;
  789. X      for(wear_high = wear_low;
  790. X          wear_high < inven_ctr && inventory[wear_high].tval >=TV_MIN_WEAR;
  791. X          wear_high++)
  792. X        ;
  793. X      wear_high--;
  794. X      if (wear_low > wear_high)
  795. X        msg_print("You have nothing to wear or wield.");
  796. X      else
  797. X        {
  798. X          if (scr_state != BLANK_SCR && scr_state != INVEN_SCR)
  799. X        inven_screen(WEAR_SCR);
  800. X          selecting = TRUE;
  801. X        }
  802. X      break;
  803. X    case 'x':
  804. X      if (inventory[INVEN_WIELD].tval == TV_NOTHING &&
  805. X          inventory[INVEN_AUX].tval == TV_NOTHING)
  806. X        msg_print("But you are wielding no weapons.");
  807. X#ifdef ATARIST_MWC
  808. X      else if ((holder = TR_CURSED) & inventory[INVEN_WIELD].flags)
  809. X#else
  810. X      else if (TR_CURSED & inventory[INVEN_WIELD].flags)
  811. X#endif
  812. X        {
  813. X          objdes(prt1, &inventory[INVEN_WIELD], FALSE);
  814. X          (void) sprintf(prt2,
  815. X             "The %s you are wielding appears to be cursed.", prt1);
  816. X          msg_print(prt2);
  817. X        }
  818. X      else
  819. X        {
  820. X          free_turn_flag = FALSE;
  821. X          tmp_obj = inventory[INVEN_AUX];
  822. X          inventory[INVEN_AUX] = inventory[INVEN_WIELD];
  823. X          inventory[INVEN_WIELD] = tmp_obj;
  824. X          if (scr_state == EQUIP_SCR)
  825. X        scr_left = show_equip(show_weight_flag, scr_left);
  826. X          py_bonuses(&inventory[INVEN_AUX], -1);     /* Subtract bonuses */
  827. X          py_bonuses(&inventory[INVEN_WIELD], 1);       /* Add bonuses    */
  828. X          if (inventory[INVEN_WIELD].tval != TV_NOTHING)
  829. X        {
  830. X          (void) strcpy(prt1, "Primary weapon   : ");
  831. X          objdes(prt2, &inventory[INVEN_WIELD], TRUE);
  832. X          msg_print(strcat(prt1, prt2));
  833. X        }
  834. X          else
  835. X        msg_print("No primary weapon.");
  836. X          /* this is a new weapon, so clear the heavy flag */
  837. X          weapon_heavy = FALSE;
  838. X          check_strength();
  839. X        }
  840. X      break;
  841. X    case ' ':    /* Dummy command to return again to main prompt. */
  842. X      break;
  843. X    case '?':
  844. X      inven_screen(HELP_SCR);
  845. X      break;
  846. X    default:
  847. X      /* Nonsense command                       */
  848. X      bell();
  849. X      break;
  850. X    }
  851. X
  852. X      /* Clear the doing_inven flag here, instead of at beginning, so that
  853. X     can use it to control when messages above appear. */
  854. X      doing_inven = 0;
  855. X
  856. X      /* Keep looking for objects to drop/wear/take off/throw off */
  857. X      which = 'z';
  858. X      while (selecting && free_turn_flag)
  859. X    {
  860. X      swap = "";
  861. X      if (command == 'w')
  862. X        {
  863. X          from = wear_low;
  864. X          to = wear_high;
  865. X          prompt = "Wear/Wield";
  866. X        }
  867. X      else
  868. X        {
  869. X          from = 0;
  870. X          if (command == 'd')
  871. X        {
  872. X          to = inven_ctr - 1;
  873. X          prompt = "Drop";
  874. X          if (equip_ctr > 0)
  875. X            swap = ", / for Equip";
  876. X        }
  877. X          else
  878. X        {
  879. X          to = equip_ctr - 1;
  880. X          if (command == 't')
  881. X            prompt = "Take off";
  882. X          else    /* command == 'r' */
  883. X            {
  884. X              prompt = "Throw off";
  885. X              if (inven_ctr > 0)
  886. X            swap = ", / for Inven";
  887. X            }
  888. X        }
  889. X        }
  890. X      if (from > to)
  891. X        selecting = FALSE;
  892. X      else
  893. X        {
  894. X          if (scr_state == BLANK_SCR)
  895. X        disp = ", * to list";
  896. X          else
  897. X        disp = "";
  898. X          (void) sprintf(prt1,
  899. X              "(%c-%c%s%s, space to break, ESC to exit) %s which one?",
  900. X              from+'a', to+'a', disp, swap, prompt);
  901. X
  902. X          /* Abort everything. */
  903. X          if (!get_com(prt1, &which))
  904. X        {
  905. X          selecting = FALSE;
  906. X          which = ESCAPE;
  907. X        }
  908. X          /* Draw the screen and maybe exit to main prompt. */
  909. X          else if (which == ' ' || which == '*')
  910. X        {
  911. X          if (command == 't' || command == 'r')
  912. X            inven_screen(EQUIP_SCR);
  913. X          else if (command == 'w' && scr_state != INVEN_SCR)
  914. X            inven_screen(WEAR_SCR);
  915. X          else
  916. X            inven_screen(INVEN_SCR);
  917. X          if (which == ' ')
  918. X            selecting = FALSE;
  919. X        }
  920. X          /* Swap screens (for drop) */
  921. X          else if (which == '/' && swap[0])
  922. X        {
  923. X          if (command == 'd')
  924. X            command = 'r';
  925. X          else
  926. X            command = 'd';
  927. X          if (scr_state == EQUIP_SCR)
  928. X            inven_screen(INVEN_SCR);
  929. X          else if (scr_state == INVEN_SCR)
  930. X            inven_screen(EQUIP_SCR);
  931. X        }
  932. X          else if ((which < from + 'a' || which > to + 'a')
  933. X               && (which < from + 'A' || which > to + 'A'))
  934. X        bell();
  935. X          else  /* Found an item! */
  936. X        {
  937. X          if (isupper((int)which))
  938. X            item = which - 'A';
  939. X          else
  940. X            item = which - 'a';
  941. X          if (command == 'r' || command == 't')
  942. X            {
  943. X              /* Get its place in the equipment list. */
  944. X              tmp = item;
  945. X              item = 21;
  946. X              do
  947. X            {
  948. X              item++;
  949. X              if (inventory[item].tval != TV_NOTHING)
  950. X                tmp--;
  951. X            }
  952. X              while (tmp >= 0);
  953. X              if (isupper((int)which) && !verify(prompt, item))
  954. X            item = -1;
  955. X#ifdef ATARIST_MWC
  956. X              else if ((holder = TR_CURSED) & inventory[item].flags)
  957. X#else
  958. X              else if (TR_CURSED & inventory[item].flags)
  959. X#endif
  960. X            {
  961. X              msg_print("Hmmm, it seems to be cursed.");
  962. X              item = -1;
  963. X            }
  964. X              else if (command == 't' &&
  965. X                   !inven_check_num(&inventory[item]))
  966. X            {
  967. X              if (cave[char_row][char_col].tptr != 0)
  968. X                {
  969. X                  msg_print("You can't carry it.");
  970. X                  item = -1;
  971. X                }
  972. X              else if (get_check("You can't carry it.  Drop it?"))
  973. X                command = 'r';
  974. X              else
  975. X                item = -1;
  976. X            }
  977. X              if (item >= 0)
  978. X            {
  979. X              if (command == 'r')
  980. X                {
  981. X                  inven_drop(item, TRUE);
  982. X                  /* As a safety measure, set the player's inven
  983. X                 weight to 0, when the last object is dropped*/
  984. X                  if (inven_ctr == 0 && equip_ctr == 0)
  985. X                inven_weight = 0;
  986. X                }
  987. X              else
  988. X                {
  989. X                  slot = inven_carry(&inventory[item]);
  990. X                  takeoff(item, slot);
  991. X                }
  992. X              check_strength();
  993. X              free_turn_flag = FALSE;
  994. X              if (command == 'r')
  995. X                selecting = FALSE;
  996. X            }
  997. X            }
  998. X          else if (command == 'w')
  999. X            {
  1000. X              /* Wearing. Go to a bit of trouble over replacing
  1001. X             existing equipment. */
  1002. X              if (isupper((int)which) && !verify(prompt, item))
  1003. X            item = -1;
  1004. X              else switch(inventory[item].tval)
  1005. X            { /* Slot for equipment       */
  1006. X            case TV_SLING_AMMO: case TV_BOLT: case TV_ARROW:
  1007. X            case TV_BOW: case TV_HAFTED: case TV_POLEARM:
  1008. X            case TV_SWORD: case TV_DIGGING: case TV_SPIKE:
  1009. X              slot = INVEN_WIELD; break;
  1010. X            case TV_LIGHT: slot = INVEN_LIGHT; break;
  1011. X            case TV_BOOTS: slot = INVEN_FEET; break;
  1012. X            case TV_GLOVES: slot = INVEN_HANDS; break;
  1013. X            case TV_CLOAK: slot = INVEN_OUTER; break;
  1014. X            case TV_HELM: slot = INVEN_HEAD; break;
  1015. X            case TV_SHIELD: slot = INVEN_ARM; break;
  1016. X            case TV_HARD_ARMOR: case TV_SOFT_ARMOR:
  1017. X              slot = INVEN_BODY; break;
  1018. X            case TV_AMULET: slot = INVEN_NECK; break;
  1019. X            case TV_RING:
  1020. X              if (inventory[INVEN_RIGHT].tval == TV_NOTHING)
  1021. X                slot = INVEN_RIGHT;
  1022. X              else if (inventory[INVEN_LEFT].tval == TV_NOTHING)
  1023. X                slot = INVEN_LEFT;
  1024. X              else
  1025. X                {
  1026. X                  slot = 0;
  1027. X                  /* Rings. Give some choice over where they go. */
  1028. X                  do
  1029. X                {
  1030. X                  if (!get_com(
  1031. X                   "Put ring on which hand (l/r/L/R)?", &query))
  1032. X                    {
  1033. X                      item = -1;
  1034. X                      slot = -1;
  1035. X                    }
  1036. X                  else if (query == 'l')
  1037. X                    slot = INVEN_LEFT;
  1038. X                  else if (query == 'r')
  1039. X                    slot = INVEN_RIGHT;
  1040. X                  else
  1041. X                    {
  1042. X                      if (query == 'L')
  1043. X                    slot = INVEN_LEFT;
  1044. X                      else if (query == 'R')
  1045. X                    slot = INVEN_RIGHT;
  1046. X                      else
  1047. X                    bell();
  1048. X                      if (slot && !verify("Replace", slot))
  1049. X                    slot = 0;
  1050. X                    }
  1051. X                }
  1052. X                  while(slot == 0);
  1053. X                }
  1054. X              break;
  1055. X            default:
  1056. X          msg_print("IMPOSSIBLE: I don't see how you can use that.");
  1057. X              item = -1;
  1058. X              break;
  1059. X            }
  1060. X              if (item >= 0 && inventory[slot].tval != TV_NOTHING)
  1061. X            {
  1062. X#ifdef ATARIST_MWC
  1063. X              if ((holder = TR_CURSED) & inventory[slot].flags)
  1064. X#else
  1065. X              if (TR_CURSED & inventory[slot].flags)
  1066. X#endif
  1067. X                {
  1068. X                  objdes(prt1, &inventory[slot], FALSE);
  1069. X                  (void) sprintf(prt2, "The %s you are ", prt1);
  1070. X                  if (slot == INVEN_HEAD)
  1071. X                (void) strcat(prt2, "wielding ");
  1072. X                  else
  1073. X                (void) strcat(prt2, "wearing ");
  1074. X                  msg_print(strcat(prt2, "appears to be cursed."));
  1075. X                  item = -1;
  1076. X                }
  1077. X              else if (inventory[item].subval == ITEM_GROUP_MIN &&
  1078. X                   inventory[item].number > 1 &&
  1079. X                   !inven_check_num(&inventory[slot]))
  1080. X                {
  1081. X                  /* this can happen if try to wield a torch, and
  1082. X                 have more than one in your inventory */
  1083. X               msg_print("You will have to drop something first.");
  1084. X                  item = -1;
  1085. X                }
  1086. X            }
  1087. X              if (item >= 0)
  1088. X            {
  1089. X              /* OK. Wear it. */
  1090. X              free_turn_flag = FALSE;
  1091. X
  1092. X              /* first remove new item from inventory */
  1093. X              tmp_obj = inventory[item];
  1094. X              i_ptr = &tmp_obj;
  1095. X
  1096. X              wear_high--;
  1097. X              /* Fix for torches       */
  1098. X              if (i_ptr->number > 1
  1099. X                  && i_ptr->subval <= ITEM_SINGLE_STACK_MAX)
  1100. X                {
  1101. X                  i_ptr->number = 1;
  1102. X                  wear_high++;
  1103. X                }
  1104. X              inven_weight += i_ptr->weight*i_ptr->number;
  1105. X              inven_destroy(item);    /* Subtracts weight */
  1106. X
  1107. X              /* second, add old item to inv and remove from
  1108. X                 equipment list, if necessary */
  1109. X              i_ptr = &inventory[slot];
  1110. X              if (i_ptr->tval != TV_NOTHING)
  1111. X                {
  1112. X                  tmp2 = inven_ctr;
  1113. X                  tmp = inven_carry(i_ptr);
  1114. X                  /* if item removed did not stack with anything in
  1115. X                 inventory, then increment wear_high */
  1116. X                  if (inven_ctr != tmp2)
  1117. X                wear_high++;
  1118. X                  takeoff(slot, tmp);
  1119. X                }
  1120. X
  1121. X              /* third, wear new item */
  1122. X              *i_ptr = tmp_obj;
  1123. X              equip_ctr++;
  1124. X              py_bonuses(i_ptr, 1);
  1125. X              if (slot == INVEN_WIELD)
  1126. X                string = "You are wielding";
  1127. X              else if (slot == INVEN_LIGHT)
  1128. X                string = "Your light source is";
  1129. X              else
  1130. X                string = "You are wearing";
  1131. X              objdes(prt2, i_ptr, TRUE);
  1132. X              /* Get the right equipment letter. */
  1133. X              tmp = INVEN_WIELD;
  1134. X              item = 0;
  1135. X              while (tmp != slot)
  1136. X                if (inventory[tmp++].tval != TV_NOTHING)
  1137. X                  item++;
  1138. X
  1139. X              (void) sprintf(prt1, "%s %s (%c)", string, prt2,
  1140. X                     'a'+item);
  1141. X              msg_print(prt1);
  1142. X              /* this is a new weapon, so clear the heavy flag */
  1143. X              if (slot == INVEN_WIELD)
  1144. X                weapon_heavy = FALSE;
  1145. X              check_strength();
  1146. X#ifdef ATARIST_MWC
  1147. X              if (i_ptr->flags & (holder = TR_CURSED))
  1148. X#else
  1149. X              if (i_ptr->flags & TR_CURSED)
  1150. X#endif
  1151. X                {
  1152. X                  msg_print("Oops! It feels deathly cold!");
  1153. X                  add_inscribe(i_ptr, ID_DAMD);
  1154. X                  /* To force a cost of 0, even if unidentified. */
  1155. X                  i_ptr->cost = -1;
  1156. X                }
  1157. X            }
  1158. X            }
  1159. X          else /* command == 'd' */
  1160. X            {
  1161. X              if (inventory[item].number > 1)
  1162. X            {
  1163. X              objdes(prt1, &inventory[item], TRUE);
  1164. X              prt1[strlen(prt1)-1] = '?';
  1165. X              (void) sprintf(prt2, "Drop all %s [y/n]", prt1);
  1166. X              prt1[strlen(prt1)-1] = '.';
  1167. X              prt(prt2, 0, 0);
  1168. X              query = inkey();
  1169. X              if (query != 'y' && query != 'n')
  1170. X                {
  1171. X                  if (query != ESCAPE)
  1172. X                bell();
  1173. X                  erase_line(MSG_LINE, 0);
  1174. X                  item = -1;
  1175. X                }
  1176. X            }
  1177. X              else if (isupper((int)which) && !verify(prompt, item))
  1178. X            item = -1;
  1179. X              else
  1180. X            query = 'y';
  1181. X              if (item >= 0)
  1182. X            {
  1183. X              free_turn_flag = FALSE;    /* Player turn   */
  1184. X              inven_drop(item, query == 'y');
  1185. X              check_strength();
  1186. X            }
  1187. X              selecting = FALSE;
  1188. X              /* As a safety measure, set the player's inven weight
  1189. X             to 0, when the last object is dropped.  */
  1190. X              if (inven_ctr == 0 && equip_ctr == 0)
  1191. X            inven_weight = 0;
  1192. X            }
  1193. X          if (free_turn_flag == FALSE && scr_state == BLANK_SCR)
  1194. X            selecting = FALSE;
  1195. X        }
  1196. X        }
  1197. X    }
  1198. X      if (which == ESCAPE || scr_state == BLANK_SCR)
  1199. X    command = ESCAPE;
  1200. X      else if (!free_turn_flag)
  1201. X    {
  1202. X      /* Save state for recovery if they want to call us again next turn.*/
  1203. X      if (selecting)
  1204. X        doing_inven = command;
  1205. X      else
  1206. X        doing_inven = ' ';    /* A dummy command to recover screen. */
  1207. X      /* flush last message before clearing screen_change and exiting */
  1208. X      msg_print(CNIL);
  1209. X      screen_change = FALSE;/* This lets us know if the world changes */
  1210. X      command = ESCAPE;
  1211. X    }
  1212. X      else
  1213. X    {
  1214. X      /* Put an appropriate header. */
  1215. X      if (scr_state == INVEN_SCR)
  1216. X        {
  1217. X          if (! show_weight_flag || inven_ctr == 0)
  1218. X        (void) sprintf(prt1,
  1219. X            "You are carrying %d.%d pounds. In your pack there is %s",
  1220. X                   inven_weight / 10, inven_weight % 10,
  1221. X                   (inven_ctr == 0 ? "nothing." : "-"));
  1222. X          else
  1223. X        (void) sprintf (prt1,
  1224. X    "You are carrying %d.%d pounds. Your capacity is %d.%d pounds. %s",
  1225. X                inven_weight / 10, inven_weight % 10,
  1226. X                weight_limit () / 10, weight_limit () % 10,
  1227. X                "In your pack is -");
  1228. X          prt(prt1, 0, 0);
  1229. X        }
  1230. X      else if (scr_state == WEAR_SCR)
  1231. X        {
  1232. X          if (wear_high < wear_low)
  1233. X        prt("You have nothing you could wield.", 0, 0);
  1234. X          else
  1235. X        prt("You could wield -", 0, 0);
  1236. X        }
  1237. X      else if (scr_state == EQUIP_SCR)
  1238. X        {
  1239. X          if (equip_ctr == 0)
  1240. X        prt("You are not using anything.", 0, 0);
  1241. X          else
  1242. X        prt("You are using -", 0, 0);
  1243. X        }
  1244. X      else
  1245. X        prt("Allowed commands:", 0, 0);
  1246. X      erase_line(scr_base, scr_left);
  1247. X      put_buffer("e/i/t/w/x/d/?/ESC:", scr_base, 60);
  1248. X      command = inkey();
  1249. X      erase_line(scr_base, scr_left);
  1250. X    }
  1251. X    }
  1252. X  while (command != ESCAPE);
  1253. X  if (scr_state != BLANK_SCR)
  1254. X    restore_screen();
  1255. X  calc_bonuses();
  1256. X}
  1257. X
  1258. X
  1259. X/* Get the ID of an item and return the CTR value of it    -RAK-    */
  1260. Xint get_item(com_val, pmt, i, j, mask, message)
  1261. Xint *com_val;
  1262. Xchar *pmt;
  1263. Xint i, j;
  1264. Xchar *mask;
  1265. Xchar *message;
  1266. X{
  1267. X  vtype out_val;
  1268. X  char which;
  1269. X  register int test_flag, item;
  1270. X  int full, i_scr, redraw;
  1271. X
  1272. X  item = FALSE;
  1273. X  redraw = FALSE;
  1274. X  *com_val = 0;
  1275. X  i_scr = 1;
  1276. X  if (j > INVEN_WIELD)
  1277. X    {
  1278. X      full = TRUE;
  1279. X      if (inven_ctr == 0)
  1280. X    {
  1281. X      i_scr = 0;
  1282. X      j = equip_ctr - 1;
  1283. X    }
  1284. X      else
  1285. X    j = inven_ctr - 1;
  1286. X    }
  1287. X  else
  1288. X    full = FALSE;
  1289. X
  1290. X  if (inven_ctr > 0 || (full && equip_ctr > 0))
  1291. X    {
  1292. X      do
  1293. X    {
  1294. X      if (redraw)
  1295. X        {
  1296. X          if (i_scr > 0)
  1297. X        (void) show_inven (i, j, FALSE, 80, mask);
  1298. X          else
  1299. X        (void) show_equip (FALSE, 80);
  1300. X        }
  1301. X      if (full)
  1302. X        (void) sprintf(out_val,
  1303. X               "(%s: %c-%c,%s / for %s, or ESC) %s",
  1304. X               (i_scr > 0 ? "Inven" : "Equip"), i+'a', j+'a',
  1305. X               (redraw ? "" : " * to see,"),
  1306. X               (i_scr > 0 ? "Equip" : "Inven"), pmt);
  1307. X      else
  1308. X        (void) sprintf(out_val,
  1309. X               "(Items %c-%c,%s ESC to exit) %s", i+'a', j+'a',
  1310. X               (redraw ? "" : " * for inventory list,"), pmt);
  1311. X      test_flag = FALSE;
  1312. X      prt(out_val, 0, 0);
  1313. X      do
  1314. X        {
  1315. X          which = inkey();
  1316. X          switch(which)
  1317. X        {
  1318. X        case ESCAPE:
  1319. X          test_flag = TRUE;
  1320. X          free_turn_flag = TRUE;
  1321. X          i_scr = -1;
  1322. X          break;
  1323. X        case '/':
  1324. X          if (full)
  1325. X            {
  1326. X              if (i_scr > 0)
  1327. X            {
  1328. X              if (equip_ctr == 0)
  1329. X                {
  1330. X                  prt("But you're not using anything -more-",0,0);
  1331. X                  (void) inkey();
  1332. X                }
  1333. X              else
  1334. X                {
  1335. X                  i_scr = 0;
  1336. X                  test_flag = TRUE;
  1337. X                  if (redraw)
  1338. X                {
  1339. X                  j = equip_ctr;
  1340. X                  while (j < inven_ctr)
  1341. X                    {
  1342. X                      j++;
  1343. X                      erase_line(j, 0);
  1344. X                    }
  1345. X                }
  1346. X                  j = equip_ctr - 1;
  1347. X                }
  1348. X              prt(out_val, 0, 0);
  1349. X            }
  1350. X              else
  1351. X            {
  1352. X              if (inven_ctr == 0)
  1353. X                {
  1354. X                prt("But you're not carrying anything -more-",0,0);
  1355. X                  (void) inkey();
  1356. X                }
  1357. X              else
  1358. X                {
  1359. X                  i_scr = 1;
  1360. X                  test_flag = TRUE;
  1361. X                  if (redraw)
  1362. X                {
  1363. X                  j = inven_ctr;
  1364. X                  while (j < equip_ctr)
  1365. X                    {
  1366. X                      j++;
  1367. X                      erase_line (j, 0);
  1368. X                    }
  1369. X                }
  1370. X                  j = inven_ctr - 1;
  1371. X                }
  1372. X            }
  1373. X            }
  1374. X          break;
  1375. X        case '*':
  1376. X          if (!redraw)
  1377. X            {
  1378. X              test_flag = TRUE;
  1379. X              save_screen();
  1380. X              redraw = TRUE;
  1381. X            }
  1382. X          break;
  1383. X        default:
  1384. X          if (isupper((int)which))
  1385. X            *com_val = which - 'A';
  1386. X          else
  1387. X            *com_val = which - 'a';
  1388. X          if ((*com_val >= i) && (*com_val <= j)
  1389. X              && (mask == CNIL || mask[*com_val]))
  1390. X            {
  1391. X              if (i_scr == 0)
  1392. X            {
  1393. X              i = 21;
  1394. X              j = *com_val;
  1395. X              do
  1396. X                {
  1397. X                  while (inventory[++i].tval == TV_NOTHING);
  1398. X                  j--;
  1399. X                }
  1400. X              while (j >= 0);
  1401. X              *com_val = i;
  1402. X            }
  1403. X              if (isupper((int)which) && !verify("Try", *com_val))
  1404. X            {
  1405. X              test_flag = TRUE;
  1406. X              free_turn_flag = TRUE;
  1407. X              i_scr = -1;
  1408. X              break;
  1409. X            }
  1410. X              test_flag = TRUE;
  1411. X              item = TRUE;
  1412. X              i_scr = -1;
  1413. X            }
  1414. X          else if (message)
  1415. X            {
  1416. X              msg_print (message);
  1417. X              /* Set test_flag to force redraw of the question.  */
  1418. X              test_flag = TRUE;
  1419. X            }
  1420. X          else
  1421. X            bell();
  1422. X          break;
  1423. X        }
  1424. X        }
  1425. X      while (!test_flag);
  1426. X    }
  1427. X      while (i_scr >= 0);
  1428. X      if (redraw)
  1429. X    restore_screen();
  1430. X      erase_line(MSG_LINE, 0);
  1431. X    }
  1432. X  else
  1433. X    prt("You are not carrying anything.", 0, 0);
  1434. X  return(item);
  1435. X}
  1436. X
  1437. X/* I may have written the town level code, but I'm not exactly     */
  1438. X/* proud of it.     Adding the stores required some real slucky     */
  1439. X/* hooks which I have not had time to re-think.         -RAK-     */
  1440. X
  1441. X/* Returns true if player has no light            -RAK-    */
  1442. Xint no_light()
  1443. X{
  1444. X  register cave_type *c_ptr;
  1445. X
  1446. X  c_ptr = &cave[char_row][char_col];
  1447. X  if (!c_ptr->tl && !c_ptr->pl)
  1448. X    return TRUE;
  1449. X  return FALSE;
  1450. X}
  1451. X
  1452. X
  1453. X/* map rogue_like direction commands into numbers */
  1454. Xstatic char map_roguedir(comval)
  1455. Xregister char comval;
  1456. X{
  1457. X  switch(comval)
  1458. X    {
  1459. X    case 'h':
  1460. X      comval = '4';
  1461. X      break;
  1462. X    case 'y':
  1463. X      comval = '7';
  1464. X      break;
  1465. X    case 'k':
  1466. X      comval = '8';
  1467. X      break;
  1468. X    case 'u':
  1469. X      comval = '9';
  1470. X      break;
  1471. X    case 'l':
  1472. X      comval = '6';
  1473. X      break;
  1474. X    case 'n':
  1475. X      comval = '3';
  1476. X      break;
  1477. X    case 'j':
  1478. X      comval = '2';
  1479. X      break;
  1480. X    case 'b':
  1481. X      comval = '1';
  1482. X      break;
  1483. X    case '.':
  1484. X      comval = '5';
  1485. X      break;
  1486. X    }
  1487. X  return(comval);
  1488. X}
  1489. X
  1490. X
  1491. X/* Prompts for a direction                -RAK-    */
  1492. X/* Direction memory added, for repeated commands.  -CJS */
  1493. Xint get_dir(prompt, dir)
  1494. Xchar *prompt;
  1495. Xint *dir;
  1496. X{
  1497. X  char command;
  1498. X  int save;
  1499. X  static char prev_dir;        /* Direction memory. -CJS- */
  1500. X
  1501. X  if (default_dir)    /* used in counted commands. -CJS- */
  1502. X    {
  1503. X      *dir = prev_dir;
  1504. X      return TRUE;
  1505. X    }
  1506. X  if (prompt == CNIL)
  1507. X    prompt = "Which direction?";
  1508. X  for (;;)
  1509. X    {
  1510. X      save = command_count;    /* Don't end a counted command. -CJS- */
  1511. X#ifdef MAC
  1512. X      if (!get_comdir(prompt, &command))
  1513. X#else
  1514. X      if (!get_com(prompt, &command))
  1515. X#endif
  1516. X    {
  1517. X      free_turn_flag = TRUE;
  1518. X      return FALSE;
  1519. X    }
  1520. X      command_count = save;
  1521. X      if (rogue_like_commands)
  1522. X    command = map_roguedir(command);
  1523. X      if (command >= '1' && command <= '9' && command != '5')
  1524. X    {
  1525. X      prev_dir = command - '0';
  1526. X      *dir = prev_dir;
  1527. X      return TRUE;
  1528. X    }
  1529. X      bell();
  1530. X    }
  1531. X}
  1532. X
  1533. X
  1534. X
  1535. X/* Similar to get_dir, except that no memory exists, and it is        -CJS-
  1536. X   allowed to enter the null direction. */
  1537. Xint get_alldir(prompt, dir)
  1538. Xchar *prompt;
  1539. Xint *dir;
  1540. X{
  1541. X  char command;
  1542. X
  1543. X  for(;;)
  1544. X    {
  1545. X#ifdef MAC
  1546. X      if (!get_comdir(prompt, &command))
  1547. X#else
  1548. X      if (!get_com(prompt, &command))
  1549. X#endif
  1550. X    {
  1551. X      free_turn_flag = TRUE;
  1552. X      return FALSE;
  1553. X    }
  1554. X      if (rogue_like_commands)
  1555. X    command = map_roguedir(command);
  1556. X      if (command >= '1' && command <= '9')
  1557. X    {
  1558. X      *dir = command - '0';
  1559. X      return TRUE;
  1560. X    }
  1561. X      bell();
  1562. X    }
  1563. X}
  1564. X
  1565. X
  1566. X/* Moves creature record from one space to another    -RAK-    */
  1567. Xvoid move_rec(y1, x1, y2, x2)
  1568. Xregister int y1, x1, y2, x2;
  1569. X{
  1570. X  int tmp;
  1571. X
  1572. X  /* this always works correctly, even if y1==y2 and x1==x2 */
  1573. X  tmp = cave[y1][x1].cptr;
  1574. X  cave[y1][x1].cptr = 0;
  1575. X  cave[y2][x2].cptr = tmp;
  1576. X}
  1577. X
  1578. X
  1579. X/* Room is lit, make it appear                -RAK-    */
  1580. Xvoid light_room(y, x)
  1581. Xint y, x;
  1582. X{
  1583. X  register int i, j, start_col, end_col;
  1584. X  int tmp1, tmp2, start_row, end_row;
  1585. X  register cave_type *c_ptr;
  1586. X  int tval;
  1587. X
  1588. X  tmp1 = (SCREEN_HEIGHT/2);
  1589. X  tmp2 = (SCREEN_WIDTH /2);
  1590. X  start_row = (y/tmp1)*tmp1;
  1591. X  start_col = (x/tmp2)*tmp2;
  1592. X  end_row = start_row + tmp1 - 1;
  1593. X  end_col = start_col + tmp2 - 1;
  1594. X  for (i = start_row; i <= end_row; i++)
  1595. X    for (j = start_col; j <= end_col; j++)
  1596. X      {
  1597. X    c_ptr = &cave[i][j];
  1598. X    if (c_ptr->lr && ! c_ptr->pl)
  1599. X      {
  1600. X        c_ptr->pl = TRUE;
  1601. X        if (c_ptr->fval == DARK_FLOOR)
  1602. X          c_ptr->fval = LIGHT_FLOOR;
  1603. X        if (! c_ptr->fm && c_ptr->tptr != 0)
  1604. X          {
  1605. X        tval = t_list[c_ptr->tptr].tval;
  1606. X        if (tval >= TV_MIN_VISIBLE && tval <= TV_MAX_VISIBLE)
  1607. X          c_ptr->fm = TRUE;
  1608. X          }
  1609. X        print(loc_symbol(i, j), i, j);
  1610. X      }
  1611. X      }
  1612. X}
  1613. X
  1614. X
  1615. X/* Lights up given location                -RAK-    */
  1616. Xvoid lite_spot(y, x)
  1617. Xregister int y, x;
  1618. X{
  1619. X  if (panel_contains(y, x))
  1620. X    print(loc_symbol(y, x), y, x);
  1621. X}
  1622. X
  1623. X
  1624. X/* Normal movement                    */
  1625. X/* When FIND_FLAG,  light only permanent features    */
  1626. Xstatic void sub1_move_light(y1, x1, y2, x2)
  1627. Xregister int x1, x2;
  1628. Xint y1, y2;
  1629. X{
  1630. X  register int i, j;
  1631. X  register cave_type *c_ptr;
  1632. X  int tval, top, left, bottom, right;
  1633. X
  1634. X  if (light_flag)
  1635. X    {
  1636. X      for (i = y1-1; i <= y1+1; i++)       /* Turn off lamp light    */
  1637. X    for (j = x1-1; j <= x1+1; j++)
  1638. X      cave[i][j].tl = FALSE;
  1639. X      if (find_flag && !find_prself)
  1640. X    light_flag = FALSE;
  1641. X    }
  1642. X  else if (!find_flag || find_prself)
  1643. X    light_flag = TRUE;
  1644. X
  1645. X  for (i = y2-1; i <= y2+1; i++)
  1646. X    for (j = x2-1; j <= x2+1; j++)
  1647. X      {
  1648. X    c_ptr = &cave[i][j];
  1649. X    /* only light up if normal movement */
  1650. X    if (light_flag)
  1651. X      c_ptr->tl = TRUE;
  1652. X    if (c_ptr->fval >= MIN_CAVE_WALL)
  1653. X      c_ptr->pl = TRUE;
  1654. X    else if (!c_ptr->fm && c_ptr->tptr != 0)
  1655. X      {
  1656. X        tval = t_list[c_ptr->tptr].tval;
  1657. X        if ((tval >= TV_MIN_VISIBLE) && (tval <= TV_MAX_VISIBLE))
  1658. X          c_ptr->fm = TRUE;
  1659. X      }
  1660. X      }
  1661. X
  1662. X  /* From uppermost to bottom most lines player was on.     */
  1663. X  if (y1 < y2)
  1664. X    {
  1665. X      top = y1 - 1;
  1666. X      bottom = y2 + 1;
  1667. X    }
  1668. X  else
  1669. X    {
  1670. X      top = y2 - 1;
  1671. X      bottom = y1 + 1;
  1672. X    }
  1673. X  if (x1 < x2)
  1674. X    {
  1675. X      left = x1 - 1;
  1676. X      right = x2 + 1;
  1677. X    }
  1678. X  else
  1679. X    {
  1680. X      left = x2 - 1;
  1681. X      right = x1 + 1;
  1682. X    }
  1683. X  for (i = top; i <= bottom; i++)
  1684. X    for (j = left; j <= right; j++)   /* Leftmost to rightmost do*/
  1685. X      print(loc_symbol(i, j), i, j);
  1686. X}
  1687. X
  1688. X
  1689. X/* When blinded,  move only the player symbol.        */
  1690. X/* With no light,  movement becomes involved.        */
  1691. Xstatic void sub3_move_light(y1, x1, y2, x2)
  1692. Xregister int y1, x1;
  1693. Xint y2, x2;
  1694. X{
  1695. X  register int i, j;
  1696. X
  1697. X  if (light_flag)
  1698. X    {
  1699. X      for (i = y1-1; i <= y1+1; i++)
  1700. X    for (j = x1-1; j <= x1+1; j++)
  1701. X      {
  1702. X        cave[i][j].tl = FALSE;
  1703. X        print(loc_symbol(i, j), i, j);
  1704. X      }
  1705. X      light_flag = FALSE;
  1706. X    }
  1707. X  else if (!find_flag || find_prself)
  1708. X    print(loc_symbol(y1, x1), y1, x1);
  1709. X
  1710. X  if (!find_flag || find_prself)
  1711. X    print('@', y2, x2);
  1712. X}
  1713. X
  1714. X
  1715. X/* Package for moving the character's light about the screen     */
  1716. X/* Four cases : Normal, Finding, Blind, and Nolight     -RAK-     */
  1717. Xvoid move_light(y1, x1, y2, x2)
  1718. Xint y1, x1, y2, x2;
  1719. X{
  1720. X  if (py.flags.blind > 0 || !player_light)
  1721. X    sub3_move_light(y1, x1, y2, x2);
  1722. X  else
  1723. X    sub1_move_light(y1, x1, y2, x2);
  1724. X}
  1725. X
  1726. X
  1727. X/* Something happens to disturb the player.        -CJS-
  1728. X   The first arg indicates a major disturbance, which affects search.
  1729. X   The second arg indicates a light change. */
  1730. Xvoid disturb(s, l)
  1731. Xint s, l;
  1732. X{
  1733. X  command_count = 0;
  1734. X  if (s && (py.flags.status & PY_SEARCH))
  1735. X    search_off();
  1736. X  if (py.flags.rest != 0)
  1737. X    rest_off();
  1738. X  if (l || find_flag)
  1739. X    {
  1740. X      find_flag = FALSE;
  1741. X      check_view();
  1742. X    }
  1743. X  flush();
  1744. X}
  1745. X
  1746. X
  1747. X/* Search Mode enhancement                -RAK-    */
  1748. Xvoid search_on()
  1749. X{
  1750. X  change_speed(1);
  1751. X  py.flags.status |= PY_SEARCH;
  1752. X  prt_state();
  1753. X  prt_speed();
  1754. X  py.flags.food_digested++;
  1755. X}
  1756. X
  1757. Xvoid search_off()
  1758. X{
  1759. X#ifdef ATARIST_MWC
  1760. X  int32u holder;
  1761. X#endif
  1762. X
  1763. X  check_view();
  1764. X  change_speed(-1);
  1765. X#ifdef ATARIST_MWC
  1766. X  py.flags.status &= ~(holder = PY_SEARCH);
  1767. X#else
  1768. X  py.flags.status &= ~PY_SEARCH;
  1769. X#endif
  1770. X  prt_state();
  1771. X  prt_speed();
  1772. X  py.flags.food_digested--;
  1773. X}
  1774. X
  1775. X
  1776. X/* Resting allows a player to safely restore his hp    -RAK-    */
  1777. Xvoid rest()
  1778. X{
  1779. X  int rest_num;
  1780. X  vtype rest_str;
  1781. X
  1782. X  if (command_count > 0)
  1783. X    {
  1784. X      rest_num = command_count;
  1785. X      command_count = 0;
  1786. X    }
  1787. X  else
  1788. X    {
  1789. X      prt("Rest for how long? ", 0, 0);
  1790. X      rest_num = 0;
  1791. X      if (get_string(rest_str, 0, 19, 5))
  1792. X    {
  1793. X      if (rest_str[0] == '*')
  1794. X        rest_num = -MAX_SHORT;
  1795. X      else
  1796. X        rest_num = atoi(rest_str);
  1797. X    }
  1798. X    }
  1799. X  /* check for reasonable value, must be positive number in range of a
  1800. X     short, or must be -MAX_SHORT */
  1801. X  if ((rest_num == -MAX_SHORT)
  1802. X      || (rest_num > 0) && (rest_num < MAX_SHORT))
  1803. X    {
  1804. X      if (py.flags.status & PY_SEARCH)
  1805. X    search_off();
  1806. X      py.flags.rest = rest_num;
  1807. X      py.flags.status |= PY_REST;
  1808. X      prt_state();
  1809. X      py.flags.food_digested--;
  1810. X      prt ("Press any key to stop resting...", 0, 0);
  1811. X      put_qio();
  1812. X    }
  1813. X  else
  1814. X    {
  1815. X      if (rest_num != 0)
  1816. X    msg_print ("Invalid rest count.");
  1817. X      erase_line(MSG_LINE, 0);
  1818. X      free_turn_flag = TRUE;
  1819. X    }
  1820. X}
  1821. X
  1822. Xvoid rest_off()
  1823. X{
  1824. X#ifdef ATARIST_MWC
  1825. X  int32u holder;
  1826. X#endif
  1827. X
  1828. X  py.flags.rest = 0;
  1829. X#ifdef ATARIST_MWC
  1830. X  py.flags.status &= ~(holder = PY_REST);
  1831. X#else
  1832. X  py.flags.status &= ~PY_REST;
  1833. X#endif
  1834. X  prt_state();
  1835. X  msg_print(CNIL); /* flush last message, or delete "press any key" message */
  1836. X  py.flags.food_digested++;
  1837. X}
  1838. X
  1839. X
  1840. X/* Attacker's level and plusses,  defender's AC        -RAK-    */
  1841. Xint test_hit(bth, level, pth, ac, attack_type)
  1842. Xint bth, level, pth, ac, attack_type;
  1843. X{
  1844. X  register int i, die;
  1845. X
  1846. X  disturb (1, 0);
  1847. X  i = bth + pth * BTH_PLUS_ADJ
  1848. X    + (level * class_level_adj[py.misc.pclass][attack_type]);
  1849. X  /* pth could be less than 0 if player wielding weapon too heavy for him */
  1850. X  /* always miss 1 out of 20, always hit 1 out of 20 */
  1851. X  die = randint (20);
  1852. X  if ((die != 1) && ((die == 20)
  1853. X             || ((i > 0) && (randint (i) > ac))))  /* normal hit */
  1854. X    return TRUE;
  1855. X  else
  1856. X    return FALSE;
  1857. X}
  1858. X
  1859. X
  1860. X/* Decreases players hit points and sets death flag if necessary*/
  1861. X/*                             -RAK-     */
  1862. Xvoid take_hit(damage, hit_from)
  1863. Xint damage;
  1864. Xchar *hit_from;
  1865. X{
  1866. X  if (py.flags.invuln > 0)  damage = 0;
  1867. X  py.misc.chp -= damage;
  1868. X  if (py.misc.chp < 0)
  1869. X    {
  1870. X      if (!death)
  1871. X    {
  1872. X      death = TRUE;
  1873. X      (void) strcpy(died_from, hit_from);
  1874. X      total_winner = FALSE;
  1875. X    }
  1876. X      new_level_flag = TRUE;
  1877. X    }
  1878. X  else
  1879. X    prt_chp();
  1880. X}
  1881. END_OF_FILE
  1882. if test 45054 -ne `wc -c <'source/moria1.c'`; then
  1883.     echo shar: \"'source/moria1.c'\" unpacked with wrong size!
  1884. fi
  1885. # end of 'source/moria1.c'
  1886. fi
  1887. if test -f 'util/mc/mon.inf' -a "${1}" != "-c" ; then 
  1888.   echo shar: Will not clobber existing file \"'util/mc/mon.inf'\"
  1889. else
  1890. echo shar: Extracting \"'util/mc/mon.inf'\" \(7711 characters\)
  1891. sed "s/^X//" >'util/mc/mon.inf' <<'END_OF_FILE'
  1892. Xclass antlion {
  1893. X    speed: 1;
  1894. X    move: move_normal, random_20;
  1895. X    defense: animal, frost, fire;
  1896. X    cchar: "A";
  1897. X    treasure: ~carry_obj;
  1898. X    sleep: 40;
  1899. X    special: eats_other;
  1900. X};
  1901. X
  1902. Xcreature "Giant Grey Ant Lion": antlion {
  1903. X    level: 26;    xp: 90;        hd: 19 d 8;
  1904. X    radius: 10;    ac: 40;
  1905. X    attack: bites for 2 d 12 of normal_damage;
  1906. X};
  1907. X
  1908. Xcreature "Giant White Ant Lion": antlion {
  1909. X    level: 30;    xp: 175;    hd: 20 d 8;
  1910. X    radius: 12;    ac: 45;
  1911. X    attack: bites for 3 d 10 of cold_damage;
  1912. X    defense: ~frost;
  1913. X};
  1914. X
  1915. Xcreature "Giant Black Ant Lion": antlion {
  1916. X    level: 31;    xp: 170;    hd: 23 d 8;
  1917. X    radius: 14;    ac: 45;
  1918. X    attack: bites for 2 d 12 of normal_damage,
  1919. X        spits for 3 d 6 of acid_damage;
  1920. X};
  1921. X
  1922. Xcreature "Giant Red Ant Lion": antlion {
  1923. X    level: 35;    xp: 350;    hd: 23 d 8;
  1924. X    radius: 14;    ac: 48;
  1925. X    attack: bites for 3 d 12 of fire_damage;
  1926. X    defense: ~fire, infra;
  1927. X};
  1928. X
  1929. Xcreature "Giant Mottled Ant Lion": antlion {
  1930. X    level: 36;    xp: 350;    hd: 24 d 8;
  1931. X    radius: 14;    ac: 50;
  1932. X    attack: bites for 2 d 10 of normal_damage;
  1933. X};
  1934. X
  1935. Xclass ant {
  1936. X    speed: 1;
  1937. X    move: move_normal;
  1938. X    defense: animal;
  1939. X    cchar: "a";
  1940. X    treasure: ~carry_obj;
  1941. X};
  1942. X
  1943. Xcreature "Giant Black Ant": ant {
  1944. X    level: 2;    xp: 8;        hd: 3 d 6;
  1945. X    radius: 14;    ac: 20;        sleep: 40;
  1946. X    move: random_20;
  1947. X    attack: bites for 1 d 4 of normal_damage;
  1948. X};
  1949. X
  1950. Xcreature "Giant White Ant": ant {
  1951. X    level: 3;    xp: 7;        hd: 3 d 6;
  1952. X    radius: 8;    ac: 16;        sleep: 80;
  1953. X    attack: hits for 1 d 4 of normal_damage;
  1954. X};
  1955. X
  1956. Xcreature "Giant Red Ant": ant {
  1957. X    level: 9;    xp: 22;        hd: 4 d 8;
  1958. X    radius: 12;    ac: 34;        sleep: 60;
  1959. X    attack: bites for 1 d 4 of normal_damage,
  1960. X        stings for 1 d 4 of lose_str;
  1961. X};
  1962. X
  1963. Xcreature "Giant Clear Ant": ant {
  1964. X    level: 12;    xp: 24;        hd: 3 d 7;
  1965. X    radius: 12;    ac: 18;        sleep: 60;
  1966. X    special: invisible;
  1967. X    attack: bites for 1 d 4 of normal_damage;
  1968. X};
  1969. X
  1970. Xcreature "Giant Ebony Ant": ant {
  1971. X    level: 15;    xp: 3;        hd: 3 d 4;
  1972. X    radius: 12;    ac: 24;        sleep: 60;
  1973. X    attack: bites for 2 d 3 of normal_damage;
  1974. X    special: multiply;
  1975. X};
  1976. X
  1977. Xcreature "Giant Silver Ant": ant {
  1978. X    level: 23;    xp: 45;        hd: 6 d 8;
  1979. X    radius: 15;    ac: 38;        sleep: 60;
  1980. X    move: random_20;
  1981. X    attack: bites for 4 d 4 of acid_damage;
  1982. X};
  1983. X
  1984. Xcreature "Giant Static Ant": ant {
  1985. X    level: 30;    xp: 80;        hd: 8 d 8;
  1986. X    radius: 10;    ac: 40;        sleep: 60;
  1987. X    move: random_20;
  1988. X    attack: bites for 5 d 5 of lightning_damage;
  1989. X};
  1990. X
  1991. Xcreature "Giant Hunter Ant": ant {
  1992. X    level: 32;    xp: 150;    hd: 12 d 8;
  1993. X    radius: 16;    ac: 40;        sleep: 1;
  1994. X    attack: bites for 4 d 8 of normal_damage;
  1995. X};
  1996. X
  1997. Xclass centipede {
  1998. X    speed: 1;
  1999. X    move: move_normal;
  2000. X    defense: ~animal;
  2001. X    cchar: "c";
  2002. X    treasure: ~carry_obj;
  2003. X    sleep: 50;
  2004. X};
  2005. X
  2006. Xcreature "Giant Yellow Centipede" : centipede {
  2007. X    level: 1;
  2008. X    xp: 2;
  2009. X    ac: 12;
  2010. X    radius: 8;
  2011. X    hd: 2 d 6;
  2012. X    attack: bites for 1 d 3 of normal_damage,
  2013. X        bites for 1 d 3 of normal_damage;
  2014. X};
  2015. X
  2016. Xcreature "Giant White Centipede" : centipede {
  2017. X    level: 1;
  2018. X    xp: 2;
  2019. X    ac: 10;
  2020. X    radius: 7;
  2021. X    hd: 3 d 5;
  2022. X    move: random_20;
  2023. X    attack: bites for 1 d 2 of normal_damage,
  2024. X        bites for 1 d 2 of normal_damage;
  2025. X};
  2026. X
  2027. Xcreature "Metallic Green Centipede" : centipede {
  2028. X    speed: 2;
  2029. X    level: 2;
  2030. X    xp: 3;
  2031. X    ac: 4;
  2032. X    radius: 5;
  2033. X    hd: 4 d 4;
  2034. X    move: random_40;
  2035. X    attack: crawls_on for 1 d 1 of normal_damage;
  2036. X};
  2037. X
  2038. Xcreature "Metallic Blue Centipede" : centipede {
  2039. X    speed: 2;
  2040. X    level: 3;
  2041. X    xp: 7;
  2042. X    ac: 6;
  2043. X    radius: 6;
  2044. X    hd: 4 d 5;
  2045. X    move: random_40;
  2046. X    attack: crawls_on for 1 d 2 of normal_damage;
  2047. X};
  2048. X
  2049. Xcreature "Metallic Red Centipede" : centipede {
  2050. X    speed: 2;
  2051. X    level: 3;
  2052. X    xp: 12;
  2053. X    ac: 9;
  2054. X    radius: 9;
  2055. X    hd: 4 d 8;
  2056. X    move: random_20;
  2057. X    attack: crawls_on for 1 d 2 of normal_damage;
  2058. X};
  2059. X
  2060. Xcreature "Giant Black Centipede" : centipede {
  2061. X    level: 4;
  2062. X    xp: 11;
  2063. X    ac: 20;
  2064. X    radius: 8;
  2065. X    hd: 5 d 8;
  2066. X    move: random_75;
  2067. X    attack: bites for 1 d 2 of normal_damage,
  2068. X        stings for 1 d 2 of normal_damage;
  2069. X};
  2070. X
  2071. Xcreature "Giant Blue Centipede" : centipede {
  2072. X    level: 4;
  2073. X    xp: 10;
  2074. X    ac: 20;
  2075. X    radius: 8;
  2076. X    hd: 4 d 8;
  2077. X    attack: bites for 1 d 3 of normal_damage,
  2078. X        stings for 1 d 4 of normal_damage;
  2079. X};
  2080. X
  2081. Xcreature "Giant Red Centipede" : centipede {
  2082. X    level: 10;
  2083. X    speed: 2;
  2084. X    xp: 24;
  2085. X    ac: 26;
  2086. X    radius: 12;
  2087. X    hd: 3 d 8;
  2088. X    attack: bites for 1 d 2 of normal_damage,
  2089. X        stings for 1 d 2 of poison;
  2090. X};
  2091. X
  2092. X#
  2093. X# here be the dragons
  2094. X#
  2095. X
  2096. Xclass dragon {
  2097. X    defense: evil, dragon, infra;
  2098. X    treasure: carry_obj, carry_gold, has_random_60,
  2099. X        has_random_90, has_1d2_obj;
  2100. X    spell: fear;
  2101. X    move: move_normal, random_20;
  2102. X    radius: 20;
  2103. X    sleep: 50;
  2104. X};
  2105. X
  2106. Xclass young_dragon: dragon {
  2107. X    ac: 50;        spell 10%:;        speed: 1;    cchar: "d";
  2108. X    attack: claws for 1 d 4 of normal_damage,
  2109. X        claws for 1 d 4 of normal_damage,
  2110. X        bites for 1 d 6 of normal_damage;
  2111. X};
  2112. X
  2113. Xclass mature_dragon: dragon {
  2114. X    spell 10%:;        speed: 1;    cchar: "d";
  2115. X    defense: max_hp;
  2116. X    treasure: ~has_1d2_obj, has_2d2_obj;
  2117. X};
  2118. X
  2119. Xcreature "Young Blue Dragon": young_dragon {
  2120. X    level: 29;    xp: 300;    hd: 33 d 8;
  2121. X    breath: light;
  2122. X};
  2123. X
  2124. Xcreature "Young White Dragon": young_dragon {
  2125. X    level: 29;    xp: 275;    hd: 32 d 8;
  2126. X    defense: fire;
  2127. X    breath: frost;
  2128. X};
  2129. X
  2130. Xcreature "Young Green Dragon": young_dragon {
  2131. X    level: 29;    xp: 290;    hd: 32 d 8;
  2132. X    breath: gas;
  2133. X};
  2134. X
  2135. Xcreature "Young Black Dragon" : young_dragon {
  2136. X    level: 35;    xp: 600;    hd: 32 d 8;        ac: 55;
  2137. X    defense: max_hp;
  2138. X    breath: acid;
  2139. X    attack: claws for 1 d 5 of normal_damage,
  2140. X        claws for 1 d 5 of normal_damage,
  2141. X        bites for 1 d 6 of normal_damage;
  2142. X};
  2143. X
  2144. Xcreature "Young Red Dragon" : young_dragon {
  2145. X    level: 35;    xp: 650;    hd: 36 d 8;        ac: 60;
  2146. X    defense: max_hp, frost;
  2147. X    breath: fire;
  2148. X    attack: claws for 1 d 8 of normal_damage,
  2149. X        claws for 1 d 8 of normal_damage,
  2150. X        bites for 2 d 8 of normal_damage;
  2151. X};
  2152. X
  2153. Xcreature "Mature White Dragon" : mature_dragon {
  2154. X    level: 35;    xp: 1000;    hd: 48 d 8;        ac: 65;
  2155. X    attack: claws for 1 d 8 of normal_damage,
  2156. X        claws for 1 d 8 of normal_damage,
  2157. X        bites for 2 d 8 of normal_damage;
  2158. X};
  2159. X
  2160. Xclass ghost {
  2161. X    move: move_normal;
  2162. X    defense: undead, evil, no_sleep;
  2163. X    cchar: "G";
  2164. X    spell 7%:;
  2165. X    special: invisible, phase, picks_up;
  2166. X    treasure: carry_obj, carry_gold;
  2167. X};
  2168. X
  2169. Xcreature "Poltergeist": ghost {
  2170. X    level: 3;    xp: 6;        hd: 2 d 5;
  2171. X    treasure: has_random_60, has_random_90;
  2172. X    move: random_75, random_40, random_20;
  2173. X    spell: tel_short;
  2174. X    sleep: 75;    radius: 8;    ac: 15;     speed: 3;
  2175. X    attack: hits for 1 d 1 of cause_fear;
  2176. X};
  2177. X
  2178. Xcreature "Green Glutton Ghost": ghost {
  2179. X    level: 5;    xp: 15;        hd: 3 d 6;
  2180. X    treasure: has_random_60, has_random_90;
  2181. X    move: random_75, random_40;
  2182. X    spell: tel_short, tel_long;
  2183. X    sleep: 10;    radius: 10;    ac: 20;        speed: 3;
  2184. X    attack: slimes for 1 d 1 of eat_food;
  2185. X};
  2186. X
  2187. Xcreature "Lost Soul": ghost {
  2188. X    level: 7;    xp: 18;        hd: 2 d 8;
  2189. X    treasure: has_random_60, has_random_90;
  2190. X    move: random_40, random_20;
  2191. X    spell: drain_mana, tel_long;
  2192. X    sleep: 10;    radius: 4;    ac: 10;        speed: 1;
  2193. X    attack: hits for 2 d 2 of normal_damage,
  2194. X        touches for 0 d 0 of lose_wis;
  2195. X};
  2196. X
  2197. Xcreature "Moaning Spirit": ghost {
  2198. X    level: 12;    xp: 44;        hd: 4 d 8;
  2199. X    treasure: has_random_60, has_random_90;
  2200. X    move: random_40, random_20;
  2201. X    spell: drain_mana, tel_long;
  2202. X    sleep: 30;    radius: 6;    ac: 20;        speed: 1;
  2203. X    attack: wails for 0 d 0 of cause_fear,
  2204. X        touches for 1 d 8 of lose_dex;
  2205. X};
  2206. X
  2207. Xcreature "Banshee": ghost {
  2208. X    level: 24;    xp: 60;        hd: 6 d 8;
  2209. X    treasure: has_random_60, has_random_90;
  2210. X    move: random_40;
  2211. X    spell: drain_mana, tel_long;
  2212. X    sleep: 10;    radius: 20;    ac: 24;        speed: 2;
  2213. X    attack: wails for 0 d 0 of cause_fear,
  2214. X        touches for 14 d 8 of lose_exp;
  2215. X};
  2216. X
  2217. Xcreature "Ghost": ghost {
  2218. X    level: 31;    xp: 350;    hd: 13 d 8;
  2219. X    treasure: has_1d2_obj, has_random_60;
  2220. X    move: random_20;
  2221. X    spell: drain_mana, tel_long;
  2222. X    sleep: 10;    radius: 20;    ac: 30;        speed: 2;
  2223. X    defense: max_hp;
  2224. X    attack: wails for 0 d 0 of cause_fear,
  2225. X        touches for 22 d 8 of lose_exp,
  2226. X        claws for 1 d 10 of lose_int;
  2227. X};
  2228. X
  2229. Xcreature "Spirit Troll": ghost {
  2230. X    level: 34;    xp: 425;    hd: 15 d 8;
  2231. X    treasure: has_1d2_obj, has_random_60;
  2232. X    move: random_20;
  2233. X    spell: drain_mana, tel_long;
  2234. X    sleep: 10;    radius: 20;    ac: 56;        speed: 1;
  2235. X    defense: max_hp;
  2236. X    attack: claws for 1 d 5 of normal_damage,
  2237. X        claws for 1 d 5 of normal_damage,
  2238. X        bites for 1 d 6 of normal_damage,
  2239. X        touches for 0 d 0 of lose_wis;
  2240. X};
  2241. END_OF_FILE
  2242. if test 7711 -ne `wc -c <'util/mc/mon.inf'`; then
  2243.     echo shar: \"'util/mc/mon.inf'\" unpacked with wrong size!
  2244. fi
  2245. # end of 'util/mc/mon.inf'
  2246. fi
  2247. echo shar: End of archive 7 \(of 39\).
  2248. cp /dev/null ark7isdone
  2249. MISSING=""
  2250. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 ; do
  2251.     if test ! -f ark${I}isdone ; then
  2252.     MISSING="${MISSING} ${I}"
  2253.     fi
  2254. done
  2255. if test "${MISSING}" = "" ; then
  2256.     echo You have unpacked all 39 archives.
  2257.     echo "Now run "bldfiles.sh" to build split files"
  2258.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2259. else
  2260.     echo You still need to unpack the following archives:
  2261.     echo "        " ${MISSING}
  2262. fi
  2263. ##  End of shell archive.
  2264. exit 0
  2265.