PageRenderTime 70ms CodeModel.GetById 33ms RepoModel.GetById 0ms app.codeStats 0ms

/src/cmd1.c

https://github.com/NickMcConnell/Beleriand
C | 1061 lines | 577 code | 210 blank | 274 comment | 216 complexity | e3b75cee16b53904b56fcfc0948c1f74 MD5 | raw file
  1. /** \file cmd1.c
  2. \brief Commands, part 1
  3. * Searching, pickup, effects of traps, move one square (including special
  4. * terrain effects), and the running algorithm.
  5. *
  6. * Tim Baker's easy patch installed.
  7. *
  8. * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
  9. *
  10. * This work is free software; you can redistribute it and/or modify it
  11. * under the terms of either:
  12. *
  13. * a) the GNU General Public License as published by the Free Software
  14. * Foundation, version 2, or
  15. *
  16. * b) the "Angband licence":
  17. * This software may be copied and distributed for educational, research,
  18. * and not for profit purposes provided that this copyright and statement
  19. * are included in all such copies. Other copyrights may also apply.
  20. */
  21. #include "angband.h"
  22. #include "cave.h"
  23. #include "cmds.h"
  24. #include "generate.h"
  25. #include "history.h"
  26. #include "monster.h"
  27. #include "tvalsval.h"
  28. #include "object.h"
  29. #include "spells.h"
  30. #include "squelch.h"
  31. #include "trap.h"
  32. /**
  33. * Search for hidden things
  34. */
  35. bool search(bool verbose)
  36. {
  37. int py = p_ptr->py;
  38. int px = p_ptr->px;
  39. int y, x, chance;
  40. bool found = FALSE;
  41. object_type *o_ptr;
  42. /* Start with base search ability */
  43. chance = p_ptr->state.skills[SKILL_SEARCH];
  44. /* Penalize various conditions */
  45. if (p_ptr->timed[TMD_BLIND] || no_light())
  46. chance = chance / 10;
  47. if (p_ptr->timed[TMD_CONFUSED] || p_ptr->timed[TMD_IMAGE])
  48. chance = chance / 10;
  49. /* Prevent fruitless searches */
  50. if (chance <= 0) {
  51. if (verbose) {
  52. msg("You can't make out your surroundings well enough to search.");
  53. /* Cancel repeat */
  54. disturb(0, 0);
  55. }
  56. return FALSE;
  57. }
  58. /* Search the nearby grids, which are always in bounds */
  59. for (y = (py - 1); y <= (py + 1); y++) {
  60. for (x = (px - 1); x <= (px + 1); x++) {
  61. /* Sometimes, notice things */
  62. if (randint0(100) < chance) {
  63. /* Invisible trap */
  64. if (cave_invisible_trap(y, x)) {
  65. found = TRUE;
  66. /* Reveal one or more traps, display a message */
  67. if (reveal_trap(y, x, chance, TRUE)) {
  68. /* Disturb */
  69. disturb(0, 0);
  70. }
  71. }
  72. /* Secret door */
  73. if (cave_feat[y][x] == FEAT_SECRET) {
  74. found = TRUE;
  75. /* Message */
  76. msg("You have found a secret door.");
  77. /* Pick a door */
  78. place_closed_door(y, x);
  79. /* Disturb */
  80. disturb(0, 0);
  81. }
  82. /* Scan all objects in the grid */
  83. for (o_ptr = get_first_object(y, x); o_ptr;
  84. o_ptr = get_next_object(o_ptr)) {
  85. /* Skip non-chests */
  86. if (o_ptr->tval != TV_CHEST)
  87. continue;
  88. /* Skip disarmed chests */
  89. if (o_ptr->pval <= 0)
  90. continue;
  91. /* Skip non-trapped chests */
  92. if (!chest_traps[o_ptr->pval])
  93. continue;
  94. /* Identify once */
  95. if (!object_known_p(o_ptr)) {
  96. found = TRUE;
  97. /* Message */
  98. msg("You have discovered a trap on the chest!");
  99. /* Know the trap */
  100. object_known(o_ptr);
  101. /* Notice it */
  102. disturb(0, 0);
  103. }
  104. }
  105. }
  106. }
  107. }
  108. if (verbose && !found) {
  109. if (chance >= 100)
  110. msg("There are no secrets here.");
  111. else
  112. msg("You found nothing.");
  113. }
  114. return TRUE;
  115. }
  116. /*** Pickup ***/
  117. /*
  118. * Pickup all gold at the player's current location.
  119. */
  120. static void py_pickup_gold(void)
  121. {
  122. int py = p_ptr->py;
  123. int px = p_ptr->px;
  124. s32b total_gold = 0L;
  125. byte *treasure;
  126. s16b this_o_idx, next_o_idx = 0;
  127. object_type *o_ptr;
  128. int sound_msg;
  129. bool verbal = FALSE;
  130. /* Allocate an array of ordinary gold objects */
  131. treasure = C_ZNEW(SV_GOLD_MAX, byte);
  132. /* Pick up all the ordinary gold objects */
  133. for (this_o_idx = cave_o_idx[py][px]; this_o_idx;
  134. this_o_idx = next_o_idx) {
  135. /* Get the object */
  136. o_ptr = &o_list[this_o_idx];
  137. /* Get the next object */
  138. next_o_idx = o_ptr->next_o_idx;
  139. /* Ignore if not legal treasure */
  140. if ((o_ptr->tval != TV_GOLD) || (o_ptr->sval > SV_GOLD_MAX))
  141. continue;
  142. /* Note that we have this kind of treasure */
  143. treasure[o_ptr->sval - 1]++;
  144. /* Remember whether feedback message is in order */
  145. if (!squelch_item_ok(o_ptr))
  146. verbal = TRUE;
  147. /* Increment total value */
  148. total_gold += (s32b) o_ptr->pval;
  149. /* Delete the gold */
  150. delete_object_idx(this_o_idx);
  151. }
  152. /* Pick up the gold, if present */
  153. if (total_gold) {
  154. char buf[1024];
  155. char tmp[80];
  156. int i, count, total, k_idx;
  157. /* Build a message */
  158. (void) strnfmt(buf, sizeof(buf),
  159. "You have found %ld gold pieces worth of ",
  160. (long) total_gold);
  161. /* Count the types of treasure present */
  162. for (total = 0, i = 0; i < SV_GOLD_MAX; i++) {
  163. if (treasure[i])
  164. total++;
  165. }
  166. /* List the treasure types */
  167. for (count = 0, i = 0; i < SV_GOLD_MAX; i++) {
  168. /* Skip if no treasure of this type */
  169. if (!treasure[i])
  170. continue;
  171. /* Get this object index */
  172. k_idx = lookup_kind(TV_GOLD, i + 1);
  173. /* Skip past errors XXX */
  174. if (k_idx <= 0)
  175. continue;
  176. /* Get the object name */
  177. object_kind_name(tmp, sizeof tmp, k_idx, TRUE);
  178. /* Build up the pickup string */
  179. my_strcat(buf, tmp, sizeof(buf));
  180. /* Added another kind of treasure */
  181. count++;
  182. /* Add a comma if necessary */
  183. if ((total > 2) && (count < total))
  184. my_strcat(buf, ",", sizeof(buf));
  185. /* Add an "and" if necessary */
  186. if ((total >= 2) && (count == total - 1))
  187. my_strcat(buf, " and", sizeof(buf));
  188. /* Add a space or period if necessary */
  189. if (count < total)
  190. my_strcat(buf, " ", sizeof(buf));
  191. else
  192. my_strcat(buf, ".", sizeof(buf));
  193. }
  194. /* Determine which sound to play */
  195. if (total_gold < 200)
  196. sound_msg = MSG_MONEY1;
  197. else if (total_gold < 600)
  198. sound_msg = MSG_MONEY2;
  199. else
  200. sound_msg = MSG_MONEY3;
  201. /* Display the message */
  202. if (verbal)
  203. msgt(sound_msg, buf);
  204. /* Add gold to purse */
  205. p_ptr->au += total_gold;
  206. /* Redraw gold */
  207. p_ptr->redraw |= (PR_GOLD);
  208. }
  209. /* Free the gold array */
  210. FREE(treasure);
  211. }
  212. /**
  213. * Return TRUE if the given object can be automatically picked up
  214. */
  215. static bool auto_pickup_okay(object_type * o_ptr)
  216. {
  217. if (!inven_carry_okay(o_ptr))
  218. return FALSE;
  219. if (OPT(pickup_always) || check_for_inscrip(o_ptr, "=g"))
  220. return TRUE;
  221. if (check_for_inscrip(o_ptr, "@f") || check_for_inscrip(o_ptr, "@v"))
  222. return TRUE;
  223. if (OPT(pickup_inven) && inven_stack_okay(o_ptr))
  224. return TRUE;
  225. return FALSE;
  226. }
  227. /**
  228. * Carry an object and delete it.
  229. */
  230. extern void py_pickup_aux(int o_idx, bool domsg)
  231. {
  232. int slot, quiver_slot = 0;
  233. char o_name[120];
  234. object_type *o_ptr = &o_list[o_idx];
  235. object_type *i_ptr = &p_ptr->inventory[INVEN_LIGHT];
  236. bitflag f[OF_SIZE], obvious_mask[OF_SIZE];
  237. flags_init(obvious_mask, OF_SIZE, OF_OBVIOUS_MASK, FLAG_END);
  238. of_copy(f, o_ptr->flags_obj);
  239. /* Carry the object */
  240. slot = inven_carry(p_ptr, o_ptr);
  241. /* Handle errors (paranoia) */
  242. if (slot < 0)
  243. return;
  244. /* If we have picked up ammo which matches something in the quiver, note
  245. * that it so that we can wield it later (and suppress pick up message) */
  246. if (obj_is_quiver_obj(o_ptr)) {
  247. int i;
  248. for (i = QUIVER_START; i < QUIVER_END; i++) {
  249. if (!p_ptr->inventory[i].k_idx)
  250. continue;
  251. if (!object_similar(&p_ptr->inventory[i], o_ptr,
  252. OSTACK_QUIVER))
  253. continue;
  254. quiver_slot = i;
  255. break;
  256. }
  257. }
  258. /* Get the object again */
  259. o_ptr = &p_ptr->inventory[slot];
  260. /* Set squelch status */
  261. p_ptr->notice |= PN_SQUELCH;
  262. /* Stone of Lore gives id on pickup */
  263. if (!object_known_p(o_ptr)) {
  264. if (i_ptr->sval == SV_STONE_LORE)
  265. identify_object(o_ptr);
  266. /* Otherwise pseudo-ID */
  267. else {
  268. bool heavy = FALSE;
  269. int feel;
  270. /* Heavy sensing */
  271. heavy = (player_has(PF_PSEUDO_ID_HEAVY));
  272. /* Type of feeling */
  273. feel =
  274. (heavy ? value_check_aux1(o_ptr) :
  275. value_check_aux2(o_ptr));
  276. /* We have "felt" it */
  277. o_ptr->ident |= (IDENT_SENSE);
  278. /* Inscribe it textually */
  279. o_ptr->feel = feel;
  280. /* Set squelch flag as appropriate */
  281. p_ptr->notice |= PN_SQUELCH;
  282. }
  283. }
  284. /* Log artifacts if found */
  285. if (artifact_p(o_ptr))
  286. history_add_artifact(o_ptr->name1, object_is_known(o_ptr), TRUE);
  287. /* Notice dice and other obvious stuff */
  288. notice_other(IF_DD_DS, slot + 1);
  289. (void) of_inter(f, obvious_mask);
  290. of_union(o_ptr->id_obj, f);
  291. /* Average things are average */
  292. if ((o_ptr->feel == FEEL_AVERAGE)
  293. && (is_weapon(o_ptr) || is_armour(o_ptr))) {
  294. notice_other(IF_AC, slot + 1);
  295. notice_other(IF_TO_A, slot + 1);
  296. notice_other(IF_TO_H, slot + 1);
  297. notice_other(IF_TO_D, slot + 1);
  298. }
  299. /* Recalculate the bonuses */
  300. p_ptr->update |= (PU_BONUS);
  301. /* Optionally, display a message */
  302. if (domsg && !quiver_slot) {
  303. /* Describe the object */
  304. object_desc(o_name, sizeof(o_name), o_ptr,
  305. ODESC_PREFIX | ODESC_FULL);
  306. /* Message */
  307. msg("You have %s (%c).", o_name, index_to_label(slot));
  308. }
  309. /* Delete the object */
  310. delete_object_idx(o_idx);
  311. /* If we have a quiver slot that this item matches, use it */
  312. if (quiver_slot)
  313. wield_item(o_ptr, slot, quiver_slot);
  314. }
  315. /**
  316. * Pick up objects and treasure on the floor, now also used for telekinesis.
  317. *
  318. * Called with pickup:
  319. * 0 to grab gold and describe non-gold objects.
  320. * 1 to pick up objects either with or without displaying a menu.
  321. * 2 to pick up objects, forcing a menu for multiple objects.
  322. * 3 to pick up objects, forcing a menu for any number of objects.
  323. *
  324. * Scan the list of objects in that floor grid. Pick up gold automatically.
  325. * Pick up objects automatically until pile or backpack space is full if
  326. * auto-pickup option is on, carry_query_floor option is not, and menus are
  327. * not forced (which the "get" command does). Otherwise, store objects on
  328. * floor in an array, and tally both how many there are and can be picked up.
  329. *
  330. * If the player is not picking up objects, describe a single object or
  331. * indicate the presence of a floor stack. If player is picking up objects,
  332. * name a single object, or indicate a stack of objects, that cannot go in
  333. * the backpack.
  334. *
  335. * Pick up a single object without menus, unless menus for single items are
  336. * forced. Confirm pickup if that option is on.
  337. *
  338. * Pick up multiple objects (unless using autopickup, no confirm) using Tim
  339. * Baker's menu system. Recursively call this function (forcing menus for any
  340. * number of objects) until objects are gone, backpack is full, or player is
  341. * satisfied.
  342. *
  343. * Keep track of number of objects picked up (to calculate time spent).
  344. */
  345. byte py_pickup(int pickup, int y, int x)
  346. {
  347. s16b this_o_idx, next_o_idx = 0;
  348. char o_name[120];
  349. object_type *o_ptr;
  350. /* Objects picked up. Used to determine time cost of command. */
  351. byte objs_picked_up = 0;
  352. size_t floor_num = 0;
  353. int floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0;
  354. int can_pickup = 0;
  355. bool call_function_again = FALSE;
  356. bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_light()));
  357. bool domsg = TRUE;
  358. bool telekinesis = ((y != p_ptr->py) || (x != p_ptr->px));
  359. /* Always pickup gold, effortlessly */
  360. if (!telekinesis)
  361. py_pickup_gold();
  362. /* Nothing to pick up -- return */
  363. if (!cave_o_idx[y][x])
  364. return (objs_picked_up);
  365. /* Scan the pile of objects */
  366. for (this_o_idx = cave_o_idx[y][x]; this_o_idx;
  367. this_o_idx = next_o_idx) {
  368. /* Access the object */
  369. o_ptr = &o_list[this_o_idx];
  370. /* Access the next object */
  371. next_o_idx = o_ptr->next_o_idx;
  372. /* Ordinary pickup */
  373. if (!telekinesis) {
  374. /* Ignore all hidden objects and non-objects */
  375. if (squelch_hide_item(o_ptr) || !o_ptr->k_idx)
  376. continue;
  377. /* Hack -- disturb */
  378. disturb(0, 0);
  379. /* Automatically pick up some items */
  380. if (auto_pickup_okay(o_ptr)) {
  381. /* Pick up the object */
  382. py_pickup_aux(this_o_idx, TRUE);
  383. objs_picked_up++;
  384. /* Check the next object */
  385. continue;
  386. }
  387. }
  388. /* Tally objects and store them in an array. */
  389. /* Remember this object index */
  390. floor_list[floor_num] = this_o_idx;
  391. /* Count non-gold objects that remain on the floor. */
  392. floor_num++;
  393. /* Tally objects that can be picked up. */
  394. if (inven_carry_okay(o_ptr))
  395. can_pickup++;
  396. }
  397. /* There are no non-gold objects */
  398. if (!floor_num)
  399. return (objs_picked_up);
  400. /* Get hold of the last floor index */
  401. floor_o_idx = floor_list[floor_num - 1];
  402. /* Mention the objects if player is not picking them up. */
  403. if (pickup == 0 || !(can_pickup || telekinesis)) {
  404. const char *p = "see";
  405. /* One object */
  406. if (floor_num == 1) {
  407. if (!can_pickup)
  408. p = "have no room for";
  409. else if (blind)
  410. p = "feel";
  411. /* Get the object */
  412. o_ptr = &o_list[floor_o_idx];
  413. /* Describe the object. Less detail if blind. */
  414. if (blind)
  415. object_desc(o_name, sizeof(o_name), o_ptr,
  416. ODESC_PREFIX | ODESC_BASE);
  417. else
  418. object_desc(o_name, sizeof(o_name), o_ptr,
  419. ODESC_PREFIX | ODESC_FULL);
  420. /* Message */
  421. message_flush();
  422. msg("You %s %s.", p, o_name);
  423. } else {
  424. /* Optionally, display more information about floor items */
  425. if (OPT(pickup_detail)) {
  426. ui_event e;
  427. if (!can_pickup)
  428. p = "have no room for the following objects";
  429. else if (blind)
  430. p = "feel something on the floor";
  431. /* Scan all marked objects in the grid */
  432. floor_num =
  433. scan_floor(floor_list, N_ELEMENTS(floor_list), y, x,
  434. 0x03);
  435. /* Save screen */
  436. screen_save();
  437. /* Display objects on the floor */
  438. show_floor(floor_list, floor_num, (OLIST_WEIGHT));
  439. /* Display prompt */
  440. prt(format("You %s: ", p), 0, 0);
  441. /* Move cursor back to character, if needed */
  442. if (OPT(highlight_player))
  443. move_cursor_relative(p_ptr->py, p_ptr->px);
  444. /* Wait for it. Use key as next command. */
  445. e = inkey_ex();
  446. Term_event_push(&e);
  447. /* Restore screen */
  448. screen_load();
  449. }
  450. /* Show less detail */
  451. else {
  452. message_flush();
  453. if (!can_pickup)
  454. msg("You have no room for any of the items on the floor.");
  455. else
  456. msg("You %s a pile of %d items.",
  457. (blind ? "feel" : "see"), floor_num);
  458. }
  459. }
  460. /* Done */
  461. return (objs_picked_up);
  462. }
  463. /* We can pick up objects. Menus are not requested (yet). */
  464. if (pickup == 1) {
  465. /* Scan floor (again) */
  466. floor_num =
  467. scan_floor(floor_list, N_ELEMENTS(floor_list), y, x, 0x03);
  468. /* Use a menu interface for multiple objects, or get single objects */
  469. if (floor_num > 1)
  470. pickup = 2;
  471. else
  472. this_o_idx = floor_o_idx;
  473. }
  474. /* Display a list if requested. */
  475. if (pickup == 2) {
  476. const char *q, *s;
  477. int item;
  478. /* Get an object or exit. */
  479. q = "Get which item?";
  480. s = "You see nothing there.";
  481. /* Telekinesis */
  482. if (telekinesis) {
  483. item_tester_hook = inven_carry_okay;
  484. if (!get_item(&item, q, s, CMD_PICKUP, USE_TARGET))
  485. return (objs_picked_up);
  486. this_o_idx = 0 - item;
  487. } else {
  488. /* Restrict the choices */
  489. item_tester_hook = inven_carry_okay;
  490. if (!get_item(&item, q, s, CMD_PICKUP, USE_FLOOR))
  491. return (objs_picked_up);
  492. this_o_idx = 0 - item;
  493. call_function_again = TRUE;
  494. }
  495. /* With a list, we do not need explicit pickup messages */
  496. domsg = FALSE;
  497. }
  498. /* Pick up object, if legal */
  499. if (this_o_idx) {
  500. /* Regular pickup or telekinesis with pack not full */
  501. if (can_pickup) {
  502. /* Pick up the object */
  503. py_pickup_aux(this_o_idx, domsg);
  504. }
  505. /* Telekinesis with pack full */
  506. else {
  507. /* Access the object */
  508. o_ptr = &o_list[this_o_idx];
  509. /* Drop it */
  510. drop_near(o_ptr, -1, p_ptr->py, p_ptr->px, TRUE);
  511. /* Delete the old object */
  512. delete_object_idx(this_o_idx);
  513. }
  514. }
  515. /* Indicate an object picked up. */
  516. objs_picked_up = 1;
  517. /* If requested, call this function recursively. Count objects picked up.
  518. * Force the display of a menu in all cases. */
  519. if (call_function_again)
  520. objs_picked_up += py_pickup(2, y, x);
  521. /* Indicate how many objects have been picked up. */
  522. return (objs_picked_up);
  523. }
  524. /**
  525. * Handle falling off cliffs
  526. */
  527. void fall_off_cliff(int levels)
  528. {
  529. int dam;
  530. msg("You fall into the darkness!");
  531. /* New chunk */
  532. chunk_change(1, 0, 0);
  533. /* Hit the ground... */
  534. if (!tf_has(f_info[cave_feat[p_ptr->py][p_ptr->px]].flags, TF_FALL)) {
  535. if (p_ptr->state.ffall) {
  536. notice_obj(OF_FEATHER, 0);
  537. dam = damroll(2 * levels, 8);
  538. (void) inc_timed(TMD_STUN, damroll(2 * levels, 8), TRUE);
  539. (void) inc_timed(TMD_CUT, damroll(2 * levels, 8), TRUE);
  540. } else {
  541. dam = damroll(4 * levels, 8);
  542. (void) inc_timed(TMD_STUN, damroll(4 * levels, 8), TRUE);
  543. (void) inc_timed(TMD_CUT, damroll(4 * levels, 8), TRUE);
  544. }
  545. take_hit(dam, "falling off a precipice");
  546. }
  547. /* ...or not */
  548. else
  549. fall_off_cliff(levels + 1);
  550. }
  551. /**
  552. * Move player in the given direction, with the given "pickup" flag.
  553. *
  554. * This routine should only be called when energy has been expended.
  555. *
  556. * Note that this routine handles monsters in the destination grid,
  557. * and also handles attempting to move into walls/doors/etc.
  558. */
  559. void move_player(int dir)
  560. {
  561. int py = p_ptr->py;
  562. int px = p_ptr->px;
  563. byte str_escape, dex_escape;
  564. /* Permit the player to move? */
  565. bool can_move = FALSE;
  566. /* Player is jumping off a cliff */
  567. bool falling = FALSE;
  568. /* Player hits a trap (always unless flying) */
  569. bool trapped = TRUE;
  570. int temp;
  571. int y, x;
  572. feature_type *f_ptr;
  573. /* Find the result of moving */
  574. y = py + ddy[dir];
  575. x = px + ddx[dir];
  576. f_ptr = &f_info[cave_feat[y][x]];
  577. /* Hack -- attack monsters */
  578. if (cave_m_idx[y][x] > 0) {
  579. /* Attack */
  580. if (py_attack(y, x, TRUE))
  581. return;
  582. }
  583. /* It takes some dexterity, or failing that strength, to get out of pits */
  584. if (cave_feat[py][px] == FEAT_PIT) {
  585. str_escape = adj_dex_dis[p_ptr->state.stat_ind[A_STR]];
  586. dex_escape = adj_dex_dis[p_ptr->state.stat_ind[A_DEX]];
  587. /* First attempt to leap out of the pit, */
  588. if ((dex_escape + 1) * 2 < randint1(16)) {
  589. /* then attempt to climb out of the pit. */
  590. if (str_escape + 3 < randint1(16)) {
  591. /* Failure costs a turn. */
  592. msg("You remain stuck in the pit.");
  593. return;
  594. } else
  595. msg("You clamber out of the pit.");
  596. } else
  597. msg("You leap out of the pit.");
  598. }
  599. /* Option to disarm a visible trap. -TNB- */
  600. /* Hack - Rogues can walk over their own trap - BR */
  601. if (OPT(easy_alter) && cave_visible_trap(y, x)
  602. && cave_player_trap(y, x)) {
  603. bool more = FALSE;
  604. /* Auto-repeat if not already repeating */
  605. if (cmd_get_nrepeats() == 0)
  606. cmd_set_repeat(99);
  607. more = do_cmd_disarm_aux(y, x);
  608. /* Cancel repeat unless we may continue */
  609. if (!more)
  610. disturb(0, 0);
  611. return;
  612. }
  613. /* Some terrain is impassable for the player, such as stone walls. */
  614. else if (!tf_has(f_ptr->flags, TF_PASSABLE)) {
  615. /* Disturb the player */
  616. disturb(0, 0);
  617. /* Notice unknown obstacles */
  618. if (!cave_has(cave_info[y][x], CAVE_MARK)) {
  619. /* Closed door */
  620. if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
  621. msgt(MSG_HITWALL, "You feel a door blocking your way.");
  622. cave_on(cave_info[y][x], CAVE_MARK);
  623. light_spot(y, x);
  624. }
  625. /* Wall (or secret door) */
  626. else {
  627. msgt(MSG_HITWALL, "You feel a wall blocking your way.");
  628. cave_on(cave_info[y][x], CAVE_MARK);
  629. light_spot(y, x);
  630. }
  631. }
  632. /* Mention known obstacles */
  633. else {
  634. /* Closed door */
  635. if (tf_has(f_ptr->flags, TF_DOOR_CLOSED)) {
  636. /* Option to automatically open doors. -TNB- */
  637. if (OPT(easy_alter)) {
  638. bool more = FALSE;
  639. /* Auto-repeat if not already repeating */
  640. if (cmd_get_nrepeats() == 0)
  641. cmd_set_repeat(99);
  642. /* Open the door */
  643. more = do_cmd_open_aux(y, x);
  644. /* Cancel repeat unless we may continue */
  645. if (!more)
  646. disturb(0, 0);
  647. return;
  648. }
  649. /* Otherwise, a message. */
  650. msgt(MSG_HITWALL, "There is a door blocking your way.");
  651. }
  652. /* Wall (or secret door) */
  653. else {
  654. msgt(MSG_HITWALL, "There is a wall blocking your way.");
  655. }
  656. }
  657. /* Sound */
  658. sound(MSG_HITWALL);
  659. }
  660. /* Normal movement */
  661. else {
  662. /* Assume terrain can be traversed normally. */
  663. can_move = TRUE;
  664. /*** Handle traversable terrain. ***/
  665. if (tf_has(f_ptr->flags, TF_ROCK)) {
  666. /* Dwarves move easily through rubble */
  667. if (player_has(PF_DWARVEN))
  668. can_move = TRUE;
  669. /* Bats, dragons can fly */
  670. else if ((p_ptr->schange == SHAPE_BAT)
  671. || (p_ptr->schange == SHAPE_WYRM))
  672. can_move = TRUE;
  673. /* Require more energy */
  674. else {
  675. can_move = TRUE;
  676. p_ptr->energy_use += 100;
  677. }
  678. }
  679. if (tf_has(f_ptr->flags, TF_TREE)) {
  680. /* Druids, rangers, elves and ents (SJGU) slip easily under
  681. * trees */
  682. if (((player_has(PF_WOODSMAN)) || (player_has(PF_ELVEN)))
  683. || (player_has(PF_WOODEN)))
  684. can_move = TRUE;
  685. /* Bats, dragons can fly */
  686. else if ((p_ptr->schange == SHAPE_BAT)
  687. || (p_ptr->schange == SHAPE_WYRM))
  688. can_move = TRUE;
  689. /* Require more energy */
  690. else {
  691. can_move = TRUE;
  692. p_ptr->energy_use += 100;
  693. }
  694. }
  695. /* Water now slows rather than stopping -NRM- */
  696. if (tf_has(f_ptr->flags, TF_WATERY)) {
  697. /* Stop any run. */
  698. disturb(0, 0);
  699. can_move = TRUE;
  700. /* Speed will need updating */
  701. p_ptr->update |= PU_BONUS;
  702. }
  703. if (tf_has(f_ptr->flags, TF_FIERY)) {
  704. /* Assume player will continue. */
  705. temp = TRUE;
  706. /* Smart enough to stop running. */
  707. if (p_ptr->running) {
  708. if (!get_check("Lava blocks your path. Step into it? ")) {
  709. temp = FALSE;
  710. p_ptr->running = 0;
  711. }
  712. }
  713. /* Smart enough to sense trouble. */
  714. else if ((!p_resist_pos(P_RES_FIRE))
  715. || (!p_resist_strong(P_RES_FIRE)
  716. && (p_ptr->chp <= 100))
  717. || (!p_immune(P_RES_FIRE) && (p_ptr->chp <= 30))) {
  718. if (!get_check
  719. ("The heat of the lava scalds you! Really enter? ")) {
  720. temp = FALSE;
  721. }
  722. }
  723. /* Enter if OK or confirmed. */
  724. if (temp) {
  725. /* Can always cross. */
  726. can_move = TRUE;
  727. /* Feather fall makes one lightfooted. */
  728. if (p_ptr->state.ffall) {
  729. notice_obj(OF_FEATHER, 0);
  730. temp = 49 + randint1(51);
  731. } else
  732. temp = 124 + randint1(126);
  733. /* Will take serious fire damage. */
  734. fire_dam(temp, "burnt to a cinder in molten lava");
  735. }
  736. else
  737. /* Player refuse to go. */
  738. can_move = FALSE;
  739. }
  740. if (tf_has(f_ptr->flags, TF_FALL)) {
  741. /* Bats, dragons can fly */
  742. if (!(p_ptr->schange == SHAPE_BAT) &&
  743. !(p_ptr->schange == SHAPE_WYRM)) {
  744. /* Assume player will continue. */
  745. temp = TRUE;
  746. /* Smart enough to stop running. */
  747. if (p_ptr->running) {
  748. if (!get_check
  749. ("You have come to a cliff. Step off it? ")) {
  750. can_move = FALSE;
  751. temp = FALSE;
  752. p_ptr->running = 0;
  753. }
  754. }
  755. /* Smart enough to sense trouble. */
  756. else if (!p_ptr->timed[TMD_BLIND]) {
  757. if (!get_check("It's a cliff! Really step off it? ")) {
  758. can_move = FALSE;
  759. temp = FALSE;
  760. }
  761. }
  762. /* Step off if confirmed. */
  763. if (temp) {
  764. /* Will take serious damage. */
  765. falling = TRUE;
  766. }
  767. }
  768. }
  769. }
  770. /* If the player can move, handle various things. */
  771. if (can_move) {
  772. /* Move player */
  773. monster_swap(py, px, y, x);
  774. /* Update speed if stepping out of water */
  775. if (tf_has(f_info[cave_feat[py][px]].flags, TF_WATERY))
  776. p_ptr->update |= PU_BONUS;
  777. /* Update stealth for Unlight */
  778. if (player_has(PF_UNLIGHT))
  779. p_ptr->update |= PU_BONUS;
  780. /* Update speed for elven woodspersons */
  781. if (player_has(PF_WOODSMAN) && player_has(PF_ELVEN))
  782. p_ptr->update |= PU_BONUS;
  783. /* Superstealth for ents in trees SJGU */
  784. if ((player_has(PF_WOODEN)) &&
  785. (tf_has
  786. (f_info[cave_feat[p_ptr->py][p_ptr->px]].flags, TF_TREE))) {
  787. if (!(tf_has(f_info[cave_feat[py][px]].flags, TF_TREE))
  788. || !(p_ptr->timed[TMD_SSTEALTH])) {
  789. (void) inc_timed(TMD_SSTEALTH, 1, FALSE);
  790. p_ptr->update |= (PU_BONUS);
  791. }
  792. } else if ((player_has(PF_WOODEN))
  793. && (tf_has(f_info[cave_feat[py][px]].flags, TF_TREE))) {
  794. if (p_ptr->timed[TMD_SSTEALTH]) {
  795. (void) dec_timed(TMD_SSTEALTH, 1, FALSE);
  796. p_ptr->update |= (PU_BONUS);
  797. }
  798. }
  799. /* New location */
  800. y = py = p_ptr->py;
  801. x = px = p_ptr->px;
  802. f_ptr = &f_info[cave_feat[y][x]];
  803. /* Fall off a cliff */
  804. if (falling)
  805. fall_off_cliff(0);
  806. /* Spontaneous Searching */
  807. if (p_ptr->state.skills[SKILL_SEARCH_FREQUENCY] > 49) {
  808. (void) search(FALSE);
  809. } else if (0 ==
  810. randint0(50 -
  811. p_ptr->state.skills[SKILL_SEARCH_FREQUENCY])) {
  812. (void) search(FALSE);
  813. }
  814. /* Continuous Searching */
  815. if (p_ptr->searching) {
  816. (void) search(FALSE);
  817. }
  818. /* Handle objects (later) */
  819. p_ptr->notice |= (PN_PICKUP);
  820. /* Flying players have a chance to miss traps */
  821. if ((p_ptr->schange == SHAPE_BAT)
  822. || (p_ptr->schange == SHAPE_WYRM)) {
  823. if (cave_invisible_trap(y, x) && cave_player_trap(y, x)
  824. && (randint0(3) != 0))
  825. trapped = FALSE;
  826. else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
  827. (randint0(10) != 0))
  828. trapped = FALSE;
  829. }
  830. /* Discover invisible traps */
  831. if (cave_invisible_trap(y, x) && trapped) {
  832. /* Disturb */
  833. disturb(0, 0);
  834. /* Hit the trap. */
  835. hit_trap(y, x);
  836. }
  837. /* Set off a visible trap */
  838. else if (cave_visible_trap(y, x) && cave_player_trap(y, x) &&
  839. trapped) {
  840. /* Disturb */
  841. disturb(0, 0);
  842. /* Hit the trap. */
  843. hit_trap(y, x);
  844. }
  845. /* Walk on a monster trap */
  846. else if (cave_monster_trap(y, x)) {
  847. msg("You inspect your cunning trap.");
  848. }
  849. }
  850. }