home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / games / volume9 / umoria3 / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-05-21  |  62.7 KB

  1. Path: uunet!zephyr.ens.tek.com!tekred!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v09i058:  umoria3 - single player dungeon simulation (ver. 5.2), Part04/31
  5. Message-ID: <5589@tekred.CNA.TEK.COM>
  6. Date: 16 May 90 19:11:09 GMT
  7. Sender: news@tekred.CNA.TEK.COM
  8. Lines: 2342
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
  12. Posting-number: Volume 9, Issue 58
  13. Archive-name: umoria3/Part04
  14. Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87
  15.  
  16.  
  17.  
  18. #! /bin/sh
  19. # This is a shell archive.  Remove anything before this line, then unpack
  20. # it by saving it into a file and typing "sh file".  To overwrite existing
  21. # files, type "sh file -c".  You can also feed this as standard input via
  22. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  23. # will see the following message at the end:
  24. #        "End of archive 4 (of 31)."
  25. # Contents:  source/moria2.c
  26. # Wrapped by billr@saab on Wed May 16 11:58:18 1990
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'source/moria2.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'source/moria2.c'\"
  30. else
  31. echo shar: Extracting \"'source/moria2.c'\" \(59994 characters\)
  32. sed "s/^X//" >'source/moria2.c' <<'END_OF_FILE'
  33. X/* moria2.c: misc code, mainly to handle player commands
  34. X
  35. X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
  36. X
  37. X   This software may be copied and distributed for educational, research, and
  38. X   not for profit purposes provided that this copyright and statement are
  39. X   included in all such copies. */
  40. X
  41. X#include <ctype.h>
  42. X
  43. X#include "constant.h"
  44. X#include "config.h"
  45. X#include "types.h"
  46. X#include "externs.h"
  47. X
  48. X#ifdef USG
  49. X#ifndef ATARIST_MWC
  50. X#include <string.h>
  51. X#endif
  52. X#else
  53. X#include <strings.h>
  54. X#endif
  55. X
  56. X
  57. X#if defined(LINT_ARGS)
  58. Xstatic int look_ray(int, int, int);
  59. Xstatic int look_see(int, int, int *);
  60. Xstatic void hit_trap(int, int);
  61. Xstatic void carry(int, int, int);
  62. Xstatic int summon_object(int, int, int, int);
  63. Xstatic void py_attack(int, int);
  64. Xstatic void chest_trap(int, int);
  65. Xstatic void inven_throw(int, struct inven_type *);
  66. Xstatic void facts(struct inven_type *, int *, int *, int *, int *);
  67. Xstatic void drop_throw(int, int, struct inven_type *);
  68. Xstatic void py_bash(int, int);
  69. X#else
  70. Xstatic int look_ray();
  71. Xstatic int look_see();
  72. X#endif
  73. X
  74. X/* Player hit a trap.    (Chuckle)            -RAK-    */
  75. Xstatic void hit_trap(y, x)
  76. Xint y, x;
  77. X{
  78. X  int i, ty, tx, num, dam;
  79. X  register cave_type *c_ptr;
  80. X  register struct misc *p_ptr;
  81. X  register inven_type *t_ptr;
  82. X  bigvtype tmp;
  83. X
  84. X  end_find();
  85. X  change_trap(y, x);
  86. X  c_ptr = &cave[y][x];
  87. X  p_ptr = &py.misc;
  88. X  t_ptr = &t_list[c_ptr->tptr];
  89. X  dam = pdamroll(t_ptr->damage);
  90. X  switch(t_ptr->subval)
  91. X    {
  92. X    case 1:  /* Open pit*/
  93. X      msg_print("You fell into a pit!");
  94. X      if (py.flags.ffall)
  95. X    msg_print("You gently float down.");
  96. X      else
  97. X      {
  98. X    objdes(tmp, t_ptr, TRUE);
  99. X    take_hit(dam, tmp);
  100. X      }
  101. X      break;
  102. X    case 2: /* Arrow trap*/
  103. X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
  104. X    {
  105. X      objdes(tmp, t_ptr, TRUE);
  106. X      take_hit(dam, tmp);
  107. X      msg_print("An arrow hits you.");
  108. X    }
  109. X      else
  110. X    msg_print("An arrow barely misses you.");
  111. X      break;
  112. X    case 3: /* Covered pit*/
  113. X      msg_print("You fell into a covered pit.");
  114. X      if (py.flags.ffall)
  115. X    msg_print("You gently float down.");
  116. X      else
  117. X      {
  118. X    objdes(tmp, t_ptr, TRUE);
  119. X    take_hit(dam, tmp);
  120. X      }
  121. X      place_trap(y, x, 0);
  122. X      break;
  123. X    case 4: /* Trap door*/
  124. X      msg_print("You fell through a trap door!");
  125. X      new_level_flag = TRUE;
  126. X      dun_level++;
  127. X      if (py.flags.ffall)
  128. X    msg_print("You gently float down.");
  129. X      else
  130. X      {
  131. X    objdes(tmp, t_ptr, TRUE);
  132. X    take_hit(dam, tmp);
  133. X      }
  134. X      break;
  135. X    case 5: /* Sleep gas*/
  136. X      if (py.flags.paralysis == 0)
  137. X    {
  138. X      msg_print("A strange white mist surrounds you!");
  139. X      if (py.flags.free_act)
  140. X        msg_print("You are unaffected.");
  141. X      else
  142. X        {
  143. X          msg_print("You fall asleep.");
  144. X          py.flags.paralysis += randint(10) + 4;
  145. X        }
  146. X    }
  147. X      break;
  148. X    case 6: /* Hid Obj*/
  149. X      (void) delete_object(y, x);
  150. X      place_object(y, x);
  151. X      msg_print("Hmmm, there was something under this rock.");
  152. X      break;
  153. X    case 7:  /* STR Dart*/
  154. X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
  155. X    {
  156. X      if (!py.flags.sustain_str)
  157. X        {
  158. X          (void) dec_stat(A_STR);
  159. X          objdes(tmp, t_ptr, TRUE);
  160. X          take_hit(dam, tmp);
  161. X          msg_print("A small dart weakens you!");
  162. X        }
  163. X      else
  164. X        msg_print("A small dart hits you.");
  165. X    }
  166. X      else
  167. X    msg_print("A small dart barely misses you.");
  168. X      break;
  169. X    case 8: /* Teleport*/
  170. X      teleport_flag = TRUE;
  171. X      msg_print("You hit a teleport trap!");
  172. X      break;
  173. X    case 9: /* Rockfall*/
  174. X      take_hit(dam, "a falling rock");
  175. X      (void) delete_object(y, x);
  176. X      place_rubble(y, x);
  177. X      msg_print("You are hit by falling rock.");
  178. X      break;
  179. X    case 10: /* Corrode gas*/
  180. X      corrode_gas("corrosion gas");
  181. X      msg_print("A strange red gas surrounds you.");
  182. X      break;
  183. X    case 11: /* Summon mon*/
  184. X      (void) delete_object(y, x);    /* Rune disappears.    */
  185. X      num = 2 + randint (3);
  186. X      for (i = 0; i < num; i++)
  187. X    {
  188. X      ty = y;
  189. X      tx = x;
  190. X      (void) summon_monster(&ty, &tx, FALSE);
  191. X    }
  192. X      break;
  193. X    case 12: /* Fire trap*/
  194. X      fire_dam(dam, "a fire trap");
  195. X      msg_print("You are enveloped in flames!");
  196. X      break;
  197. X    case 13: /* Acid trap*/
  198. X      acid_dam(dam, "an acid trap");
  199. X      msg_print("You are splashed with acid!");
  200. X      break;
  201. X    case 14: /* Poison gas*/
  202. X      poison_gas(dam, "a poison gas trap");
  203. X      msg_print("A pungent green gas surrounds you!");
  204. X      break;
  205. X    case 15: /* Blind Gas */
  206. X      msg_print("A black gas surrounds you!");
  207. X      py.flags.blind += randint(50) + 50;
  208. X      break;
  209. X    case 16: /* Confuse Gas*/
  210. X      msg_print("A gas of scintillating colors surrounds you!");
  211. X      py.flags.confused += randint(15) + 15;
  212. X      break;
  213. X    case 17: /* Slow Dart*/
  214. X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
  215. X    {
  216. X      objdes(tmp, t_ptr, TRUE);
  217. X      take_hit(dam, tmp);
  218. X      msg_print("A small dart hits you!");
  219. X      if (py.flags.free_act)
  220. X        msg_print("You are unaffected.");
  221. X      else
  222. X        py.flags.slow += randint(20) + 10;
  223. X    }
  224. X      else
  225. X    msg_print("A small dart barely misses you.");
  226. X      break;
  227. X    case 18: /* CON Dart*/
  228. X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac, CLA_MISC_HIT))
  229. X    {
  230. X      if (!py.flags.sustain_con)
  231. X        {
  232. X          (void) dec_stat(A_CON);
  233. X          objdes(tmp, t_ptr, TRUE);
  234. X          take_hit(dam, tmp);
  235. X          msg_print("A small dart saps your health!");
  236. X        }
  237. X      else
  238. X        msg_print("A small dart hits you.");
  239. X    }
  240. X      else
  241. X    msg_print("A small dart barely misses you.");
  242. X      break;
  243. X    case 19: /*Secret Door*/
  244. X      break;
  245. X    case 99: /* Scare Mon*/
  246. X      break;
  247. X
  248. X      /* Town level traps are special,    the stores.    */
  249. X    case 101: /* General    */
  250. X      enter_store(0);
  251. X      break;
  252. X    case 102: /* Armory        */
  253. X      enter_store(1);
  254. X      break;
  255. X    case 103: /* Weaponsmith*/
  256. X      enter_store(2);
  257. X      break;
  258. X    case 104: /* Temple        */
  259. X      enter_store(3);
  260. X      break;
  261. X    case 105: /* Alchemy    */
  262. X      enter_store(4);
  263. X      break;
  264. X    case 106: /* Magic-User */
  265. X      enter_store(5);
  266. X      break;
  267. X
  268. X    default:
  269. X      msg_print("Unknown trap value.");
  270. X      break;
  271. X    }
  272. X}
  273. X
  274. X
  275. X/* Return spell number and failure chance        -RAK-    */
  276. X/* returns -1 if no spells in book
  277. X   returns 1 if choose a spell in book to cast
  278. X   returns 0 if don't choose a spell, i.e. exit with an escape */
  279. Xint cast_spell(prompt, item_val, sn, sc)
  280. Xchar *prompt;
  281. Xint item_val;
  282. Xint *sn, *sc;
  283. X{
  284. X  int32u j;
  285. X  register int i, k;
  286. X  int spell[31], result, first_spell;
  287. X  register spell_type *s_ptr;
  288. X
  289. X  result = -1;
  290. X  i = 0;
  291. X  j = inventory[item_val].flags;
  292. X  first_spell = bit_pos(&j);
  293. X  /* set j again, since bit_pos modified it */
  294. X  j = inventory[item_val].flags & spell_learned;
  295. X  s_ptr = magic_spell[py.misc.pclass-1];
  296. X  while (j)
  297. X    {
  298. X      k = bit_pos(&j);
  299. X      if (s_ptr[k].slevel <= py.misc.lev)
  300. X    {
  301. X      spell[i] = k;
  302. X      i++;
  303. X    }
  304. X    }
  305. X  if (i > 0)
  306. X    {
  307. X      result = get_spell(spell, i, sn, sc, prompt, first_spell);
  308. X      if (result && magic_spell[py.misc.pclass-1][*sn].smana > py.misc.cmana)
  309. X    {
  310. X      if (py.misc.pclass)
  311. X        result = get_check("You summon your limited strength to cast this one! Confirm?");
  312. X      else
  313. X        result = get_check("The gods may think you presumptuous for this! Confirm?");
  314. X    }
  315. X    }
  316. X  return(result);
  317. X}
  318. X
  319. X
  320. X/* Player is on an object.  Many things can happen based -RAK-    */
  321. X/* on the TVAL of the object.  Traps are set off, money and most */
  322. X/* objects are picked up.  Some objects, such as open doors, just*/
  323. X/* sit there.                               */
  324. Xstatic void carry(y, x, pickup)
  325. Xint y, x;
  326. Xint pickup;
  327. X{
  328. X  register int locn, i;
  329. X  bigvtype out_val, tmp_str;
  330. X  register cave_type *c_ptr;
  331. X  register inven_type *i_ptr;
  332. X
  333. X  c_ptr = &cave[y][x];
  334. X  i_ptr = &t_list[c_ptr->tptr];
  335. X  i = t_list[c_ptr->tptr].tval;
  336. X  if (i <= TV_MAX_PICK_UP)
  337. X    {
  338. X      end_find();
  339. X      /* There's GOLD in them thar hills!      */
  340. X      if (i == TV_GOLD)
  341. X    {
  342. X      py.misc.au += i_ptr->cost;
  343. X      objdes(tmp_str, i_ptr, TRUE);
  344. X      (void) sprintf(out_val,
  345. X             "You have found %ld gold pieces worth of %s",
  346. X             i_ptr->cost, tmp_str);
  347. X      prt_gold();
  348. X      (void) delete_object(y, x);
  349. X      msg_print(out_val);
  350. X    }
  351. X      else
  352. X    {
  353. X      if (inven_check_num(i_ptr))       /* Too many objects?        */
  354. X        {                /* Okay,  pick it up      */
  355. X          if (pickup && prompt_carry_flag)
  356. X        {
  357. X          objdes(tmp_str, i_ptr, TRUE);
  358. X          /* change the period to a question mark */
  359. X          tmp_str[strlen(tmp_str)-1] = '?';
  360. X          (void) sprintf(out_val, "Pick up %s", tmp_str);
  361. X          pickup = get_check(out_val);
  362. X        }
  363. X          /* Check to see if it will change the players speed. */
  364. X          if (pickup && !inven_check_weight(i_ptr))
  365. X        {
  366. X          objdes(tmp_str, i_ptr, TRUE);
  367. X          /* change the period to a question mark */
  368. X          tmp_str[strlen(tmp_str)-1] = '?';
  369. X          (void) sprintf(out_val,
  370. X                 "Exceed your weight limit to pick up %s",
  371. X                 tmp_str);
  372. X          pickup = get_check(out_val);
  373. X        }
  374. X          /* Attempt to pick up an object.           */
  375. X          if (pickup)
  376. X        {
  377. X          locn = inven_carry(i_ptr);
  378. X          objdes(tmp_str, &inventory[locn], TRUE);
  379. X          (void) sprintf(out_val, "You have %s (%c)",tmp_str,locn+'a');
  380. X          msg_print(out_val);
  381. X          (void) delete_object(y, x);
  382. X        }
  383. X        }
  384. X      else
  385. X        {
  386. X          objdes(tmp_str, i_ptr, TRUE);
  387. X          (void) sprintf(out_val, "You can't carry %s", tmp_str);
  388. X          msg_print(out_val);
  389. X        }
  390. X    }
  391. X    }
  392. X  /* OPPS!                   */
  393. X  else if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP || i == TV_STORE_DOOR)
  394. X    hit_trap(y, x);
  395. X}
  396. X
  397. X
  398. X/* Deletes a monster entry from the level        -RAK-    */
  399. Xvoid delete_monster(j)
  400. Xint j;
  401. X{
  402. X  register monster_type *m_ptr;
  403. X
  404. X  m_ptr = &m_list[j];
  405. X  cave[m_ptr->fy][m_ptr->fx].cptr = 0;
  406. X  if (m_ptr->ml)
  407. X    lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  408. X  if (j != mfptr - 1)
  409. X    {
  410. X      m_ptr = &m_list[mfptr - 1];
  411. X      cave[m_ptr->fy][m_ptr->fx].cptr = j;
  412. X      m_list[j] = m_list[mfptr - 1];
  413. X    }
  414. X  mfptr--;
  415. X  m_list[mfptr] = blank_monster;
  416. X  if (mon_tot_mult > 0)
  417. X    mon_tot_mult--;
  418. X}
  419. X
  420. X/* The following two procedures implement the same function as delete monster.
  421. X   However, they are used within creatures(), because deleting a monster
  422. X   while scanning the m_list causes two problems, monsters might get two
  423. X   turns, and m_ptr/monptr might be invalid after the delete_monster.
  424. X   Hence the delete is done in two steps. */
  425. X/* fix1_delete_monster does everything delete_monster does except delete
  426. X   the monster record and reduce mfptr, this is called in breathe, and
  427. X   a couple of places in creatures.c */
  428. Xvoid fix1_delete_monster(j)
  429. Xint j;
  430. X{
  431. X  register monster_type *m_ptr;
  432. X
  433. X  m_ptr = &m_list[j];
  434. X  /* force the hp negative to ensure that the monster is dead, for example,
  435. X     if the monster was just eaten by another, it will still have positive
  436. X     hit points */
  437. X  m_ptr->hp = -1;
  438. X  cave[m_ptr->fy][m_ptr->fx].cptr = 0;
  439. X  if (m_ptr->ml)
  440. X    lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
  441. X  if (mon_tot_mult > 0)
  442. X    mon_tot_mult--;
  443. X}
  444. X
  445. X/* fix2_delete_monster does everything in delete_monster that wasn't done
  446. X   by fix1_monster_delete above, this is only called in creatures() */
  447. Xvoid fix2_delete_monster(j)
  448. Xint j;
  449. X{
  450. X  register monster_type *m_ptr;
  451. X
  452. X  if (j != mfptr - 1)
  453. X    {
  454. X      m_ptr = &m_list[mfptr - 1];
  455. X      cave[m_ptr->fy][m_ptr->fx].cptr = j;
  456. X      m_list[j] = m_list[mfptr - 1];
  457. X    }
  458. X  m_list[mfptr - 1] = blank_monster;
  459. X  mfptr--;
  460. X}
  461. X
  462. X
  463. X/* Creates objects nearby the coordinates given        -RAK-      */
  464. Xstatic int summon_object(y, x, num, typ)
  465. Xint y, x, num, typ;
  466. X{
  467. X  register int i, j, k;
  468. X  register cave_type *c_ptr;
  469. X  int real_typ, res;
  470. X
  471. X  if (typ == 1)
  472. X    real_typ = 1; /* typ == 1 -> objects */
  473. X  else
  474. X    real_typ = 256; /* typ == 2 -> gold */
  475. X  res = 0;
  476. X  do
  477. X    {
  478. X      i = 0;
  479. X      do
  480. X    {
  481. X      j = y - 3 + randint(5);
  482. X      k = x - 3 + randint(5);
  483. X      if (in_bounds(j, k) && los(y, x, j, k))
  484. X        {
  485. X          c_ptr = &cave[j][k];
  486. X          if (c_ptr->fval <= MAX_OPEN_SPACE && (c_ptr->tptr == 0))
  487. X        {
  488. X          if (typ == 3) /* typ == 3 -> 50% objects, 50% gold */
  489. X            {
  490. X              if (randint(100) < 50)
  491. X            real_typ = 1;
  492. X              else
  493. X            real_typ = 256;
  494. X            }
  495. X          if (real_typ == 1)
  496. X            place_object(j, k);
  497. X          else
  498. X            place_gold(j, k);
  499. X          lite_spot(j, k);
  500. X          if (test_light(j, k))
  501. X            res += real_typ;
  502. X          i = 20;
  503. X        }
  504. X        }
  505. X      i++;
  506. X    }
  507. X      while (i <= 20);
  508. X      num--;
  509. X    }
  510. X  while (num != 0);
  511. X  return res;
  512. X}
  513. X
  514. X
  515. X/* Deletes object from given location            -RAK-    */
  516. Xint delete_object(y, x)
  517. Xint y, x;
  518. X{
  519. X  register int delete;
  520. X  register cave_type *c_ptr;
  521. X
  522. X  c_ptr = &cave[y][x];
  523. X  if (c_ptr->fval == BLOCKED_FLOOR)
  524. X    c_ptr->fval = CORR_FLOOR;
  525. X  pusht(c_ptr->tptr);
  526. X  c_ptr->tptr = 0;
  527. X  c_ptr->fm = FALSE;
  528. X  lite_spot(y, x);
  529. X  if (test_light(y, x))
  530. X    delete = TRUE;
  531. X  else
  532. X    delete = FALSE;
  533. X  return(delete);
  534. X}
  535. X
  536. X
  537. X/* Allocates objects upon a creatures death        -RAK-    */
  538. X/* Oh well,  another creature bites the dust.  Reward the victor*/
  539. X/* based on flags set in the main creature record         */
  540. X/* Returns a mask of bits from the given flags which indicates what the
  541. X   monster is seen to have dropped.  This may be added to monster memory. */
  542. Xint32u monster_death(y, x, flags)
  543. Xint y, x;
  544. Xregister int32u flags;
  545. X{
  546. X  register int i, number;
  547. X  int32u dump, res;
  548. X#if defined(ATARIST_MWC)
  549. X  int32u holder;    /* avoid a compiler bug */
  550. X#endif
  551. X
  552. X#if !defined(ATARIST_MWC)
  553. X  if (flags & CM_CARRY_OBJ)
  554. X    i = 1;
  555. X  else
  556. X    i = 0;
  557. X  if (flags & CM_CARRY_GOLD)
  558. X    i += 2;
  559. X
  560. X  number = 0;
  561. X  if ((flags & CM_60_RANDOM) && (randint(100) < 60))
  562. X    number++;
  563. X  if ((flags & CM_90_RANDOM) && (randint(100) < 90))
  564. X    number++;
  565. X  if (flags & CM_1D2_OBJ)
  566. X    number += randint(2);
  567. X  if (flags & CM_2D2_OBJ)
  568. X    number += damroll(2, 2);
  569. X  if (flags & CM_4D2_OBJ)
  570. X    number += damroll(4, 2);
  571. X  if (number > 0)
  572. X    dump = summon_object(y, x, number, i);
  573. X  else
  574. X    dump = 0;
  575. X#else
  576. X  holder = CM_CARRY_OBJ;
  577. X  if (flags & holder)
  578. X    i = 1;
  579. X  else
  580. X    i = 0;
  581. X  holder = CM_CARRY_GOLD;
  582. X  if (flags & holder)
  583. X    i += 2;
  584. X
  585. X  number = 0;
  586. X  holder = CM_60_RANDOM;
  587. X  if ((flags & holder) && (randint(100) < 60))
  588. X    number++;
  589. X  holder = CM_90_RANDOM;
  590. X  if ((flags & holder) && (randint(100) < 90))
  591. X    number++;
  592. X  holder = CM_1D2_OBJ;
  593. X  if (flags & holder)
  594. X    number += randint(2);
  595. X  holder = CM_2D2_OBJ;
  596. X  if (flags & holder)
  597. X    number += damroll(2, 2);
  598. X  holder = CM_4D2_OBJ;
  599. X  if (flags & holder)
  600. X    number += damroll(4, 2);
  601. X  if (number > 0)
  602. X    dump = summon_object(y, x, number, i);
  603. X  else
  604. X    dump = 0;
  605. X
  606. X
  607. X#endif
  608. X
  609. X#if defined(ATARIST_MWC)
  610. X  holder = CM_WIN;
  611. X  if (flags & holder)
  612. X#else
  613. X  if (flags & CM_WIN)
  614. X#endif
  615. X    {
  616. X      total_winner = TRUE;
  617. X      prt_winner();
  618. X      msg_print("*** CONGRATULATIONS *** You have won the game.");
  619. X      msg_print("You cannot save this game, but you may retire when ready.");
  620. X    }
  621. X
  622. X  if (dump)
  623. X    {
  624. X      res = 0;
  625. X      if (dump & 255)
  626. X#ifdef ATARIST_MWC
  627. X    {
  628. X      holder = CM_CARRY_OBJ;
  629. X      res |= holder;
  630. X    }
  631. X#else
  632. X        res |= CM_CARRY_OBJ;
  633. X#endif
  634. X      if (dump >= 256)
  635. X#ifdef ATARIST_MWC
  636. X    {
  637. X      holder = CM_CARRY_GOLD;
  638. X      res |= holder;
  639. X    }
  640. X#else
  641. X    res |= CM_CARRY_GOLD;
  642. X#endif
  643. X      dump = (dump % 256) + (dump / 256);  /* number of items */
  644. X      res |= dump << CM_TR_SHIFT;
  645. X    }
  646. X  else
  647. X    res = 0;
  648. X
  649. X  return res;
  650. X}
  651. X
  652. X
  653. X/* Decreases monsters hit points and deletes monster if needed.    */
  654. X/* (Picking on my babies.)                   -RAK-   */
  655. Xint mon_take_hit(monptr, dam)
  656. Xint monptr, dam;
  657. X{
  658. X  register int32u i;
  659. X  int32 new_exp, new_exp_frac;
  660. X  register monster_type *m_ptr;
  661. X  register struct misc *p_ptr;
  662. X  register creature_type *c_ptr;
  663. X  int m_take_hit;
  664. X  int32u tmp;
  665. X#ifdef ATARIST_MWC
  666. X  int32u holder;
  667. X#endif
  668. X
  669. X  m_ptr = &m_list[monptr];
  670. X  m_ptr->hp -= dam;
  671. X  m_ptr->csleep = 0;
  672. X  if (m_ptr->hp < 0)
  673. X    {
  674. X      i = monster_death((int)m_ptr->fy, (int)m_ptr->fx,
  675. X            c_list[m_ptr->mptr].cmove);
  676. X      if ((py.flags.blind < 1 && m_ptr->ml)
  677. X      || (c_list[m_ptr->mptr].cmove & CM_WIN))
  678. X    {
  679. X#ifdef ATARIST_MWC
  680. X      holder = CM_TREASURE;
  681. X      tmp = (c_recall[m_ptr->mptr].r_cmove & holder) >> CM_TR_SHIFT;
  682. X      if (tmp > ((i & holder) >> CM_TR_SHIFT))
  683. X        i = (i & ~holder) | (tmp << CM_TR_SHIFT);
  684. X      c_recall[m_ptr->mptr].r_cmove =
  685. X        (c_recall[m_ptr->mptr].r_cmove & ~holder) | i;
  686. X#else
  687. X      tmp = (c_recall[m_ptr->mptr].r_cmove & CM_TREASURE) >> CM_TR_SHIFT;
  688. X      if (tmp > ((i & CM_TREASURE) >> CM_TR_SHIFT))
  689. X        i = (i & ~CM_TREASURE) | (tmp << CM_TR_SHIFT);
  690. X      c_recall[m_ptr->mptr].r_cmove =
  691. X        (c_recall[m_ptr->mptr].r_cmove & ~CM_TREASURE) | i;
  692. X#endif
  693. X      if (c_recall[m_ptr->mptr].r_kills < MAX_SHORT)
  694. X        c_recall[m_ptr->mptr].r_kills++;
  695. X    }
  696. X      c_ptr = &c_list[m_ptr->mptr];
  697. X      p_ptr = &py.misc;
  698. X
  699. X      new_exp = ((long)c_ptr->mexp * c_ptr->level) / p_ptr->lev;
  700. X      new_exp_frac = ((((long)c_ptr->mexp * c_ptr->level) % p_ptr->lev)
  701. X    * 0x10000L / p_ptr->lev) + p_ptr->exp_frac;
  702. X      if (new_exp_frac >= 0x10000L)
  703. X    {
  704. X      new_exp++;
  705. X      p_ptr->exp_frac = new_exp_frac - 0x10000L;
  706. X    }
  707. X      else
  708. X    p_ptr->exp_frac = new_exp_frac;
  709. X
  710. X      p_ptr->exp += new_exp;
  711. X      /* can't call prt_experience() here, as that would result in "new level"
  712. X     message appearing before "monster dies" message */
  713. X      m_take_hit = m_ptr->mptr;
  714. X      /* in case this is called from within creatures(), this is a
  715. X     horrible hack, the m_list/creatures() code needs to be
  716. X     rewritten */
  717. X      if (hack_monptr < monptr)
  718. X    delete_monster(monptr);
  719. X      else
  720. X    fix1_delete_monster(monptr);
  721. X    }
  722. X  else
  723. X    m_take_hit = -1;
  724. X  return(m_take_hit);
  725. X}
  726. X
  727. X
  728. X/* Player attacks a (poor, defenseless) creature    -RAK-    */
  729. Xstatic void py_attack(y, x)
  730. Xint y, x;
  731. X{
  732. X  register int k, blows;
  733. X  int crptr, monptr, tot_tohit, base_tohit;
  734. X  vtype m_name, out_val;
  735. X  register inven_type *i_ptr;
  736. X  register struct misc *p_ptr;
  737. X
  738. X  crptr = cave[y][x].cptr;
  739. X  monptr = m_list[crptr].mptr;
  740. X  m_list[crptr].csleep = 0;
  741. X  i_ptr = &inventory[INVEN_WIELD];
  742. X  /* Does the player know what he's fighting?       */
  743. X  if (!m_list[crptr].ml)
  744. X    (void) strcpy(m_name, "it");
  745. X  else
  746. X    (void) sprintf(m_name, "the %s", c_list[monptr].name);
  747. X  if (i_ptr->tval != TV_NOTHING)        /* Proper weapon */
  748. X    blows = attack_blows((int)i_ptr->weight, &tot_tohit);
  749. X  else                      /* Bare hands?   */
  750. X    {
  751. X      blows = 2;
  752. X      tot_tohit = -3;
  753. X    }
  754. X  if ((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW))
  755. X    /* Fix for arrows */
  756. X    blows = 1;
  757. X  p_ptr = &py.misc;
  758. X  tot_tohit += p_ptr->ptohit;
  759. X  /* if creature not lit, make it more difficult to hit */
  760. X  if (m_list[crptr].ml)
  761. X    base_tohit = p_ptr->bth;
  762. X  else
  763. X    base_tohit = (p_ptr->bth / 2) - (tot_tohit * (BTH_PLUS_ADJ-1))
  764. X      - (p_ptr->lev * class_level_adj[p_ptr->pclass][CLA_BTH] / 2);
  765. X
  766. X  /* Loop for number of blows,    trying to hit the critter.      */
  767. X  do
  768. X    {
  769. X      if (test_hit(base_tohit, (int)p_ptr->lev, tot_tohit,
  770. X           (int)c_list[monptr].ac, CLA_BTH))
  771. X    {
  772. X      (void) sprintf(out_val, "You hit %s.", m_name);
  773. X      msg_print(out_val);
  774. X      if (i_ptr->tval != TV_NOTHING)
  775. X        {
  776. X          k = pdamroll(i_ptr->damage);
  777. X          k = tot_dam(i_ptr, k, monptr);
  778. X          k = critical_blow((int)i_ptr->weight, tot_tohit, k, CLA_BTH);
  779. X        }
  780. X      else                  /* Bare hands!?  */
  781. X        {
  782. X          k = damroll(1, 1);
  783. X          k = critical_blow(1, 0, k, CLA_BTH);
  784. X        }
  785. X      k += p_ptr->ptodam;
  786. X      if (k < 0)  k = 0;
  787. X
  788. X      if (py.flags.confuse_monster)
  789. X        {
  790. X          py.flags.confuse_monster = FALSE;
  791. X          msg_print("Your hands stop glowing.");
  792. X          if ((c_list[monptr].cdefense & CD_NO_SLEEP)
  793. X          || (randint(MAX_MONS_LEVEL) < c_list[monptr].level))
  794. X        (void) sprintf(out_val, "%s is unaffected.", m_name);
  795. X          else
  796. X        {
  797. X          (void) sprintf(out_val, "%s appears confused.", m_name);
  798. X          m_list[crptr].confused = TRUE;
  799. X        }
  800. X          msg_print(out_val);
  801. X          if (m_list[crptr].ml && randint(4) == 1)
  802. X        c_recall[monptr].r_cdefense |=
  803. X          c_list[monptr].cdefense & CD_NO_SLEEP;
  804. X        }
  805. X
  806. X      /* See if we done it in.                 */
  807. X      if (mon_take_hit(crptr, k) >= 0)
  808. X        {
  809. X          (void) sprintf(out_val, "You have slain %s.", m_name);
  810. X          msg_print(out_val);
  811. X          prt_experience();
  812. X          blows = 0;
  813. X        }
  814. X
  815. X      if ((i_ptr->tval >= TV_SLING_AMMO)
  816. X          && (i_ptr->tval <= TV_ARROW)) /* Use missiles up*/
  817. X        {
  818. X          i_ptr->number--;
  819. X          inven_weight -= i_ptr->weight;
  820. X          py.flags.status |= PY_STR_WGT;
  821. X          if (i_ptr->number == 0)
  822. X        {
  823. X          equip_ctr--;
  824. X          py_bonuses(i_ptr, -1);
  825. X          invcopy(i_ptr, OBJ_NOTHING);
  826. X          calc_bonuses();
  827. X        }
  828. X        }
  829. X    }
  830. X      else
  831. X    {
  832. X      (void) sprintf(out_val, "You miss %s.", m_name);
  833. X      msg_print(out_val);
  834. X    }
  835. X      blows--;
  836. X    }
  837. X  while (blows >= 1);
  838. X}
  839. X
  840. X
  841. X/* Moves player from one space to another.        -RAK-    */
  842. X/* Note: This routine has been pre-declared; see that for argument*/
  843. Xvoid move_char(dir, do_pickup)
  844. Xint dir, do_pickup;
  845. X{
  846. X  int old_row, old_col, old_find_flag;
  847. X  int y, x;
  848. X  register int i, j;
  849. X  register cave_type *c_ptr, *d_ptr;
  850. X
  851. X  if ((py.flags.confused > 0) &&    /* Confused?         */
  852. X      (randint(4) > 1) &&        /* 75% random movement   */
  853. X      (dir != 5))            /* Never random if sitting*/
  854. X    {
  855. X      dir = randint(9);
  856. X      end_find();
  857. X    }
  858. X  y = char_row;
  859. X  x = char_col;
  860. X  if (mmove(dir, &y, &x))    /* Legal move?          */
  861. X    {
  862. X      c_ptr = &cave[y][x];
  863. X      /* if there is no creature, or an unlit creature in the walls then... */
  864. X      /* disallow attacks against unlit creatures in walls because moving into
  865. X     a wall is a free turn normally, hence don't give player free turns
  866. X     attacking each wall in an attempt to locate the invisible creature,
  867. X     instead force player to tunnel into walls which always takes a turn */
  868. X      if ((c_ptr->cptr < 2)
  869. X      || (!m_list[c_ptr->cptr].ml && c_ptr->fval >= MIN_CLOSED_SPACE))
  870. X    {
  871. X      if (c_ptr->fval <= MAX_OPEN_SPACE) /* Open floor spot    */
  872. X        {
  873. X          /* Make final assignments of char co-ords */
  874. X          old_row = char_row;
  875. X          old_col = char_col;
  876. X          char_row = y;
  877. X          char_col = x;
  878. X          /* Move character record (-1)           */
  879. X          move_rec(old_row, old_col, char_row, char_col);
  880. X          /* Check for new panel               */
  881. X          if (get_panel(char_row, char_col, FALSE))
  882. X        prt_map();
  883. X          /* Check to see if he should stop           */
  884. X          if (find_flag)
  885. X        area_affect(dir, char_row, char_col);
  886. X          /* Check to see if he notices something  */
  887. X          /* fos may be negative if have good rings of searching */
  888. X          if ((py.misc.fos <= 1) || (randint(py.misc.fos) == 1) ||
  889. X          (search_flag))
  890. X        search(char_row, char_col, py.misc.srh);
  891. X          /* A room of light should be lit.         */
  892. X          if (c_ptr->fval == LIGHT_FLOOR)
  893. X        {
  894. X          if (!c_ptr->pl && !py.flags.blind)
  895. X            light_room(char_row, char_col);
  896. X        }
  897. X          /* In doorway of light-room?           */
  898. X          else if (c_ptr->lr && (py.flags.blind < 1))
  899. X        for (i = (char_row - 1); i <= (char_row + 1); i++)
  900. X          for (j = (char_col - 1); j <= (char_col + 1); j++)
  901. X            {
  902. X              d_ptr = &cave[i][j];
  903. X              if ((d_ptr->fval == LIGHT_FLOOR) && (!d_ptr->pl))
  904. X            light_room(i, j);
  905. X            }
  906. X          /* Move the light source               */
  907. X          move_light(old_row, old_col, char_row, char_col);
  908. X          /* An object is beneath him.         */
  909. X          if (c_ptr->tptr != 0)
  910. X        {
  911. X          carry(char_row, char_col, do_pickup);
  912. X          /* if stepped on falling rock trap, and space contains
  913. X             rubble, then step back into a clear area */
  914. X          if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
  915. X            {
  916. X              move_rec(char_row, char_col, old_row, old_col);
  917. X              move_light(char_row, char_col, old_row, old_col);
  918. X              char_row = old_row;
  919. X              char_col = old_col;
  920. X              /* check to see if we have stepped back onto another
  921. X             trap, if so, set it off */
  922. X              c_ptr = &cave[char_row][char_col];
  923. X              if (c_ptr->tptr != 0)
  924. X            {
  925. X              i = t_list[c_ptr->tptr].tval;
  926. X              if (i == TV_INVIS_TRAP || i == TV_VIS_TRAP
  927. X                  || i == TV_STORE_DOOR)
  928. X                hit_trap(char_row, char_col);
  929. X            }
  930. X            }
  931. X        }
  932. X        }
  933. X      else      /*Can't move onto floor space*/
  934. X        {
  935. X          if (!find_flag && (c_ptr->tptr != 0))
  936. X        {
  937. X          if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
  938. X            msg_print("There is rubble blocking your way.");
  939. X          else if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
  940. X            msg_print("There is a closed door blocking your way.");
  941. X        }
  942. X          else
  943. X        end_find();
  944. X          free_turn_flag = TRUE;
  945. X        }
  946. X    }
  947. X      else      /* Attacking a creature! */
  948. X    {
  949. X      old_find_flag = find_flag;
  950. X      end_find();
  951. X      /* if player can see monster, and was in find mode, then nothing */
  952. X      if (m_list[c_ptr->cptr].ml && old_find_flag)
  953. X        {
  954. X          /* did not do anything this turn */
  955. X          free_turn_flag = TRUE;
  956. X        }
  957. X      else
  958. X        {
  959. X          if (py.flags.afraid < 1)        /* Coward?    */
  960. X        py_attack(y, x);
  961. X          else                /* Coward!    */
  962. X        msg_print("You are too afraid!");
  963. X        }
  964. X    }
  965. X    }
  966. X}
  967. X
  968. X
  969. X/* Chests have traps too.                -RAK-    */
  970. X/* Note: Chest traps are based on the FLAGS value         */
  971. Xstatic void chest_trap(y, x)
  972. Xint y, x;
  973. X{
  974. X  register int i;
  975. X  int j, k;
  976. X  register inven_type *t_ptr;
  977. X
  978. X  t_ptr = &t_list[cave[y][x].tptr];
  979. X  if (CH_LOSE_STR & t_ptr->flags)
  980. X    {
  981. X      msg_print("A small needle has pricked you!");
  982. X      if (!py.flags.sustain_str)
  983. X    {
  984. X      (void) dec_stat(A_STR);
  985. X      take_hit(damroll(1, 4), "a poison needle");
  986. X      msg_print("You feel weakened!");
  987. X    }
  988. X      else
  989. X    msg_print("You are unaffected.");
  990. X    }
  991. X  if (CH_POISON & t_ptr->flags)
  992. X    {
  993. X      msg_print("A small needle has pricked you!");
  994. X      take_hit(damroll(1, 6), "a poison needle");
  995. X      py.flags.poisoned += 10 + randint(20);
  996. X    }
  997. X  if (CH_PARALYSED & t_ptr->flags)
  998. X    {
  999. X      msg_print("A puff of yellow gas surrounds you!");
  1000. X      if (py.flags.free_act)
  1001. X    msg_print("You are unaffected.");
  1002. X      else
  1003. X    {
  1004. X      msg_print("You choke and pass out.");
  1005. X      py.flags.paralysis = 10 + randint(20);
  1006. X    }
  1007. X    }
  1008. X  if (CH_SUMMON & t_ptr->flags)
  1009. X    {
  1010. X      for (i = 0; i < 3; i++)
  1011. X    {
  1012. X      j = y;
  1013. X      k = x;
  1014. X      (void) summon_monster(&j, &k, FALSE);
  1015. X    }
  1016. X    }
  1017. X  if (CH_EXPLODE & t_ptr->flags)
  1018. X    {
  1019. X      msg_print("There is a sudden explosion!");
  1020. X      (void) delete_object(y, x);
  1021. X      take_hit(damroll(5, 8), "an exploding chest");
  1022. X    }
  1023. X}
  1024. X
  1025. X
  1026. X/* Opens a closed door or closed chest.        -RAK-    */
  1027. Xvoid openobject()
  1028. X{
  1029. X  int y, x, i, dir;
  1030. X  int flag, no_object;
  1031. X  register cave_type *c_ptr;
  1032. X  register inven_type *t_ptr;
  1033. X  register struct misc *p_ptr;
  1034. X  register monster_type *m_ptr;
  1035. X  vtype m_name, out_val;
  1036. X
  1037. X  y = char_row;
  1038. X  x = char_col;
  1039. X  if (get_dir(NULL, &dir))
  1040. X    {
  1041. X      (void) mmove(dir, &y, &x);
  1042. X      c_ptr = &cave[y][x];
  1043. X      no_object = FALSE;
  1044. X      if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
  1045. X      (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR
  1046. X       || t_list[c_ptr->tptr].tval == TV_CHEST))
  1047. X    {
  1048. X      m_ptr = &m_list[c_ptr->cptr];
  1049. X      if (m_ptr->ml)
  1050. X        (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
  1051. X      else
  1052. X        (void) strcpy (m_name, "Something");
  1053. X      (void) sprintf(out_val, "%s is in your way!", m_name);
  1054. X      msg_print(out_val);
  1055. X    }
  1056. X      else if (c_ptr->tptr != 0)
  1057. X    /* Closed door         */
  1058. X    if (t_list[c_ptr->tptr].tval == TV_CLOSED_DOOR)
  1059. X      {
  1060. X        t_ptr = &t_list[c_ptr->tptr];
  1061. X        if (t_ptr->p1 > 0)     /* It's locked.    */
  1062. X          {
  1063. X        p_ptr = &py.misc;
  1064. X        i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
  1065. X          + (class_level_adj[p_ptr->pclass][CLA_DISARM]
  1066. X             * p_ptr->lev / 3);
  1067. X        if (py.flags.confused > 0)
  1068. X          msg_print("You are too confused to pick the lock.");
  1069. X        else if ((i-t_ptr->p1) > randint(100))
  1070. X          {
  1071. X            msg_print("You have picked the lock.");
  1072. X            py.misc.exp++;
  1073. X            prt_experience();
  1074. X            t_ptr->p1 = 0;
  1075. X          }
  1076. X        else
  1077. X          count_msg_print("You failed to pick the lock.");
  1078. X          }
  1079. X        else if (t_ptr->p1 < 0)     /* It's stuck      */
  1080. X          msg_print("It appears to be stuck.");
  1081. X        if (t_ptr->p1 == 0)
  1082. X          {
  1083. X        invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
  1084. X        c_ptr->fval = CORR_FLOOR;
  1085. X        lite_spot(y, x);
  1086. X        command_count = 0;
  1087. X          }
  1088. X      }
  1089. X      /* Open a closed chest.             */
  1090. X    else if (t_list[c_ptr->tptr].tval == TV_CHEST)
  1091. X      {
  1092. X        p_ptr = &py.misc;
  1093. X        i = p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
  1094. X          + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
  1095. X        t_ptr = &t_list[c_ptr->tptr];
  1096. X        flag = FALSE;
  1097. X        if (CH_LOCKED & t_ptr->flags)
  1098. X          if (py.flags.confused > 0)
  1099. X        msg_print("You are too confused to pick the lock.");
  1100. X          else if ((i-(int)t_ptr->level) > randint(100))
  1101. X        {
  1102. X          msg_print("You have picked the lock.");
  1103. X          flag = TRUE;
  1104. X          py.misc.exp += t_ptr->level;
  1105. X          prt_experience();
  1106. X        }
  1107. X          else
  1108. X        count_msg_print("You failed to pick the lock.");
  1109. X        else
  1110. X          flag = TRUE;
  1111. X        if (flag)
  1112. X          {
  1113. X        t_ptr->flags &= ~CH_LOCKED;
  1114. X        t_ptr->name2 = SN_EMPTY;
  1115. X        known2(t_ptr);
  1116. X        t_ptr->cost = 0;
  1117. X          }
  1118. X        flag = FALSE;
  1119. X        /* Was chest still trapped?     (Snicker)   */
  1120. X        if ((CH_LOCKED & t_ptr->flags) == 0)
  1121. X          {
  1122. X        chest_trap(y, x);
  1123. X        if (c_ptr->tptr != 0)
  1124. X          flag = TRUE;
  1125. X          }
  1126. X        /* Chest treasure is allocated as if a creature   */
  1127. X        /* had been killed.                   */
  1128. X        if (flag)
  1129. X          {
  1130. X        /* clear the cursed chest/monster win flag, so that people
  1131. X           can not win by opening a cursed chest */
  1132. X        t_list[c_ptr->tptr].flags &= ~TR_CURSED;
  1133. X        (void) monster_death(y, x, t_list[c_ptr->tptr].flags);
  1134. X        t_list[c_ptr->tptr].flags = 0;
  1135. X          }
  1136. X      }
  1137. X    else
  1138. X      no_object = TRUE;
  1139. X      else
  1140. X    no_object = TRUE;
  1141. X
  1142. X      if (no_object)
  1143. X    {
  1144. X      msg_print("I do not see anything you can open there.");
  1145. X      free_turn_flag = TRUE;
  1146. X    }
  1147. X    }
  1148. X}
  1149. X
  1150. X
  1151. X/* Closes an open door.                -RAK-    */
  1152. Xvoid closeobject()
  1153. X{
  1154. X  int y, x, dir, no_object;
  1155. X  vtype out_val, m_name;
  1156. X  register cave_type *c_ptr;
  1157. X  register monster_type *m_ptr;
  1158. X
  1159. X  y = char_row;
  1160. X  x = char_col;
  1161. X  if (get_dir(NULL, &dir))
  1162. X    {
  1163. X      (void) mmove(dir, &y, &x);
  1164. X      c_ptr = &cave[y][x];
  1165. X      no_object = FALSE;
  1166. X      if (c_ptr->tptr != 0)
  1167. X    if (t_list[c_ptr->tptr].tval == TV_OPEN_DOOR)
  1168. X      if (c_ptr->cptr == 0)
  1169. X        if (t_list[c_ptr->tptr].p1 == 0)
  1170. X          {
  1171. X        invcopy(&t_list[c_ptr->tptr], OBJ_CLOSED_DOOR);
  1172. X        c_ptr->fval = BLOCKED_FLOOR;
  1173. X        lite_spot(y, x);
  1174. X          }
  1175. X        else
  1176. X          msg_print("The door appears to be broken.");
  1177. X      else
  1178. X        {
  1179. X          m_ptr = &m_list[c_ptr->cptr];
  1180. X          if (m_ptr->ml)
  1181. X        (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
  1182. X          else
  1183. X        (void) strcpy (m_name, "Something");
  1184. X          (void) sprintf(out_val, "%s is in your way!", m_name);
  1185. X          msg_print(out_val);
  1186. X        }
  1187. X    else
  1188. X      no_object = TRUE;
  1189. X      else
  1190. X    no_object = TRUE;
  1191. X
  1192. X      if (no_object)
  1193. X    {
  1194. X      msg_print("I do not see anything you can close there.");
  1195. X      free_turn_flag = TRUE;
  1196. X    }
  1197. X    }
  1198. X}
  1199. X
  1200. X
  1201. X/* Tunneling through real wall: 10, 11, 12        -RAK-    */
  1202. X/* Used by TUNNEL and WALL_TO_MUD                 */
  1203. Xint twall(y, x, t1, t2)
  1204. Xint y, x, t1, t2;
  1205. X{
  1206. X  register int i, j;
  1207. X  register cave_type *c_ptr;
  1208. X  int res, found;
  1209. X
  1210. X  res = FALSE;
  1211. X  if (t1 > t2)
  1212. X    {
  1213. X      c_ptr = &cave[y][x];
  1214. X      if (c_ptr->lr)
  1215. X    {
  1216. X      /* should become a room space, check to see whether it should be
  1217. X         LIGHT_FLOOR or DARK_FLOOR */
  1218. X      found = FALSE;
  1219. X      for (i = y-1; i <= y+1; i++)
  1220. X        for (j = x-1; j <= x+1; j++)
  1221. X          if (cave[i][j].fval <= MAX_CAVE_ROOM)
  1222. X        {
  1223. X          c_ptr->fval = cave[i][j].fval;
  1224. X          c_ptr->pl = cave[i][j].pl;
  1225. X          found = TRUE;
  1226. X          break;
  1227. X        }
  1228. X      if (!found)
  1229. X        {
  1230. X          c_ptr->fval = CORR_FLOOR;
  1231. X          c_ptr->pl = FALSE;
  1232. X        }
  1233. X    }
  1234. X      else
  1235. X    {
  1236. X      /* should become a corridor space */
  1237. X      c_ptr->fval  = CORR_FLOOR;
  1238. X      c_ptr->pl = FALSE;
  1239. X    }
  1240. X      c_ptr->fm = FALSE;
  1241. X      if (panel_contains(y, x))
  1242. X    if ((c_ptr->tl || c_ptr->pl) && c_ptr->tptr != 0)
  1243. X      msg_print("You have found something!");
  1244. X      lite_spot(y, x);
  1245. X      res = TRUE;
  1246. X    }
  1247. X  return(res);
  1248. X}
  1249. X
  1250. X
  1251. X/* Tunnels through rubble and walls            -RAK-    */
  1252. X/* Must take into account: secret doors,  special tools          */
  1253. Xvoid tunnel(dir)
  1254. Xint dir;
  1255. X{
  1256. X  register int i, tabil;
  1257. X  register cave_type *c_ptr;
  1258. X  register inven_type *i_ptr;
  1259. X  int y, x;
  1260. X  monster_type *m_ptr;
  1261. X  vtype out_val, m_name;
  1262. X
  1263. X  if ((py.flags.confused > 0) &&    /* Confused?         */
  1264. X      (randint(4) > 1))            /* 75% random movement   */
  1265. X    dir = randint(9);
  1266. X  y = char_row;
  1267. X  x = char_col;
  1268. X  (void) mmove(dir, &y, &x);
  1269. X
  1270. X  c_ptr = &cave[y][x];
  1271. X  /* Compute the digging ability of player; based on       */
  1272. X  /* strength, and type of tool used               */
  1273. X  tabil = py.stats.use_stat[A_STR];
  1274. X  i_ptr = &inventory[INVEN_WIELD];
  1275. X  if (c_ptr->cptr > 1)
  1276. X    {
  1277. X      m_ptr = &m_list[c_ptr->cptr];
  1278. X      if (m_ptr->ml)
  1279. X    (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
  1280. X      else
  1281. X    (void) strcpy (m_name, "Something");
  1282. X      (void) sprintf(out_val, "%s is in your way!", m_name);
  1283. X      msg_print(out_val);
  1284. X
  1285. X      /* let the player attack the creature */
  1286. X      if (py.flags.afraid < 1)
  1287. X    py_attack(y, x);
  1288. X      else
  1289. X    msg_print("You are too afraid!");
  1290. X    }
  1291. X  else if (i_ptr->tval != TV_NOTHING)
  1292. X    {
  1293. X      if (TR_TUNNEL & i_ptr->flags)
  1294. X    tabil += 25 + i_ptr->p1*50;
  1295. X      else
  1296. X    {
  1297. X      tabil += (i_ptr->damage[0]*i_ptr->damage[1]) + i_ptr->tohit
  1298. X        + i_ptr->todam;
  1299. X      /* divide by two so that digging without shovel isn't too easy */
  1300. X      tabil >>= 1;
  1301. X    }
  1302. X
  1303. X      /* Regular walls; Granite, magma intrusion, quartz vein  */
  1304. X      /* Don't forget the boundary walls, made of titanium (255)*/
  1305. X      switch(c_ptr->fval)
  1306. X    {
  1307. X    case GRANITE_WALL:
  1308. X      i = randint(1200) + 80;
  1309. X      if (twall(y, x, tabil, i))
  1310. X        msg_print("You have finished the tunnel.");
  1311. X      else
  1312. X        count_msg_print("You tunnel into the granite wall.");
  1313. X      break;
  1314. X    case MAGMA_WALL:
  1315. X      i = randint(600) + 10;
  1316. X      if (twall(y, x, tabil, i))
  1317. X        msg_print("You have finished the tunnel.");
  1318. X      else
  1319. X        count_msg_print("You tunnel into the magma intrusion.");
  1320. X      break;
  1321. X    case QUARTZ_WALL:
  1322. X      i = randint(400) + 10;
  1323. X      if (twall(y, x, tabil, i))
  1324. X        msg_print("You have finished the tunnel.");
  1325. X      else
  1326. X        count_msg_print("You tunnel into the quartz vein.");
  1327. X      break;
  1328. X    case BOUNDARY_WALL:
  1329. X      msg_print("This seems to be permanent rock.");
  1330. X      break;
  1331. X    default:
  1332. X      /* Is there an object in the way?  (Rubble and secret doors)*/
  1333. X      if (c_ptr->tptr != 0)
  1334. X        {
  1335. X          /* Rubble.     */
  1336. X          if (t_list[c_ptr->tptr].tval == TV_RUBBLE)
  1337. X        {
  1338. X          if (tabil > randint(180))
  1339. X            {
  1340. X              (void) delete_object(y, x);
  1341. X              msg_print("You have removed the rubble.");
  1342. X              if (randint(10) == 1)
  1343. X            {
  1344. X              place_object(y, x);
  1345. X              if (test_light(y, x))
  1346. X                msg_print("You have found something!");
  1347. X            }
  1348. X              lite_spot(y, x);
  1349. X            }
  1350. X          else
  1351. X            count_msg_print("You dig in the rubble.");
  1352. X        }
  1353. X          /* Secret doors.*/
  1354. X          else if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
  1355. X        {
  1356. X          count_msg_print("You tunnel into the granite wall.");
  1357. X          search(char_row, char_col, py.misc.srh);
  1358. X        }
  1359. X          else
  1360. X        {
  1361. X          msg_print("You can't tunnel through that.");
  1362. X          free_turn_flag = TRUE;
  1363. X        }
  1364. X        }
  1365. X      else
  1366. X        {
  1367. X          msg_print("Tunnel through what?  Empty air?!?");
  1368. X          free_turn_flag = TRUE;
  1369. X        }
  1370. X      break;
  1371. X    }
  1372. X    }
  1373. X  else
  1374. X    msg_print("You dig with your hands, making no progress.");
  1375. X}
  1376. X
  1377. X
  1378. X/* Disarms a trap                    -RAK-    */
  1379. Xvoid disarm_trap()
  1380. X{
  1381. X  int y, x, level, tmp, dir, no_disarm;
  1382. X  register int tot, i;
  1383. X  register cave_type *c_ptr;
  1384. X  register inven_type *i_ptr;
  1385. X  monster_type *m_ptr;
  1386. X  vtype m_name, out_val;
  1387. X
  1388. X  y = char_row;
  1389. X  x = char_col;
  1390. X  if (get_dir(NULL, &dir))
  1391. X    {
  1392. X      (void) mmove(dir, &y, &x);
  1393. X      c_ptr = &cave[y][x];
  1394. X      no_disarm = FALSE;
  1395. X      if (c_ptr->cptr > 1 && c_ptr->tptr != 0 &&
  1396. X      (t_list[c_ptr->tptr].tval == TV_VIS_TRAP
  1397. X       || t_list[c_ptr->tptr].tval == TV_CHEST))
  1398. X    {
  1399. X      m_ptr = &m_list[c_ptr->cptr];
  1400. X      if (m_ptr->ml)
  1401. X        (void) sprintf (m_name, "The %s", c_list[m_ptr->mptr].name);
  1402. X      else
  1403. X        (void) strcpy (m_name, "Something");
  1404. X      (void) sprintf(out_val, "%s is in your way!", m_name);
  1405. X      msg_print(out_val);
  1406. X    }
  1407. X      else if (c_ptr->tptr != 0)
  1408. X    {
  1409. X      tot = py.misc.disarm + 2*todis_adj() + stat_adj(A_INT)
  1410. X        + (class_level_adj[py.misc.pclass][CLA_DISARM] * py.misc.lev / 3);
  1411. X      if ((py.flags.blind > 0) || (no_light()))
  1412. X        tot = tot / 10;
  1413. X      if (py.flags.confused > 0)
  1414. X        tot = tot / 10;
  1415. X      if (py.flags.image > 0)
  1416. X        tot = tot / 10;
  1417. X      i_ptr = &t_list[c_ptr->tptr];
  1418. X      i = i_ptr->tval;
  1419. X      level = i_ptr->level;
  1420. X      if (i == TV_VIS_TRAP)            /* Floor trap    */
  1421. X        {
  1422. X          if ((tot + 100 - level) > randint(100))
  1423. X        {
  1424. X          msg_print("You have disarmed the trap.");
  1425. X          py.misc.exp += i_ptr->p1;
  1426. X          (void) delete_object(y, x);
  1427. X          /* make sure we move onto the trap even if confused */
  1428. X          tmp = py.flags.confused;
  1429. X          py.flags.confused = 0;
  1430. X          move_char(dir, FALSE);
  1431. X          py.flags.confused = tmp;
  1432. X          prt_experience();
  1433. X        }
  1434. X          /* avoid randint(0) call */
  1435. X          else if ((tot > 5) && (randint(tot) > 5))
  1436. X        count_msg_print("You failed to disarm the trap.");
  1437. X          else
  1438. X        {
  1439. X          msg_print("You set the trap off!");
  1440. X          /* make sure we move onto the trap even if confused */
  1441. X          tmp = py.flags.confused;
  1442. X          py.flags.confused = 0;
  1443. X          move_char(dir, FALSE);
  1444. X          py.flags.confused += tmp;
  1445. X        }
  1446. X        }
  1447. X      else if (i == TV_CHEST)
  1448. X        {
  1449. X          if (!known2_p(i_ptr))
  1450. X        {
  1451. X          msg_print("I don't see a trap.");
  1452. X          free_turn_flag = TRUE;
  1453. X        }
  1454. X          else if (CH_TRAPPED & i_ptr->flags)
  1455. X        {
  1456. X          if ((tot - level) > randint(100))
  1457. X            {
  1458. X              i_ptr->flags &= ~CH_TRAPPED;
  1459. X              if (CH_LOCKED & i_ptr->flags)
  1460. X            i_ptr->name2 = SN_LOCKED;
  1461. X              else
  1462. X            i_ptr->name2 = SN_DISARMED;
  1463. X              msg_print("You have disarmed the chest.");
  1464. X              known2(i_ptr);
  1465. X              py.misc.exp += level;
  1466. X              prt_experience();
  1467. X            }
  1468. X          else if ((tot > 5) && (randint(tot) > 5))
  1469. X            count_msg_print("You failed to disarm the chest.");
  1470. X          else
  1471. X            {
  1472. X              msg_print("You set a trap off!");
  1473. X              known2(i_ptr);
  1474. X              chest_trap(y, x);
  1475. X            }
  1476. X        }
  1477. X          else
  1478. X        {
  1479. X          msg_print("The chest was not trapped.");
  1480. X          free_turn_flag = TRUE;
  1481. X        }
  1482. X        }
  1483. X      else
  1484. X        no_disarm = TRUE;
  1485. X    }
  1486. X      else
  1487. X    no_disarm = TRUE;
  1488. X
  1489. X      if (no_disarm)
  1490. X    {
  1491. X      msg_print("I do not see anything to disarm there.");
  1492. X      free_turn_flag = TRUE;
  1493. X    }
  1494. X    }
  1495. X}
  1496. X
  1497. X
  1498. X/* An enhanced look, with peripheral vision. Looking all 8    -CJS-
  1499. X   directions will see everything which ought to be visible. Can
  1500. X   specify direction 5, which looks in all directions.
  1501. X
  1502. X   For the purpose of hindering vision, each place is regarded as
  1503. X   a diamond just touching its four immediate neighbours. A
  1504. X   diamond is opaque if it is a wall, or shut door, or something
  1505. X   like that. A place is visible if any part of its diamond is
  1506. X   visible: i.e. there is a line from the view point to part of
  1507. X   the diamond which does not pass through any opaque diamonds.
  1508. X
  1509. X   Consider the following situation:
  1510. X
  1511. X     @....                X    X   X    X   X
  1512. X     .##..               / \ / \ / \ / \ / \
  1513. X     .....              X @ X . X . X 1 X . X
  1514. X                   \ / \ / \ / \ / \ /
  1515. X                    X    X   X    X   X
  1516. X       Expanded view, with       / \ / \ / \ / \ / \
  1517. X       diamonds inscribed      X . X # X # X 2 X . X
  1518. X       about each point,       \ / \ / \ / \ / \ /
  1519. X       and some locations        X    X   X    X   X
  1520. X       numbered.           / \ / \ / \ / \ / \
  1521. X                  X . X . X . X 3 X 4 X
  1522. X                   \ / \ / \ / \ / \ /
  1523. X                    X    X   X    X   X
  1524. X    - Location 1 is fully visible.
  1525. X    - Location 2 is visible, even though partially obscured.
  1526. X    - Location 3 is invisible, but if either # were
  1527. X      transparent, it would be visible.
  1528. X    - Location 4 is completely obscured by a single #.
  1529. X
  1530. X   The function which does the work is look_ray. It sets up its
  1531. X   own co-ordinate frame (global variables map back to the
  1532. X   dungeon frame) and looks for everything between two angles
  1533. X   specified from a central line. It is recursive, and each call
  1534. X   looks at stuff visible along a line parallel to the center
  1535. X   line, and a set distance away from it. A diagonal look uses
  1536. X   more extreme peripheral vision from the closest horizontal and
  1537. X   vertical directions; horizontal or vertical looks take a call
  1538. X   for each side of the central line. */
  1539. X
  1540. X/* Globally accessed variables: gl_nseen counts the number of places where
  1541. X   something is seen. gl_rock indicates a look for rock or objects.
  1542. X
  1543. X   The others map co-ords in the ray frame to dungeon co-ords.
  1544. X
  1545. X   dungeon y = char_row     + gl_fyx * (ray x)  + gl_fyy * (ray y)
  1546. X   dungeon x = char_col     + gl_fxx * (ray x)  + gl_fxy * (ray y) */
  1547. Xstatic int gl_fxx, gl_fxy, gl_fyx, gl_fyy;
  1548. Xstatic int gl_nseen, gl_noquery;
  1549. Xstatic int gl_rock;
  1550. X/* Intended to be indexed by dir/2, since is only relevant to horizontal or
  1551. X   vertical directions. */
  1552. Xstatic int set_fxy[] = { 0,  1,     0,  0, -1 };
  1553. Xstatic int set_fxx[] = { 0,  0, -1,  1,     0 };
  1554. Xstatic int set_fyy[] = { 0,  0,     1, -1,     0 };
  1555. Xstatic int set_fyx[] = { 0,  1,     0,  0, -1 };
  1556. X/* Map diagonal-dir/2 to a normal-dir/2. */
  1557. Xstatic int map_diag1[] = { 1, 3, 0, 2, 4 };
  1558. Xstatic int map_diag2[] = { 2, 1, 0, 4, 3 };
  1559. X
  1560. X#define GRADF    10000    /* Any sufficiently big number will do */
  1561. X
  1562. X/* Look at what we can see. This is a free move.
  1563. X
  1564. X   Prompts for a direction, and then looks at every object in
  1565. X   turn within a cone of vision in that direction. For each
  1566. X   object, the cursor is moved over the object, a description is
  1567. X   given, and we wait for the user to type something. Typing
  1568. X   ESCAPE will abort the entire look.
  1569. X
  1570. X   Looks first at real objects and monsters, and looks at rock
  1571. X   types only after all other things have been seen.  Only looks at rock
  1572. X   types if the highlight_seams option is set. */
  1573. X
  1574. Xvoid look()
  1575. X{
  1576. X  register int i, abort;
  1577. X  int dir, dummy;
  1578. X
  1579. X  if (py.flags.blind > 0)
  1580. X    msg_print("You can't see a damn thing!");
  1581. X  else if (py.flags.image > 0)
  1582. X    msg_print("You can't believe what you are seeing! It's like a dream!");
  1583. X  else if (get_alldir("Look which direction?", &dir))
  1584. X    {
  1585. X      abort = FALSE;
  1586. X      gl_nseen = 0;
  1587. X      gl_rock = 0;
  1588. X      gl_noquery = FALSE;    /* Have to set this up for the look_see */
  1589. X      if (look_see(0, 0, &dummy))
  1590. X    abort = TRUE;
  1591. X      else
  1592. X    {
  1593. X      do
  1594. X        {
  1595. X          abort = FALSE;
  1596. X          if (dir == 5)
  1597. X        {
  1598. X          for (i = 1; i <= 4; i++)
  1599. X            {
  1600. X              gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
  1601. X              gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
  1602. X              if (look_ray(0, 2*GRADF-1, 1))
  1603. X            {
  1604. X              abort = TRUE;
  1605. X              break;
  1606. X            }
  1607. X              gl_fxy = -gl_fxy;
  1608. X              gl_fyy = -gl_fyy;
  1609. X              if (look_ray(0, 2*GRADF, 2))
  1610. X            {
  1611. X              abort = TRUE;
  1612. X              break;
  1613. X            }
  1614. X            }
  1615. X        }
  1616. X          else if ((dir & 1) == 0)    /* Straight directions */
  1617. X        {
  1618. X          i = dir >> 1;
  1619. X          gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
  1620. X          gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
  1621. X          if (look_ray(0, GRADF, 1))
  1622. X            abort = TRUE;
  1623. X          else
  1624. X            {
  1625. X              gl_fxy = -gl_fxy;
  1626. X              gl_fyy = -gl_fyy;
  1627. X              abort = look_ray(0, GRADF, 2);
  1628. X            }
  1629. X        }
  1630. X          else
  1631. X        {
  1632. X          i = map_diag1[dir >> 1];
  1633. X          gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
  1634. X          gl_fxy = -set_fxy[i]; gl_fyy = -set_fyy[i];
  1635. X          if (look_ray(1, 2*GRADF, GRADF))
  1636. X            abort = TRUE;
  1637. X          else
  1638. X            {
  1639. X              i = map_diag2[dir >> 1];
  1640. X              gl_fxx = set_fxx[i]; gl_fyx = set_fyx[i];
  1641. X              gl_fxy = set_fxy[i]; gl_fyy = set_fyy[i];
  1642. X              abort = look_ray(1, 2*GRADF-1, GRADF);
  1643. X            }
  1644. X        }
  1645. X        }
  1646. X      while (abort == FALSE && highlight_seams && (++gl_rock < 2));
  1647. X      if (abort)
  1648. X        msg_print("--Aborting look--");
  1649. X      else
  1650. X        {
  1651. X          if (gl_nseen)
  1652. X        {
  1653. X          if (dir == 5)
  1654. X            msg_print("That's all you see.");
  1655. X          else
  1656. X            msg_print("That's all you see in that direction.");
  1657. X        }
  1658. X          else if (dir == 5)
  1659. X        msg_print("You see nothing of interest.");
  1660. X          else
  1661. X        msg_print("You see nothing of interest in that direction.");
  1662. X        }
  1663. X    }
  1664. X    }
  1665. X}
  1666. X
  1667. X/* Look at everything within a cone of vision between two ray
  1668. X   lines emanating from the player, and y or more places away
  1669. X   from the direct line of view. This is recursive.
  1670. X
  1671. X   Rays are specified by gradients, y over x, multiplied by
  1672. X   2*GRADF. This is ONLY called with gradients between 2*GRADF
  1673. X   (45 degrees) and 1 (almost horizontal).
  1674. X
  1675. X   (y axis)/ angle from
  1676. X     ^      /        ___ angle to
  1677. X     |     /     ___
  1678. X  ...|../.....___.................... parameter y (look at things in the
  1679. X     | /   ___                  cone, and on or above this line)
  1680. X     |/ ___
  1681. X     @-------------------->   direction in which you are looking. (x axis)
  1682. X     |
  1683. X     | */
  1684. Xstatic int look_ray(y, from, to)
  1685. Xint y, from, to;
  1686. X{
  1687. X  register int max_x, x;
  1688. X  int transparent;
  1689. X
  1690. X  /* from is the larger angle of the ray, since we scan towards the
  1691. X     center line. If from is smaller, then the ray does not exist. */
  1692. X  if (from <= to || y > MAX_SIGHT)
  1693. X    return FALSE;
  1694. X  /* Find first visible location along this line. Minimum x such
  1695. X     that (2x-1)/x < from/GRADF <=> x > GRADF(2x-1)/from. This may
  1696. X     be called with y=0 whence x will be set to 0. Thus we need a
  1697. X     special fix. */
  1698. X  x = (long)GRADF * (2 * y - 1) / from + 1;
  1699. X  if (x <= 0)
  1700. X    x = 1;
  1701. X
  1702. X  /* Find last visible location along this line.
  1703. X     Maximum x such that (2x+1)/x > to/GRADF <=> x < GRADF(2x+1)/to */
  1704. X  max_x = ((long)GRADF * (2 * y + 1) - 1) / to;
  1705. X  if (max_x > MAX_SIGHT)
  1706. X    max_x = MAX_SIGHT;
  1707. X  if (max_x < x)
  1708. X    return FALSE;
  1709. X
  1710. X  /* gl_noquery is a HACK to prevent doubling up on direct lines of
  1711. X     sight. If 'to' is    greater than 1, we do not really look at
  1712. X     stuff along the direct line of sight, but we do have to see
  1713. X     what is opaque for the purposes of obscuring other objects. */
  1714. X  if (y == 0 && to > 1 || y == x && from < GRADF*2)
  1715. X    gl_noquery = TRUE;
  1716. X  else
  1717. X    gl_noquery = FALSE;
  1718. X  if (look_see(x, y, &transparent))
  1719. X    return TRUE;
  1720. X  if (y == x)
  1721. X    gl_noquery = FALSE;
  1722. X  if (transparent)
  1723. X    goto init_transparent;
  1724. X
  1725. X  for (;;)
  1726. X    {
  1727. X      /* Look down the window we've found. */
  1728. X      if (look_ray(y+1, from, (int)((2 * y + 1) * (long)GRADF / x)))
  1729. X    return TRUE;
  1730. X      /* Find the start of next window. */
  1731. X      do
  1732. X    {
  1733. X      if (x == max_x)
  1734. X        return FALSE;
  1735. X      /* See if this seals off the scan. (If y is zero, then it will.) */
  1736. X      from = (2 * y - 1) * (long)GRADF / x;
  1737. X      if (from <= to)
  1738. X        return FALSE;
  1739. X      x++;
  1740. X      if (look_see(x, y, &transparent))
  1741. X        return TRUE;
  1742. X    }
  1743. X      while(!transparent);
  1744. X    init_transparent:
  1745. X      /* Find the end of this window of visibility. */
  1746. X      do
  1747. X    {
  1748. X      if (x == max_x)
  1749. X        /* The window is trimmed by an earlier limit. */
  1750. X        return look_ray(y+1, from, to);
  1751. X      x++;
  1752. X      if (look_see(x, y, &transparent))
  1753. X        return TRUE;
  1754. X    }
  1755. X      while(transparent);
  1756. X    }
  1757. X}
  1758. X
  1759. Xstatic int look_see(x, y, transparent)
  1760. Xregister int x, y;
  1761. Xint *transparent;
  1762. X{
  1763. X  char *dstring, *string, query;
  1764. X  register cave_type *c_ptr;
  1765. X  register int j;
  1766. X  bigvtype out_val, tmp_str;
  1767. X
  1768. X  if (x < 0 || y < 0 || y > x)
  1769. X    {
  1770. X      (void) sprintf(tmp_str, "Illegal call to look_see(%d, %d)", x, y);
  1771. X      msg_print(tmp_str);
  1772. X    }
  1773. X  if (x == 0 && y == 0)
  1774. X    dstring = "You are on";
  1775. X  else
  1776. X    dstring = "You see";
  1777. X  j = char_col + gl_fxx * x + gl_fxy * y;
  1778. X  y = char_row + gl_fyx * x + gl_fyy * y;
  1779. X  x = j;
  1780. X  if (!panel_contains(y, x))
  1781. X    {
  1782. X      *transparent = FALSE;
  1783. X      return FALSE;
  1784. X    }
  1785. X  c_ptr = &cave[y][x];
  1786. X  *transparent = c_ptr->fval <= MAX_OPEN_SPACE;
  1787. X  if (gl_noquery)
  1788. X    return FALSE; /* Don't look at a direct line of sight. A hack. */
  1789. X  out_val[0] = 0;
  1790. X  if (gl_rock == 0 && c_ptr->cptr > 1 && m_list[c_ptr->cptr].ml)
  1791. X    {
  1792. X      j = m_list[c_ptr->cptr].mptr;
  1793. X      (void) sprintf(out_val, "%s %s %s. [(r)ecall]",
  1794. X             dstring,
  1795. X             is_a_vowel( c_list[j].name[0] ) ? "an" : "a",
  1796. X             c_list[j].name);
  1797. X      dstring = "It is on";
  1798. X      prt(out_val, 0, 0);
  1799. X      move_cursor_relative(y, x);
  1800. X      query = inkey();
  1801. X      if (query == 'r' || query == 'R')
  1802. X    {
  1803. X      save_screen();
  1804. X      query = roff_recall(j);
  1805. X      restore_screen();
  1806. X    }
  1807. X    }
  1808. X  if (c_ptr->tl || c_ptr->pl || c_ptr->fm)
  1809. X    {
  1810. X      if (c_ptr->tptr != 0)
  1811. X    {
  1812. X      if (t_list[c_ptr->tptr].tval == TV_SECRET_DOOR)
  1813. X        goto granite;
  1814. X      if (gl_rock ==0 && t_list[c_ptr->tptr].tval != TV_INVIS_TRAP)
  1815. X        {
  1816. X          objdes(tmp_str, &t_list[c_ptr->tptr], TRUE);
  1817. X          (void) sprintf(out_val, "%s %s ---pause---", dstring, tmp_str);
  1818. X          dstring = "It is in";
  1819. X          prt(out_val, 0, 0);
  1820. X          move_cursor_relative(y, x);
  1821. X          query = inkey();
  1822. X        }
  1823. X    }
  1824. X      if ((gl_rock || out_val[0]) && c_ptr->fval >= MIN_CLOSED_SPACE)
  1825. X    {
  1826. X      switch(c_ptr->fval)
  1827. X        {
  1828. X        case BOUNDARY_WALL:
  1829. X        case GRANITE_WALL:
  1830. X        granite:
  1831. X          /* Granite is only interesting if it contains something. */
  1832. X          if(out_val[0])
  1833. X        string = "a granite wall";
  1834. X          else
  1835. X        string = NULL;    /* In case we jump here */
  1836. X          break;
  1837. X        case MAGMA_WALL: string = "some dark rock";
  1838. X          break;
  1839. X        case QUARTZ_WALL: string = "a quartz vein";
  1840. X          break;
  1841. X        default: string = NULL;
  1842. X          break;
  1843. X        }
  1844. X      if (string)
  1845. X        {
  1846. X          (void) sprintf(out_val, "%s %s ---pause---", dstring, string);
  1847. X          prt(out_val, 0, 0);
  1848. X          move_cursor_relative(y, x);
  1849. X          query = inkey();
  1850. X        }
  1851. X    }
  1852. X    }
  1853. X  if (out_val[0])
  1854. X    {
  1855. X      gl_nseen++;
  1856. X      if (query == ESCAPE)
  1857. X    return TRUE;
  1858. X    }
  1859. X
  1860. X  return FALSE;
  1861. X}
  1862. X
  1863. X
  1864. Xstatic void inven_throw(item_val, t_ptr)
  1865. Xint item_val;
  1866. Xinven_type *t_ptr;
  1867. X{
  1868. X  register inven_type *i_ptr;
  1869. X
  1870. X  i_ptr = &inventory[item_val];
  1871. X  *t_ptr = *i_ptr;
  1872. X  if (i_ptr->number > 1)
  1873. X    {
  1874. X      t_ptr->number = 1;
  1875. X      i_ptr->number--;
  1876. X      inven_weight -= i_ptr->weight;
  1877. X      py.flags.status |= PY_STR_WGT;
  1878. X    }
  1879. X  else
  1880. X    inven_destroy(item_val);
  1881. X}
  1882. X
  1883. X
  1884. X/* Obtain the hit and damage bonuses and the maximum distance for a
  1885. X   thrown missile. */
  1886. Xstatic void facts(i_ptr, tbth, tpth, tdam, tdis)
  1887. Xregister inven_type *i_ptr;
  1888. Xint *tbth, *tpth, *tdam, *tdis;
  1889. X{
  1890. X  register int tmp_weight;
  1891. X
  1892. X  if (i_ptr->weight < 1)
  1893. X    tmp_weight = 1;
  1894. X  else
  1895. X    tmp_weight = i_ptr->weight;
  1896. X
  1897. X  /* Throwing objects            */
  1898. X  *tdam = pdamroll(i_ptr->damage) + i_ptr->todam;
  1899. X  *tbth = py.misc.bthb * 75 / 100;
  1900. X  *tpth = py.misc.ptohit + i_ptr->tohit;
  1901. X
  1902. X  /* Add this back later if the correct throwing device. -CJS- */
  1903. X  if (inventory[INVEN_WIELD].tval != TV_NOTHING)
  1904. X    *tpth -= inventory[INVEN_WIELD].tohit;
  1905. X
  1906. X  *tdis = (((py.stats.use_stat[A_STR]+20)*10)/tmp_weight);
  1907. X  if (*tdis > 10)  *tdis = 10;
  1908. X
  1909. X  /* multiply damage bonuses instead of adding, when have proper
  1910. X     missile/weapon combo, this makes them much more useful */
  1911. X
  1912. X  /* Using Bows,  slings,  or crossbows    */
  1913. X  if (inventory[INVEN_WIELD].tval == TV_BOW)
  1914. X    switch(inventory[INVEN_WIELD].p1)
  1915. X      {
  1916. X      case 1:
  1917. X    if (i_ptr->tval == TV_SLING_AMMO) /* Sling and ammo */
  1918. X      {
  1919. X        *tbth = py.misc.bthb;
  1920. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1921. X        *tdam += inventory[INVEN_WIELD].todam;
  1922. X        *tdam = *tdam * 2;
  1923. X        *tdis = 20;
  1924. X      }
  1925. X    break;
  1926. X      case 2:
  1927. X    if (i_ptr->tval == TV_ARROW)      /* Short Bow and Arrow    */
  1928. X      {
  1929. X        *tbth = py.misc.bthb;
  1930. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1931. X        *tdam += inventory[INVEN_WIELD].todam;
  1932. X        *tdam = *tdam * 2;
  1933. X        *tdis = 25;
  1934. X      }
  1935. X    break;
  1936. X      case 3:
  1937. X    if (i_ptr->tval == TV_ARROW)      /* Long Bow and Arrow    */
  1938. X      {
  1939. X        *tbth = py.misc.bthb;
  1940. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1941. X        *tdam += inventory[INVEN_WIELD].todam;
  1942. X        *tdam = *tdam * 3;
  1943. X        *tdis = 30;
  1944. X      }
  1945. X    break;
  1946. X      case 4:
  1947. X    if (i_ptr->tval == TV_ARROW)      /* Composite Bow and Arrow*/
  1948. X      {
  1949. X        *tbth = py.misc.bthb;
  1950. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1951. X        *tdam += inventory[INVEN_WIELD].todam;
  1952. X        *tdam = *tdam * 4;
  1953. X        *tdis = 35;
  1954. X      }
  1955. X    break;
  1956. X      case 5:
  1957. X    if (i_ptr->tval == TV_BOLT)      /* Light Crossbow and Bolt*/
  1958. X      {
  1959. X        *tbth = py.misc.bthb;
  1960. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1961. X        *tdam += inventory[INVEN_WIELD].todam;
  1962. X        *tdam = *tdam * 3;
  1963. X        *tdis = 25;
  1964. X      }
  1965. X    break;
  1966. X      case 6:
  1967. X    if (i_ptr->tval == TV_BOLT)      /* Heavy Crossbow and Bolt*/
  1968. X      {
  1969. X        *tbth = py.misc.bthb;
  1970. X        *tpth += 2 * inventory[INVEN_WIELD].tohit;
  1971. X        *tdam += inventory[INVEN_WIELD].todam;
  1972. X        *tdam = *tdam * 4;
  1973. X        *tdis = 35;
  1974. X      }
  1975. X    break;
  1976. X      }
  1977. X}
  1978. X
  1979. X
  1980. Xstatic void drop_throw(y, x, t_ptr)
  1981. Xint y, x;
  1982. Xinven_type *t_ptr;
  1983. X{
  1984. X  register int i, j, k;
  1985. X  int flag, cur_pos;
  1986. X  bigvtype out_val, tmp_str;
  1987. X  register cave_type *c_ptr;
  1988. X
  1989. X  flag = FALSE;
  1990. X  i = y;
  1991. X  j = x;
  1992. X  k = 0;
  1993. X  if (randint(10) > 1)
  1994. X    {
  1995. X      do
  1996. X    {
  1997. X      if (in_bounds(i, j))
  1998. X        {
  1999. X          c_ptr = &cave[i][j];
  2000. X          if (c_ptr->fval <= MAX_OPEN_SPACE && c_ptr->tptr == 0)
  2001. X        flag = TRUE;
  2002. X        }
  2003. X      if (!flag)
  2004. X        {
  2005. X          i = y + randint(3) - 2;
  2006. X          j = x + randint(3) - 2;
  2007. X          k++;
  2008. X        }
  2009. X    }
  2010. X      while ((!flag) && (k <= 9));
  2011. X    }
  2012. X  if (flag)
  2013. X    {
  2014. X      cur_pos = popt();
  2015. X      cave[i][j].tptr = cur_pos;
  2016. X      t_list[cur_pos] = *t_ptr;
  2017. X      lite_spot(i, j);
  2018. X    }
  2019. X  else
  2020. X    {
  2021. X      objdes(tmp_str, t_ptr, FALSE);
  2022. X      (void) sprintf(out_val, "The %s disappears.", tmp_str);
  2023. X      msg_print(out_val);
  2024. X    }
  2025. X}
  2026. X
  2027. X/* Throw an object across the dungeon.        -RAK-    */
  2028. X/* Note: Flasks of oil do fire damage                 */
  2029. X/* Note: Extra damage and chance of hitting when missiles are used*/
  2030. X/*     with correct weapon.  I.E.  wield bow and throw arrow.     */
  2031. Xvoid throw_object()
  2032. X{
  2033. X  int item_val, tbth, tpth, tdam, tdis;
  2034. X  int y, x, oldy, oldx, cur_dis, dir;
  2035. X  int flag, visible;
  2036. X  bigvtype out_val, tmp_str;
  2037. X  inven_type throw_obj;
  2038. X  register cave_type *c_ptr;
  2039. X  register monster_type *m_ptr;
  2040. X  register int i;
  2041. X  char tchar;
  2042. X
  2043. X  if (inven_ctr == 0)
  2044. X    {
  2045. X      msg_print("But you are not carrying anything.");
  2046. X      free_turn_flag = TRUE;
  2047. X    }
  2048. X  else if (get_item(&item_val, "Fire/Throw which one?", 0, inven_ctr-1))
  2049. X    {
  2050. X      if (get_dir(NULL, &dir))
  2051. X    {
  2052. X      desc_remain(item_val);
  2053. X      if (py.flags.confused > 0)
  2054. X        {
  2055. X          msg_print("You are confused.");
  2056. X          do
  2057. X        {
  2058. X          dir = randint(9);
  2059. X        }
  2060. X          while (dir == 5);
  2061. X        }
  2062. X      inven_throw(item_val, &throw_obj);
  2063. X      facts(&throw_obj, &tbth, &tpth, &tdam, &tdis);
  2064. X      tchar = throw_obj.tchar;
  2065. X      flag = FALSE;
  2066. X      y = char_row;
  2067. X      x = char_col;
  2068. X      oldy = char_row;
  2069. X      oldx = char_col;
  2070. X      cur_dis = 0;
  2071. X      do
  2072. X        {
  2073. X          (void) mmove(dir, &y, &x);
  2074. X          cur_dis++;
  2075. X          lite_spot(oldy, oldx);
  2076. X          if (cur_dis > tdis)  flag = TRUE;
  2077. X          c_ptr = &cave[y][x];
  2078. X          if ((c_ptr->fval <= MAX_OPEN_SPACE) && (!flag))
  2079. X        {
  2080. X          if (c_ptr->cptr > 1)
  2081. X            {
  2082. X              flag = TRUE;
  2083. X              m_ptr = &m_list[c_ptr->cptr];
  2084. X              tbth = tbth - cur_dis;
  2085. X              /* if monster not lit, make it much more difficult to
  2086. X             hit, subtract off most bonuses, and reduce bthb
  2087. X             depending on distance */
  2088. X              if (!m_ptr->ml)
  2089. X            tbth = (tbth / (cur_dis+2))
  2090. X              - (py.misc.lev *
  2091. X                 class_level_adj[py.misc.pclass][CLA_BTHB] / 2)
  2092. X                - (tpth * (BTH_PLUS_ADJ-1));
  2093. X              if (test_hit(tbth, (int)py.misc.lev, tpth,
  2094. X                   (int)c_list[m_ptr->mptr].ac, CLA_BTHB))
  2095. X            {
  2096. X              i = m_ptr->mptr;
  2097. X              objdes(tmp_str, &throw_obj, FALSE);
  2098. X              /* Does the player know what he's fighting?       */
  2099. X              if (!m_ptr->ml)
  2100. X                {
  2101. X                  (void) sprintf(out_val,
  2102. X               "You hear a cry as the %s finds a mark.", tmp_str);
  2103. X                  visible = FALSE;
  2104. X                }
  2105. X              else
  2106. X                {
  2107. X                  (void) sprintf(out_val, "The %s hits the %s.",
  2108. X                         tmp_str, c_list[i].name);
  2109. X                  visible = TRUE;
  2110. X                }
  2111. X              msg_print(out_val);
  2112. X              tdam = tot_dam(&throw_obj, tdam, i);
  2113. X              tdam = critical_blow((int)throw_obj.weight,
  2114. X                           tpth, tdam, CLA_BTHB);
  2115. X              i = mon_take_hit((int)c_ptr->cptr, tdam);
  2116. X              if (i >= 0)
  2117. X                {
  2118. X                  if (!visible)
  2119. X                msg_print("You have killed something!");
  2120. X                  else
  2121. X                {
  2122. X              (void) sprintf(out_val,"You have killed the %s.",
  2123. X                         c_list[i].name);
  2124. X                  msg_print(out_val);
  2125. X                }
  2126. X                  prt_experience();
  2127. X                }
  2128. X            }
  2129. X              else
  2130. X            drop_throw(oldy, oldx, &throw_obj);
  2131. X            }
  2132. X          else
  2133. X            {    /* do not test c_ptr->fm here */
  2134. X              if (panel_contains(y, x) && (py.flags.blind < 1)
  2135. X              && (c_ptr->tl || c_ptr->pl))
  2136. X            {
  2137. X              print(tchar, y, x);
  2138. X              put_qio(); /* show object moving */
  2139. X            }
  2140. X            }
  2141. X        }
  2142. X          else
  2143. X        {
  2144. X          flag = TRUE;
  2145. X          drop_throw(oldy, oldx, &throw_obj);
  2146. X        }
  2147. X          oldy = y;
  2148. X          oldx = x;
  2149. X        }
  2150. X      while (!flag);
  2151. X    }
  2152. X    }
  2153. X}
  2154. X
  2155. X
  2156. X/* Make a bash attack on someone.                -CJS-
  2157. X   Used to be part of bash above. */
  2158. Xstatic void py_bash(y, x)
  2159. Xint y, x;
  2160. X{
  2161. X  int monster, k, avg_max_hp, base_tohit;
  2162. X  register creature_type *c_ptr;
  2163. X  register monster_type *m_ptr;
  2164. X  vtype m_name, out_val;
  2165. X
  2166. X  monster = cave[y][x].cptr;
  2167. X  m_ptr = &m_list[monster];
  2168. X  c_ptr = &c_list[m_ptr->mptr];
  2169. X  m_ptr->csleep = 0;
  2170. X  /* Does the player know what he's fighting?       */
  2171. X  if (!m_ptr->ml)
  2172. X    (void) strcpy(m_name, "it");
  2173. X  else
  2174. X    (void) sprintf(m_name, "the %s", c_ptr->name);
  2175. X  base_tohit = py.stats.use_stat[A_STR] + inventory[INVEN_ARM].weight/2
  2176. X    + py.misc.wt/10;
  2177. X  if (!m_ptr->ml)
  2178. X    base_tohit = (base_tohit / 2) - (py.stats.use_stat[A_DEX]*(BTH_PLUS_ADJ-1))
  2179. X      - (py.misc.lev * class_level_adj[py.misc.pclass][CLA_BTH] / 2);
  2180. X
  2181. X  if (test_hit(base_tohit, (int)py.misc.lev,
  2182. X           (int)py.stats.use_stat[A_DEX], (int)c_ptr->ac, CLA_BTH))
  2183. X    {
  2184. X      (void) sprintf(out_val, "You hit %s.", m_name);
  2185. X      msg_print(out_val);
  2186. X      k = pdamroll(inventory[INVEN_ARM].damage);
  2187. X      k = critical_blow((int)(inventory[INVEN_ARM].weight / 4
  2188. X                  + py.stats.use_stat[A_STR]), 0, k, CLA_BTH);
  2189. X      k += py.misc.wt/60 + 3;
  2190. X
  2191. X      /* See if we done it in.                     */
  2192. X      if (mon_take_hit(monster, k) >= 0)
  2193. X    {
  2194. X      (void) sprintf(out_val, "You have slain %s.", m_name);
  2195. X      msg_print(out_val);
  2196. X      prt_experience();
  2197. X    }
  2198. X      else
  2199. X    {
  2200. X      m_name[0] = toupper((int)m_name[0]); /* Capitalize */
  2201. X      /* Can not stun Balrog */
  2202. X      avg_max_hp = (c_ptr->cdefense & CD_MAX_HP ? 
  2203. X            c_ptr->hd[0] * c_ptr->hd[1] :
  2204. X            (c_ptr->hd[0] * (c_ptr->hd[1] + 1)) >> 1);
  2205. X      if ((100 + randint(400) + randint(400))
  2206. X          > (m_ptr->hp + avg_max_hp))
  2207. X        {
  2208. X          m_ptr->stunned += randint(3) + 1;
  2209. X          if (m_ptr->stunned > 24)    m_ptr->stunned = 24;
  2210. X          (void) sprintf(out_val, "%s appears stunned!", m_name);
  2211. X        }
  2212. X      else
  2213. X        (void) sprintf(out_val, "%s ignores your bash!", m_name);
  2214. X      msg_print(out_val);
  2215. X    }
  2216. X    }
  2217. X  else
  2218. X    {
  2219. X      (void) sprintf(out_val, "You miss %s.", m_name);
  2220. X      msg_print(out_val);
  2221. X    }
  2222. X  if (randint(150) > py.stats.use_stat[A_DEX])
  2223. X    {
  2224. X      msg_print("You are off balance.");
  2225. X      py.flags.paralysis = 1 + randint(2);
  2226. X    }
  2227. X}
  2228. X
  2229. X
  2230. X/* Bash open a door or chest                -RAK-    */
  2231. X/* Note: Affected by strength and weight of character
  2232. X
  2233. X   For a closed door, p1 is positive if locked; negative if
  2234. X   stuck. A disarm spell unlocks and unjams doors!
  2235. X
  2236. X   For an open door, p1 is positive for a broken door.
  2237. X
  2238. X   A closed door can be opened - harder if locked. Any door might
  2239. X   be bashed open (and thereby broken). Bashing a door is
  2240. X   (potentially) faster! You move into the door way. To open a
  2241. X   stuck door, it must be bashed. A closed door can be jammed
  2242. X   (which makes it stuck if previously locked).
  2243. X
  2244. X   Creatures can also open doors. A creature with open door
  2245. X   ability will (if not in the line of sight) move though a
  2246. X   closed or secret door with no changes. If in the line of
  2247. X   sight, closed door are openned, & secret door revealed.
  2248. X   Whether in the line of sight or not, such a creature may
  2249. X   unlock or unstick a door.
  2250. X
  2251. X   A creature with no such ability will attempt to bash a
  2252. X   non-secret door. */
  2253. Xvoid bash()
  2254. X{
  2255. X  int y, x, dir, tmp, no_bash;
  2256. X  register cave_type *c_ptr;
  2257. X  register inven_type *t_ptr;
  2258. X
  2259. X  y = char_row;
  2260. X  x = char_col;
  2261. X  if (get_dir(NULL, &dir))
  2262. X    {
  2263. X      no_bash = FALSE;
  2264. X      (void) mmove(dir, &y, &x);
  2265. X      c_ptr = &cave[y][x];
  2266. X      if (c_ptr->cptr > 1)
  2267. X    {
  2268. X      if (py.flags.afraid > 0)
  2269. X        msg_print("You are afraid!");
  2270. X      else
  2271. X        py_bash(y, x);
  2272. X    }
  2273. X      else if (c_ptr->tptr != 0)
  2274. X    {
  2275. X      t_ptr = &t_list[c_ptr->tptr];
  2276. X      if (t_ptr->tval == TV_CLOSED_DOOR)
  2277. X        {
  2278. X          count_msg_print("You smash into the door!");
  2279. X          tmp = py.stats.use_stat[A_STR] + py.misc.wt / 2;
  2280. X          /* Use (roughly) similar method as for monsters. */
  2281. X          if (randint(tmp*(20+abs(t_ptr->p1))) < 10*(tmp-abs(t_ptr->p1)))
  2282. X        {
  2283. X          msg_print("The door crashes open!");
  2284. X          invcopy(&t_list[c_ptr->tptr], OBJ_OPEN_DOOR);
  2285. X          t_ptr->p1 = randint(2) - 1; /* 50% chance of breaking door */
  2286. X          c_ptr->fval = CORR_FLOOR;
  2287. X          if (py.flags.confused == 0)
  2288. X            move_char(dir, FALSE);
  2289. X          else
  2290. X            lite_spot(y, x);
  2291. X        }
  2292. X          else if (randint(150) > py.stats.use_stat[A_DEX])
  2293. X        {
  2294. X          msg_print("You are off-balance.");
  2295. X          py.flags.paralysis = 1 + randint(2);
  2296. X        }
  2297. X          else if (command_count == 0)
  2298. X        msg_print("The door holds firm.");
  2299. X        }
  2300. X      else if (t_ptr->tval == TV_CHEST)
  2301. X        {
  2302. X          if (randint(10) == 1)
  2303. X        {
  2304. X          msg_print("You have destroyed the chest.");
  2305. X          msg_print("and its contents!");
  2306. X          t_ptr->index = OBJ_RUINED_CHEST;
  2307. X          t_ptr->flags = 0;
  2308. X        }
  2309. X          else if ((CH_LOCKED & t_ptr->flags) && (randint(10) == 1))
  2310. X        {
  2311. X          msg_print("The lock breaks open!");
  2312. X          t_ptr->flags &= ~CH_LOCKED;
  2313. X        }
  2314. X          else
  2315. X        count_msg_print("The chest holds firm.");
  2316. X        }
  2317. X      else
  2318. X        no_bash = TRUE;
  2319. X    }
  2320. X      else
  2321. X    no_bash = TRUE;
  2322. X
  2323. X      if (no_bash)
  2324. X    {
  2325. X      msg_print("I do not see anything you can bash there.");
  2326. X      free_turn_flag = TRUE;
  2327. X    }
  2328. X    }
  2329. X}
  2330. END_OF_FILE
  2331. if test 59994 -ne `wc -c <'source/moria2.c'`; then
  2332.     echo shar: \"'source/moria2.c'\" unpacked with wrong size!
  2333. fi
  2334. # end of 'source/moria2.c'
  2335. fi
  2336. echo shar: End of archive 4 \(of 31\).
  2337. cp /dev/null ark4isdone
  2338. MISSING=""
  2339. 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 ; do
  2340.     if test ! -f ark${I}isdone ; then
  2341.     MISSING="${MISSING} ${I}"
  2342.     fi
  2343. done
  2344. if test "${MISSING}" = "" ; then
  2345.     echo You have unpacked all 31 archives.
  2346.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2347. else
  2348.     echo You still need to unpack the following archives:
  2349.     echo "        " ${MISSING}
  2350. fi
  2351. ##  End of shell archive.
  2352. exit 0
  2353.