home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / games / 183 < prev    next >
Encoding:
Internet Message Format  |  1992-08-22  |  57.1 KB

  1. Path: sparky!uunet!zephyr.ens.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v14i053:  umoria4 - single player dungeon simulation (ver. 5.5), Part21/39
  5. Message-ID: <3417@master.CNA.TEK.COM>
  6. Date: 22 Aug 92 22:12:25 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 2162
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: grabiner@math.harvard.edu (David Grabiner)
  12. Posting-number: Volume 14, Issue 53
  13. Archive-name: umoria4/Part21
  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 21 (of 39)."
  26. # Contents:  source/misc3.c.2 source/moria2.c unix/Makefile
  27. # Wrapped by billr@saab on Thu Aug 20 09:11:31 1992
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'source/misc3.c.2' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'source/misc3.c.2'\"
  31. else
  32. echo shar: Extracting \"'source/misc3.c.2'\" \(30036 characters\)
  33. sed "s/^X//" >'source/misc3.c.2' <<'END_OF_FILE'
  34. X  register int weight_cap;
  35. X
  36. X  weight_cap = py.stats.use_stat[A_STR] * PLAYER_WEIGHT_CAP + py.misc.wt;
  37. X  if (weight_cap > 3000)  weight_cap = 3000;
  38. X  return(weight_cap);
  39. X}
  40. X
  41. X
  42. X/* this code must be identical to the inven_carry() code below */
  43. Xint inven_check_num (t_ptr)
  44. Xregister inven_type *t_ptr;
  45. X{
  46. X  register int i;
  47. X
  48. X  if (inven_ctr < INVEN_WIELD)
  49. X    return TRUE;
  50. X  else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
  51. X    for (i = 0; i < inven_ctr; i++)
  52. X      if (inventory[i].tval == t_ptr->tval &&
  53. X      inventory[i].subval == t_ptr->subval &&
  54. X      /* make sure the number field doesn't overflow */
  55. X      ((int)inventory[i].number + (int)t_ptr->number < 256) &&
  56. X      /* they always stack (subval < 192), or else they have same p1 */
  57. X      ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
  58. X      /* only stack if both or neither are identified */
  59. X      && (known1_p(&inventory[i]) == known1_p(t_ptr)))
  60. X    return TRUE;
  61. X  return FALSE;
  62. X}
  63. X
  64. X/* return FALSE if picking up an object would change the players speed */
  65. Xint inven_check_weight(i_ptr)
  66. Xregister inven_type *i_ptr;
  67. X{
  68. X  register int i, new_inven_weight;
  69. X
  70. X  i = weight_limit();
  71. X  new_inven_weight = i_ptr->number*i_ptr->weight + inven_weight;
  72. X  if (i < new_inven_weight)
  73. X    i = new_inven_weight / (i + 1);
  74. X  else
  75. X    i = 0;
  76. X
  77. X  if (pack_heavy != i)
  78. X    return FALSE;
  79. X  else
  80. X    return TRUE;
  81. X}
  82. X
  83. X
  84. X/* Are we strong enough for the current pack and weapon?  -CJS-     */
  85. Xvoid check_strength()
  86. X{
  87. X  register int i;
  88. X  register inven_type *i_ptr;
  89. X#ifdef ATARIST_MWC
  90. X  int32u holder;
  91. X#endif
  92. X
  93. X  i_ptr = &inventory[INVEN_WIELD];
  94. X  if (i_ptr->tval != TV_NOTHING
  95. X      && (py.stats.use_stat[A_STR]*15 < i_ptr->weight))
  96. X    {
  97. X      if (weapon_heavy == FALSE)
  98. X    {
  99. X      msg_print("You have trouble wielding such a heavy weapon.");
  100. X      weapon_heavy = TRUE;
  101. X      calc_bonuses();
  102. X    }
  103. X    }
  104. X  else if (weapon_heavy == TRUE)
  105. X    {
  106. X      weapon_heavy = FALSE;
  107. X      if (i_ptr->tval != TV_NOTHING)
  108. X    msg_print("You are strong enough to wield your weapon.");
  109. X      calc_bonuses();
  110. X    }
  111. X  i = weight_limit();
  112. X  if (i < inven_weight)
  113. X    i = inven_weight / (i+1);
  114. X  else
  115. X    i = 0;
  116. X  if (pack_heavy != i)
  117. X    {
  118. X      if (pack_heavy < i)
  119. X    msg_print("Your pack is so heavy that it slows you down.");
  120. X      else
  121. X    msg_print("You move more easily under the weight of your pack.");
  122. X      change_speed(i - pack_heavy);
  123. X      pack_heavy = i;
  124. X    }
  125. X#ifdef ATARIST_MWC
  126. X  py.flags.status &= ~(holder = PY_STR_WGT);
  127. X#else
  128. X  py.flags.status &= ~PY_STR_WGT;
  129. X#endif
  130. X}
  131. X
  132. X
  133. X/* Add an item to players inventory.  Return the    */
  134. X/* item position for a description if needed.           -RAK-   */
  135. X/* this code must be identical to the inven_check_num() code above */
  136. Xint inven_carry(i_ptr)
  137. Xregister inven_type *i_ptr;
  138. X{
  139. X  register int locn, i;
  140. X  register int typ, subt;
  141. X  register inven_type *t_ptr;
  142. X  int known1p, always_known1p;
  143. X#ifdef ATARIST_MWC
  144. X  int32u holder;
  145. X#endif
  146. X
  147. X  typ = i_ptr->tval;
  148. X  subt = i_ptr->subval;
  149. X  known1p = known1_p (i_ptr);
  150. X  always_known1p = (object_offset (i_ptr) == -1);
  151. X  /* Now, check to see if player can carry object  */
  152. X  for (locn = 0; ; locn++)
  153. X    {
  154. X      t_ptr = &inventory[locn];
  155. X      if ((typ == t_ptr->tval) && (subt == t_ptr->subval)
  156. X      && (subt >= ITEM_SINGLE_STACK_MIN) &&
  157. X      ((int)t_ptr->number + (int)i_ptr->number < 256) &&
  158. X      ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1)) &&
  159. X      /* only stack if both or neither are identified */
  160. X      (known1p == known1_p(t_ptr)))
  161. X    {
  162. X      t_ptr->number += i_ptr->number;
  163. X      break;
  164. X    }
  165. X      /* For items which are always known1p, i.e. never have a 'color',
  166. X     insert them into the inventory in sorted order.  */
  167. X      else if ((typ == t_ptr->tval && subt < t_ptr->subval
  168. X        && always_known1p)
  169. X           || (typ > t_ptr->tval))
  170. X    {
  171. X      for (i = inven_ctr - 1; i >= locn; i--)
  172. X        inventory[i+1] = inventory[i];
  173. X      inventory[locn] = *i_ptr;
  174. X      inven_ctr++;
  175. X      break;
  176. X    }
  177. X    }
  178. X
  179. X  inven_weight += i_ptr->number*i_ptr->weight;
  180. X#ifdef ATARIST_MWC
  181. X  py.flags.status |= (holder = PY_STR_WGT);
  182. X#else
  183. X  py.flags.status |= PY_STR_WGT;
  184. X#endif
  185. X  return locn;
  186. X}
  187. X
  188. X
  189. X/* Returns spell chance of failure for spell        -RAK-    */
  190. Xint spell_chance(spell)
  191. Xint spell;
  192. X{
  193. X  register spell_type *s_ptr;
  194. X  register int chance;
  195. X  register int stat;
  196. X
  197. X  s_ptr = &magic_spell[py.misc.pclass-1][spell];
  198. X  chance = s_ptr->sfail - 3*(py.misc.lev-s_ptr->slevel);
  199. X  if (class[py.misc.pclass].spell == MAGE)
  200. X    stat = A_INT;
  201. X  else
  202. X    stat = A_WIS;
  203. X  chance -= 3 * (stat_adj(stat)-1);
  204. X  if (s_ptr->smana > py.misc.cmana)
  205. X    chance += 5 * (s_ptr->smana-py.misc.cmana);
  206. X  if (chance > 95)
  207. X    chance = 95;
  208. X  else if (chance < 5)
  209. X    chance = 5;
  210. X  return chance;
  211. X}
  212. X
  213. X
  214. X/* Print list of spells                    -RAK-    */
  215. X/* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num
  216. X                  >=0: spells numbered by offset from nonconsec */
  217. Xvoid print_spells(spell, num, comment, nonconsec)
  218. Xint *spell;
  219. Xregister int num;
  220. Xint comment, nonconsec;
  221. X{
  222. X  register int i, j;
  223. X  vtype out_val;
  224. X  register spell_type *s_ptr;
  225. X  int col, offset;
  226. X  char *p;
  227. X  char spell_char;
  228. X
  229. X  if (comment)
  230. X    col = 22;
  231. X  else
  232. X    col = 31;
  233. X  offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  234. X  erase_line(1, col);
  235. X  put_buffer("Name", 1, col+5);
  236. X  put_buffer("Lv Mana Fail", 1, col+35);
  237. X  /* only show the first 22 choices */
  238. X  if (num > 22)
  239. X    num = 22;
  240. X  for (i = 0; i < num; i++)
  241. X    {
  242. X      j = spell[i];
  243. X      s_ptr = &magic_spell[py.misc.pclass-1][j];
  244. X      if (comment == FALSE)
  245. X    p = "";
  246. X      else if ((spell_forgotten & (1L << j)) != 0)
  247. X    p = " forgotten";
  248. X      else if ((spell_learned & (1L << j)) == 0)
  249. X    p = " unknown";
  250. X      else if ((spell_worked & (1L << j)) == 0)
  251. X    p = " untried";
  252. X      else
  253. X    p = "";
  254. X      /* determine whether or not to leave holes in character choices,
  255. X     nonconsec -1 when learning spells, consec offset>=0 when asking which
  256. X     spell to cast */
  257. X      if (nonconsec == -1)
  258. X    spell_char = 'a' + i;
  259. X      else
  260. X    spell_char = 'a' + j - nonconsec;
  261. X      (void) sprintf(out_val, "  %c) %-30s%2d %4d %3d%%%s", spell_char,
  262. X             spell_names[j+offset], s_ptr->slevel, s_ptr->smana,
  263. X             spell_chance (j), p);
  264. X      prt(out_val, 2+i, col);
  265. X    }
  266. X}
  267. X
  268. X
  269. X/* Returns spell pointer                -RAK-    */
  270. Xint get_spell(spell, num, sn, sc, prompt, first_spell)
  271. Xint *spell;
  272. Xregister int num;
  273. Xregister int *sn, *sc;
  274. Xchar *prompt;
  275. Xint first_spell;
  276. X{
  277. X  register spell_type *s_ptr;
  278. X  int flag, redraw, offset, i;
  279. X  char choice;
  280. X  vtype out_str, tmp_str;
  281. X
  282. X  *sn = -1;
  283. X  flag = FALSE;
  284. X  (void) sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
  285. X         spell[0]+'a'-first_spell, spell[num-1]+'a'-first_spell,
  286. X         prompt);
  287. X  redraw = FALSE;
  288. X  offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
  289. X  while (flag == FALSE && get_com (out_str, &choice))
  290. X    {
  291. X      if (isupper((int)choice))
  292. X    {
  293. X      *sn = choice-'A'+first_spell;
  294. X      /* verify that this is in spell[], at most 22 entries in spell[] */
  295. X      for (i = 0; i < num; i++)
  296. X        if (*sn == spell[i])
  297. X          break;
  298. X      if (i == num)
  299. X        *sn = -2;
  300. X      else
  301. X        {
  302. X          s_ptr = &magic_spell[py.misc.pclass-1][*sn];
  303. X          (void) sprintf (tmp_str, "Cast %s (%d mana, %d%% fail)?",
  304. X                  spell_names[*sn+offset], s_ptr->smana,
  305. X                  spell_chance (*sn));
  306. X          if (get_check (tmp_str))
  307. X        flag = TRUE;
  308. X          else
  309. X        *sn = -1;
  310. X        }
  311. X    }
  312. X      else if (islower((int)choice))
  313. X    {
  314. X      *sn = choice-'a'+first_spell;
  315. X      /* verify that this is in spell[], at most 22 entries in spell[] */
  316. X      for (i = 0; i < num; i++)
  317. X        if (*sn == spell[i])
  318. X          break;
  319. X      if (i == num)
  320. X        *sn = -2;
  321. X      else
  322. X        flag = TRUE;
  323. X    }
  324. X      else if (choice == '*')
  325. X    {
  326. X      /* only do this drawing once */
  327. X      if (!redraw)
  328. X        {
  329. X          save_screen ();
  330. X          redraw = TRUE;
  331. X          print_spells (spell, num, FALSE, first_spell);
  332. X        }
  333. X    }
  334. X      else if (isalpha((int)choice))
  335. X    *sn = -2;
  336. X      else
  337. X    {
  338. X      *sn = -1;
  339. X      bell();
  340. X    }
  341. X      if (*sn == -2)
  342. X    {
  343. X      (void) sprintf (tmp_str, "You don't know that %s.",
  344. X              (offset == SPELL_OFFSET ? "spell" : "prayer"));
  345. X      msg_print(tmp_str);
  346. X    }
  347. X    }
  348. X  if (redraw)
  349. X    restore_screen ();
  350. X
  351. X  erase_line(MSG_LINE, 0);
  352. X  if (flag)
  353. X    *sc = spell_chance (*sn);
  354. X
  355. X  return(flag);
  356. X}
  357. X
  358. X
  359. X/* calculate number of spells player should have, and learn forget spells
  360. X   until that number is met -JEW- */
  361. Xvoid calc_spells(stat)
  362. Xint stat;
  363. X{
  364. X  register int i;
  365. X  register int32u mask;
  366. X  int32u spell_flag;
  367. X  int j, offset;
  368. X  int num_allowed, new_spells, num_known, levels;
  369. X  vtype tmp_str;
  370. X  char *p;
  371. X  register struct misc *p_ptr;
  372. X  register spell_type *msp_ptr;
  373. X
  374. X  p_ptr = &py.misc;
  375. X  msp_ptr = &magic_spell[p_ptr->pclass-1][0];
  376. X  if (stat == A_INT)
  377. X    {
  378. X      p = "spell";
  379. X      offset = SPELL_OFFSET;
  380. X    }
  381. X  else
  382. X    {
  383. X      p = "prayer";
  384. X      offset = PRAYER_OFFSET;
  385. X    }
  386. X
  387. X  /* check to see if know any spells greater than level, eliminate them */
  388. X  for (i = 31, mask = 0x80000000L; mask; mask >>= 1, i--)
  389. X    if (mask & spell_learned)
  390. X      {
  391. X    if (msp_ptr[i].slevel > p_ptr->lev)
  392. X      {
  393. X        spell_learned &= ~mask;
  394. X        spell_forgotten |= mask;
  395. X        (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  396. X               spell_names[i+offset]);
  397. X        msg_print(tmp_str);
  398. X      }
  399. X    else
  400. X      break;
  401. X      }
  402. X
  403. X  /* calc number of spells allowed */
  404. X  levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  405. X  switch(stat_adj(stat))
  406. X    {
  407. X    case 0:            num_allowed = 0; break;
  408. X    case 1: case 2: case 3: num_allowed = 1 * levels; break;
  409. X    case 4: case 5:        num_allowed = 3 * levels / 2; break;
  410. X    case 6:            num_allowed = 2 * levels; break;
  411. X    case 7:            num_allowed = 5 * levels / 2; break;
  412. X    }
  413. X
  414. X  num_known = 0;
  415. X  for (mask = 0x1; mask; mask <<= 1)
  416. X    if (mask & spell_learned)
  417. X      num_known++;
  418. X  new_spells = num_allowed - num_known;
  419. X
  420. X  if (new_spells > 0)
  421. X    {
  422. X      /* remember forgotten spells while forgotten spells exist of new_spells
  423. X     positive, remember the spells in the order that they were learned */
  424. X      for (i = 0; (spell_forgotten && new_spells
  425. X           && (i < num_allowed) && (i < 32)); i++)
  426. X    {
  427. X      /* j is (i+1)th spell learned */
  428. X      j = spell_order[i];
  429. X      /* shifting by amounts greater than number of bits in long gives
  430. X         an undefined result, so don't shift for unknown spells */
  431. X      if (j == 99)
  432. X        mask = 0x0;
  433. X      else
  434. X        mask = 1L << j;
  435. X      if (mask & spell_forgotten)
  436. X        {
  437. X          if (msp_ptr[j].slevel <= p_ptr->lev)
  438. X        {
  439. X          new_spells--;
  440. X          spell_forgotten &= ~mask;
  441. X          spell_learned |= mask;
  442. X          (void) sprintf(tmp_str, "You have remembered the %s of %s.",
  443. X                 p, spell_names[j+offset]);
  444. X          msg_print(tmp_str);
  445. X        }
  446. X          else
  447. X        num_allowed++;
  448. X        }
  449. X    }
  450. X
  451. X      if (new_spells > 0)
  452. X    {
  453. X      /* determine which spells player can learn */
  454. X      /* must check all spells here, in gain_spell() we actually check
  455. X         if the books are present */
  456. X      spell_flag = 0x7FFFFFFFL & ~spell_learned;
  457. X
  458. X      mask = 0x1;
  459. X      i = 0;
  460. X      for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  461. X        if (spell_flag & mask)
  462. X          {
  463. X        spell_flag &= ~mask;
  464. X        if (msp_ptr[j].slevel <= p_ptr->lev)
  465. X          i++;
  466. X          }
  467. X
  468. X      if (new_spells > i)
  469. X        new_spells = i;
  470. X    }
  471. X    }
  472. X  else if (new_spells < 0)
  473. X    {
  474. X      /* forget spells until new_spells zero or no more spells know, spells
  475. X     are forgotten in the opposite order that they were learned */
  476. X      for (i = 31; new_spells && spell_learned; i--)
  477. X    {
  478. X      /* j is the (i+1)th spell learned */
  479. X      j = spell_order[i];
  480. X      /* shifting by amounts greater than number of bits in long gives
  481. X         an undefined result, so don't shift for unknown spells */
  482. X      if (j == 99)
  483. X        mask = 0x0;
  484. X      else
  485. X        mask = 1L << j;
  486. X      if (mask & spell_learned)
  487. X        {
  488. X          spell_learned &= ~mask;
  489. X          spell_forgotten |= mask;
  490. X          new_spells++;
  491. X          (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
  492. X                 spell_names[j+offset]);
  493. X          msg_print(tmp_str);
  494. X        }
  495. X    }
  496. X
  497. X      new_spells = 0;
  498. X    }
  499. X
  500. X  if (new_spells != py.flags.new_spells)
  501. X    {
  502. X      if (new_spells > 0 && py.flags.new_spells == 0)
  503. X    {
  504. X      (void) sprintf(tmp_str, "You can learn some new %ss now.", p);
  505. X      msg_print(tmp_str);
  506. X    }
  507. X
  508. X      py.flags.new_spells = new_spells;
  509. X      py.flags.status |= PY_STUDY;
  510. X    }
  511. X}
  512. X
  513. X
  514. X/* gain spells when player wants to        - jw */
  515. Xvoid gain_spells()
  516. X{
  517. X  char query;
  518. X  int stat, diff_spells, new_spells;
  519. X  int spells[31], offset, last_known;
  520. X  register int i, j;
  521. X  register int32u spell_flag, mask;
  522. X  vtype tmp_str;
  523. X  struct misc *p_ptr;
  524. X  register spell_type *msp_ptr;
  525. X
  526. X  /* Priests don't need light because they get spells from their god,
  527. X     so only fail when can't see if player has MAGE spells.  This check
  528. X     is done below.  */
  529. X  if (py.flags.confused > 0)
  530. X    {
  531. X      msg_print("You are too confused.");
  532. X      return;
  533. X    }
  534. X
  535. X  new_spells = py.flags.new_spells;
  536. X  diff_spells = 0;
  537. X  p_ptr = &py.misc;
  538. X  msp_ptr = &magic_spell[p_ptr->pclass-1][0];
  539. X  if (class[p_ptr->pclass].spell == MAGE)
  540. X    {
  541. X      stat = A_INT;
  542. X      offset = SPELL_OFFSET;
  543. X
  544. X      /* People with MAGE spells can't learn spells if they can't read their
  545. X     books.  */
  546. X      if (py.flags.blind > 0)
  547. X    {
  548. X      msg_print("You can't see to read your spell book!");
  549. X      return;
  550. X    }
  551. X      else if (no_light())
  552. X    {
  553. X      msg_print("You have no light to read by.");
  554. X      return;
  555. X    }
  556. X    }
  557. X  else
  558. X    {
  559. X      stat = A_WIS;
  560. X      offset = PRAYER_OFFSET;
  561. X    }
  562. X
  563. X  for (last_known = 0; last_known < 32; last_known++)
  564. X    if (spell_order[last_known] == 99)
  565. X      break;
  566. X
  567. X  if (!new_spells)
  568. X    {
  569. X      (void) sprintf(tmp_str, "You can't learn any new %ss!",
  570. X             (stat == A_INT ? "spell" : "prayer"));
  571. X      msg_print(tmp_str);
  572. X      free_turn_flag = TRUE;
  573. X    }
  574. X  else
  575. X    {
  576. X      /* determine which spells player can learn */
  577. X      /* mages need the book to learn a spell, priests do not need the book */
  578. X      if (stat == A_INT)
  579. X    {
  580. X      spell_flag = 0;
  581. X      for (i = 0; i < inven_ctr; i++)
  582. X        if (inventory[i].tval == TV_MAGIC_BOOK)
  583. X          spell_flag |= inventory[i].flags;
  584. X    }
  585. X      else
  586. X    spell_flag = 0x7FFFFFFF;
  587. X
  588. X      /* clear bits for spells already learned */
  589. X      spell_flag &= ~spell_learned;
  590. X
  591. X      mask = 0x1;
  592. X      i = 0;
  593. X      for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
  594. X    if (spell_flag & mask)
  595. X      {
  596. X        spell_flag &= ~mask;
  597. X        if (msp_ptr[j].slevel <= p_ptr->lev)
  598. X          {
  599. X        spells[i] = j;
  600. X        i++;
  601. X          }
  602. X      }
  603. X
  604. X      if (new_spells > i)
  605. X    {
  606. X      msg_print("You seem to be missing a book.");
  607. X      diff_spells = new_spells - i;
  608. X      new_spells = i;
  609. X    }
  610. X      if (new_spells == 0)
  611. X    ;
  612. X      else if (stat == A_INT)
  613. X    {
  614. X      /* get to choose which mage spells will be learned */
  615. X      save_screen();
  616. X      print_spells (spells, i, FALSE, -1);
  617. X      while (new_spells && get_com ("Learn which spell?", &query))
  618. X        {
  619. X          j = query - 'a';
  620. X          /* test j < 23 in case i is greater than 22, only 22 spells
  621. X         are actually shown on the screen, so limit choice to those */
  622. X          if (j >= 0 && j < i && j < 22)
  623. X        {
  624. X          new_spells--;
  625. X          spell_learned |= 1L << spells[j];
  626. X          spell_order[last_known++] = spells[j];
  627. X          for (; j <= i-1; j++)
  628. X            spells[j] = spells[j+1];
  629. X          i--;
  630. X          erase_line (j+1, 31);
  631. X          print_spells (spells, i, FALSE, -1);
  632. X        }
  633. X          else
  634. X        bell();
  635. X        }
  636. X      restore_screen();
  637. X    }
  638. X      else
  639. X    {
  640. X      /* pick a prayer at random */
  641. X      while (new_spells)
  642. X        {
  643. X          j = randint(i) - 1;
  644. X          spell_learned |= 1L << spells[j];
  645. X          spell_order[last_known++] = spells[j];
  646. X          (void) sprintf (tmp_str,
  647. X                  "You have learned the prayer of %s.",
  648. X                  spell_names[spells[j]+offset]);
  649. X          msg_print(tmp_str);
  650. X          for (; j <= i-1; j++)
  651. X        spells[j] = spells[j+1];
  652. X          i--;
  653. X          new_spells--;
  654. X        }
  655. X    }
  656. X      py.flags.new_spells = new_spells + diff_spells;
  657. X      if (py.flags.new_spells == 0)
  658. X    py.flags.status |= PY_STUDY;
  659. X      /* set the mana for first level characters when they learn their
  660. X     first spell */
  661. X      if (py.misc.mana == 0)
  662. X    calc_mana(stat);
  663. X    }
  664. X}
  665. X
  666. X
  667. X/* Gain some mana if you know at least one spell    -RAK-    */
  668. Xvoid calc_mana(stat)
  669. Xint stat;
  670. X{
  671. X  register int new_mana, levels;
  672. X  register struct misc *p_ptr;
  673. X  register int32 value;
  674. X#ifdef ATARIST_MWC
  675. X  int32u holder;
  676. X#endif
  677. X
  678. X  p_ptr = &py.misc;
  679. X  if (spell_learned != 0)
  680. X    {
  681. X      levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
  682. X      switch(stat_adj(stat))
  683. X    {
  684. X    case 0: new_mana = 0; break;
  685. X    case 1: case 2: new_mana = 1 * levels; break;
  686. X    case 3: new_mana = 3 * levels / 2; break;
  687. X    case 4: new_mana = 2 * levels; break;
  688. X    case 5: new_mana = 5 * levels / 2; break;
  689. X    case 6: new_mana = 3 * levels; break;
  690. X    case 7: new_mana = 4 * levels; break;
  691. X    }
  692. X      /* increment mana by one, so that first level chars have 2 mana */
  693. X      if (new_mana > 0)
  694. X    new_mana++;
  695. X
  696. X      /* mana can be zero when creating character */
  697. X      if (p_ptr->mana != new_mana)
  698. X    {
  699. X      if (p_ptr->mana != 0)
  700. X        {
  701. X          /* change current mana proportionately to change of max mana,
  702. X         divide first to avoid overflow, little loss of accuracy */
  703. X          value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
  704. X        / p_ptr->mana * new_mana;
  705. X          p_ptr->cmana = value >> 16;
  706. X          p_ptr->cmana_frac = value & 0xFFFF;
  707. X        }
  708. X      else
  709. X        {
  710. X          p_ptr->cmana = new_mana;
  711. X          p_ptr->cmana_frac = 0;
  712. X        }
  713. X      p_ptr->mana = new_mana;
  714. X      /* can't print mana here, may be in store or inventory mode */
  715. X#ifdef ATARIST_MWC
  716. X      py.flags.status |= (holder = PY_MANA);
  717. X#else
  718. X      py.flags.status |= PY_MANA;
  719. X#endif
  720. X    }
  721. X    }
  722. X  else if (p_ptr->mana != 0)
  723. X    {
  724. X      p_ptr->mana = 0;
  725. X      p_ptr->cmana = 0;
  726. X      /* can't print mana here, may be in store or inventory mode */
  727. X#ifdef ATARIST_MWC
  728. X      py.flags.status |= (holder = PY_MANA);
  729. X#else
  730. X      py.flags.status |= PY_MANA;
  731. X#endif
  732. X    }
  733. X}
  734. X
  735. X
  736. X/* Increases hit points and level            -RAK-    */
  737. Xstatic void gain_level()
  738. X{
  739. X  register int32 dif_exp, need_exp;
  740. X  vtype out_val;
  741. X  register struct misc *p_ptr;
  742. X  register class_type *c_ptr;
  743. X
  744. X  p_ptr = &py.misc;
  745. X  p_ptr->lev++;
  746. X  (void) sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
  747. X  msg_print(out_val);
  748. X  calc_hitpoints();
  749. X
  750. X  need_exp = player_exp[p_ptr->lev-1] * p_ptr->expfact / 100;
  751. X  if (p_ptr->exp > need_exp)
  752. X    {
  753. X      /* lose some of the 'extra' exp when gain a level */
  754. X      dif_exp = p_ptr->exp - need_exp;
  755. X      p_ptr->exp = need_exp + (dif_exp / 2);
  756. X    }
  757. X  prt_level();
  758. X  prt_title();
  759. X  c_ptr = &class[p_ptr->pclass];
  760. X  if (c_ptr->spell == MAGE)
  761. X    {
  762. X      calc_spells(A_INT);
  763. X      calc_mana(A_INT);
  764. X    }
  765. X  else if (c_ptr->spell == PRIEST)
  766. X    {
  767. X      calc_spells(A_WIS);
  768. X      calc_mana(A_WIS);
  769. X    }
  770. X}
  771. X
  772. X/* Prints experience                    -RAK-    */
  773. Xvoid prt_experience()
  774. X{
  775. X  register struct misc *p_ptr;
  776. X
  777. X  p_ptr = &py.misc;
  778. X  if (p_ptr->exp > MAX_EXP)
  779. X    p_ptr->exp = MAX_EXP;
  780. X
  781. X  if (p_ptr->lev < MAX_PLAYER_LEVEL)
  782. X    while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp)
  783. X      gain_level();
  784. X
  785. X  if (p_ptr->exp > p_ptr->max_exp)
  786. X    p_ptr->max_exp = p_ptr->exp;
  787. X
  788. X  prt_long(p_ptr->exp, 14, STAT_COLUMN+6);
  789. X}
  790. X
  791. X
  792. X/* Calculate the players hit points */
  793. Xvoid calc_hitpoints()
  794. X{
  795. X  register int hitpoints;
  796. X  register struct misc *p_ptr;
  797. X  register int32 value;
  798. X#ifdef ATARIST_MWC
  799. X  int32u holder;
  800. X#endif
  801. X
  802. X  p_ptr = &py.misc;
  803. X  hitpoints = player_hp[p_ptr->lev-1] + (con_adj() * p_ptr->lev);
  804. X  /* always give at least one point per level + 1 */
  805. X  if (hitpoints < (p_ptr->lev + 1))
  806. X    hitpoints = p_ptr->lev + 1;
  807. X
  808. X  if (py.flags.status & PY_HERO)
  809. X    hitpoints += 10;
  810. X  if (py.flags.status & PY_SHERO)
  811. X    hitpoints += 20;
  812. X
  813. X  /* mhp can equal zero while character is being created */
  814. X  if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0))
  815. X    {
  816. X      /* change current hit points proportionately to change of mhp,
  817. X     divide first to avoid overflow, little loss of accuracy */
  818. X      value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
  819. X    * hitpoints;
  820. X      p_ptr->chp = value >> 16;
  821. X      p_ptr->chp_frac = value & 0xFFFF;
  822. X      p_ptr->mhp = hitpoints;
  823. X
  824. X      /* can't print hit points here, may be in store or inventory mode */
  825. X#ifdef ATARIST_MWC
  826. X      py.flags.status |= (holder = PY_HP);
  827. X#else
  828. X      py.flags.status |= PY_HP;
  829. X#endif
  830. X    }
  831. X}
  832. X
  833. X
  834. X/* Inserts a string into a string                */
  835. Xvoid insert_str(object_str, mtc_str, insert)
  836. Xchar *object_str, *mtc_str, *insert;
  837. X{
  838. X  int obj_len;
  839. X  char *bound, *pc;
  840. X  register int i, mtc_len;
  841. X  register char *temp_obj, *temp_mtc;
  842. X  char out_val[80];
  843. X
  844. X  mtc_len = strlen(mtc_str);
  845. X  obj_len = strlen(object_str);
  846. X  bound = object_str + obj_len - mtc_len;
  847. X  for (pc = object_str; pc <= bound; pc++)
  848. X    {
  849. X      temp_obj = pc;
  850. X      temp_mtc = mtc_str;
  851. X      for (i = 0; i < mtc_len; i++)
  852. X    if (*temp_obj++ != *temp_mtc++)
  853. X      break;
  854. X      if (i == mtc_len)
  855. X    break;
  856. X    }
  857. X
  858. X  if (pc <= bound)
  859. X    {
  860. X#ifdef __TURBOC__
  861. X      /* Avoid complaint about possible loss of significance.  */
  862. X      (void) strncpy(out_val, object_str, (size_t)(pc-object_str));
  863. X#else
  864. X      (void) strncpy(out_val, object_str, (pc-object_str));
  865. X#endif
  866. X      /* Turbo C needs int for array index.  */
  867. X      out_val[(int)(pc-object_str)] = '\0';
  868. X      if (insert)
  869. X    (void) strcat(out_val, insert);
  870. X      (void) strcat(out_val, (char *)(pc+mtc_len));
  871. X      (void) strcpy(object_str, out_val);
  872. X    }
  873. X}
  874. X
  875. X
  876. X#if 0
  877. X/* this is no longer used anywhere */
  878. X/* Inserts a number into a string                */
  879. Xvoid insert_num(object_str, mtc_str, number, show_sign)
  880. Xchar *object_str;
  881. Xregister char *mtc_str;
  882. Xint number;
  883. Xint show_sign;
  884. X{
  885. X  int mlen;
  886. X  vtype str1, str2;
  887. X  register char *string, *tmp_str;
  888. X  int flag;
  889. X
  890. X  flag = 1;
  891. X  mlen = strlen(mtc_str);
  892. X  tmp_str = object_str;
  893. X  do
  894. X    {
  895. X      string = index(tmp_str, mtc_str[0]);
  896. X      if (string == CNIL)
  897. X    flag = 0;
  898. X      else
  899. X    {
  900. X      flag = strncmp(string, mtc_str, mlen);
  901. X      if (flag)
  902. X        tmp_str = string+1;
  903. X    }
  904. X    }
  905. X  while (flag);
  906. X  if (string)
  907. X    {
  908. X#ifdef __TURBOC__
  909. X      /* Avoid complaint about possible loss of significance.  */
  910. X      (void) strncpy(str1, object_str, (size_t)(string - object_str));
  911. X#else
  912. X      (void) strncpy(str1, object_str, string - object_str);
  913. X#endif
  914. X      /* Turbo C needs int for array index.  */
  915. X      str1[(int)(string - object_str)] = '\0';
  916. X      (void) strcpy(str2, string + mlen);
  917. X      if ((number >= 0) && (show_sign))
  918. X    (void) sprintf(object_str, "%s+%d%s", str1, number, str2);
  919. X      else
  920. X    (void) sprintf(object_str, "%s%d%s", str1, number, str2);
  921. X    }
  922. X}
  923. X#endif
  924. X
  925. Xvoid insert_lnum(object_str, mtc_str, number, show_sign)
  926. Xchar *object_str;
  927. Xregister char *mtc_str;
  928. Xint32 number;
  929. Xint show_sign;
  930. X{
  931. X  int mlen;
  932. X  vtype str1, str2;
  933. X  register char *string, *tmp_str;
  934. X  int flag;
  935. X
  936. X  flag = 1;
  937. X  mlen = strlen(mtc_str);
  938. X  tmp_str = object_str;
  939. X  do
  940. X    {
  941. X      string = index(tmp_str, mtc_str[0]);
  942. X      if (string == 0)
  943. X    flag = 0;
  944. X      else
  945. X    {
  946. X      flag = strncmp(string, mtc_str, mlen);
  947. X      if (flag)
  948. X        tmp_str = string+1;
  949. X    }
  950. X    }
  951. X  while (flag);
  952. X  if (string)
  953. X    {
  954. X      (void) strncpy(str1, object_str, string - object_str);
  955. X      str1[string - object_str] = '\0';
  956. X      (void) strcpy(str2, string + mlen);
  957. X      if ((number >= 0) && (show_sign))
  958. X    (void) sprintf(object_str, "%s+%ld%s", str1, number, str2);
  959. X      else
  960. X    (void) sprintf(object_str, "%s%ld%s", str1, number, str2);
  961. X    }
  962. X}
  963. X
  964. X
  965. X/* lets anyone enter wizard mode after a disclaimer...        - JEW - */
  966. Xint enter_wiz_mode()
  967. X{
  968. X  register int answer;
  969. X
  970. X  if (!noscore)
  971. X    {
  972. X      msg_print("Wizard mode is for debugging and experimenting.");
  973. X      answer = get_check(
  974. X    "The game will not be scored if you enter wizard mode. Are you sure?");
  975. X    }
  976. X  if (noscore || answer)
  977. X    {
  978. X      noscore |= 0x2;
  979. X      wizard = TRUE;
  980. X      return(TRUE);
  981. X    }
  982. X  return(FALSE);
  983. X}
  984. X
  985. X
  986. X/* Weapon weight VS strength and dexterity        -RAK-    */
  987. Xint attack_blows(weight, wtohit)
  988. Xint weight;
  989. Xint *wtohit;
  990. X{
  991. X  register int adj_weight;
  992. X  register int str_index, dex_index, s, d;
  993. X
  994. X  s = py.stats.use_stat[A_STR];
  995. X  d = py.stats.use_stat[A_DEX];
  996. X  if (s * 15 < weight)
  997. X    {
  998. X      *wtohit = s * 15 - weight;
  999. X      return 1;
  1000. X    }
  1001. X  else
  1002. X    {
  1003. X      *wtohit = 0;
  1004. X      if      (d <  10)     dex_index = 0;
  1005. X      else if (d <  19)     dex_index = 1;
  1006. X      else if (d <  68)     dex_index = 2;
  1007. X      else if (d < 108)     dex_index = 3;
  1008. X      else if (d < 118)     dex_index = 4;
  1009. X      else         dex_index = 5;
  1010. X      adj_weight = (s * 10 / weight);
  1011. X      if      (adj_weight < 2)    str_index = 0;
  1012. X      else if (adj_weight < 3)    str_index = 1;
  1013. X      else if (adj_weight < 4)    str_index = 2;
  1014. X      else if (adj_weight < 5)    str_index = 3;
  1015. X      else if (adj_weight < 7)    str_index = 4;
  1016. X      else if (adj_weight < 9)    str_index = 5;
  1017. X      else            str_index = 6;
  1018. X      return (int)blows_table[str_index][dex_index];
  1019. X    }
  1020. X}
  1021. X
  1022. X
  1023. X/* Special damage due to magical abilities of object    -RAK-    */
  1024. Xint tot_dam(i_ptr, tdam, monster)
  1025. Xregister inven_type *i_ptr;
  1026. Xregister int tdam;
  1027. Xint monster;
  1028. X{
  1029. X  register creature_type *m_ptr;
  1030. X  register recall_type *r_ptr;
  1031. X#ifdef ATARIST_MWC
  1032. X  int32u holder;
  1033. X#endif
  1034. X
  1035. X#ifdef ATARIST_MWC
  1036. X  if ((i_ptr->flags & (holder = TR_EGO_WEAPON)) &&
  1037. X#else
  1038. X  if ((i_ptr->flags & TR_EGO_WEAPON) &&
  1039. X#endif
  1040. X      (((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
  1041. X       ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
  1042. X       (i_ptr->tval == TV_FLASK)))
  1043. X    {
  1044. X      m_ptr = &c_list[monster];
  1045. X      r_ptr = &c_recall[monster];
  1046. X      /* Slay Dragon  */
  1047. X      if ((m_ptr->cdefense & CD_DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON))
  1048. X    {
  1049. X      tdam = tdam * 4;
  1050. X      r_ptr->r_cdefense |= CD_DRAGON;
  1051. X    }
  1052. X      /* Slay Undead  */
  1053. X#ifdef ATARIST_MWC
  1054. X      else if ((m_ptr->cdefense & CD_UNDEAD)
  1055. X           && (i_ptr->flags & (holderr = TR_SLAY_UNDEAD)))
  1056. X#else
  1057. X      else if ((m_ptr->cdefense & CD_UNDEAD)
  1058. X           && (i_ptr->flags & TR_SLAY_UNDEAD))
  1059. X#endif
  1060. X    {
  1061. X      tdam = tdam * 3;
  1062. X      r_ptr->r_cdefense |= CD_UNDEAD;
  1063. X    }
  1064. X      /* Slay Animal  */
  1065. X      else if ((m_ptr->cdefense & CD_ANIMAL)
  1066. X           && (i_ptr->flags & TR_SLAY_ANIMAL))
  1067. X    {
  1068. X      tdam = tdam * 2;
  1069. X      r_ptr->r_cdefense |= CD_ANIMAL;
  1070. X    }
  1071. X      /* Slay Evil     */
  1072. X      else if ((m_ptr->cdefense & CD_EVIL) && (i_ptr->flags & TR_SLAY_EVIL))
  1073. X    {
  1074. X      tdam = tdam * 2;
  1075. X      r_ptr->r_cdefense |= CD_EVIL;
  1076. X    }
  1077. X      /* Frost           */
  1078. X#ifdef ATARIST_MWC
  1079. X      else if ((m_ptr->cdefense & CD_FROST)
  1080. X           && (i_ptr->flags & (holder = TR_FROST_BRAND)))
  1081. X#else
  1082. X      else if ((m_ptr->cdefense & CD_FROST)
  1083. X           && (i_ptr->flags & TR_FROST_BRAND))
  1084. X#endif
  1085. X    {
  1086. X      tdam = tdam * 3 / 2;
  1087. X      r_ptr->r_cdefense |= CD_FROST;
  1088. X    }
  1089. X      /* Fire          */
  1090. X#ifdef ATARIST_MWC
  1091. X      else if ((m_ptr->cdefense & CD_FIRE)
  1092. X           && (i_ptr->flags & (holder = TR_FLAME_TONGUE)))
  1093. X#else
  1094. X      else if ((m_ptr->cdefense & CD_FIRE)
  1095. X           && (i_ptr->flags & TR_FLAME_TONGUE))
  1096. X#endif
  1097. X    {
  1098. X      tdam = tdam * 3 / 2;
  1099. X      r_ptr->r_cdefense |= CD_FIRE;
  1100. X    }
  1101. X    }
  1102. X  return(tdam);
  1103. X}
  1104. X
  1105. X
  1106. X/* Critical hits, Nasty way to die.            -RAK-    */
  1107. Xint critical_blow(weight, plus, dam, attack_type)
  1108. Xregister int weight, plus, dam;
  1109. Xint attack_type;
  1110. X{
  1111. X  register int critical;
  1112. X
  1113. X  critical = dam;
  1114. X  /* Weight of weapon, plusses to hit, and character level all        */
  1115. X  /* contribute to the chance of a critical               */
  1116. X  if (randint(5000) <= (int)(weight + 5 * plus
  1117. X                 + (class_level_adj[py.misc.pclass][attack_type]
  1118. X                * py.misc.lev)))
  1119. X    {
  1120. X      weight += randint(650);
  1121. X      if (weight < 400)
  1122. X    {
  1123. X      critical = 2*dam + 5;
  1124. X      msg_print("It was a good hit! (x2 damage)");
  1125. X    }
  1126. X      else if (weight < 700)
  1127. X    {
  1128. X      critical = 3*dam + 10;
  1129. X      msg_print("It was an excellent hit! (x3 damage)");
  1130. X    }
  1131. X      else if (weight < 900)
  1132. X    {
  1133. X      critical = 4*dam + 15;
  1134. X      msg_print("It was a superb hit! (x4 damage)");
  1135. X    }
  1136. X      else
  1137. X    {
  1138. X      critical = 5*dam + 20;
  1139. X      msg_print("It was a *GREAT* hit! (x5 damage)");
  1140. X    }
  1141. X    }
  1142. X  return(critical);
  1143. X}
  1144. X
  1145. X
  1146. X/* Given direction "dir", returns new row, column location -RAK- */
  1147. Xint mmove(dir, y, x)
  1148. Xint dir;
  1149. Xregister int *y, *x;
  1150. X{
  1151. X  register int new_row, new_col;
  1152. X  int bool;
  1153. X
  1154. X  switch(dir)
  1155. X    {
  1156. X    case 1:
  1157. X      new_row = *y + 1;
  1158. X      new_col = *x - 1;
  1159. X      break;
  1160. X    case 2:
  1161. X      new_row = *y + 1;
  1162. X      new_col = *x;
  1163. X      break;
  1164. X    case 3:
  1165. X      new_row = *y + 1;
  1166. X      new_col = *x + 1;
  1167. X      break;
  1168. X    case 4:
  1169. X      new_row = *y;
  1170. X      new_col = *x - 1;
  1171. X      break;
  1172. X    case 5:
  1173. X      new_row = *y;
  1174. X      new_col = *x;
  1175. X      break;
  1176. X    case 6:
  1177. X      new_row = *y;
  1178. X      new_col = *x + 1;
  1179. X      break;
  1180. X    case 7:
  1181. X      new_row = *y - 1;
  1182. X      new_col = *x - 1;
  1183. X      break;
  1184. X    case 8:
  1185. X      new_row = *y - 1;
  1186. X      new_col = *x;
  1187. X      break;
  1188. X    case 9:
  1189. X      new_row = *y - 1;
  1190. X      new_col = *x + 1;
  1191. X      break;
  1192. X    }
  1193. X  bool = FALSE;
  1194. X  if ((new_row >= 0) && (new_row < cur_height)
  1195. X      && (new_col >= 0) && (new_col < cur_width))
  1196. X    {
  1197. X      *y = new_row;
  1198. X      *x = new_col;
  1199. X      bool = TRUE;
  1200. X    }
  1201. X  return(bool);
  1202. X}
  1203. X
  1204. X/* Saving throws for player character.        -RAK-    */
  1205. Xint player_saves()
  1206. X{
  1207. X  /* MPW C couldn't handle the expression, so split it into two parts */
  1208. X  int16 temp = class_level_adj[py.misc.pclass][CLA_SAVE];
  1209. X
  1210. X  if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
  1211. X               + (temp * py.misc.lev / 3)))
  1212. X    return(TRUE);
  1213. X  else
  1214. X    return(FALSE);
  1215. X}
  1216. X
  1217. X
  1218. X/* Finds range of item in inventory list        -RAK-    */
  1219. Xint find_range(item1, item2, j, k)
  1220. Xint item1, item2;
  1221. Xregister int *j, *k;
  1222. X{
  1223. X  register int i;
  1224. X  register inven_type *i_ptr;
  1225. X  int flag;
  1226. X
  1227. X  i = 0;
  1228. X  *j = -1;
  1229. X  *k = -1;
  1230. X  flag = FALSE;
  1231. X  i_ptr = &inventory[0];
  1232. X  while (i < inven_ctr)
  1233. X    {
  1234. X      if (!flag)
  1235. X    {
  1236. X      if ((i_ptr->tval == item1) || (i_ptr->tval == item2))
  1237. X        {
  1238. X          flag = TRUE;
  1239. X          *j = i;
  1240. X        }
  1241. X    }
  1242. X      else
  1243. X    {
  1244. X      if ((i_ptr->tval != item1) && (i_ptr->tval != item2))
  1245. X        {
  1246. X          *k = i - 1;
  1247. X          break;
  1248. X        }
  1249. X    }
  1250. X      i++;
  1251. X      i_ptr++;
  1252. X    }
  1253. X  if (flag && (*k == -1))
  1254. X    *k = inven_ctr - 1;
  1255. X  return(flag);
  1256. X}
  1257. X
  1258. X
  1259. X/* Teleport the player to a new location        -RAK-    */
  1260. Xvoid teleport(dis)
  1261. Xint dis;
  1262. X{
  1263. X  register int y, x, i, j;
  1264. X
  1265. X  do
  1266. X    {
  1267. X      y = randint(cur_height) - 1;
  1268. X      x = randint(cur_width) - 1;
  1269. X      while (distance(y, x, char_row, char_col) > dis)
  1270. X    {
  1271. X      y += ((char_row-y)/2);
  1272. X      x += ((char_col-x)/2);
  1273. X    }
  1274. X    }
  1275. X  while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (cave[y][x].cptr >= 2));
  1276. X  move_rec(char_row, char_col, y, x);
  1277. X  for (i = char_row-1; i <= char_row+1; i++)
  1278. X    for (j = char_col-1; j <= char_col+1; j++)
  1279. X      {
  1280. X    cave[i][j].tl = FALSE;
  1281. X    lite_spot(i, j);
  1282. X      }
  1283. X  lite_spot(char_row, char_col);
  1284. X  char_row = y;
  1285. X  char_col = x;
  1286. X  check_view();
  1287. X  creatures(FALSE);
  1288. X  teleport_flag = FALSE;
  1289. X}
  1290. END_OF_FILE
  1291. if test 30036 -ne `wc -c <'source/misc3.c.2'`; then
  1292.     echo shar: \"'source/misc3.c.2'\" unpacked with wrong size!
  1293. fi
  1294. # end of 'source/misc3.c.2'
  1295. fi
  1296. if test -f 'source/moria2.c' -a "${1}" != "-c" ; then 
  1297.   echo shar: Will not clobber existing file \"'source/moria2.c'\"
  1298. else
  1299. echo shar: Extracting \"'source/moria2.c'\" \(19056 characters\)
  1300. sed "s/^X//" >'source/moria2.c' <<'END_OF_FILE'
  1301. X/* source/moria2.c: misc code, mainly handles player movement, inventory, etc
  1302. X
  1303. X   Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
  1304. X
  1305. X   This software may be copied and distributed for educational, research, and
  1306. X   not for profit purposes provided that this copyright and statement are
  1307. X   included in all such copies. */
  1308. X
  1309. X#include <stdio.h>
  1310. X
  1311. X#include "config.h"
  1312. X#include "constant.h"
  1313. X#include "types.h"
  1314. X#include "externs.h"
  1315. X
  1316. X#if defined(LINT_ARGS)
  1317. Xstatic int see_wall(int, int, int);
  1318. Xstatic int see_nothing(int, int, int);
  1319. X#else
  1320. Xstatic int see_wall();
  1321. X#endif
  1322. X
  1323. X
  1324. X/* Change a trap from invisible to visible        -RAK-    */
  1325. X/* Note: Secret doors are handled here                 */
  1326. Xvoid change_trap(y, x)
  1327. Xregister int y, x;
  1328. X{
  1329. X  register cave_type *c_ptr;
  1330. X  register inven_type *t_ptr;
  1331. X
  1332. X  c_ptr = &cave[y][x];
  1333. X  t_ptr = &t_list[c_ptr->tptr];
  1334. X  if (t_ptr->tval == TV_INVIS_TRAP)
  1335. X    {
  1336. X      t_ptr->tval = TV_VIS_TRAP;
  1337. X      lite_spot(y, x);
  1338. X    }
  1339. X  else if (t_ptr->tval == TV_SECRET_DOOR)
  1340. X    {
  1341. X      /* change secret door to closed door */
  1342. X      t_ptr->index = OBJ_CLOSED_DOOR;
  1343. X      t_ptr->tval = object_list[OBJ_CLOSED_DOOR].tval;
  1344. X      t_ptr->tchar = object_list[OBJ_CLOSED_DOOR].tchar;
  1345. X      lite_spot(y, x);
  1346. X    }
  1347. X}
  1348. X
  1349. X
  1350. X/* Searches for hidden things.            -RAK-    */
  1351. Xvoid search(y, x, chance)
  1352. Xint y, x, chance;
  1353. X{
  1354. X  register int i, j;
  1355. X  register cave_type *c_ptr;
  1356. X  register inven_type *t_ptr;
  1357. X  register struct flags *p_ptr;
  1358. X  bigvtype tmp_str, tmp_str2;
  1359. X
  1360. X  p_ptr = &py.flags;
  1361. X  if (p_ptr->confused > 0)
  1362. X    chance = chance / 10;
  1363. X  if ((p_ptr->blind > 0) || no_light())
  1364. X    chance = chance / 10;
  1365. X  if (p_ptr->image > 0)
  1366. X    chance = chance / 10;
  1367. X  for (i = (y - 1); i <= (y + 1); i++)
  1368. X    for (j = (x - 1); j <= (x + 1); j++)
  1369. X      if (randint(100) < chance)    /* always in_bounds here */
  1370. X    {
  1371. X      c_ptr = &cave[i][j];
  1372. X      /* Search for hidden objects           */
  1373. X      if (c_ptr->tptr != 0)
  1374. X        {
  1375. X          t_ptr = &t_list[c_ptr->tptr];
  1376. X          /* Trap on floor?               */
  1377. X          if (t_ptr->tval == TV_INVIS_TRAP)
  1378. X        {
  1379. X          objdes(tmp_str2, t_ptr, TRUE);
  1380. X          (void) sprintf(tmp_str,"You have found %s",tmp_str2);
  1381. X          msg_print(tmp_str);
  1382. X          change_trap(i, j);
  1383. X          end_find();
  1384. X        }
  1385. X          /* Secret door?               */
  1386. X          else if (t_ptr->tval == TV_SECRET_DOOR)
  1387. X        {
  1388. X          msg_print("You have found a secret door.");
  1389. X          change_trap(i, j);
  1390. X          end_find();
  1391. X        }
  1392. X          /* Chest is trapped?           */
  1393. X          else if (t_ptr->tval == TV_CHEST)
  1394. X        {
  1395. X          /* mask out the treasure bits */
  1396. X          if ((t_ptr->flags & CH_TRAPPED) > 1)
  1397. X            if (!known2_p(t_ptr))
  1398. X              {
  1399. X            known2(t_ptr);
  1400. X            msg_print("You have discovered a trap on the chest!");
  1401. X              }
  1402. X            else
  1403. X              msg_print("The chest is trapped!");
  1404. X        }
  1405. X        }
  1406. X    }
  1407. X}
  1408. X
  1409. X
  1410. X/* The running algorithm:            -CJS-
  1411. X
  1412. X   Overview: You keep moving until something interesting happens.
  1413. X   If you are in an enclosed space, you follow corners. This is
  1414. X   the usual corridor scheme. If you are in an open space, you go
  1415. X   straight, but stop before entering enclosed space. This is
  1416. X   analogous to reaching doorways. If you have enclosed space on
  1417. X   one side only (that is, running along side a wall) stop if
  1418. X   your wall opens out, or your open space closes in. Either case
  1419. X   corresponds to a doorway.
  1420. X
  1421. X   What happens depends on what you can really SEE. (i.e. if you
  1422. X   have no light, then running along a dark corridor is JUST like
  1423. X   running in a dark room.) The algorithm works equally well in
  1424. X   corridors, rooms, mine tailings, earthquake rubble, etc, etc.
  1425. X
  1426. X   These conditions are kept in static memory:
  1427. X    find_openarea     You are in the open on at least one
  1428. X             side.
  1429. X    find_breakleft     You have a wall on the left, and will
  1430. X             stop if it opens
  1431. X    find_breakright     You have a wall on the right, and will
  1432. X             stop if it opens
  1433. X
  1434. X   To initialize these conditions is the task of find_init. If
  1435. X   moving from the square marked @ to the square marked . (in the
  1436. X   two diagrams below), then two adjacent sqares on the left and
  1437. X   the right (L and R) are considered. If either one is seen to
  1438. X   be closed, then that side is considered to be closed. If both
  1439. X   sides are closed, then it is an enclosed (corridor) run.
  1440. X
  1441. X     LL        L
  1442. X    @.           L.R
  1443. X     RR           @R
  1444. X
  1445. X   Looking at more than just the immediate squares is
  1446. X   significant. Consider the following case. A run along the
  1447. X   corridor will stop just before entering the center point,
  1448. X   because a choice is clearly established. Running in any of
  1449. X   three available directions will be defined as a corridor run.
  1450. X   Note that a minor hack is inserted to make the angled corridor
  1451. X   entry (with one side blocked near and the other side blocked
  1452. X   further away from the runner) work correctly. The runner moves
  1453. X   diagonally, but then saves the previous direction as being
  1454. X   straight into the gap. Otherwise, the tail end of the other
  1455. X   entry would be perceived as an alternative on the next move.
  1456. X
  1457. X       #.#
  1458. X      ##.##
  1459. X      .@...
  1460. X      ##.##
  1461. X       #.#
  1462. X
  1463. X   Likewise, a run along a wall, and then into a doorway (two
  1464. X   runs) will work correctly. A single run rightwards from @ will
  1465. X   stop at 1. Another run right and down will enter the corridor
  1466. X   and make the corner, stopping at the 2.
  1467. X
  1468. X    #@      1
  1469. X    ########### ######
  1470. X    2        #
  1471. X    #############
  1472. X    #
  1473. X
  1474. X   After any move, the function area_affect is called to
  1475. X   determine the new surroundings, and the direction of
  1476. X   subsequent moves. It takes a location (at which the runner has
  1477. X   just arrived) and the previous direction (from which the
  1478. X   runner is considered to have come). Moving one square in some
  1479. X   direction places you adjacent to three or five new squares
  1480. X   (for straight and diagonal moves) to which you were not
  1481. X   previously adjacent.
  1482. X
  1483. X       ...!      ...           EG Moving from 1 to 2.
  1484. X       .12!      .1.!          . means previously adjacent
  1485. X       ...!      ..2!          ! means newly adjacent
  1486. X           !!!
  1487. X
  1488. X   You STOP if you can't even make the move in the chosen
  1489. X   direction. You STOP if any of the new squares are interesting
  1490. X   in any way: usually containing monsters or treasure. You STOP
  1491. X   if any of the newly adjacent squares seem to be open, and you
  1492. X   are also looking for a break on that side. (i.e. find_openarea
  1493. X   AND find_break) You STOP if any of the newly adjacent squares
  1494. X   do NOT seem to be open and you are in an open area, and that
  1495. X   side was previously entirely open.
  1496. X
  1497. X   Corners: If you are not in the open (i.e. you are in a
  1498. X   corridor) and there is only one way to go in the new squares,
  1499. X   then turn in that direction. If there are more than two new
  1500. X   ways to go, STOP. If there are two ways to go, and those ways
  1501. X   are separated by a square which does not seem to be open, then
  1502. X   STOP.
  1503. X
  1504. X   Otherwise, we have a potential corner. There are two new open
  1505. X   squares, which are also adjacent. One of the new squares is
  1506. X   diagonally located, the other is straight on (as in the
  1507. X   diagram). We consider two more squares further out (marked
  1508. X   below as ?).
  1509. X      .X
  1510. X     @.?
  1511. X      #?
  1512. X   If they are both seen to be closed, then it is seen that no
  1513. X   benefit is gained from moving straight. It is a known corner.
  1514. X   To cut the corner, go diagonally, otherwise go straight, but
  1515. X   pretend you stepped diagonally into that next location for a
  1516. X   full view next time. Conversely, if one of the ? squares is
  1517. X   not seen to be closed, then there is a potential choice. We check
  1518. X   to see whether it is a potential corner or an intersection/room entrance.
  1519. X   If the square two spaces straight ahead, and the space marked with 'X'
  1520. X   are both blank, then it is a potential corner and enter if find_examine
  1521. X   is set, otherwise must stop because it is not a corner. */
  1522. X
  1523. X/* The cycle lists the directions in anticlockwise order, for    -CJS-
  1524. X   over two complete cycles. The chome array maps a direction on
  1525. X   to its position in the cycle.
  1526. X*/
  1527. Xstatic int cycle[] = { 1, 2, 3, 6, 9, 8, 7, 4, 1, 2, 3, 6, 9, 8, 7, 4, 1 };
  1528. Xstatic int chome[] = { -1, 8, 9, 10, 7, -1, 11, 6, 5, 4 };
  1529. Xstatic int find_openarea, find_breakright, find_breakleft, find_prevdir;
  1530. Xstatic int find_direction; /* Keep a record of which way we are going. */
  1531. X
  1532. Xvoid find_init(dir)
  1533. Xint dir;
  1534. X{
  1535. X  int row, col, deepleft, deepright;
  1536. X  register int i, shortleft, shortright;
  1537. X
  1538. X  row = char_row;
  1539. X  col = char_col;
  1540. X  if (!mmove(dir, &row, &col))
  1541. X    find_flag = FALSE;
  1542. X  else
  1543. X    {
  1544. X      find_direction = dir;
  1545. X      find_flag = 1;
  1546. X      find_breakright = find_breakleft = FALSE;
  1547. X      find_prevdir = dir;
  1548. X      if (py.flags.blind < 1)
  1549. X    {
  1550. X      i = chome[dir];
  1551. X      deepleft = deepright = FALSE;
  1552. X      shortright = shortleft = FALSE;
  1553. X      if (see_wall(cycle[i+1], char_row, char_col))
  1554. X        {
  1555. X          find_breakleft = TRUE;
  1556. X          shortleft = TRUE;
  1557. X        }
  1558. X      else if (see_wall(cycle[i+1], row, col))
  1559. X        {
  1560. X          find_breakleft = TRUE;
  1561. X          deepleft = TRUE;
  1562. X        }
  1563. X      if (see_wall(cycle[i-1], char_row, char_col))
  1564. X        {
  1565. X          find_breakright = TRUE;
  1566. X          shortright = TRUE;
  1567. X        }
  1568. X      else if (see_wall(cycle[i-1], row, col))
  1569. X        {
  1570. X          find_breakright = TRUE;
  1571. X          deepright = TRUE;
  1572. X        }
  1573. X      if (find_breakleft && find_breakright)
  1574. X        {
  1575. X          find_openarea = FALSE;
  1576. X          if (dir & 1)
  1577. X        {        /* a hack to allow angled corridor entry */
  1578. X          if (deepleft && !deepright)
  1579. X            find_prevdir = cycle[i-1];
  1580. X          else if (deepright && !deepleft)
  1581. X            find_prevdir = cycle[i+1];
  1582. X        }
  1583. X          /* else if there is a wall two spaces ahead and seem to be in a
  1584. X         corridor, then force a turn into the side corridor, must
  1585. X         be moving straight into a corridor here */
  1586. X          else if (see_wall(cycle[i], row, col))
  1587. X        {
  1588. X          if (shortleft && !shortright)
  1589. X            find_prevdir = cycle[i-2];
  1590. X          else if (shortright && !shortleft)
  1591. X            find_prevdir = cycle[i+2];
  1592. X        }
  1593. X        }
  1594. X      else
  1595. X        find_openarea = TRUE;
  1596. X    }
  1597. X    }
  1598. X
  1599. X  /* We must erase the player symbol '@' here, because sub3_move_light()
  1600. X     does not erase the previous location of the player when in find mode
  1601. X     and when find_prself is FALSE.  The player symbol is not draw at all
  1602. X     in this case while moving, so the only problem is on the first turn
  1603. X     of find mode, when the initial position of the character must be erased.
  1604. X     Hence we must do the erasure here.  */
  1605. X  if (! light_flag && ! find_prself)
  1606. X    print(loc_symbol(char_row, char_col), char_row, char_col);
  1607. X
  1608. X  move_char(dir, TRUE);
  1609. X  if (find_flag == FALSE)
  1610. X    command_count = 0;
  1611. X}
  1612. X
  1613. Xvoid find_run()
  1614. X{
  1615. X  /* prevent infinite loops in find mode, will stop after moving 100 times */
  1616. X  if (find_flag++ > 100)
  1617. X    {
  1618. X      msg_print("You stop running to catch your breath.");
  1619. X      end_find();
  1620. X    }
  1621. X  else
  1622. X    move_char(find_direction, TRUE);
  1623. X}
  1624. X
  1625. X/* Switch off the run flag - and get the light correct. -CJS- */
  1626. Xvoid end_find()
  1627. X{
  1628. X  if (find_flag)
  1629. X    {
  1630. X      find_flag = FALSE;
  1631. X      move_light(char_row, char_col, char_row, char_col);
  1632. X    }
  1633. X}
  1634. X
  1635. X/* Do we see a wall? Used in running.        -CJS- */
  1636. Xstatic int see_wall(dir, y, x)
  1637. Xint dir, y, x;
  1638. X{
  1639. X  char c;
  1640. X
  1641. X  if (!mmove(dir, &y, &x))    /* check to see if movement there possible */
  1642. X    return TRUE;
  1643. X#ifdef MSDOS
  1644. X  else if ((c = loc_symbol(y, x)) == wallsym || c == '%')
  1645. X#else
  1646. X#ifdef ATARI_ST
  1647. X  else if ((c = loc_symbol(y, x)) == (unsigned char)240 || c == '%')
  1648. X#else
  1649. X  else if ((c = loc_symbol(y, x)) == '#' || c == '%')
  1650. X#endif
  1651. X#endif
  1652. X    return TRUE;
  1653. X  else
  1654. X    return FALSE;
  1655. X}
  1656. X
  1657. X/* Do we see anything? Used in running.        -CJS- */
  1658. Xstatic int see_nothing(dir, y, x)
  1659. Xint dir, y, x;
  1660. X{
  1661. X  if (!mmove(dir, &y, &x))    /* check to see if movement there possible */
  1662. X    return FALSE;
  1663. X  else if (loc_symbol(y, x) == ' ')
  1664. X    return TRUE;
  1665. X  else
  1666. X    return FALSE;
  1667. X}
  1668. X
  1669. X
  1670. X/* Determine the next direction for a run, or if we should stop.  -CJS- */
  1671. Xvoid area_affect(dir, y, x)
  1672. Xint dir, y, x;
  1673. X{
  1674. X  int newdir, t, inv, check_dir, row, col;
  1675. X  register int i, max, option, option2;
  1676. X  register cave_type *c_ptr;
  1677. X
  1678. X  if (py.flags.blind < 1)
  1679. X    {
  1680. X      option = 0;
  1681. X      option2 = 0;
  1682. X      dir = find_prevdir;
  1683. X      max = (dir & 1) + 1;
  1684. X      /* Look at every newly adjacent square. */
  1685. X      for(i = -max; i <= max; i++)
  1686. X    {
  1687. X      newdir = cycle[chome[dir]+i];
  1688. X      row = y;
  1689. X      col = x;
  1690. X      if (mmove(newdir, &row, &col))
  1691. X        {
  1692. X          /* Objects player can see (Including doors?) cause a stop. */
  1693. X          c_ptr = &cave[row][col];
  1694. X          if (player_light || c_ptr->tl || c_ptr->pl || c_ptr->fm)
  1695. X        {
  1696. X          if (c_ptr->tptr != 0)
  1697. X            {
  1698. X              t = t_list[c_ptr->tptr].tval;
  1699. X              if (t != TV_INVIS_TRAP && t != TV_SECRET_DOOR
  1700. X              && (t != TV_OPEN_DOOR || !find_ignore_doors))
  1701. X            {
  1702. X              end_find();
  1703. X              return;
  1704. X            }
  1705. X            }
  1706. X          /* Also Creatures        */
  1707. X          /* the monster should be visible since update_mon() checks
  1708. X             for the special case of being in find mode */
  1709. X          if (c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
  1710. X            {
  1711. X              end_find();
  1712. X              return;
  1713. X            }
  1714. X          inv = FALSE;
  1715. X        }
  1716. X          else
  1717. X        inv = TRUE;    /* Square unseen. Treat as open. */
  1718. X
  1719. X          if (c_ptr->fval <= MAX_OPEN_SPACE || inv)
  1720. X        {
  1721. X          if (find_openarea)
  1722. X            {
  1723. X              /* Have we found a break? */
  1724. X              if (i < 0)
  1725. X            {
  1726. X              if (find_breakright)
  1727. X                {
  1728. X                  end_find();
  1729. X                  return;
  1730. X                }
  1731. X            }
  1732. X              else if (i > 0)
  1733. X            {
  1734. X              if (find_breakleft)
  1735. X                {
  1736. X                  end_find();
  1737. X                  return;
  1738. X                }
  1739. X            }
  1740. X            }
  1741. X          else if (option == 0)
  1742. X            option = newdir;    /* The first new direction. */
  1743. X          else if (option2 != 0)
  1744. X            {
  1745. X              end_find();    /* Three new directions. STOP. */
  1746. X              return;
  1747. X            }
  1748. X          else if (option != cycle[chome[dir]+i-1])
  1749. X            {
  1750. X              end_find();    /* If not adjacent to prev, STOP */
  1751. X              return;
  1752. X            }
  1753. X          else
  1754. X            {
  1755. X              /* Two adjacent choices. Make option2 the diagonal,
  1756. X             and remember the other diagonal adjacent to the first
  1757. X             option. */
  1758. X              if ((newdir & 1) == 1)
  1759. X            {
  1760. X              check_dir = cycle[chome[dir]+i-2];
  1761. X              option2 = newdir;
  1762. X            }
  1763. X              else
  1764. X            {
  1765. X              check_dir = cycle[chome[dir]+i+1];
  1766. X              option2 = option;
  1767. X              option = newdir;
  1768. X            }
  1769. X            }
  1770. X        }
  1771. X          else if (find_openarea)
  1772. X        {
  1773. X          /* We see an obstacle. In open area, STOP if on a side
  1774. X             previously open. */
  1775. X          if (i < 0)
  1776. X            {
  1777. X              if (find_breakleft)
  1778. X            {
  1779. X              end_find();
  1780. X              return;
  1781. X            }
  1782. X              find_breakright = TRUE;
  1783. X            }
  1784. X          else if (i > 0)
  1785. X            {
  1786. X              if (find_breakright)
  1787. X            {
  1788. X              end_find();
  1789. X              return;
  1790. X            }
  1791. X              find_breakleft = TRUE;
  1792. X            }
  1793. X        }
  1794. X        }
  1795. X    }
  1796. X
  1797. X      if (find_openarea == FALSE)
  1798. X    {    /* choose a direction. */
  1799. X      if (option2 == 0 || (find_examine && !find_cut))
  1800. X        {
  1801. X          /* There is only one option, or if two, then we always examine
  1802. X         potential corners and never cur known corners, so you step
  1803. X         into the straight option. */
  1804. X          if (option != 0)
  1805. X        find_direction = option;
  1806. X          if (option2 == 0)
  1807. X        find_prevdir = option;
  1808. X          else
  1809. X        find_prevdir = option2;
  1810. X        }
  1811. X      else
  1812. X        {
  1813. X          /* Two options! */
  1814. X          row = y;
  1815. X          col = x;
  1816. X          (void) mmove(option, &row, &col);
  1817. X          if (!see_wall(option, row, col)
  1818. X          || !see_wall(check_dir, row, col))
  1819. X        {
  1820. X          /* Don't see that it is closed off.  This could be a
  1821. X             potential corner or an intersection. */
  1822. X          if (find_examine && see_nothing(option, row, col)
  1823. X              && see_nothing(option2, row, col))
  1824. X            /* Can not see anything ahead and in the direction we are
  1825. X               turning, assume that it is a potential corner. */
  1826. X            {
  1827. X              find_direction = option;
  1828. X              find_prevdir = option2;
  1829. X            }
  1830. X          else
  1831. X            /* STOP: we are next to an intersection or a room */
  1832. X            end_find();
  1833. X        }
  1834. X          else if (find_cut)
  1835. X        {
  1836. X          /* This corner is seen to be enclosed; we cut the corner. */
  1837. X          find_direction = option2;
  1838. X          find_prevdir = option2;
  1839. X        }
  1840. X          else
  1841. X        {
  1842. X          /* This corner is seen to be enclosed, and we deliberately
  1843. X             go the long way. */
  1844. X          find_direction = option;
  1845. X          find_prevdir = option2;
  1846. X        }
  1847. X        }
  1848. X    }
  1849. X    }
  1850. X}
  1851. X
  1852. X
  1853. X/* AC gets worse                    -RAK-    */
  1854. X/* Note: This routine affects magical AC bonuses so that stores      */
  1855. X/*     can detect the damage.                     */
  1856. Xint minus_ac(typ_dam)
  1857. Xint32u typ_dam;
  1858. X{
  1859. X  register int i, j;
  1860. X  int tmp[6], minus;
  1861. X  register inven_type *i_ptr;
  1862. X  bigvtype out_val, tmp_str;
  1863. X
  1864. X  i = 0;
  1865. X  if (inventory[INVEN_BODY].tval != TV_NOTHING)
  1866. X    {
  1867. X      tmp[i] = INVEN_BODY;
  1868. X      i++;
  1869. X    }
  1870. X  if (inventory[INVEN_ARM].tval != TV_NOTHING)
  1871. X    {
  1872. X      tmp[i] = INVEN_ARM;
  1873. X      i++;
  1874. X    }
  1875. X  if (inventory[INVEN_OUTER].tval != TV_NOTHING)
  1876. X    {
  1877. X      tmp[i] = INVEN_OUTER;
  1878. X      i++;
  1879. X    }
  1880. X  if (inventory[INVEN_HANDS].tval != TV_NOTHING)
  1881. X    {
  1882. X      tmp[i] = INVEN_HANDS;
  1883. X      i++;
  1884. X    }
  1885. X  if (inventory[INVEN_HEAD].tval != TV_NOTHING)
  1886. X    {
  1887. X      tmp[i] = INVEN_HEAD;
  1888. X      i++;
  1889. X    }
  1890. X  /* also affect boots */
  1891. X  if (inventory[INVEN_FEET].tval != TV_NOTHING)
  1892. X    {
  1893. X      tmp[i] = INVEN_FEET;
  1894. X      i++;
  1895. X    }
  1896. X  minus = FALSE;
  1897. X  if (i > 0)
  1898. X    {
  1899. X      j = tmp[randint(i) - 1];
  1900. X      i_ptr = &inventory[j];
  1901. X      if (i_ptr->flags & typ_dam)
  1902. X    {
  1903. X      objdes(tmp_str, &inventory[j], FALSE);
  1904. X      (void) sprintf(out_val, "Your %s resists damage!", tmp_str);
  1905. X      msg_print(out_val);
  1906. X      minus = TRUE;
  1907. X    }
  1908. X      else if ((i_ptr->ac+i_ptr->toac) > 0)
  1909. X    {
  1910. X      objdes(tmp_str, &inventory[j], FALSE);
  1911. X      (void) sprintf(out_val, "Your %s is damaged!", tmp_str);
  1912. X      msg_print(out_val);
  1913. X      i_ptr->toac--;
  1914. X      calc_bonuses();
  1915. X      minus = TRUE;
  1916. X    }
  1917. X    }
  1918. X  return(minus);
  1919. X}
  1920. X
  1921. X
  1922. X/* Corrode the unsuspecting person's armor         -RAK-     */
  1923. Xvoid corrode_gas(kb_str)
  1924. Xchar *kb_str;
  1925. X{
  1926. X#ifdef ATARIST_MWC
  1927. X  int32u holder;
  1928. X#endif
  1929. X
  1930. X#ifdef ATARIST_MWC
  1931. X  if (!minus_ac((int32u) (holder = TR_RES_ACID)))
  1932. X#else
  1933. X  if (!minus_ac((int32u) TR_RES_ACID))
  1934. X#endif
  1935. X    take_hit(randint(8), kb_str);
  1936. X  if (inven_damage(set_corrodes, 5) > 0)
  1937. X    msg_print("There is an acrid smell coming from your pack.");
  1938. X}
  1939. X
  1940. X
  1941. X/* Poison gas the idiot.                -RAK-    */
  1942. Xvoid poison_gas(dam, kb_str)
  1943. Xint dam;
  1944. Xchar *kb_str;
  1945. X{
  1946. X  take_hit(dam, kb_str);
  1947. X  py.flags.poisoned += 12 + randint(dam);
  1948. X}
  1949. X
  1950. X
  1951. X/* Burn the fool up.                    -RAK-    */
  1952. Xvoid fire_dam(dam, kb_str)
  1953. Xint dam;
  1954. Xchar *kb_str;
  1955. X{
  1956. X  if (py.flags.fire_resist)
  1957. X    dam = dam / 3;
  1958. X  if (py.flags.resist_heat > 0)
  1959. X    dam = dam / 3;
  1960. X  take_hit(dam, kb_str);
  1961. X  if (inven_damage(set_flammable, 3) > 0)
  1962. X    msg_print("There is smoke coming from your pack!");
  1963. X}
  1964. X
  1965. X
  1966. X/* Freeze him to death.                -RAK-    */
  1967. Xvoid cold_dam(dam, kb_str)
  1968. Xint dam;
  1969. Xchar *kb_str;
  1970. X{
  1971. X  if (py.flags.cold_resist)
  1972. X    dam = dam / 3;
  1973. X  if (py.flags.resist_cold > 0)
  1974. X    dam = dam / 3;
  1975. X  take_hit(dam, kb_str);
  1976. X  if (inven_damage(set_frost_destroy, 5) > 0)
  1977. X    msg_print("Something shatters inside your pack!");
  1978. X}
  1979. X
  1980. X
  1981. X/* Lightning bolt the sucker away.            -RAK-    */
  1982. Xvoid light_dam(dam, kb_str)
  1983. Xint dam;
  1984. Xchar *kb_str;
  1985. X{
  1986. X  if (py.flags.lght_resist)
  1987. X    take_hit((dam / 3), kb_str);
  1988. X  else
  1989. X    take_hit(dam, kb_str);
  1990. X  if (inven_damage(set_lightning_destroy, 3) > 0)
  1991. X    msg_print("There are sparks coming from your pack!");
  1992. X}
  1993. X
  1994. X
  1995. X/* Throw acid on the hapless victim            -RAK-    */
  1996. Xvoid acid_dam(dam, kb_str)
  1997. Xint dam;
  1998. Xchar *kb_str;
  1999. X{
  2000. X  register int flag;
  2001. X#ifdef ATARIST_MWC
  2002. X  int32u holder;
  2003. X#endif
  2004. X
  2005. X  flag = 0;
  2006. X#ifdef ATARIST_MWC
  2007. X  if (minus_ac((int32u) (holder = TR_RES_ACID)))
  2008. X#else
  2009. X  if (minus_ac((int32u) TR_RES_ACID))
  2010. X#endif
  2011. X    flag = 1;
  2012. X  if (py.flags.acid_resist)
  2013. X    flag += 2;
  2014. X  take_hit (dam / (flag + 1), kb_str);
  2015. X  if (inven_damage(set_acid_affect, 3) > 0)
  2016. X    msg_print("There is an acrid smell coming from your pack!");
  2017. X}
  2018. END_OF_FILE
  2019. if test 19056 -ne `wc -c <'source/moria2.c'`; then
  2020.     echo shar: \"'source/moria2.c'\" unpacked with wrong size!
  2021. fi
  2022. # end of 'source/moria2.c'
  2023. fi
  2024. if test -f 'unix/Makefile' -a "${1}" != "-c" ; then 
  2025.   echo shar: Will not clobber existing file \"'unix/Makefile'\"
  2026. else
  2027. echo shar: Extracting \"'unix/Makefile'\" \(4363 characters\)
  2028. sed "s/^X//" >'unix/Makefile' <<'END_OF_FILE'
  2029. X# BINDIR is the directory where the moria binary while be put
  2030. X# LIBDIR is where the other files (score, news, hours) will be put
  2031. X# LIBDIR must be the same directory defined in config.h
  2032. X# OWNER is who you want the game to be chown to.
  2033. X# GROUP is who you wnat the game to be chgrp to.
  2034. XBINDIR = /usr/public
  2035. XLIBDIR = /usr/public/morialib
  2036. XOWNER = wilson
  2037. XGROUP = wilson
  2038. X
  2039. X# For testing and debugging the program, it is best to use this line.
  2040. X# CFLAGS = -g
  2041. X# For playing the game, you may want to use this line
  2042. XCFLAGS = -O
  2043. X
  2044. X# For BSD Systems
  2045. XCURSES = -lcurses -ltermcap
  2046. X# For SYS V Systems
  2047. X# CURSES = -lcurses
  2048. X# For XENIX, some XENIX systems may need -ltinfo
  2049. X# CURSES = -ltcap -ltermcap -lx
  2050. X
  2051. X# For AIX systems, compiling in the BSD world; SYS_V must not be defined in
  2052. X# config.h if you use this.
  2053. X#LFLAGS = -lbsd
  2054. X# Normal systems don't require anything here.
  2055. XLFLAGS = 
  2056. X
  2057. XCC = cc
  2058. X
  2059. XSRCS = main.c misc1.c misc2.c misc3.c misc4.c store1.c files.c io.c \
  2060. X    create.c desc.c generate.c sets.c dungeon.c creature.c death.c \
  2061. X    eat.c help.c magic.c potions.c prayer.c save.c staffs.c wands.c \
  2062. X    scrolls.c spells.c wizard.c store2.c signals.c moria1.c moria2.c \
  2063. X    moria3.c moria4.c monsters.c treasure.c variable.c rnd.c recall.c \
  2064. X    unix.c player.c tables.c
  2065. X
  2066. XOBJS = main.o misc1.o misc2.o misc3.o misc4.o store1.o files.o io.o \
  2067. X    create.o desc.o generate.o sets.o dungeon.o creature.o death.o \
  2068. X    eat.o help.o magic.o potions.o prayer.o save.o staffs.o wands.o \
  2069. X    scrolls.o spells.o wizard.o store2.o signals.o moria1.o moria2.o \
  2070. X    moria3.o moria4.o monsters.o treasure.o variable.o rnd.o recall.o \
  2071. X    unix.o player.o tables.o
  2072. X
  2073. XLIBFILES = hours news origcmds.hlp owizcmds.hlp roglcmds.hlp rwizcmds.hlp \
  2074. X    version.hlp welcome.hlp
  2075. X
  2076. Xmoria : $(OBJS)
  2077. X    $(CC) -o moria $(CFLAGS) $(OBJS) $(CURSES) $(LFLAGS)
  2078. X
  2079. Xlintout : $(SRCS)
  2080. X    lint $(SRCS) $(CURSES) > lintout
  2081. X
  2082. Xlintout2 : $(SRCS)
  2083. X    lint -bach $(SRCS) $(CURSES) > lintout
  2084. X
  2085. XTAGS : $(SRCS)
  2086. X    ctags -x $(SRCS) > TAGS
  2087. X
  2088. X# you must define BINDIR and LIBDIR before installing
  2089. X# assumes that BINDIR and LIBDIR exist
  2090. Xinstall:
  2091. X    chmod 755 $(BINDIR)
  2092. X    cp moria $(BINDIR)
  2093. X    chmod 4711 $(BINDIR)/moria
  2094. X    chmod 711 $(LIBDIR)
  2095. X    (cd files; cp $(LIBFILES) $(LIBDIR))
  2096. X    (cd $(LIBDIR); chmod 444 $(LIBFILES))
  2097. X    (cd $(LIBDIR); touch scores; chmod 644 scores)
  2098. X    chown $(OWNER) $(BINDIR)/moria
  2099. X    chgrp $(GROUP) $(BINDIR)/moria
  2100. X    (cd $(LIBDIR); chown $(OWNER) $(LIBFILES) scores)
  2101. X    (cd $(LIBDIR); chgrp $(GROUP) $(LIBFILES) scores)
  2102. X# If you are short on disk space, or aren't interested in debugging moria.
  2103. X#    strip $(BINDIR)/moria
  2104. X
  2105. Xclean:
  2106. X    rm -r *.o
  2107. X    rm -i moria
  2108. X
  2109. Xcreate.o: constant.h types.h externs.h config.h
  2110. Xcreature.o: constant.h types.h externs.h config.h
  2111. Xdeath.o: constant.h types.h externs.h config.h
  2112. Xdesc.o: constant.h types.h externs.h config.h
  2113. Xdungeon.o: constant.h types.h externs.h config.h
  2114. Xeat.o: constant.h types.h externs.h config.h
  2115. Xfiles.o: constant.h types.h externs.h config.h
  2116. Xgenerate.o: constant.h types.h externs.h config.h
  2117. Xhelp.o: constant.h types.h externs.h config.h
  2118. Xio.o: constant.h types.h externs.h config.h
  2119. Xmagic.o: constant.h types.h externs.h config.h
  2120. Xmain.o: constant.h types.h externs.h config.h
  2121. Xmisc1.o: constant.h types.h externs.h config.h
  2122. Xmisc2.o: constant.h types.h externs.h config.h
  2123. Xmisc3.o: constant.h types.h externs.h config.h
  2124. Xmisc4.o: constant.h types.h externs.h config.h
  2125. Xmonsters.o: constant.h types.h config.h
  2126. Xmoria1.o: constant.h types.h externs.h config.h
  2127. Xmoria2.o: constant.h types.h externs.h config.h
  2128. Xmoria3.o: constant.h types.h externs.h config.h
  2129. Xmoria4.o: constant.h types.h externs.h config.h
  2130. Xplayer.o: constant.h types.h config.h
  2131. Xpotions.o: constant.h types.h externs.h config.h
  2132. Xprayer.o: constant.h types.h externs.h config.h
  2133. Xrecall.o: constant.h config.h types.h externs.h
  2134. Xrnd.o: constant.h types.h
  2135. Xsave.o: constant.h types.h externs.h config.h
  2136. Xscrolls.o: constant.h types.h externs.h config.h
  2137. Xsets.o: constant.h config.h
  2138. Xsignals.o: constant.h types.h externs.h config.h
  2139. Xspells.o: constant.h types.h externs.h config.h
  2140. Xstaffs.o: constant.h types.h externs.h config.h
  2141. Xstore1.o: constant.h types.h externs.h config.h
  2142. Xstore2.o: constant.h types.h externs.h config.h
  2143. Xtables.o: constant.h types.h config.h
  2144. Xtreasure.o: constant.h types.h config.h
  2145. Xunix.o: constant.h config.h types.h externs.h
  2146. Xvariable.o: constant.h types.h config.h
  2147. Xwands.o: constant.h types.h externs.h config.h
  2148. Xwizard.o: constant.h types.h externs.h config.h
  2149. END_OF_FILE
  2150. if test 4363 -ne `wc -c <'unix/Makefile'`; then
  2151.     echo shar: \"'unix/Makefile'\" unpacked with wrong size!
  2152. fi
  2153. # end of 'unix/Makefile'
  2154. fi
  2155. echo shar: End of archive 21 \(of 39\).
  2156. cp /dev/null ark21isdone
  2157. MISSING=""
  2158. 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
  2159.     if test ! -f ark${I}isdone ; then
  2160.     MISSING="${MISSING} ${I}"
  2161.     fi
  2162. done
  2163. if test "${MISSING}" = "" ; then
  2164.     echo You have unpacked all 39 archives.
  2165.     echo "Now run "bldfiles.sh" to build split files"
  2166.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2167. else
  2168.     echo You still need to unpack the following archives:
  2169.     echo "        " ${MISSING}
  2170. fi
  2171. ##  End of shell archive.
  2172. exit 0
  2173.