PageRenderTime 63ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/spells2.c

https://bitbucket.org/ekolis/jackband
C | 3377 lines | 1744 code | 759 blank | 874 comment | 436 complexity | 329e98fab3875b793ffff07e6197ecdf MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. * File: spells2.c
  3. * Purpose: Various assorted spell effects
  4. *
  5. * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
  6. *
  7. * This work is free software; you can redistribute it and/or modify it
  8. * under the terms of either:
  9. *
  10. * a) the GNU General Public License as published by the Free Software
  11. * Foundation, version 2, or
  12. *
  13. * b) the "Angband licence":
  14. * This software may be copied and distributed for educational, research,
  15. * and not for profit purposes provided that this copyright and statement
  16. * are included in all such copies. Other copyrights may also apply.
  17. */
  18. #include "angband.h"
  19. #include "object/tvalsval.h"
  20. /*
  21. * Increase players hit points, notice effects
  22. */
  23. bool hp_player(int num)
  24. {
  25. /* Healing needed */
  26. if (p_ptr->chp < p_get_mhp())
  27. {
  28. /* Gain hitpoints */
  29. p_ptr->chp += num;
  30. /* Enforce maximum */
  31. if (p_ptr->chp >= p_get_mhp())
  32. {
  33. p_ptr->chp = p_get_mhp();
  34. p_ptr->chp_frac = 0;
  35. }
  36. /* Redraw */
  37. p_ptr->redraw |= (PR_HP);
  38. /* Print a nice message */
  39. if (num < 5)
  40. msg_print("You feel a little better.");
  41. else if (num < 15)
  42. msg_print("You feel better.");
  43. else if (num < 35)
  44. msg_print("You feel much better.");
  45. else
  46. msg_print("You feel very good.");
  47. /* Notice */
  48. return (TRUE);
  49. }
  50. /* Ignore */
  51. return (FALSE);
  52. }
  53. /*
  54. * Heal the player by a given percentage of his wounds, or a minimum
  55. * amount, whichever is larger.
  56. *
  57. * Copied wholesale from EyAngband.
  58. */
  59. bool heal_player(int perc, int min)
  60. {
  61. int i;
  62. /* Paranoia */
  63. if ((perc <= 0) && (min <= 0)) return (FALSE);
  64. /* No healing needed */
  65. if (p_ptr->chp >= p_get_mhp()) return (FALSE);
  66. /* Figure healing level */
  67. i = ((p_get_mhp() - p_ptr->chp) * perc) / 100;
  68. /* Enforce minimums */
  69. if (i < min) i = min;
  70. /* Actual healing */
  71. return hp_player(i);
  72. }
  73. /*
  74. * Leave a "glyph of warding" which prevents monster movement
  75. */
  76. void warding_glyph(void)
  77. {
  78. int py = p_ptr->py;
  79. int px = p_ptr->px;
  80. if (cave_feat[py][px] != FEAT_FLOOR)
  81. {
  82. msg_print("There is no clear floor on which to cast the spell.");
  83. return;
  84. }
  85. /* Create a glyph */
  86. cave_set_feat(py, px, FEAT_GLYPH);
  87. }
  88. /*
  89. * Array of stat "descriptions"
  90. */
  91. static cptr desc_stat_pos[] =
  92. {
  93. "strong",
  94. "smart",
  95. "wise",
  96. "dextrous",
  97. "healthy",
  98. "cute"
  99. };
  100. /*
  101. * Array of stat "descriptions"
  102. */
  103. static cptr desc_stat_neg[] =
  104. {
  105. "weak",
  106. "stupid",
  107. "naive",
  108. "clumsy",
  109. "sickly",
  110. "ugly"
  111. };
  112. /*
  113. * Lose a "point"
  114. */
  115. bool do_dec_stat(int stat, bool perma)
  116. {
  117. bool sust = FALSE;
  118. /* Get the "sustain" */
  119. switch (stat)
  120. {
  121. case A_STR:
  122. if (p_ptr->state.sustain_str) sust = TRUE;
  123. wieldeds_notice_flag(OF_SUST_STR);
  124. break;
  125. case A_INT:
  126. if (p_ptr->state.sustain_int) sust = TRUE;
  127. wieldeds_notice_flag(OF_SUST_INT);
  128. break;
  129. case A_WIS:
  130. if (p_ptr->state.sustain_wis) sust = TRUE;
  131. wieldeds_notice_flag(OF_SUST_WIS);
  132. break;
  133. case A_DEX:
  134. if (p_ptr->state.sustain_dex) sust = TRUE;
  135. wieldeds_notice_flag(OF_SUST_DEX);
  136. break;
  137. case A_CON:
  138. if (p_ptr->state.sustain_con) sust = TRUE;
  139. wieldeds_notice_flag(OF_SUST_CON);
  140. break;
  141. case A_CHR:
  142. if (p_ptr->state.sustain_chr) sust = TRUE;
  143. wieldeds_notice_flag(OF_SUST_CHR);
  144. break;
  145. }
  146. /* Sustain */
  147. if (sust && !perma)
  148. {
  149. /* Message */
  150. msg_format("You feel very %s for a moment, but the feeling passes.",
  151. desc_stat_neg[stat]);
  152. /* Notice effect */
  153. return (TRUE);
  154. }
  155. /* Attempt to reduce the stat */
  156. if (dec_stat(stat, perma))
  157. {
  158. /* Message */
  159. message_format(MSG_DRAIN_STAT, stat, "You feel very %s.", desc_stat_neg[stat]);
  160. /* Notice effect */
  161. return (TRUE);
  162. }
  163. /* Nothing obvious */
  164. return (FALSE);
  165. }
  166. /*
  167. * Restore lost "points" in a stat
  168. */
  169. bool do_res_stat(int stat)
  170. {
  171. /* Attempt to increase */
  172. if (res_stat(stat))
  173. {
  174. /* Message */
  175. msg_format("You feel less %s.", desc_stat_neg[stat]);
  176. /* Notice */
  177. return (TRUE);
  178. }
  179. /* Nothing obvious */
  180. return (FALSE);
  181. }
  182. /*
  183. * Gain a "point" in a stat
  184. */
  185. bool do_inc_stat(int stat)
  186. {
  187. bool res;
  188. /* Restore strength */
  189. res = res_stat(stat);
  190. /* Attempt to increase */
  191. if (inc_stat(stat))
  192. {
  193. /* Message */
  194. msg_format("You feel very %s!", desc_stat_pos[stat]);
  195. /* Notice */
  196. return (TRUE);
  197. }
  198. /* Restoration worked */
  199. if (res)
  200. {
  201. /* Message */
  202. msg_format("You feel less %s.", desc_stat_neg[stat]);
  203. /* Notice */
  204. return (TRUE);
  205. }
  206. /* Nothing obvious */
  207. return (FALSE);
  208. }
  209. /*
  210. * Identify everything being carried.
  211. * Done by a potion of "self knowledge".
  212. */
  213. void identify_pack(void)
  214. {
  215. int i;
  216. /* Simply identify and know every item */
  217. for (i = 0; i < ALL_INVEN_TOTAL; i++)
  218. {
  219. object_type *o_ptr = &inventory[i];
  220. /* Skip non-objects */
  221. if (!o_ptr->k_idx) continue;
  222. /* Aware and Known */
  223. if (object_is_known(o_ptr)) continue;
  224. /* Identify it */
  225. do_ident_item(i, o_ptr);
  226. /* repeat with same slot */
  227. i--;
  228. }
  229. }
  230. /*
  231. * Used by the "enchant" function (chance of failure)
  232. */
  233. static const int enchant_table[16] =
  234. {
  235. 0, 10, 50, 100, 200,
  236. 300, 400, 500, 700, 950,
  237. 990, 992, 995, 997, 999,
  238. 1000
  239. };
  240. /*
  241. * Hack -- Removes curse from an object.
  242. */
  243. static void uncurse_object(object_type *o_ptr)
  244. {
  245. /* Uncurse it */
  246. flags_clear(o_ptr->flags, OF_SIZE, OF_CURSE_MASK, FLAG_END);
  247. }
  248. /*
  249. * Removes curses from items in inventory.
  250. *
  251. * \param heavy removes heavy curses if true
  252. *
  253. * \returns number of items uncursed
  254. */
  255. static int remove_curse_aux(bool heavy)
  256. {
  257. int i, cnt = 0;
  258. /* Attempt to uncurse items being worn */
  259. for (i = INVEN_WIELD; i < ALL_INVEN_TOTAL; i++)
  260. {
  261. object_type *o_ptr = &inventory[i];
  262. if (!o_ptr->k_idx) continue;
  263. if (!cursed_p(o_ptr)) continue;
  264. /* Heavily cursed items need a special spell */
  265. if (of_has(o_ptr->flags, OF_HEAVY_CURSE) && !heavy) continue;
  266. /* Perma-cursed items can never be removed */
  267. if (of_has(o_ptr->flags, OF_PERMA_CURSE)) continue;
  268. /* Uncurse, and update things */
  269. uncurse_object(o_ptr);
  270. p_ptr->update |= (PU_BONUS);
  271. p_ptr->redraw |= (PR_EQUIP);
  272. /* Count the uncursings */
  273. cnt++;
  274. }
  275. /* Return "something uncursed" */
  276. return (cnt);
  277. }
  278. /*
  279. * Remove most curses
  280. */
  281. bool remove_curse(void)
  282. {
  283. return (remove_curse_aux(FALSE));
  284. }
  285. /*
  286. * Remove all curses
  287. */
  288. bool remove_all_curse(void)
  289. {
  290. return (remove_curse_aux(TRUE));
  291. }
  292. /*
  293. * Restores any drained experience
  294. */
  295. bool restore_level(void)
  296. {
  297. int i;
  298. /* Restore experience */
  299. //if (p_curclass.exp < p_curclass.max_exp)
  300. {
  301. /* Message */
  302. msg_print("You feel your life energies returning.");
  303. for (i = 0; i < PY_MAX_CLASSES; i++)
  304. {
  305. /* Restore the experience */
  306. pc_array[i].exp = pc_array[i].max_exp;
  307. }
  308. /* Check the experience */
  309. check_experience();
  310. /* Did something */
  311. return (TRUE);
  312. }
  313. /* No effect */
  314. return (FALSE);
  315. }
  316. /*
  317. * Set word of recall as appropriate
  318. */
  319. void set_recall(void)
  320. {
  321. /* Ironman */
  322. if (OPT(adult_ironman) && !p_ptr->total_winner)
  323. {
  324. msg_print("Nothing happens.");
  325. return;
  326. }
  327. /* Activate recall */
  328. if (!p_ptr->word_recall)
  329. {
  330. /* Reset recall depth */
  331. if ((p_ptr->depth > 0) && (p_ptr->depth != p_ptr->max_depth))
  332. {
  333. /*
  334. * ToDo: Add a new player_type field "recall_depth"
  335. * ToDo: Poll: Always reset recall depth?
  336. */
  337. if (get_check("Reset recall depth? "))
  338. p_ptr->max_depth = p_ptr->depth;
  339. }
  340. p_ptr->word_recall = randint0(20) + 15;
  341. msg_print("The air about you becomes charged...");
  342. }
  343. /* Deactivate recall */
  344. else
  345. {
  346. p_ptr->word_recall = 0;
  347. msg_print("A tension leaves the air around you...");
  348. }
  349. /* Redraw status line */
  350. p_ptr->redraw = PR_STATUS;
  351. handle_stuff();
  352. }
  353. /*** Detection spells ***/
  354. /*
  355. * Useful constants for the area around the player to detect.
  356. * This is instead of using circular detection spells.
  357. */
  358. #define DETECT_DIST_X 40 /* Detect 42 grids to the left & right */
  359. #define DETECT_DIST_Y 22 /* Detect 22 grids to the top & bottom */
  360. /*
  361. * Map an area around the player.
  362. *
  363. * We must never attempt to map the outer dungeon walls, or we
  364. * might induce illegal cave grid references.
  365. */
  366. void map_area(void)
  367. {
  368. int i, x, y;
  369. int x1, x2, y1, y2;
  370. /* Pick an area to map */
  371. y1 = p_ptr->py - DETECT_DIST_Y;
  372. y2 = p_ptr->py + DETECT_DIST_Y;
  373. x1 = p_ptr->px - DETECT_DIST_X;
  374. x2 = p_ptr->px + DETECT_DIST_X;
  375. if (y1 < 0) y1 = 0;
  376. if (x1 < 0) x1 = 0;
  377. /* Scan the dungeon */
  378. for (y = y1; y < y2; y++)
  379. {
  380. for (x = x1; x < x2; x++)
  381. {
  382. /* All non-walls are "checked" */
  383. if (cave_feat[y][x] < FEAT_SECRET)
  384. {
  385. if (!in_bounds_fully(y, x)) continue;
  386. /* Memorize normal features */
  387. if (cave_feat[y][x] > FEAT_INVIS)
  388. {
  389. /* Memorize the object */
  390. cave_info[y][x] |= (CAVE_MARK);
  391. light_spot(y, x);
  392. }
  393. /* Memorize known walls */
  394. for (i = 0; i < 8; i++)
  395. {
  396. int yy = y + ddy_ddd[i];
  397. int xx = x + ddx_ddd[i];
  398. /* Memorize walls (etc) */
  399. if (cave_feat[yy][xx] >= FEAT_SECRET)
  400. {
  401. /* Memorize the walls */
  402. cave_info[yy][xx] |= (CAVE_MARK);
  403. light_spot(yy, xx);
  404. }
  405. }
  406. }
  407. }
  408. }
  409. }
  410. /*
  411. * Detect traps around the player.
  412. */
  413. bool detect_traps(bool aware)
  414. {
  415. int y, x;
  416. int x1, x2, y1, y2;
  417. bool detect = FALSE;
  418. (void)aware;
  419. /* Pick an area to map */
  420. y1 = p_ptr->py - DETECT_DIST_Y;
  421. y2 = p_ptr->py + DETECT_DIST_Y;
  422. x1 = p_ptr->px - DETECT_DIST_X;
  423. x2 = p_ptr->px + DETECT_DIST_X;
  424. if (y1 < 0) y1 = 0;
  425. if (x1 < 0) x1 = 0;
  426. /* Scan the dungeon */
  427. for (y = y1; y < y2; y++)
  428. {
  429. for (x = x1; x < x2; x++)
  430. {
  431. if (!in_bounds_fully(y, x)) continue;
  432. /* Detect invisible traps */
  433. if (cave_feat[y][x] == FEAT_INVIS)
  434. {
  435. /* Pick a trap */
  436. pick_trap(y, x);
  437. }
  438. /* Detect traps */
  439. if ((cave_feat[y][x] >= FEAT_TRAP_HEAD) &&
  440. (cave_feat[y][x] <= FEAT_TRAP_TAIL))
  441. {
  442. /* Hack -- Memorize */
  443. cave_info[y][x] |= (CAVE_MARK);
  444. /* We found something to detect */
  445. detect = TRUE;
  446. }
  447. /* Mark as trap-detected */
  448. cave_info2[y][x] |= (CAVE2_DTRAP);
  449. }
  450. }
  451. /* Rescan the map for the new dtrap edge */
  452. for (y = y1 - 1; y < y2 + 1; y++)
  453. {
  454. for (x = x1 - 1; x < x2 + 1; x++)
  455. {
  456. if (!in_bounds_fully(y, x)) continue;
  457. /* Redraw */
  458. light_spot(y, x);
  459. }
  460. }
  461. /* Describe */
  462. if (detect)
  463. msg_print("You sense the presence of traps!");
  464. /* Trap detection always makes you aware, even if no traps are present */
  465. else
  466. msg_print("You sense no traps.");
  467. /* Mark the redraw flag */
  468. p_ptr->redraw |= (PR_DTRAP);
  469. /* Result */
  470. return (TRUE);
  471. }
  472. /*
  473. * Detect doors and stairs around the player.
  474. */
  475. bool detect_doorstairs(bool aware)
  476. {
  477. int y, x;
  478. int x1, x2, y1, y2;
  479. bool doors = FALSE, stairs = FALSE;
  480. /* Pick an area to map */
  481. y1 = p_ptr->py - DETECT_DIST_Y;
  482. y2 = p_ptr->py + DETECT_DIST_Y;
  483. x1 = p_ptr->px - DETECT_DIST_X;
  484. x2 = p_ptr->px + DETECT_DIST_X;
  485. if (y1 < 0) y1 = 0;
  486. if (x1 < 0) x1 = 0;
  487. /* Scan the dungeon */
  488. for (y = y1; y < y2; y++)
  489. {
  490. for (x = x1; x < x2; x++)
  491. {
  492. if (!in_bounds_fully(y, x)) continue;
  493. /* Detect secret doors */
  494. if (cave_feat[y][x] == FEAT_SECRET)
  495. place_closed_door(y, x);
  496. /* Detect doors */
  497. if (((cave_feat[y][x] >= FEAT_DOOR_HEAD) &&
  498. (cave_feat[y][x] <= FEAT_DOOR_TAIL)) ||
  499. ((cave_feat[y][x] == FEAT_OPEN) ||
  500. (cave_feat[y][x] == FEAT_BROKEN)))
  501. {
  502. /* Hack -- Memorize */
  503. cave_info[y][x] |= (CAVE_MARK);
  504. /* Redraw */
  505. light_spot(y, x);
  506. /* Obvious */
  507. doors = TRUE;
  508. }
  509. /* Detect stairs */
  510. if ((cave_feat[y][x] == FEAT_LESS) ||
  511. (cave_feat[y][x] == FEAT_MORE))
  512. {
  513. /* Hack -- Memorize */
  514. cave_info[y][x] |= (CAVE_MARK);
  515. /* Redraw */
  516. light_spot(y, x);
  517. /* Obvious */
  518. stairs = TRUE;
  519. }
  520. }
  521. }
  522. /* Describe */
  523. if (doors && !stairs) msg_print("You sense the presence of doors!");
  524. else if (!doors && stairs) msg_print("You sense the presence of stairs!");
  525. else if (doors && stairs) msg_print("You sense the presence of doors and stairs!");
  526. else if (aware && !doors && !stairs) msg_print("You sense no doors or stairs.");
  527. /* Result */
  528. return (doors || stairs);
  529. }
  530. /*
  531. * Detect all treasure around the player.
  532. */
  533. bool detect_treasure(bool aware)
  534. {
  535. int i;
  536. int y, x;
  537. int x1, x2, y1, y2;
  538. bool gold_buried = FALSE;
  539. bool objects = FALSE;
  540. /* Pick an area to map */
  541. y1 = p_ptr->py - DETECT_DIST_Y;
  542. y2 = p_ptr->py + DETECT_DIST_Y;
  543. x1 = p_ptr->px - DETECT_DIST_X;
  544. x2 = p_ptr->px + DETECT_DIST_X;
  545. if (y1 < 0) y1 = 0;
  546. if (x1 < 0) x1 = 0;
  547. /* Scan the dungeon */
  548. for (y = y1; y < y2; y++)
  549. {
  550. for (x = x1; x < x2; x++)
  551. {
  552. if (!in_bounds_fully(y, x)) continue;
  553. /* Notice embedded gold */
  554. if ((cave_feat[y][x] == FEAT_MAGMA_H) ||
  555. (cave_feat[y][x] == FEAT_QUARTZ_H))
  556. {
  557. /* Expose the gold */
  558. cave_feat[y][x] += 0x02;
  559. }
  560. /* Magma/Quartz + Known Gold */
  561. if ((cave_feat[y][x] == FEAT_MAGMA_K) ||
  562. (cave_feat[y][x] == FEAT_QUARTZ_K))
  563. {
  564. /* Hack -- Memorize */
  565. cave_info[y][x] |= (CAVE_MARK);
  566. /* Redraw */
  567. light_spot(y, x);
  568. /* Detect */
  569. gold_buried = TRUE;
  570. }
  571. }
  572. }
  573. /* Scan objects */
  574. for (i = 1; i < o_max; i++)
  575. {
  576. object_type *o_ptr = &o_list[i];
  577. /* Skip dead objects */
  578. if (!o_ptr->k_idx) continue;
  579. /* Skip held objects */
  580. if (o_ptr->held_m_idx) continue;
  581. /* Location */
  582. y = o_ptr->iy;
  583. x = o_ptr->ix;
  584. /* Only detect nearby objects */
  585. if (x < x1 || y < y1 || x > x2 || y > y2) continue;
  586. /* Hack -- memorize it */
  587. o_ptr->marked = TRUE;
  588. /* Redraw */
  589. light_spot(y, x);
  590. /* Detect */
  591. if (!squelch_hide_item(o_ptr))
  592. objects = TRUE;
  593. }
  594. if (gold_buried)
  595. msg_print("You sense the presence of buried treasure!");
  596. if (objects)
  597. msg_print("You sense the presence of objects!");
  598. if (aware && !gold_buried && !objects)
  599. msg_print("You sense no treasure or objects.");
  600. return gold_buried || objects;
  601. }
  602. /*
  603. * Quietly detect all buried treasure near the player.
  604. */
  605. bool detect_close_buried_treasure(void)
  606. {
  607. int y, x;
  608. int x1, x2, y1, y2;
  609. bool gold_buried = FALSE;
  610. /* Pick a small area to map */
  611. y1 = p_ptr->py - 3;
  612. y2 = p_ptr->py + 3;
  613. x1 = p_ptr->px - 3;
  614. x2 = p_ptr->px + 3;
  615. if (y1 < 0) y1 = 0;
  616. if (x1 < 0) x1 = 0;
  617. /* Scan the dungeon */
  618. for (y = y1; y < y2; y++)
  619. {
  620. for (x = x1; x < x2; x++)
  621. {
  622. if (!in_bounds_fully(y, x)) continue;
  623. /* Notice embedded gold */
  624. if ((cave_feat[y][x] == FEAT_MAGMA_H) ||
  625. (cave_feat[y][x] == FEAT_QUARTZ_H))
  626. {
  627. /* Expose the gold */
  628. cave_feat[y][x] += 0x02;
  629. }
  630. /* Magma/Quartz + Known Gold */
  631. if ((cave_feat[y][x] == FEAT_MAGMA_K) ||
  632. (cave_feat[y][x] == FEAT_QUARTZ_K))
  633. {
  634. /* Hack -- Memorize */
  635. cave_info[y][x] |= (CAVE_MARK);
  636. /* Redraw */
  637. light_spot(y, x);
  638. /* Detect */
  639. gold_buried = TRUE;
  640. }
  641. }
  642. }
  643. return (gold_buried);
  644. }
  645. /*
  646. * Detect "magic" objects around the player.
  647. *
  648. * This will light up all spaces with "magic" items, including artifacts,
  649. * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
  650. * and "enchanted" items of the "good" variety.
  651. *
  652. * It can probably be argued that this function is now too powerful.
  653. */
  654. bool detect_objects_magic(bool aware)
  655. {
  656. int i, y, x, tv;
  657. int x1, x2, y1, y2;
  658. bool detect = FALSE;
  659. /* Pick an area to map */
  660. y1 = p_ptr->py - DETECT_DIST_Y;
  661. y2 = p_ptr->py + DETECT_DIST_Y;
  662. x1 = p_ptr->px - DETECT_DIST_X;
  663. x2 = p_ptr->px + DETECT_DIST_X;
  664. if (y1 < 0) y1 = 0;
  665. if (x1 < 0) x1 = 0;
  666. /* Scan all objects */
  667. for (i = 1; i < o_max; i++)
  668. {
  669. object_type *o_ptr = &o_list[i];
  670. /* Skip dead objects */
  671. if (!o_ptr->k_idx) continue;
  672. /* Skip held objects */
  673. if (o_ptr->held_m_idx) continue;
  674. /* Location */
  675. y = o_ptr->iy;
  676. x = o_ptr->ix;
  677. /* Only detect nearby objects */
  678. if (x < x1 || y < y1 || x > x2 || y > y2) continue;
  679. /* Examine the tval */
  680. tv = o_ptr->tval;
  681. /* Artifacts, misc magic items, or enchanted wearables */
  682. if (artifact_p(o_ptr) || ego_item_p(o_ptr) ||
  683. (tv == TV_AMULET) || (tv == TV_RING) ||
  684. (tv == TV_STAFF) || (tv == TV_WAND) || (tv == TV_ROD) ||
  685. (tv == TV_SCROLL) || (tv == TV_POTION) ||
  686. (tv == TV_MAGIC_BOOK) || (tv == TV_PRAYER_BOOK) ||
  687. ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0)))
  688. {
  689. /* Memorize the item */
  690. o_ptr->marked = TRUE;
  691. /* Redraw */
  692. light_spot(y, x);
  693. /* Detect */
  694. if (!squelch_hide_item(o_ptr))
  695. detect = TRUE;
  696. }
  697. }
  698. if (detect)
  699. msg_print("You sense the presence of magic objects!");
  700. else if (aware && !detect)
  701. msg_print("You sense no magic objects.");
  702. return detect;
  703. }
  704. /*
  705. * Detect "normal" monsters around the player.
  706. */
  707. bool detect_monsters_normal(bool aware)
  708. {
  709. int i, y, x;
  710. int x1, x2, y1, y2;
  711. bool flag = FALSE;
  712. /* Pick an area to map */
  713. y1 = p_ptr->py - DETECT_DIST_Y;
  714. y2 = p_ptr->py + DETECT_DIST_Y;
  715. x1 = p_ptr->px - DETECT_DIST_X;
  716. x2 = p_ptr->px + DETECT_DIST_X;
  717. if (y1 < 0) y1 = 0;
  718. if (x1 < 0) x1 = 0;
  719. /* Scan monsters */
  720. for (i = 1; i < mon_max; i++)
  721. {
  722. monster_type *m_ptr = &mon_list[i];
  723. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  724. /* Skip dead monsters */
  725. if (!m_ptr->r_idx) continue;
  726. /* Location */
  727. y = m_ptr->fy;
  728. x = m_ptr->fx;
  729. /* Only detect nearby monsters */
  730. if (x < x1 || y < y1 || x > x2 || y > y2) continue;
  731. /* Detect all non-invisible monsters */
  732. if (!rf_has(r_ptr->flags, RF_INVISIBLE))
  733. {
  734. /* Optimize -- Repair flags */
  735. repair_mflag_mark = repair_mflag_show = TRUE;
  736. /* Hack -- Detect the monster */
  737. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  738. /* Update the monster */
  739. update_mon(i, FALSE);
  740. /* Detect */
  741. flag = TRUE;
  742. }
  743. }
  744. if (flag)
  745. msg_print("You sense the presence of monsters!");
  746. else if (aware && !flag)
  747. msg_print("You sense no monsters.");
  748. /* Result */
  749. return flag;
  750. }
  751. /*
  752. * Detect "invisible" monsters around the player.
  753. */
  754. bool detect_monsters_invis(bool aware)
  755. {
  756. int i, y, x;
  757. int x1, x2, y1, y2;
  758. bool flag = FALSE;
  759. /* Pick an area to map */
  760. y1 = p_ptr->py - DETECT_DIST_Y;
  761. y2 = p_ptr->py + DETECT_DIST_Y;
  762. x1 = p_ptr->px - DETECT_DIST_X;
  763. x2 = p_ptr->px + DETECT_DIST_X;
  764. if (y1 < 0) y1 = 0;
  765. if (x1 < 0) x1 = 0;
  766. /* Scan monsters */
  767. for (i = 1; i < mon_max; i++)
  768. {
  769. monster_type *m_ptr = &mon_list[i];
  770. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  771. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  772. /* Skip dead monsters */
  773. if (!m_ptr->r_idx) continue;
  774. /* Location */
  775. y = m_ptr->fy;
  776. x = m_ptr->fx;
  777. /* Only detect nearby objects */
  778. if (x < x1 || y < y1 || x > x2 || y > y2) continue;
  779. /* Detect invisible monsters */
  780. if (rf_has(r_ptr->flags, RF_INVISIBLE))
  781. {
  782. /* Take note that they are invisible */
  783. rf_on(l_ptr->flags, RF_INVISIBLE);
  784. /* Update monster recall window */
  785. if (p_ptr->monster_race_idx == m_ptr->r_idx)
  786. {
  787. /* Redraw stuff */
  788. p_ptr->redraw |= (PR_MONSTER);
  789. }
  790. /* Optimize -- Repair flags */
  791. repair_mflag_mark = repair_mflag_show = TRUE;
  792. /* Hack -- Detect the monster */
  793. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  794. /* Update the monster */
  795. update_mon(i, FALSE);
  796. /* Detect */
  797. flag = TRUE;
  798. }
  799. }
  800. if (flag)
  801. msg_print("You sense the presence of invisible creatures!");
  802. else if (aware && !flag)
  803. msg_print("You sense no invisible creatures.");
  804. return (flag);
  805. }
  806. /*
  807. * Detect "evil" monsters around the player.
  808. */
  809. bool detect_monsters_evil(bool aware)
  810. {
  811. int i, y, x;
  812. int x1, x2, y1, y2;
  813. bool flag = FALSE;
  814. /* Pick an area to map */
  815. y1 = p_ptr->py - DETECT_DIST_Y;
  816. y2 = p_ptr->py + DETECT_DIST_Y;
  817. x1 = p_ptr->px - DETECT_DIST_X;
  818. x2 = p_ptr->px + DETECT_DIST_X;
  819. if (y1 < 0) y1 = 0;
  820. if (x1 < 0) x1 = 0;
  821. /* Scan monsters */
  822. for (i = 1; i < mon_max; i++)
  823. {
  824. monster_type *m_ptr = &mon_list[i];
  825. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  826. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  827. /* Skip dead monsters */
  828. if (!m_ptr->r_idx) continue;
  829. /* Location */
  830. y = m_ptr->fy;
  831. x = m_ptr->fx;
  832. /* Only detect nearby objects */
  833. if (x < x1 || y < y1 || x > x2 || y > y2) continue;
  834. /* Detect evil monsters */
  835. if (rf_has(r_ptr->flags, RF_EVIL))
  836. {
  837. /* Take note that they are evil */
  838. rf_on(l_ptr->flags, RF_EVIL);
  839. /* Update monster recall window */
  840. if (p_ptr->monster_race_idx == m_ptr->r_idx)
  841. {
  842. /* Redraw stuff */
  843. p_ptr->redraw |= (PR_MONSTER);
  844. }
  845. /* Optimize -- Repair flags */
  846. repair_mflag_mark = repair_mflag_show = TRUE;
  847. /* Detect the monster */
  848. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  849. /* Update the monster */
  850. update_mon(i, FALSE);
  851. /* Detect */
  852. flag = TRUE;
  853. }
  854. }
  855. if (flag)
  856. msg_print("You sense the presence of evil creatures!");
  857. else if (aware && !flag)
  858. msg_print("You sense no evil creatures.");
  859. return flag;
  860. }
  861. /*
  862. * Detect everything
  863. */
  864. bool detect_all(bool aware)
  865. {
  866. bool detect = FALSE;
  867. /* Detect everything */
  868. if (detect_traps(aware)) detect = TRUE;
  869. if (detect_doorstairs(aware)) detect = TRUE;
  870. if (detect_treasure(aware)) detect = TRUE;
  871. if (detect_monsters_invis(aware)) detect = TRUE;
  872. if (detect_monsters_normal(aware)) detect = TRUE;
  873. /* Result */
  874. return (detect);
  875. }
  876. /*
  877. * Create stairs at the player location
  878. */
  879. void stair_creation(void)
  880. {
  881. int py = p_ptr->py;
  882. int px = p_ptr->px;
  883. /* XXX XXX XXX */
  884. if (!cave_valid_bold(py, px))
  885. {
  886. msg_print("The object resists the spell.");
  887. return;
  888. }
  889. /* XXX XXX XXX */
  890. delete_object(py, px);
  891. /* Create a staircase */
  892. if (!p_ptr->depth)
  893. {
  894. cave_set_feat(py, px, FEAT_MORE);
  895. }
  896. else if (is_quest(p_ptr->depth) || (p_ptr->depth >= MAX_DEPTH-1))
  897. {
  898. cave_set_feat(py, px, FEAT_LESS);
  899. }
  900. else if (randint0(100) < 50)
  901. {
  902. cave_set_feat(py, px, FEAT_MORE);
  903. }
  904. else
  905. {
  906. cave_set_feat(py, px, FEAT_LESS);
  907. }
  908. }
  909. /*
  910. * Hook to specify "weapon"
  911. */
  912. static bool item_tester_hook_weapon(const object_type *o_ptr)
  913. {
  914. switch (o_ptr->tval)
  915. {
  916. case TV_SWORD:
  917. case TV_HAFTED:
  918. case TV_POLEARM:
  919. case TV_DIGGING:
  920. case TV_BOW:
  921. case TV_BOLT:
  922. case TV_ARROW:
  923. case TV_SHOT:
  924. {
  925. return (TRUE);
  926. }
  927. }
  928. return (FALSE);
  929. }
  930. /*
  931. * Hook to specify "armour"
  932. */
  933. static bool item_tester_hook_armour(const object_type *o_ptr)
  934. {
  935. switch (o_ptr->tval)
  936. {
  937. case TV_DRAG_ARMOR:
  938. case TV_HARD_ARMOR:
  939. case TV_SOFT_ARMOR:
  940. case TV_SHIELD:
  941. case TV_CLOAK:
  942. case TV_CROWN:
  943. case TV_HELM:
  944. case TV_BOOTS:
  945. case TV_GLOVES:
  946. {
  947. return (TRUE);
  948. }
  949. }
  950. return (FALSE);
  951. }
  952. /*
  953. * Now that object flags are changing so much, it is likely that there
  954. * will be buggy objects that are marked with IDENT_KNOWN but do not
  955. * have all flags correctly marked. This function needs to allow for
  956. * reidentifying buggy objects.
  957. */
  958. static bool item_tester_unknown(const object_type *o_ptr)
  959. {
  960. /* A hack for a hack - Disable this for the 3.1.2 release */
  961. if (FALSE && object_is_not_known_consistently(o_ptr))
  962. {
  963. /*
  964. * This next hack is pretty terrible, but people playing
  965. * the nightlies will really appreciate not having to reidentify
  966. * every time a new IDENT_ flag is added. It should be
  967. * removed when the codebase is stable.
  968. */
  969. object_type *i_ptr = (object_type *) o_ptr;
  970. if (!object_check_for_ident(i_ptr))
  971. return TRUE;
  972. else
  973. return FALSE;
  974. }
  975. return object_is_known(o_ptr) ? FALSE : TRUE;
  976. }
  977. /**
  978. * Tries to increase an items bonus score, if possible.
  979. *
  980. * \returns true if the bonus was increased
  981. */
  982. bool enchant_score(s16b *score, bool is_artifact)
  983. {
  984. int chance;
  985. /* Artifacts resist enchantment half the time */
  986. if (is_artifact && randint0(100) < 50) return FALSE;
  987. /* Figure out the chance to enchant */
  988. if (*score < 0) chance = 0;
  989. else if (*score > 15) chance = 1000;
  990. else chance = enchant_table[*score];
  991. /* If we roll less-than-or-equal to chance, it fails */
  992. if (randint1(1000) <= chance) return FALSE;
  993. /* Increment the score */
  994. ++*score;
  995. return TRUE;
  996. }
  997. /**
  998. * Tries to uncurse a cursed item, if possible
  999. *
  1000. * \returns true if a curse was broken
  1001. */
  1002. bool enchant_curse(object_type *o_ptr, bool is_artifact)
  1003. {
  1004. bitflag f[OF_SIZE];
  1005. /* Extract the flags */
  1006. object_flags(o_ptr, f);
  1007. /* If the item isn't cursed (or is perma-cursed) this doesn't work */
  1008. if (!cursed_p(o_ptr) || of_has(f, OF_PERMA_CURSE)) return FALSE;
  1009. /* Artifacts resist enchanting curses away half the time */
  1010. if (is_artifact && randint0(100) < 50) return FALSE;
  1011. /* Normal items are uncursed 25% of the tiem */
  1012. if (randint0(100) >= 25) return FALSE;
  1013. /* Uncurse the item */
  1014. msg_print("The curse is broken!");
  1015. uncurse_object(o_ptr);
  1016. return TRUE;
  1017. }
  1018. /**
  1019. * Helper function for enchant() which tries to do the two things that
  1020. * enchanting an item does, namely increasing its bonuses and breaking curses
  1021. *
  1022. * \returns true if a bonus was increased or a curse was broken
  1023. */
  1024. bool enchant2(object_type *o_ptr, s16b *score)
  1025. {
  1026. bool result = FALSE;
  1027. bool is_artifact = artifact_p(o_ptr);
  1028. if (enchant_score(score, is_artifact)) result = TRUE;
  1029. if (enchant_curse(o_ptr, is_artifact)) result = TRUE;
  1030. return result;
  1031. }
  1032. /**
  1033. * Enchant an item
  1034. *
  1035. * Revamped! Now takes item pointer, number of times to try enchanting, and a
  1036. * flag of what to try enchanting. Artifacts resist enchantment some of the
  1037. * time. Also, any enchantment attempt (even unsuccessful) kicks off a parallel
  1038. * attempt to uncurse a cursed item.
  1039. *
  1040. * Note that an item can technically be enchanted all the way to +15 if you
  1041. * wait a very, very, long time. Going from +9 to +10 only works about 5% of
  1042. * the time, and from +10 to +11 only about 1% of the time.
  1043. *
  1044. * Note that this function can now be used on "piles" of items, and the larger
  1045. * the pile, the lower the chance of success.
  1046. *
  1047. * \returns true if the item was changed in some way
  1048. */
  1049. bool enchant(object_type *o_ptr, int n, int eflag)
  1050. {
  1051. int i, prob;
  1052. bool res = FALSE;
  1053. /* Large piles resist enchantment */
  1054. prob = o_ptr->number * 100;
  1055. /* Missiles are easy to enchant */
  1056. if ((o_ptr->tval == TV_BOLT) ||
  1057. (o_ptr->tval == TV_ARROW) ||
  1058. (o_ptr->tval == TV_SHOT)) prob = prob / 20;
  1059. /* Try "n" times */
  1060. for (i = 0; i < n; i++)
  1061. {
  1062. /* Roll for pile resistance */
  1063. if (prob > 100 && randint0(prob) >= 100) continue;
  1064. /* Try the three kinds of enchantment we can do */
  1065. if ((eflag & ENCH_TOHIT) && enchant2(o_ptr, &o_ptr->to_h)) res = TRUE;
  1066. if ((eflag & ENCH_TODAM) && enchant2(o_ptr, &o_ptr->to_d)) res = TRUE;
  1067. if ((eflag & ENCH_TOAC) && enchant2(o_ptr, &o_ptr->to_a)) res = TRUE;
  1068. }
  1069. /* Failure */
  1070. if (!res) return (FALSE);
  1071. /* Recalculate bonuses */
  1072. p_ptr->update |= (PU_BONUS);
  1073. /* Combine / Reorder the pack (later) */
  1074. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  1075. /* Redraw stuff */
  1076. p_ptr->redraw |= (PR_INVEN | PR_EQUIP );
  1077. /* Success */
  1078. return (TRUE);
  1079. }
  1080. /*
  1081. * Enchant an item (in the inventory or on the floor)
  1082. * Note that "num_ac" requires armour, else weapon
  1083. * Returns TRUE if attempted, FALSE if cancelled
  1084. */
  1085. bool enchant_spell(int num_hit, int num_dam, int num_ac)
  1086. {
  1087. int item;
  1088. bool okay = FALSE;
  1089. object_type *o_ptr;
  1090. char o_name[80];
  1091. cptr q, s;
  1092. /* Assume enchant weapon */
  1093. item_tester_hook = item_tester_hook_weapon;
  1094. /* Enchant armor if requested */
  1095. if (num_ac) item_tester_hook = item_tester_hook_armour;
  1096. /* Get an item */
  1097. q = "Enchant which item? ";
  1098. s = "You have nothing to enchant.";
  1099. if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
  1100. o_ptr = object_from_item_idx(item);
  1101. /* Description */
  1102. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  1103. /* Describe */
  1104. msg_format("%s %s glow%s brightly!",
  1105. ((item >= 0) ? "Your" : "The"), o_name,
  1106. ((o_ptr->number > 1) ? "" : "s"));
  1107. /* Enchant */
  1108. if (enchant(o_ptr, num_hit, ENCH_TOHIT)) okay = TRUE;
  1109. if (enchant(o_ptr, num_dam, ENCH_TODAM)) okay = TRUE;
  1110. if (enchant(o_ptr, num_ac, ENCH_TOAC)) okay = TRUE;
  1111. /* Failure */
  1112. if (!okay)
  1113. {
  1114. /* Flush */
  1115. if (OPT(flush_failure)) flush();
  1116. /* Message */
  1117. msg_print("The enchantment failed.");
  1118. }
  1119. /* Something happened */
  1120. return (TRUE);
  1121. }
  1122. /*
  1123. * Identify an object in the inventory (or on the floor)
  1124. * This routine does *not* automatically combine objects.
  1125. * Returns TRUE if something was identified, else FALSE.
  1126. */
  1127. bool ident_spell(void)
  1128. {
  1129. int item;
  1130. object_type *o_ptr;
  1131. cptr q, s;
  1132. /* Only un-id'ed items */
  1133. item_tester_hook = item_tester_unknown;
  1134. /* Get an item */
  1135. q = "Identify which item? ";
  1136. s = "You have nothing to identify.";
  1137. if (!get_item(&item, q, s, (USE_EQUIP | USE_INVEN | USE_FLOOR))) return (FALSE);
  1138. o_ptr = object_from_item_idx(item);
  1139. /* Identify the object */
  1140. do_ident_item(item, o_ptr);
  1141. /* Something happened */
  1142. return (TRUE);
  1143. }
  1144. /*
  1145. * Hook for "get_item()". Determine if something is rechargable.
  1146. */
  1147. static bool item_tester_hook_recharge(const object_type *o_ptr)
  1148. {
  1149. /* Recharge staves */
  1150. if (o_ptr->tval == TV_STAFF) return (TRUE);
  1151. /* Recharge wands */
  1152. if (o_ptr->tval == TV_WAND) return (TRUE);
  1153. /* Nope */
  1154. return (FALSE);
  1155. }
  1156. /*
  1157. * Recharge a wand or staff from the pack or on the floor.
  1158. *
  1159. * It is harder to recharge high level, and highly charged wands.
  1160. *
  1161. * XXX XXX XXX Beware of "sliding index errors".
  1162. *
  1163. * Should probably not "destroy" over-charged items, unless we
  1164. * "replace" them by, say, a broken stick or some such. The only
  1165. * reason this is okay is because "scrolls of recharging" appear
  1166. * BEFORE all staves/wands in the inventory. Note that the
  1167. * new "auto_sort_pack" option would correctly handle replacing
  1168. * the "broken" wand with any other item (i.e. a broken stick).
  1169. */
  1170. bool recharge(int num)
  1171. {
  1172. int i, t, item, lev;
  1173. object_type *o_ptr;
  1174. cptr q, s;
  1175. /* Only accept legal items */
  1176. item_tester_hook = item_tester_hook_recharge;
  1177. /* Get an item */
  1178. q = "Recharge which item? ";
  1179. s = "You have nothing to recharge.";
  1180. if (!get_item(&item, q, s, (USE_INVEN | USE_FLOOR))) return (FALSE);
  1181. o_ptr = object_from_item_idx(item);
  1182. /* Extract the object "level" */
  1183. lev = k_info[o_ptr->k_idx].level;
  1184. /* Recharge power */
  1185. i = (num + 100 - lev - (10 * (o_ptr->pval / o_ptr->number))) / 15;
  1186. /* Back-fire */
  1187. if ((i <= 1) || one_in_(i))
  1188. {
  1189. msg_print("The recharge backfires!");
  1190. msg_print("There is a bright flash of light.");
  1191. /* Reduce the charges of rods/wands/staves */
  1192. reduce_charges(o_ptr, 1);
  1193. /* Reduce and describe inventory */
  1194. if (item >= 0)
  1195. {
  1196. inven_item_increase(item, -1);
  1197. inven_item_describe(item);
  1198. inven_item_optimize(item);
  1199. }
  1200. /* Reduce and describe floor item */
  1201. else
  1202. {
  1203. floor_item_increase(0 - item, -1);
  1204. floor_item_describe(0 - item);
  1205. floor_item_optimize(0 - item);
  1206. }
  1207. }
  1208. /* Recharge */
  1209. else
  1210. {
  1211. /* Extract a "power" */
  1212. t = (num / (lev + 2)) + 1;
  1213. /* Recharge based on the power */
  1214. if (t > 0) o_ptr->pval += 2 + randint1(t);
  1215. /* We no longer think the item is empty */
  1216. o_ptr->ident &= ~(IDENT_EMPTY);
  1217. }
  1218. /* Combine / Reorder the pack (later) */
  1219. p_ptr->notice |= (PN_COMBINE | PN_REORDER);
  1220. /* Redraw stuff */
  1221. p_ptr->redraw |= (PR_INVEN);
  1222. /* Something was done */
  1223. return (TRUE);
  1224. }
  1225. /*
  1226. * Apply a "project()" directly to all viewable monsters
  1227. *
  1228. * Note that affected monsters are NOT auto-tracked by this usage.
  1229. */
  1230. bool project_los(int typ, int dam, bool obvious)
  1231. {
  1232. int i, x, y;
  1233. int flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
  1234. if(obvious) flg |= PROJECT_AWARE;
  1235. /* Affect all (nearby) monsters */
  1236. for (i = 1; i < mon_max; i++)
  1237. {
  1238. monster_type *m_ptr = &mon_list[i];
  1239. /* Paranoia -- Skip dead monsters */
  1240. if (!m_ptr->r_idx) continue;
  1241. /* Location */
  1242. y = m_ptr->fy;
  1243. x = m_ptr->fx;
  1244. /* Require line of sight */
  1245. if (!player_has_los_bold(y, x)) continue;
  1246. /* Jump directly to the target monster */
  1247. if (project(-1, 0, y, x, dam, typ, flg)) obvious = TRUE;
  1248. }
  1249. /* Result */
  1250. return (obvious);
  1251. }
  1252. /*
  1253. * Speed monsters
  1254. */
  1255. bool speed_monsters(void)
  1256. {
  1257. return (project_los(GF_OLD_SPEED, p_get_lev(), FALSE));
  1258. }
  1259. /*
  1260. * Slow monsters
  1261. */
  1262. bool slow_monsters(void)
  1263. {
  1264. return (project_los(GF_OLD_SLOW, p_get_lev(), FALSE));
  1265. }
  1266. /*
  1267. * Sleep monsters
  1268. */
  1269. bool sleep_monsters(bool aware)
  1270. {
  1271. return (project_los(GF_OLD_SLEEP, p_get_lev(), aware));
  1272. }
  1273. /*
  1274. * Confuse monsters
  1275. */
  1276. bool confuse_monsters(bool aware)
  1277. {
  1278. return (project_los(GF_OLD_CONF, p_get_lev(), aware));
  1279. }
  1280. /*
  1281. * Banish evil monsters
  1282. */
  1283. bool banish_evil(int dist)
  1284. {
  1285. return (project_los(GF_AWAY_EVIL, dist, FALSE));
  1286. }
  1287. /*
  1288. * Turn undead
  1289. */
  1290. bool turn_undead(bool aware)
  1291. {
  1292. return (project_los(GF_TURN_UNDEAD, p_get_lev(), aware));
  1293. }
  1294. /*
  1295. * Dispel undead monsters
  1296. */
  1297. bool dispel_undead(int dam)
  1298. {
  1299. return (project_los(GF_DISP_UNDEAD, dam, FALSE));
  1300. }
  1301. /*
  1302. * Dispel evil monsters
  1303. */
  1304. bool dispel_evil(int dam)
  1305. {
  1306. return (project_los(GF_DISP_EVIL, dam, FALSE));
  1307. }
  1308. /*
  1309. * Dispel all monsters
  1310. */
  1311. bool dispel_monsters(int dam)
  1312. {
  1313. return (project_los(GF_DISP_ALL, dam, FALSE));
  1314. }
  1315. /*
  1316. * Wake up all monsters, and speed up "los" monsters.
  1317. */
  1318. void aggravate_monsters(int who)
  1319. {
  1320. int i;
  1321. bool sleep = FALSE;
  1322. bool speed = FALSE;
  1323. /* Aggravate everyone nearby */
  1324. for (i = 1; i < mon_max; i++)
  1325. {
  1326. monster_type *m_ptr = &mon_list[i];
  1327. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1328. /* Paranoia -- Skip dead monsters */
  1329. if (!m_ptr->r_idx) continue;
  1330. /* Skip aggravating monster (or player) */
  1331. if (i == who) continue;
  1332. /* Wake up nearby sleeping monsters */
  1333. if (m_ptr->cdis < MAX_SIGHT * 2)
  1334. {
  1335. /* Wake up */
  1336. if (m_ptr->csleep)
  1337. {
  1338. /* Wake up */
  1339. wake_monster(m_ptr);
  1340. sleep = TRUE;
  1341. }
  1342. }
  1343. /* Speed up monsters in line of sight */
  1344. if (player_has_los_bold(m_ptr->fy, m_ptr->fx))
  1345. {
  1346. /* Speed up (instantly) to racial base + 10 */
  1347. if (m_ptr->mspeed < r_ptr->speed + 10)
  1348. {
  1349. /* Speed up */
  1350. m_ptr->mspeed = r_ptr->speed + 10;
  1351. speed = TRUE;
  1352. }
  1353. }
  1354. }
  1355. /* Messages */
  1356. if (speed) msg_print("You feel a sudden stirring nearby!");
  1357. else if (sleep) msg_print("You hear a sudden stirring in the distance!");
  1358. }
  1359. /*
  1360. * Delete all non-unique monsters of a given "type" from the level
  1361. */
  1362. bool banishment(void)
  1363. {
  1364. int i;
  1365. unsigned dam = 0;
  1366. char typ;
  1367. /* Mega-Hack -- Get a monster symbol */
  1368. if (!get_com("Choose a monster race (by symbol) to banish: ", &typ))
  1369. return FALSE;
  1370. /* Delete the monsters of that "type" */
  1371. for (i = 1; i < mon_max; i++)
  1372. {
  1373. monster_type *m_ptr = &mon_list[i];
  1374. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1375. /* Paranoia -- Skip dead monsters */
  1376. if (!m_ptr->r_idx) continue;
  1377. /* Hack -- Skip Unique Monsters */
  1378. if (rf_has(r_ptr->flags, RF_UNIQUE)) continue;
  1379. /* Skip "wrong" monsters */
  1380. if (r_ptr->d_char != typ) continue;
  1381. /* Delete the monster */
  1382. delete_monster_idx(i);
  1383. /* Take some damage */
  1384. dam += randint1(4);
  1385. }
  1386. /* Hurt the player */
  1387. take_hit(dam, "the strain of casting Banishment");
  1388. /* Update monster list window */
  1389. p_ptr->redraw |= PR_MONLIST;
  1390. /* Success */
  1391. return TRUE;
  1392. }
  1393. /*
  1394. * Delete all nearby (non-unique) monsters
  1395. */
  1396. bool mass_banishment(void)
  1397. {
  1398. int i;
  1399. unsigned dam = 0;
  1400. bool result = FALSE;
  1401. /* Delete the (nearby) monsters */
  1402. for (i = 1; i < mon_max; i++)
  1403. {
  1404. monster_type *m_ptr = &mon_list[i];
  1405. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1406. /* Paranoia -- Skip dead monsters */
  1407. if (!m_ptr->r_idx) continue;
  1408. /* Hack -- Skip unique monsters */
  1409. if (rf_has(r_ptr->flags, RF_UNIQUE)) continue;
  1410. /* Skip distant monsters */
  1411. if (m_ptr->cdis > MAX_SIGHT) continue;
  1412. /* Delete the monster */
  1413. delete_monster_idx(i);
  1414. /* Take some damage */
  1415. dam += randint1(3);
  1416. }
  1417. /* Hurt the player */
  1418. take_hit(dam, "the strain of casting Mass Banishment");
  1419. /* Calculate result */
  1420. result = (dam > 0) ? TRUE : FALSE;
  1421. /* Update monster list window */
  1422. if (result) p_ptr->redraw |= PR_MONLIST;
  1423. return (result);
  1424. }
  1425. /*
  1426. * Probe nearby monsters
  1427. */
  1428. bool probing(void)
  1429. {
  1430. int i;
  1431. bool probe = FALSE;
  1432. /* Probe all (nearby) monsters */
  1433. for (i = 1; i < mon_max; i++)
  1434. {
  1435. monster_type *m_ptr = &mon_list[i];
  1436. /* Paranoia -- Skip dead monsters */
  1437. if (!m_ptr->r_idx) continue;
  1438. /* Require line of sight */
  1439. if (!player_has_los_bold(m_ptr->fy, m_ptr->fx)) continue;
  1440. /* Probe visible monsters */
  1441. if (m_ptr->ml)
  1442. {
  1443. char m_name[80];
  1444. /* Start the message */
  1445. if (!probe) msg_print("Probing...");
  1446. /* Get "the monster" or "something" */
  1447. monster_desc(m_name, sizeof(m_name), m_ptr, MDESC_IND1);
  1448. /* Describe the monster */
  1449. msg_format("%^s has %d hit points.", m_name, m_ptr->hp);
  1450. /* Learn all of the non-spell, non-treasure flags */
  1451. lore_do_probe(i);
  1452. /* Probe worked */
  1453. probe = TRUE;
  1454. }
  1455. }
  1456. /* Done */
  1457. if (probe)
  1458. {
  1459. msg_print("That's all.");
  1460. }
  1461. /* Result */
  1462. return (probe);
  1463. }
  1464. /*
  1465. * The spell of destruction
  1466. *
  1467. * This spell "deletes" monsters (instead of "killing" them).
  1468. *
  1469. * Later we may use one function for both "destruction" and
  1470. * "earthquake" by using the "full" to select "destruction".
  1471. */
  1472. void destroy_area(int y1, int x1, int r, bool full)
  1473. {
  1474. int y, x, k, t;
  1475. bool flag = FALSE;
  1476. /* Unused parameter */
  1477. (void)full;
  1478. /* No effect in town */
  1479. if (!p_ptr->depth)
  1480. {
  1481. msg_print("The ground shakes for a moment.");
  1482. return;
  1483. }
  1484. /* Big area of affect */
  1485. for (y = (y1 - r); y <= (y1 + r); y++)
  1486. {
  1487. for (x = (x1 - r); x <= (x1 + r); x++)
  1488. {
  1489. /* Skip illegal grids */
  1490. if (!in_bounds_fully(y, x)) continue;
  1491. /* Extract the distance */
  1492. k = distance(y1, x1, y, x);
  1493. /* Stay in the circle of death */
  1494. if (k > r) continue;
  1495. /* Lose room and vault */
  1496. cave_info[y][x] &= ~(CAVE_ROOM | CAVE_ICKY);
  1497. /* Lose light and knowledge */
  1498. cave_info[y][x] &= ~(CAVE_GLOW | CAVE_MARK);
  1499. light_spot(y, x);
  1500. /* Hack -- Notice player affect */
  1501. if (cave_m_idx[y][x] < 0)
  1502. {
  1503. /* Hurt the player later */
  1504. flag = TRUE;
  1505. /* Do not hurt this grid */
  1506. continue;
  1507. }
  1508. /* Hack -- Skip the epicenter */
  1509. if ((y == y1) && (x == x1)) continue;
  1510. /* Delete the monster (if any) */
  1511. delete_monster(y, x);
  1512. /* Destroy "valid" grids */
  1513. if (cave_valid_bold(y, x))
  1514. {
  1515. int feat = FEAT_FLOOR;
  1516. /* Delete objects */
  1517. delete_object(y, x);
  1518. /* Wall (or floor) type */
  1519. t = randint0(200);
  1520. /* Granite */
  1521. if (t < 20)
  1522. {
  1523. /* Create granite wall */
  1524. feat = FEAT_WALL_EXTRA;
  1525. }
  1526. /* Quartz */
  1527. else if (t < 70)
  1528. {
  1529. /* Create quartz vein */
  1530. feat = FEAT_QUARTZ;
  1531. }
  1532. /* Magma */
  1533. else if (t < 100)
  1534. {
  1535. /* Create magma vein */
  1536. feat = FEAT_MAGMA;
  1537. }
  1538. /* Change the feature */
  1539. cave_set_feat(y, x, feat);
  1540. }
  1541. }
  1542. }
  1543. /* Hack -- Affect player */
  1544. if (flag)
  1545. {
  1546. /* Message */
  1547. msg_print("There is a searing blast of light!");
  1548. /* Blind the player */
  1549. if (!p_ptr->state.resist_blind && !p_ptr->state.resist_light)
  1550. {
  1551. /* Become blind */
  1552. (void)inc_timed(TMD_BLIND, 10 + randint1(10), TRUE);
  1553. }
  1554. }
  1555. /* Fully update the visuals */
  1556. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  1557. /* Fully update the flow */
  1558. p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW);
  1559. /* Redraw monster list */
  1560. p_ptr->redraw |= (PR_MONLIST | PR_ITEMLIST);
  1561. }
  1562. /*
  1563. * Induce an "earthquake" of the given radius at the given location.
  1564. *
  1565. * This will turn some walls into floors and some floors into walls.
  1566. *
  1567. * The player will take damage and "jump" into a safe grid if possible,
  1568. * otherwise, he will "tunnel" through the rubble instantaneously.
  1569. *
  1570. * Monsters will take damage, and "jump" into a safe grid if possible,
  1571. * otherwise they will be "buried" in the rubble, disappearing from
  1572. * the level in the same way that they do when banished.
  1573. *
  1574. * Note that players and monsters (except eaters of walls and passers
  1575. * through walls) will never occupy the same grid as a wall (or door).
  1576. */
  1577. void earthquake(int cy, int cx, int r)
  1578. {
  1579. int py = p_ptr->py;
  1580. int px = p_ptr->px;
  1581. int i, t, y, x, yy, xx, dy, dx;
  1582. int damage = 0;
  1583. int sn = 0, sy = 0, sx = 0;
  1584. bool hurt = FALSE;
  1585. bool map[32][32];
  1586. /* No effect in town */
  1587. if (!p_ptr->depth)
  1588. {
  1589. msg_print("The ground shakes for a moment.");
  1590. return;
  1591. }
  1592. /* Paranoia -- Enforce maximum range */
  1593. if (r > 12) r = 12;
  1594. /* Clear the "maximal blast" area */
  1595. for (y = 0; y < 32; y++)
  1596. {
  1597. for (x = 0; x < 32; x++)
  1598. {
  1599. map[y][x] = FALSE;
  1600. }
  1601. }
  1602. /* Check around the epicenter */
  1603. for (dy = -r; dy <= r; dy++)
  1604. {
  1605. for (dx = -r; dx <= r; dx++)
  1606. {
  1607. /* Extract the location */
  1608. yy = cy + dy;
  1609. xx = cx + dx;
  1610. /* Skip illegal grids */
  1611. if (!in_bounds_fully(yy, xx)) continue;
  1612. /* Skip distant grids */
  1613. if (distance(cy, cx, yy, xx) > r) continue;
  1614. /* Lose room and vault */
  1615. cave_info[yy][xx] &= ~(CAVE_ROOM | CAVE_ICKY);
  1616. /* Lose light and knowledge */
  1617. cave_info[yy][xx] &= ~(CAVE_GLOW | CAVE_MARK);
  1618. /* Skip the epicenter */
  1619. if (!dx && !dy) continue;
  1620. /* Skip most grids */
  1621. if (randint0(100) < 85) continue;
  1622. /* Damage this grid */
  1623. map[16+yy-cy][16+xx-cx] = TRUE;
  1624. /* Hack -- Take note of player damage */
  1625. if ((yy == py) && (xx == px)) hurt = TRUE;
  1626. }
  1627. }
  1628. /* First, affect the player (if necessary) */
  1629. if (hurt)
  1630. {
  1631. /* Check around the player */
  1632. for (i = 0; i < 8; i++)
  1633. {
  1634. /* Get the location */
  1635. y = py + ddy_ddd[i];
  1636. x = px + ddx_ddd[i];
  1637. /* Skip non-empty grids */
  1638. if (!cave_empty_bold(y, x)) continue;
  1639. /* Important -- Skip "quake" grids */
  1640. if (map[16+y-cy][16+x-cx]) continue;
  1641. /* Count "safe" grids, apply the randomizer */
  1642. if ((++sn > 1) && (randint0(sn) != 0)) continue;
  1643. /* Save the safe location */
  1644. sy = y; sx = x;
  1645. }
  1646. /* Random message */
  1647. switch (randint1(3))
  1648. {
  1649. case 1:
  1650. {
  1651. msg_print("The cave ceiling collapses!");
  1652. break;
  1653. }
  1654. case 2:
  1655. {
  1656. msg_print("The cave floor twists in an unnatural way!");
  1657. break;
  1658. }
  1659. default:
  1660. {
  1661. msg_print("The cave quakes!");
  1662. msg_print("You are pummeled with debris!");
  1663. break;
  1664. }
  1665. }
  1666. /* Hurt the player a lot */
  1667. if (!sn)
  1668. {
  1669. /* Message and damage */
  1670. msg_print("You are severely crushed!");
  1671. damage = 300;
  1672. }
  1673. /* Destroy the grid, and push the player to safety */
  1674. else
  1675. {
  1676. /* Calculate results */
  1677. switch (randint1(3))
  1678. {
  1679. case 1:
  1680. {
  1681. msg_print("You nimbly dodge the blast!");
  1682. damage = 0;
  1683. break;
  1684. }
  1685. case 2:
  1686. {
  1687. msg_print("You are bashed by rubble!");
  1688. damage = damroll(10, 4);
  1689. (void)inc_timed(TMD_STUN, randint1(50), TRUE);
  1690. break;
  1691. }
  1692. case 3:
  1693. {
  1694. msg_print("You are crushed between the floor and ceiling!");
  1695. damage = damroll(10, 4);
  1696. (void)inc_timed(TMD_STUN, randint1(50), TRUE);
  1697. break;
  1698. }
  1699. }
  1700. /* Move player */
  1701. monster_swap(py, px, sy, sx);
  1702. }
  1703. /* Take some damage */
  1704. if (damage) take_hit(damage, "an earthquake");
  1705. }
  1706. /* Examine the quaked region */
  1707. for (dy = -r; dy <= r; dy++)
  1708. {
  1709. for (dx = -r; dx <= r; dx++)
  1710. {
  1711. /* Extract the location */
  1712. yy = cy + dy;
  1713. xx = cx + dx;
  1714. /* Skip unaffected grids */
  1715. if (!map[16+yy-cy][16+xx-cx]) continue;
  1716. /* Process monsters */
  1717. if (cave_m_idx[yy][xx] > 0)
  1718. {
  1719. monster_type *m_ptr = &mon_list[cave_m_idx[yy][xx]];
  1720. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1721. /* Most monsters cannot co-exist with rock */
  1722. if (!flags_test(r_ptr->flags, RF_SIZE, RF_KILL_WALL, RF_PASS_WALL, FLAG_END))
  1723. {
  1724. char m_name[80];
  1725. /* Assume not safe */
  1726. sn = 0;
  1727. /* Monster can move to escape the wall */
  1728. if (!rf_has(r_ptr->flags, RF_NEVER_MOVE))
  1729. {
  1730. /* Look for safety */
  1731. for (i = 0; i < 8; i++)
  1732. {
  1733. /* Get the grid */
  1734. y = yy + ddy_ddd[i];
  1735. x = xx + ddx_ddd[i];
  1736. /* Skip non-empty grids */
  1737. if (!cave_empty_bold(y, x)) continue;
  1738. /* Hack -- no safety on glyph of warding */
  1739. if (cave_feat[y][x] == FEAT_GLYPH) continue;
  1740. /* Important -- Skip "quake" grids */
  1741. if (map[16+y-cy][16+x-cx]) continue;
  1742. /* Count "safe" grids, apply the randomizer */
  1743. if ((++sn > 1) && (randint0(sn) != 0)) continue;
  1744. /* Save the safe grid */
  1745. sy = y;
  1746. sx = x;
  1747. }
  1748. }
  1749. /* Describe the monster */
  1750. monster_desc(m_name, sizeof(m_name), m_ptr, 0);
  1751. /* Scream in pain */
  1752. msg_format("%^s wails out in pain!", m_name);
  1753. /* Take damage from the quake */
  1754. damage = (sn ? damroll(4, 8) : (m_ptr->hp + 1));
  1755. /* Monster is certainly awake */
  1756. wake_monster(m_ptr);
  1757. /* Apply damage directly */
  1758. m_ptr->hp -= damage;
  1759. /* Delete (not kill) "dead" monsters */
  1760. if (m_ptr->hp < 0)
  1761. {
  1762. /* Message */
  1763. msg_format("%^s is embedded in the rock!", m_name);
  1764. /* Delete the monster */
  1765. delete_monster(yy, xx);
  1766. /* No longer safe */
  1767. sn = 0;
  1768. }
  1769. /* Hack -- Escape from the rock */
  1770. if (sn)
  1771. {
  1772. /* Move the monster */
  1773. monster_swap(yy, xx, sy, sx);
  1774. }
  1775. }
  1776. }
  1777. }
  1778. }
  1779. /* XXX XXX XXX */
  1780. /* New location */
  1781. py = p_ptr->py;
  1782. px = p_ptr->px;
  1783. /* Important -- no wall on player */
  1784. map[16+py-cy][16+px-cx] = FALSE;
  1785. /* Examine the quaked region */
  1786. for (dy = -r; dy <= r; dy++)
  1787. {
  1788. for (dx = -r; dx <= r; dx++)
  1789. {
  1790. /* Extract the location */
  1791. yy = cy + dy;
  1792. xx = cx + dx;
  1793. /* ignore invalid grids */
  1794. if (!in_bounds_fully(yy, xx)) continue;
  1795. /* Note unaffected grids for light changes, etc. */
  1796. if (!map[16+yy-cy][16+xx-cx])
  1797. {
  1798. light_spot(yy, xx);
  1799. }
  1800. /* Destroy location (if valid) */
  1801. else if (cave_valid_bold(yy, xx))
  1802. {
  1803. int feat = FEAT_FLOOR;
  1804. bool floor = cave_floor_bold(yy, xx);
  1805. /* Delete objects */
  1806. delete_object(yy, xx);
  1807. /* Wall (or floor) type */
  1808. t = (floor ? randint0(100) : 200);
  1809. /* Granite */
  1810. if (t < 20)
  1811. {
  1812. /* Create granite wall */
  1813. feat = FEAT_WALL_EXTRA;
  1814. }
  1815. /* Quartz */
  1816. else if (t < 70)
  1817. {
  1818. /* Create quartz vein */
  1819. feat = FEAT_QUARTZ;
  1820. }
  1821. /* Magma */
  1822. else if (t < 100)
  1823. {
  1824. /* Create magma vein */
  1825. feat = FEAT_MAGMA;
  1826. }
  1827. /* Change the feature */
  1828. cave_set_feat(yy, xx, feat);
  1829. }
  1830. }
  1831. }
  1832. /* Fully update the visuals */
  1833. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  1834. /* Fully update the flow */
  1835. p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW);
  1836. /* Update the health bar */
  1837. p_ptr->redraw |= (PR_HEALTH);
  1838. /* Window stuff */
  1839. p_ptr->redraw |= (PR_MONLIST | PR_ITEMLIST);
  1840. }
  1841. /*
  1842. * This routine clears the entire "temp" set.
  1843. *
  1844. * This routine will Perma-Light all "temp" grids.
  1845. *
  1846. * This routine is used (only) by "light_room()"
  1847. *
  1848. * Dark grids are illuminated.
  1849. *
  1850. * Also, process all affected monsters.
  1851. *
  1852. * SMART monsters always wake up when illuminated
  1853. * NORMAL monsters wake up 1/4 the time when illuminated
  1854. * STUPID monsters wake up 1/10 the time when illuminated
  1855. */
  1856. static void cave_temp_room_light(void)
  1857. {
  1858. int i;
  1859. /* Apply flag changes */
  1860. for (i = 0; i < temp_n; i++)
  1861. {
  1862. int y = temp_y[i];
  1863. int x = temp_x[i];
  1864. /* No longer in the array */
  1865. cave_info[y][x] &= ~(CAVE_TEMP);
  1866. /* Perma-Light */
  1867. cave_info[y][x] |= (CAVE_GLOW);
  1868. }
  1869. /* Fully update the visuals */
  1870. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  1871. /* Update stuff */
  1872. update_stuff();
  1873. /* Process the grids */
  1874. for (i = 0; i < temp_n; i++)
  1875. {
  1876. int y = temp_y[i];
  1877. int x = temp_x[i];
  1878. /* Redraw the grid */
  1879. light_spot(y, x);
  1880. /* Process affected monsters */
  1881. if (cave_m_idx[y][x] > 0)
  1882. {
  1883. int chance = 25;
  1884. monster_type *m_ptr = &mon_list[cave_m_idx[y][x]];
  1885. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1886. /* Stupid monsters rarely wake up */
  1887. if (rf_has(r_ptr->flags, RF_STUPID)) chance = 10;
  1888. /* Smart monsters always wake up */
  1889. if (rf_has(r_ptr->flags, RF_SMART)) chance = 100;
  1890. /* Sometimes monsters wake up */
  1891. if (m_ptr->csleep && (randint0(100) < chance))
  1892. {
  1893. /* Wake up! */
  1894. wake_monster(m_ptr);

Large files files are truncated, but you can click here to view the full file