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

/src/spells2.c

https://github.com/NickMcConnell/Beleriand
C | 5718 lines | 3076 code | 1215 blank | 1427 comment | 827 complexity | 6d694e94c9c09f28d257dafde9823057 MD5 | raw file
  1. /** \file spells2.c
  2. \brief Spells
  3. * Healing spells, glyphs of warding, reducing or sustaining a stat, ID
  4. * everything, chance for enchant spells to fail, remove curses, regain
  5. * exp, detection spells, create stairs. Definitions of armour & weapons,
  6. * enchantment, branding, temporary branding, cursing, and ID code, what
  7. * items are rechargable and the recharging code. Various special object
  8. * spells. Spells that effect an area or LOS, lighten & darken rooms and
  9. * areas, casting ball, projection, beam, and bolt spells. Some miscel-
  10. * lanious non-damage spell functions.
  11. *
  12. * Copyright (c) 2009 Nick McConnell, Leon Marrick & Bahman Rabii,
  13. * Ben Harrison, James E. Wilson, Robert A. Koeneke
  14. *
  15. * This work is free software; you can redistribute it and/or modify it
  16. * under the terms of either:
  17. *
  18. * a) the GNU General Public License as published by the Free Software
  19. * Foundation, version 2, or
  20. *
  21. * b) the "Angband licence":
  22. * This software may be copied and distributed for educational, research,
  23. * and not for profit purposes provided that this copyright and statement
  24. * are included in all such copies. Other copyrights may also apply.
  25. */
  26. #include "angband.h"
  27. #include "cave.h"
  28. #include "history.h"
  29. #include "generate.h"
  30. #include "monster.h"
  31. #include "player.h"
  32. #include "spells.h"
  33. #include "squelch.h"
  34. #include "target.h"
  35. #include "trap.h"
  36. #include "ui-menu.h"
  37. /* Element to be proofed against in element-proofing */
  38. static bitflag el_to_proof[OF_SIZE];
  39. /**
  40. * Alter player's shape. Taken from Sangband.
  41. */
  42. void shapechange(s16b shape)
  43. {
  44. char *shapedesc = "";
  45. bool landing = FALSE;
  46. /* Were we flying? */
  47. landing = ((p_ptr->schange == SHAPE_BAT)
  48. || (p_ptr->schange == SHAPE_WYRM));
  49. /* Wonder Twin powers -- Activate! */
  50. p_ptr->schange = (byte) shape;
  51. p_ptr->update |= PU_BONUS;
  52. switch (shape) {
  53. case SHAPE_MOUSE:
  54. shapedesc = "mouse";
  55. break;
  56. case SHAPE_FERRET:
  57. shapedesc = "ferret";
  58. break;
  59. case SHAPE_HOUND:
  60. shapedesc = "hound";
  61. break;
  62. case SHAPE_GAZELLE:
  63. shapedesc = "gazelle";
  64. break;
  65. case SHAPE_LION:
  66. shapedesc = "lion";
  67. break;
  68. case SHAPE_ENT:
  69. shapedesc = "elder ent";
  70. break;
  71. case SHAPE_BAT:
  72. shapedesc = "bat";
  73. break;
  74. case SHAPE_WEREWOLF:
  75. shapedesc = "werewolf";
  76. break;
  77. case SHAPE_VAMPIRE:
  78. if ((chunk_list[p_ptr->stage].z_pos == 0)
  79. && ((turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2))) {
  80. msg("The sunlight prevents your shapechange!");
  81. shape = SHAPE_NORMAL;
  82. p_ptr->schange = (byte) shape;
  83. break;
  84. }
  85. shapedesc = "vampire";
  86. break;
  87. case SHAPE_WYRM:
  88. shapedesc = "dragon";
  89. break;
  90. case SHAPE_BEAR:
  91. shapedesc = "bear";
  92. break;
  93. default:
  94. msg("You return to your normal form.");
  95. break;
  96. }
  97. if (shape) {
  98. msg("You assume the form of a %s.", shapedesc);
  99. msg("Your equipment merges into your body.");
  100. }
  101. /* Recalculate mana. */
  102. p_ptr->update |= (PU_MANA);
  103. /* Show or hide shapechange on main window. */
  104. p_ptr->redraw |= (PR_SHAPE);
  105. if (landing) {
  106. int y = p_ptr->py, x = p_ptr->px;
  107. feature_type *f_ptr = &f_info[cave_feat[y][x]];
  108. if (tf_has(f_ptr->flags, TF_FALL))
  109. fall_off_cliff(0);
  110. else if (cave_invisible_trap(y, x)) {
  111. /* Disturb */
  112. disturb(0, 0);
  113. /* Hit the trap. */
  114. hit_trap(y, x);
  115. }
  116. /* Set off a visible trap */
  117. else if (cave_visible_trap(y, x)) {
  118. /* Disturb */
  119. disturb(0, 0);
  120. /* Hit the floor trap. */
  121. hit_trap(y, x);
  122. }
  123. }
  124. }
  125. /**
  126. * Type for choosing an elemental attack
  127. */
  128. typedef struct ele_attack_type {
  129. char *desc;
  130. u32b type;
  131. } ele_attack_type;
  132. static ele_attack_type ele_attack[] = {
  133. {"Fire Brand", ATTACK_FIRE},
  134. {"Cold Brand", ATTACK_COLD},
  135. {"Acid Brand", ATTACK_ACID},
  136. {"Elec Brand", ATTACK_ELEC}
  137. };
  138. char el_tag(menu_type * menu, int oid)
  139. {
  140. return I2A(oid);
  141. }
  142. /**
  143. * Display an entry on the sval menu
  144. */
  145. void el_display(menu_type * menu, int oid, bool cursor, int row, int col,
  146. int width)
  147. {
  148. const u16b *choice = menu->menu_data;
  149. int idx = choice[oid];
  150. byte attr = (cursor ? TERM_L_BLUE : TERM_WHITE);
  151. /* Print it */
  152. c_put_str(attr, format("%s", ele_attack[idx].desc), row, col);
  153. }
  154. /**
  155. * Deal with events on the sval menu
  156. */
  157. bool el_action(menu_type * menu, const ui_event * e, int oid)
  158. {
  159. u16b *choice = menu->menu_data;
  160. /* Choose */
  161. if (e->type == EVT_SELECT) {
  162. int idx = choice[oid];
  163. set_ele_attack(ele_attack[idx].type, 200);
  164. return FALSE;
  165. }
  166. else if (e->type == EVT_ESCAPE)
  167. return FALSE;
  168. else {
  169. int idx = choice[oid];
  170. set_ele_attack(ele_attack[idx].type, 200);
  171. return FALSE;
  172. }
  173. return FALSE;
  174. }
  175. /**
  176. * Display list of svals to be squelched.
  177. */
  178. bool el_menu(void)
  179. {
  180. menu_type menu;
  181. menu_iter menu_f = { el_tag, 0, el_display, el_action, 0 };
  182. region area = { 15, 1, 48, -1 };
  183. ui_event evt = { 0 };
  184. int cursor = 0;
  185. int num = 0;
  186. int i;
  187. u16b *choice;
  188. /* See how many attacks available */
  189. num = (p_ptr->lev - 20) / 7;
  190. /* Create the array */
  191. choice = C_ZNEW(num, u16b);
  192. /* Obvious */
  193. for (i = 0; i < num; i++) {
  194. /* Add this item to our possibles list */
  195. choice[i] = i;
  196. }
  197. /* Clear space */
  198. area.page_rows = num + 2;
  199. /* Return here if there are no attacks */
  200. if (!num) {
  201. FREE(choice);
  202. return FALSE;
  203. }
  204. /* Save the screen and clear it */
  205. screen_save();
  206. /* Help text */
  207. /* Set up the menu */
  208. WIPE(&menu, menu);
  209. menu_init(&menu, MN_SKIN_SCROLL, &menu_f);
  210. menu.title = "Choose a temporary elemental brand";
  211. menu_setpriv(&menu, num, choice);
  212. menu_layout(&menu, &area);
  213. /* Select an entry */
  214. evt = menu_select(&menu, cursor, TRUE);
  215. /* Free memory */
  216. FREE(choice);
  217. /* Load screen */
  218. screen_load();
  219. return (evt.type != EVT_ESCAPE);
  220. }
  221. /**
  222. * Choose a paladin elemental attack. -LM-
  223. */
  224. bool choose_ele_attack(void)
  225. {
  226. bool brand = FALSE;
  227. /* Save screen */
  228. screen_save();
  229. /* Choose */
  230. if (!el_menu())
  231. msg("You cancel the temporary branding.");
  232. else
  233. brand = TRUE;
  234. /* Load screen */
  235. screen_load();
  236. return brand;
  237. }
  238. /**
  239. * Array of elemental resistances
  240. */
  241. const char *ele_resist[] = {
  242. "Fire Resistance",
  243. "Cold Resistance",
  244. "Acid Resistance",
  245. "Electricity Resistance",
  246. "Poison Resistance"
  247. };
  248. char res_tag(menu_type * menu, int oid)
  249. {
  250. return I2A(oid);
  251. }
  252. /**
  253. * Display an entry on the sval menu
  254. */
  255. void res_display(menu_type * menu, int oid, bool cursor, int row, int col,
  256. int width)
  257. {
  258. const u16b *choice = menu->menu_data;
  259. int idx = choice[oid];
  260. byte attr = (cursor ? TERM_L_BLUE : TERM_WHITE);
  261. /* Print it */
  262. c_put_str(attr, format("%s", ele_resist[idx]), row, col);
  263. }
  264. /**
  265. * Deal with events on the sval menu
  266. */
  267. bool res_action(menu_type * menu, const ui_event * e, int oid)
  268. {
  269. u16b *choice = menu->menu_data;
  270. int plev = p_ptr->lev;
  271. /* Choose */
  272. if (e->type == EVT_ESCAPE)
  273. return FALSE;
  274. switch (choice[oid]) {
  275. case 0:
  276. {
  277. (void) inc_timed(TMD_OPP_FIRE, randint1(plev) + plev, TRUE);
  278. return FALSE;
  279. }
  280. case 1:
  281. {
  282. (void) inc_timed(TMD_OPP_COLD, randint1(plev) + plev, TRUE);
  283. return FALSE;
  284. }
  285. case 2:
  286. {
  287. (void) inc_timed(TMD_OPP_ACID, randint1(plev) + plev, TRUE);
  288. return FALSE;
  289. }
  290. case 3:
  291. {
  292. (void) inc_timed(TMD_OPP_ELEC, randint1(plev) + plev, TRUE);
  293. return FALSE;
  294. }
  295. case 4:
  296. {
  297. (void) inc_timed(TMD_OPP_POIS, randint1(plev) + plev, TRUE);
  298. return FALSE;
  299. }
  300. default:
  301. {
  302. return TRUE;
  303. }
  304. }
  305. }
  306. /**
  307. * Display list of svals to be squelched.
  308. */
  309. bool res_menu(void)
  310. {
  311. menu_type menu;
  312. menu_iter menu_f = { res_tag, 0, res_display, res_action, 0 };
  313. region area = { 15, 1, 48, 7 };
  314. ui_event evt = { 0 };
  315. int cursor = 0;
  316. size_t i;
  317. u16b *choice;
  318. /* Create the array */
  319. choice = C_ZNEW(5, u16b);
  320. /* Obvious */
  321. for (i = 0; i < 5; i++) {
  322. /* Add this item to our possibles list */
  323. choice[i] = i;
  324. }
  325. /* Save the screen and clear it */
  326. screen_save();
  327. /* Help text */
  328. /* Set up the menu */
  329. WIPE(&menu, menu);
  330. menu_init(&menu, MN_SKIN_SCROLL, &menu_f);
  331. menu.title = "Choose a temporary resistance";
  332. menu_setpriv(&menu, 5, choice);
  333. menu_layout(&menu, &area);
  334. /* Select an entry */
  335. evt = menu_select(&menu, cursor, TRUE);
  336. /* Free memory */
  337. FREE(choice);
  338. /* Load screen */
  339. screen_load();
  340. return (evt.type != EVT_ESCAPE);
  341. }
  342. /**
  343. * Choose an elemental resistance
  344. */
  345. extern bool choose_ele_resist(void)
  346. {
  347. bool resist = FALSE;
  348. /* Save screen */
  349. screen_save();
  350. /* Choose */
  351. if (!res_menu())
  352. msg("You cancel the temporary resistance.");
  353. else
  354. resist = TRUE;
  355. /* Load screen */
  356. screen_load();
  357. return resist;
  358. }
  359. /**
  360. * Hack -- The Athelas-creation code. -LM-
  361. */
  362. void create_athelas(void)
  363. {
  364. int py = p_ptr->py;
  365. int px = p_ptr->px;
  366. object_type *i_ptr;
  367. object_type object_type_body;
  368. /* Get local object */
  369. i_ptr = &object_type_body;
  370. /* Hack -- Make some Athelas, identify it, and drop it near the player. */
  371. object_prep(i_ptr, lookup_kind(TV_FOOD, SV_FOOD_ATHELAS), MINIMISE);
  372. /* Prevent money-making. */
  373. i_ptr->discount = 80;
  374. object_aware(i_ptr);
  375. object_known(i_ptr);
  376. drop_near(i_ptr, -1, py, px, TRUE);
  377. }
  378. /**
  379. * Controlled teleportation. -LM-
  380. * Idea from PsiAngband, through Zangband.
  381. */
  382. void dimen_door(void)
  383. {
  384. s16b ny;
  385. s16b nx;
  386. bool okay;
  387. okay = target_set_interactive(TARGET_LOOK | TARGET_GRID, -1, -1);
  388. if (!okay)
  389. return;
  390. /* grab the target coords. */
  391. target_get(&nx, &ny);
  392. /* Test for empty floor, forbid vaults or too large a distance, and insure
  393. * that this spell is never certain. */
  394. if (!cave_empty_bold(ny, nx) || cave_has(cave_info[ny][nx], CAVE_ICKY)
  395. || (distance(ny, nx, p_ptr->py, p_ptr->px) > 25)
  396. || (randint0(p_ptr->lev) == 0)) {
  397. msg("You fail to exit the astral plane correctly!");
  398. p_ptr->energy -= 50;
  399. teleport_player(15, FALSE);
  400. handle_stuff(p_ptr);
  401. }
  402. /* Controlled teleport. */
  403. else
  404. teleport_player_to(ny, nx, TRUE);
  405. }
  406. /**
  407. * Rebalance Weapon. This is a rather powerful spell, because it can be
  408. * used with any non-artifact throwing weapon, including ego-items. It is
  409. * therefore high-level, and curses weapons on failure. Do not give Assas-
  410. * sins "Break Curse". -LM-
  411. */
  412. void rebalance_weapon(void)
  413. {
  414. object_type *o_ptr;
  415. char o_name[120];
  416. /* Select the wielded melee weapon */
  417. o_ptr = &p_ptr->inventory[INVEN_WIELD];
  418. /* Nothing to rebalance */
  419. if (!o_ptr->k_idx) {
  420. msg("You are not wielding any melee weapon.");
  421. return;
  422. }
  423. /* Artifacts not allowed. */
  424. if (o_ptr->name1) {
  425. msg("Artifacts cannot be rebalanced.");
  426. return;
  427. }
  428. /* Not a throwing weapon. */
  429. if (!of_has(o_ptr->flags_obj, OF_THROWING)) {
  430. msg("The melee weapon you are wielding is not designed for throwing.");
  431. return;
  432. }
  433. /* 20% chance to curse weapon. */
  434. else if (randint1(5) == 1) {
  435. /* Description */
  436. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  437. /* Light curse and lower to_h and to_d by 2 to 5 each. */
  438. o_ptr->to_h -= (s16b) (2 + randint0(4));
  439. o_ptr->to_d -= (s16b) (2 + randint0(4));
  440. cf_on(o_ptr->flags_curse, FLAG_START + randint0(CF_MAX));
  441. /* Describe */
  442. msg("Oh no! A dreadful black aura surrounds your %s!", o_name);
  443. /* Recalculate bonuses */
  444. p_ptr->update |= (PU_BONUS);
  445. }
  446. /* Rebalance. */
  447. else {
  448. /* Grant perfect balance. */
  449. of_on(o_ptr->flags_obj, OF_PERFECT_BALANCE);
  450. /* Description */
  451. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  452. /* Describe */
  453. msg("Your %s gleams steel blue!", o_name);
  454. /* Prevent money-making. */
  455. o_ptr->discount = 80;
  456. }
  457. }
  458. /*
  459. * Increase players hit points, notice effects
  460. */
  461. bool hp_player(int num)
  462. {
  463. /* Healing needed */
  464. if (p_ptr->chp < p_ptr->mhp) {
  465. /* Gain hitpoints */
  466. p_ptr->chp += num;
  467. /* Enforce maximum */
  468. if (p_ptr->chp >= p_ptr->mhp) {
  469. p_ptr->chp = p_ptr->mhp;
  470. p_ptr->chp_frac = 0;
  471. }
  472. /* Redraw */
  473. p_ptr->redraw |= (PR_HP);
  474. /* Heal 0-4 */
  475. if (num < 5) {
  476. msg("You feel a little better.");
  477. }
  478. /* Heal 5-14 */
  479. else if (num < 15) {
  480. msg("You feel better.");
  481. }
  482. /* Heal 15-34 */
  483. else if (num < 35) {
  484. msg("You feel much better.");
  485. }
  486. /* Heal 35+ */
  487. else {
  488. msg("You feel very good.");
  489. }
  490. /* Notice */
  491. return (TRUE);
  492. }
  493. /* Ignore */
  494. return (FALSE);
  495. }
  496. /**
  497. * Jam a closed door with a magical spike.
  498. * Code is taken from do_cmd_spike. -LM-
  499. */
  500. void magic_spiking(void)
  501. {
  502. int py = p_ptr->py;
  503. int px = p_ptr->px;
  504. int y, x, i, dir;
  505. feature_type *f_ptr;
  506. /* Get a direction (or abort) */
  507. if (!get_rep_dir(&dir))
  508. return;
  509. /* Get location */
  510. y = py + ddy[dir];
  511. x = px + ddx[dir];
  512. f_ptr = &f_info[cave_feat[y][x]];
  513. /* Verify legality */
  514. if (!do_cmd_spike_test(y, x))
  515. return;
  516. /* Monster */
  517. if (cave_m_idx[y][x] > 0) {
  518. /* Message */
  519. msg("There is a monster in the way!");
  520. /* Attack */
  521. if (py_attack(y, x, TRUE))
  522. return;
  523. }
  524. /* Go for it */
  525. else {
  526. /* Verify legality */
  527. if (!do_cmd_spike_test(y, x))
  528. return;
  529. /* Successful jamming */
  530. msg("You magically jam the door.");
  531. /* Successful jamming */
  532. msg("You jam the door with a spike.");
  533. /* Convert "locked" to "stuck" XXX XXX XXX */
  534. if (!tf_has(f_ptr->flags, TF_DOOR_JAMMED)) {
  535. cave_feat[y][x] += 0x08;
  536. }
  537. /* Add three magical spikes to the door. */
  538. for (i = 0; i < 3; i++) {
  539. if (cave_feat[y][x] != FEAT_DOOR_TAIL) {
  540. cave_feat[y][x] += 0x01;
  541. }
  542. }
  543. }
  544. }
  545. /**
  546. * Leave a rune
  547. */
  548. bool lay_rune(int type)
  549. {
  550. int py = p_ptr->py;
  551. int px = p_ptr->px;
  552. trap_kind *trap_ptr = &trap_info[type];
  553. bool takes_rune = tf_has(f_info[cave_feat[py][px]].flags, TF_RUNE);
  554. /* If we're standing on a rune of mana, we can add mana to it */
  555. if ((type == RUNE_MANA) && (cave_trap_specific(py, px, RUNE_MANA))) {
  556. /* Standard mana amount */
  557. int mana = 40;
  558. /* Already full? */
  559. if (mana_reserve >= MAX_MANA_RESERVE) {
  560. msg("The rune cannot hold more mana");
  561. return (FALSE);
  562. }
  563. /* Don't put in more than we have */
  564. if (p_ptr->csp < mana)
  565. mana = p_ptr->csp;
  566. /* Don't put in more than it will hold */
  567. mana_reserve += mana;
  568. if (mana_reserve > MAX_MANA_RESERVE)
  569. mana_reserve = MAX_MANA_RESERVE;
  570. return (TRUE);
  571. }
  572. /* Need appropriate terrain and no monster */
  573. if (!takes_rune || cave_m_idx[py][px] > 0) {
  574. msg("You cannot lay a rune here.");
  575. return (FALSE);
  576. }
  577. #if 0
  578. /* Scan all objects in the grid */
  579. for (this_o_idx = cave_o_idx[py][px]; this_o_idx;
  580. this_o_idx = next_o_idx) {
  581. /* Acquire object */
  582. o_ptr = &o_list[this_o_idx];
  583. /* Acquire next object */
  584. next_o_idx = o_ptr->next_o_idx;
  585. /* Artifact */
  586. if (o_ptr->name1) {
  587. msg("There is an indestructible object here.");
  588. return (FALSE);
  589. }
  590. }
  591. /* Verify */
  592. if (cave_o_idx[py][px]) {
  593. if (!get_check("Destroy all items and lay a rune?"))
  594. return (FALSE);
  595. else {
  596. for (this_o_idx = cave_o_idx[py][px]; this_o_idx;
  597. this_o_idx = next_o_idx) {
  598. /* Acquire object */
  599. o_ptr = &o_list[this_o_idx];
  600. /* Acquire next object */
  601. next_o_idx = o_ptr->next_o_idx;
  602. /* Delete the object */
  603. delete_object_idx(this_o_idx);
  604. }
  605. /* Redraw */
  606. light_spot(py, px);
  607. }
  608. }
  609. #endif
  610. /* Limit total number of runes. */
  611. if (num_runes_on_level[type - 1] >= trap_ptr->max_num) {
  612. msg("You have reached the maximum number of runes of this type.");
  613. return (FALSE);
  614. }
  615. /* Create a rune */
  616. place_trap(py, px, type, 0);
  617. /* Increment the rune count. */
  618. num_runes_on_level[type - 1]++;
  619. /* Warning. */
  620. if (num_runes_on_level[type - 1] == trap_ptr->max_num) {
  621. msg("You have now reached your limit for runes of this type.");
  622. msg("In order to set more, remove some.");
  623. }
  624. return (TRUE);
  625. }
  626. /**
  627. * Array of stat "descriptions"
  628. */
  629. static const char *desc_stat_pos[] = {
  630. "strong",
  631. "smart",
  632. "wise",
  633. "dextrous",
  634. "healthy",
  635. "cute"
  636. };
  637. /**
  638. * Array of stat "descriptions"
  639. */
  640. static const char *desc_stat_neg[] = {
  641. "weak",
  642. "stupid",
  643. "naive",
  644. "clumsy",
  645. "sickly",
  646. "ugly"
  647. };
  648. /**
  649. * Lose a "point"
  650. */
  651. bool do_dec_stat(int stat)
  652. {
  653. bool sust = FALSE;
  654. bool clarity = (player_has(PF_CLARITY));
  655. bool athletics = (player_has(PF_ATHLETICS));
  656. /* Access the "sustain" and specialty skills */
  657. switch (stat) {
  658. case A_STR:
  659. if (p_ptr->state.sustain_str)
  660. sust = TRUE;
  661. break;
  662. case A_INT:
  663. if ((p_ptr->state.sustain_int) || (clarity && (randint0(2) != 0)))
  664. sust = TRUE;
  665. break;
  666. case A_WIS:
  667. if ((p_ptr->state.sustain_wis) || (clarity && (randint0(2) != 0)))
  668. sust = TRUE;
  669. break;
  670. case A_DEX:
  671. if ((p_ptr->state.sustain_dex)
  672. || (athletics && (randint0(2) != 0)))
  673. sust = TRUE;
  674. break;
  675. case A_CON:
  676. if ((p_ptr->state.sustain_con)
  677. || (athletics && (randint0(2) != 0)))
  678. sust = TRUE;
  679. break;
  680. case A_CHR:
  681. if (p_ptr->state.sustain_chr)
  682. sust = TRUE;
  683. break;
  684. }
  685. /* Sustain */
  686. if (sust) {
  687. /* Message */
  688. msg("You feel very %s for a moment, but the feeling passes.",
  689. desc_stat_neg[stat]);
  690. /* Notice effect */
  691. notice_obj(OBJECT_RAND_BASE_SUSTAIN + stat, 0);
  692. return (TRUE);
  693. }
  694. /* Attempt to reduce the stat */
  695. if (dec_stat(stat, 10, FALSE)) {
  696. /* Message */
  697. msg("You feel very %s.", desc_stat_neg[stat]);
  698. /* Notice effect */
  699. return (TRUE);
  700. }
  701. /* Nothing obvious */
  702. return (FALSE);
  703. }
  704. /**
  705. * Restore lost "points" in a stat
  706. */
  707. bool do_res_stat(int stat)
  708. {
  709. /* Attempt to increase */
  710. if (res_stat(stat)) {
  711. /* Message */
  712. msg("You feel less %s.", desc_stat_neg[stat]);
  713. /* Notice */
  714. return (TRUE);
  715. }
  716. /* Nothing obvious */
  717. return (FALSE);
  718. }
  719. /**
  720. * Gain a "point" in a stat
  721. */
  722. bool do_inc_stat(int stat, bool star)
  723. {
  724. bool res;
  725. /* Restore stst */
  726. res = res_stat(stat);
  727. /* Attempt to increase */
  728. if (inc_stat(stat, star)) {
  729. /* Message */
  730. msg("You feel very %s!", desc_stat_pos[stat]);
  731. /* Notice */
  732. return (TRUE);
  733. }
  734. /* Restoration worked */
  735. if (res) {
  736. /* Message */
  737. msg("You feel less %s.", desc_stat_neg[stat]);
  738. /* Notice */
  739. return (TRUE);
  740. }
  741. /* Nothing obvious */
  742. return (FALSE);
  743. }
  744. void identify_object(object_type * o_ptr)
  745. {
  746. object_kind *k_ptr;
  747. bool was_dubious = FALSE;
  748. /* Get the object kind. */
  749. k_ptr = &k_info[o_ptr->k_idx];
  750. /* See what we thought of it before */
  751. if ((o_ptr->feel == FEEL_PERILOUS)
  752. || (o_ptr->feel == FEEL_DUBIOUS_WEAK)
  753. || (o_ptr->feel == FEEL_DUBIOUS_STRONG))
  754. was_dubious = TRUE;
  755. /* Identify it fully */
  756. object_aware(o_ptr);
  757. object_known(o_ptr);
  758. /* Now we know about any ego-item type */
  759. if (o_ptr->name2)
  760. e_info[o_ptr->name2].everseen = TRUE;
  761. /* Check for known curses */
  762. if ((of_has(o_ptr->flags_obj, OF_SHOW_CURSE))
  763. || (artifact_p(o_ptr) && (o_ptr->name1 < ART_MIN_RANDOM))) {
  764. cf_copy(o_ptr->id_curse, o_ptr->flags_curse);
  765. o_ptr->ident |= IDENT_KNOW_CURSES;
  766. if (!cf_is_empty(o_ptr->flags_curse))
  767. o_ptr->ident |= IDENT_CURSED;
  768. else
  769. o_ptr->ident |= IDENT_UNCURSED;
  770. }
  771. /* If it seemed dubious but has no identifiable negatives, it's cursed */
  772. if (!item_dubious(o_ptr, FALSE) && was_dubious)
  773. o_ptr->ident |= IDENT_CURSED;
  774. /* Log artifacts to the history list. */
  775. if (artifact_p(o_ptr))
  776. history_add_artifact(o_ptr->name1, TRUE, TRUE);
  777. /* If the object is flavored, also make all items of that type, except for
  778. * variable rings and amulets, fully known. */
  779. if (k_ptr->flavor) {
  780. if ((o_ptr->tval == TV_FOOD) || (o_ptr->tval == TV_STAFF)
  781. || (o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_ROD))
  782. k_ptr->known_effect = TRUE;
  783. }
  784. /* Set squelch flag as appropriate */
  785. p_ptr->notice |= PN_SQUELCH;
  786. }
  787. /**
  788. * Identify everything being carried.
  789. * Done by a potion of "*Enlightenment*".
  790. */
  791. void identify_pack(void)
  792. {
  793. int i;
  794. /* Simply identify and know every item */
  795. for (i = 0; i < INVEN_TOTAL; i++) {
  796. object_type *o_ptr = &p_ptr->inventory[i];
  797. /* Skip non-objects */
  798. if (!o_ptr->k_idx)
  799. continue;
  800. /* Identify it */
  801. identify_object(o_ptr);
  802. }
  803. /* Recalculate bonuses */
  804. p_ptr->update |= (PU_BONUS);
  805. /* Combine / Reorder the pack (later) */
  806. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  807. /* Redraw stuff */
  808. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  809. }
  810. /**
  811. * Used by the "enchant" function (chance of failure)
  812. */
  813. static int enchant_table[16] = {
  814. 0, 10, 50, 100, 200,
  815. 300, 400, 500, 700, 950,
  816. 990, 992, 995, 997, 999,
  817. 1000
  818. };
  819. static bool item_tester_cursed(const object_type * o_ptr)
  820. {
  821. if (known_cursed_p(o_ptr)
  822. && !(of_has(o_ptr->flags_obj, OF_PERMA_CURSE)))
  823. return TRUE;
  824. else
  825. return FALSE;
  826. }
  827. /**
  828. * Attempts to remove curses from items in inventory
  829. *
  830. * Note that Items which are "Perma-Cursed"
  831. * can NEVER be uncursed.
  832. *
  833. * If good is TRUE, there is a better chance of removal. Using this spell
  834. * once makes an item fragile, which means it is likely to be destroyed on
  835. * a second attempt.
  836. */
  837. static bool remove_curse_aux(int good)
  838. {
  839. int i, item, slot;
  840. object_type *o_ptr;
  841. char o_name[120];
  842. const char *q, *s;
  843. bitflag curses[CF_SIZE];
  844. int destroy_chance = 50;
  845. int uncurse_chance = 50;
  846. bool heavy = FALSE;
  847. int feel;
  848. cf_wipe(curses);
  849. /* Only cursed items */
  850. item_tester_hook = item_tester_cursed;
  851. /* Don't restrict choices */
  852. item_tester_tval = 0;
  853. /* Get an item. */
  854. q = "Attempt to uncurse which item? ";
  855. s = "You have no curses which can be removed.";
  856. if (!get_item
  857. (&item, q, s, CMD_NULL, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
  858. return (FALSE);
  859. /* Get the item (in the pack) */
  860. if (item >= 0) {
  861. o_ptr = &p_ptr->inventory[item];
  862. }
  863. /* Get the item (on the floor) */
  864. else {
  865. o_ptr = &o_list[0 - item];
  866. }
  867. /* Artifacts are harder to uncurse and destroy */
  868. if (artifact_p(o_ptr)) {
  869. destroy_chance -= 25;
  870. uncurse_chance -= 25;
  871. }
  872. /* Try every curse, even unknown ones */
  873. for (i = cf_next(o_ptr->flags_curse, FLAG_START); i != FLAG_END;
  874. i = cf_next(o_ptr->flags_curse, i + 1))
  875. if (cf_has(o_ptr->flags_curse, i)) {
  876. /* If fragile, bad things can happen */
  877. if ((of_has(o_ptr->flags_obj, OF_FRAGILE))
  878. && (randint0(100) < destroy_chance - (good ? 10 : 0))) {
  879. /* Message */
  880. msg("There is a bang and a flash!");
  881. /* Damage */
  882. take_hit(damroll(5, 5), "Failed uncursing");
  883. /* Gone */
  884. if (item >= 0) {
  885. inven_item_increase(item, -1);
  886. inven_item_describe(item);
  887. inven_item_optimize(item);
  888. } else {
  889. floor_item_increase(0 - item, -1);
  890. floor_item_describe(0 - item);
  891. floor_item_optimize(0 - item);
  892. }
  893. return (TRUE);
  894. }
  895. /* Try once */
  896. if (randint0(100) < uncurse_chance)
  897. cf_on(curses, i);
  898. /* If good, try again */
  899. if (good && (randint0(100) < uncurse_chance))
  900. cf_on(curses, i);
  901. }
  902. /* Uncurse it */
  903. cf_negate(curses);
  904. cf_inter(o_ptr->flags_curse, curses);
  905. cf_inter(o_ptr->id_curse, curses);
  906. /* May not be cursed any more */
  907. if (cf_is_empty(o_ptr->id_curse))
  908. o_ptr->ident &= ~(IDENT_CURSED);
  909. /* Fragile now */
  910. of_on(o_ptr->flags_obj, OF_FRAGILE);
  911. of_on(o_ptr->id_obj, OF_FRAGILE);
  912. /* Known objects get free curse notification now */
  913. if (object_known_p(o_ptr)) {
  914. if (!cf_is_empty(o_ptr->flags_curse))
  915. o_ptr->ident |= IDENT_CURSED;
  916. else
  917. o_ptr->ident |= (IDENT_UNCURSED | IDENT_KNOW_CURSES);
  918. }
  919. /* Redo feeling if it's not known */
  920. else {
  921. /* Heavy sensing */
  922. heavy = (player_has(PF_PSEUDO_ID_HEAVY));
  923. /* Type of feeling */
  924. feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
  925. /* Check the slot */
  926. slot = wield_slot(o_ptr);
  927. /* Redo feeling */
  928. if (!(o_ptr->feel == feel)) {
  929. /* Get an object description */
  930. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  931. msg("You feel the %s (%c) you are %s %s now %s...", o_name,
  932. index_to_label(slot), describe_use(slot),
  933. ((o_ptr->number == 1) ? "is" : "are"), feel_text[feel]);
  934. /* We have "felt" it */
  935. o_ptr->ident |= (IDENT_SENSE);
  936. /* Inscribe it textually */
  937. o_ptr->feel = feel;
  938. /* Set squelch flag as appropriate */
  939. p_ptr->notice |= PN_SQUELCH;
  940. }
  941. }
  942. /* Recalculate the bonuses */
  943. p_ptr->update |= (PU_BONUS);
  944. /* Redraw stuff */
  945. p_ptr->redraw |= (PR_EQUIP | PR_INVEN);
  946. /* Something uncursed */
  947. if (cf_is_empty(curses))
  948. msg("You feel as if someone is watching over you.");
  949. /* Return scroll used/spell cast */
  950. return (TRUE);
  951. }
  952. /**
  953. * Remove most curses
  954. */
  955. bool remove_curse(void)
  956. {
  957. return (remove_curse_aux(FALSE));
  958. }
  959. /**
  960. * Remove all curses
  961. */
  962. bool remove_curse_good(void)
  963. {
  964. return (remove_curse_aux(TRUE));
  965. }
  966. /**
  967. * Restores any drained experience
  968. */
  969. bool restore_level(void)
  970. {
  971. /* Restore experience */
  972. if (p_ptr->exp < p_ptr->max_exp) {
  973. /* Message */
  974. msg("You feel your life energies returning.");
  975. /* Restore the experience */
  976. p_ptr->exp = p_ptr->max_exp;
  977. /* Check the experience */
  978. check_experience();
  979. /* Did something */
  980. return (TRUE);
  981. }
  982. /* No effect */
  983. return (FALSE);
  984. }
  985. /**
  986. * Forget everything
  987. */
  988. bool lose_all_info(void)
  989. {
  990. /* Mega-Hack -- Forget the map */
  991. wiz_dark();
  992. /* It worked */
  993. return (TRUE);
  994. }
  995. /**
  996. * Hack - displays areas effected by detection spells.
  997. *
  998. */
  999. static void animate_detect(int rad)
  1000. {
  1001. int py = p_ptr->py;
  1002. int px = p_ptr->px;
  1003. int x, y;
  1004. byte a, c;
  1005. int msec = op_ptr->delay_factor * op_ptr->delay_factor;
  1006. /* Exit if not desired */
  1007. if (!OPT(show_detect))
  1008. return;
  1009. /* Hack - Needs to last a bit longer to be visible */
  1010. msec *= 6;
  1011. /* Scan the maximal area of detection */
  1012. for (y = py - rad; y <= py + rad; y++) {
  1013. for (x = px - rad; x <= px + rad; x++) {
  1014. /* Ignore "illegal" locations */
  1015. if (!in_bounds(y, x))
  1016. continue;
  1017. /* Enforce a "circular" area */
  1018. if (distance(py, px, y, x) > rad)
  1019. continue;
  1020. /* Only show the region that the player can see */
  1021. if (panel_contains(y, x)) {
  1022. /* Hack - Obtain attr/char */
  1023. a = gf_to_attr[GF_DETECT][BOLT_NO_MOTION];
  1024. c = gf_to_char[GF_DETECT][BOLT_NO_MOTION];
  1025. /* Hack -- Visual effects -- Display a yellow star */
  1026. print_rel(c, a, y, x);
  1027. }
  1028. }
  1029. }
  1030. /* Flush the image of detected region */
  1031. Term_fresh();
  1032. if (p_ptr->redraw)
  1033. redraw_stuff(p_ptr);
  1034. /* Delay (efficiently) */
  1035. Term_xtra(TERM_XTRA_DELAY, msec);
  1036. /* Now erase the effect */
  1037. for (y = py - rad; y <= py + rad; y++) {
  1038. for (x = px - rad; x <= px + rad; x++) {
  1039. /* Ignore "illegal" locations */
  1040. if (!in_bounds(y, x))
  1041. continue;
  1042. /* Enforce a "circular" area */
  1043. if (distance(py, px, y, x) > rad)
  1044. continue;
  1045. /* Hack -- Erase only if needed */
  1046. if (panel_contains(y, x)) {
  1047. light_spot(y, x);
  1048. }
  1049. }
  1050. }
  1051. /* Hack -- center the cursor */
  1052. move_cursor_relative(py, px);
  1053. /* Flush screen back to normal */
  1054. Term_fresh();
  1055. if (p_ptr->redraw)
  1056. redraw_stuff(p_ptr);
  1057. /* Exit */
  1058. return;
  1059. }
  1060. /**
  1061. * Detect all traps within range
  1062. */
  1063. bool detect_traps(int range, bool show)
  1064. {
  1065. int y, x;
  1066. int py = p_ptr->py;
  1067. int px = p_ptr->px;
  1068. bool detect = FALSE;
  1069. /* Hack - flash the effected region on the current panel */
  1070. if (show)
  1071. animate_detect(range);
  1072. /* Scan the map */
  1073. for (y = 0; y < ARENA_HGT; y++) {
  1074. for (x = 0; x < ARENA_WID; x++) {
  1075. /* check range */
  1076. if (distance(py, px, y, x) <= range) {
  1077. /* Detect invisible traps */
  1078. if (cave_invisible_trap(y, x)) {
  1079. if (reveal_trap(y, x, 100, FALSE)) {
  1080. detect = TRUE;
  1081. }
  1082. }
  1083. /* Mark grid as detected */
  1084. cave_on(cave_info[y][x], CAVE_DTRAP);
  1085. }
  1086. }
  1087. }
  1088. /* Found some */
  1089. if (detect) {
  1090. /* Print success message */
  1091. msg("You detect traps.");
  1092. }
  1093. /* Redraw DTrap Status */
  1094. p_ptr->redraw |= (PR_DTRAP);
  1095. /* Result - trap detection items are easy to recognize for now -BR- */
  1096. return (TRUE);
  1097. }
  1098. /**
  1099. * Detect all doors within range
  1100. */
  1101. bool detect_doors(int range, bool show)
  1102. {
  1103. int y, x;
  1104. int py = p_ptr->py;
  1105. int px = p_ptr->px;
  1106. bool detect = FALSE;
  1107. int num = 0;
  1108. feature_type *f_ptr = NULL;
  1109. /* Hack - flash the effected region on the current panel */
  1110. if (show)
  1111. animate_detect(range);
  1112. /* Scan the map */
  1113. for (y = 0; y < ARENA_HGT; y++) {
  1114. for (x = 0; x < ARENA_WID; x++) {
  1115. /* check range */
  1116. if (distance(py, px, y, x) <= range) {
  1117. /* Detect secret doors */
  1118. if (cave_feat[y][x] == FEAT_SECRET) {
  1119. /* Pick a door */
  1120. place_closed_door(y, x);
  1121. }
  1122. /* Set the feature */
  1123. f_ptr = &f_info[cave_feat[y][x]];
  1124. /* Detect doors */
  1125. if (tf_has(f_ptr->flags, TF_DOOR_ANY)) {
  1126. /* Hack -- Memorize */
  1127. cave_on(cave_info[y][x], CAVE_MARK);
  1128. /* Redraw */
  1129. light_spot(y, x);
  1130. /* increment number found */
  1131. num++;
  1132. }
  1133. }
  1134. }
  1135. }
  1136. /* Found some */
  1137. if (num > 0) {
  1138. /* Obvious */
  1139. detect = TRUE;
  1140. /* Print success message */
  1141. msg("You detect doors.");
  1142. }
  1143. /* Result */
  1144. return (detect);
  1145. }
  1146. /**
  1147. * Detect all stairs within range
  1148. */
  1149. bool detect_stairs(int range, bool show)
  1150. {
  1151. int y, x;
  1152. int py = p_ptr->py;
  1153. int px = p_ptr->px;
  1154. int num = 0;
  1155. bool detect = FALSE;
  1156. /* Hack - flash the effected region on the current panel */
  1157. if (show)
  1158. animate_detect(range);
  1159. /* Scan the map */
  1160. for (y = 0; y < ARENA_HGT; y++) {
  1161. for (x = 0; x < ARENA_WID; x++) {
  1162. /* check range */
  1163. if (distance(py, px, y, x) <= range) {
  1164. feature_type *f_ptr = &f_info[cave_feat[y][x]];
  1165. /* Detect stairs */
  1166. if (tf_has(f_ptr->flags, TF_STAIR) ||
  1167. tf_has(f_ptr->flags, TF_PATH)) {
  1168. /* Hack -- Memorize */
  1169. cave_on(cave_info[y][x], CAVE_MARK);
  1170. /* Redraw */
  1171. light_spot(y, x);
  1172. /* increment number found */
  1173. num++;
  1174. }
  1175. }
  1176. }
  1177. }
  1178. /* Found some */
  1179. if (num > 0) {
  1180. /* Obvious */
  1181. detect = TRUE;
  1182. /* Print success message */
  1183. msg("You detect stairs.");
  1184. }
  1185. /* Result */
  1186. return (detect);
  1187. }
  1188. /**
  1189. * Detect any treasure within range
  1190. */
  1191. bool detect_treasure(int range, bool show)
  1192. {
  1193. int y, x;
  1194. int py = p_ptr->py;
  1195. int px = p_ptr->px;
  1196. bool detect = FALSE;
  1197. int num = 0;
  1198. /* Hack - flash the effected region on the current panel */
  1199. if (show)
  1200. animate_detect(range);
  1201. /* Scan the map */
  1202. for (y = 0; y < ARENA_HGT; y++) {
  1203. for (x = 0; x < ARENA_WID; x++) {
  1204. /* check range */
  1205. if (distance(py, px, y, x) <= range) {
  1206. /* Notice embedded gold */
  1207. if (cave_feat[y][x] == FEAT_MAGMA_H) {
  1208. /* Expose the gold */
  1209. cave_feat[y][x] = FEAT_MAGMA_K;
  1210. }
  1211. /* Notice embedded gold */
  1212. if (cave_feat[y][x] == FEAT_QUARTZ_H) {
  1213. /* Expose the gold */
  1214. cave_feat[y][x] = FEAT_QUARTZ_K;
  1215. }
  1216. /* Magma/Quartz + Known Gold */
  1217. if ((cave_feat[y][x] == FEAT_MAGMA_K)
  1218. || (cave_feat[y][x] == FEAT_QUARTZ_K)) {
  1219. /* Hack -- Memorize */
  1220. cave_on(cave_info[y][x], CAVE_MARK);
  1221. /* Redraw */
  1222. light_spot(y, x);
  1223. /* increment number found */
  1224. num++;
  1225. }
  1226. }
  1227. }
  1228. }
  1229. /* Found some */
  1230. if (num > 0) {
  1231. /* Obvious */
  1232. detect = TRUE;
  1233. /* Print success message */
  1234. msg("You detect buried treasure.");
  1235. }
  1236. /* Result */
  1237. return (detect);
  1238. }
  1239. /**
  1240. * Detect all "gold" objects within range
  1241. */
  1242. bool detect_objects_gold(int range, bool show)
  1243. {
  1244. int i, y, x;
  1245. int py = p_ptr->py;
  1246. int px = p_ptr->px;
  1247. int num = 0;
  1248. bool detect = FALSE;
  1249. /* Hack - flash the effected region on the current panel */
  1250. if (show)
  1251. animate_detect(range);
  1252. /* Scan objects */
  1253. for (i = 1; i < o_max; i++) {
  1254. object_type *o_ptr = &o_list[i];
  1255. /* Skip dead objects */
  1256. if (!o_ptr->k_idx)
  1257. continue;
  1258. /* Skip held objects */
  1259. if (o_ptr->held_m_idx)
  1260. continue;
  1261. /* Location */
  1262. y = o_ptr->iy;
  1263. x = o_ptr->ix;
  1264. /* check range */
  1265. if (distance(py, px, y, x) > range)
  1266. continue;
  1267. /* Detect "gold" objects */
  1268. if (o_ptr->tval == TV_GOLD) {
  1269. /* Hack -- memorize it */
  1270. o_ptr->marked = TRUE;
  1271. /* Redraw */
  1272. light_spot(y, x);
  1273. /* increment number found */
  1274. num++;
  1275. }
  1276. }
  1277. /* Found some */
  1278. if (num > 0) {
  1279. /* Obvious */
  1280. detect = TRUE;
  1281. msg("You detect treasure.");
  1282. }
  1283. /* Result */
  1284. return (detect);
  1285. }
  1286. /**
  1287. * Detect all "normal" objects within range
  1288. */
  1289. bool detect_objects_normal(int range, bool show)
  1290. {
  1291. int i, y, x;
  1292. int py = p_ptr->py;
  1293. int px = p_ptr->px;
  1294. int num = 0;
  1295. bool detect = FALSE;
  1296. /* Hack - flash the effected region on the current panel */
  1297. if (show)
  1298. animate_detect(range);
  1299. /* Scan objects */
  1300. for (i = 1; i < o_max; i++) {
  1301. object_type *o_ptr = &o_list[i];
  1302. /* Skip dead objects */
  1303. if (!o_ptr->k_idx)
  1304. continue;
  1305. /* Skip held objects */
  1306. if (o_ptr->held_m_idx)
  1307. continue;
  1308. /* Location */
  1309. y = o_ptr->iy;
  1310. x = o_ptr->ix;
  1311. /* check range */
  1312. if (distance(py, px, y, x) > range)
  1313. continue;
  1314. /* Detect "real" objects */
  1315. if (o_ptr->tval != TV_GOLD) {
  1316. /* Hack -- memorize it */
  1317. o_ptr->marked = TRUE;
  1318. /* Redraw */
  1319. light_spot(y, x);
  1320. /* increment number found */
  1321. if (!squelch_hide_item(o_ptr))
  1322. num++;
  1323. }
  1324. }
  1325. /* Found some */
  1326. if (num > 0) {
  1327. /* Obvious */
  1328. detect = TRUE;
  1329. /* Print success message */
  1330. msg("You detect objects.");
  1331. }
  1332. /* Result */
  1333. return (detect);
  1334. }
  1335. /**
  1336. * Detect all "magic" objects within range.
  1337. *
  1338. * This will light up all spaces with "magic" items, including artifacts,
  1339. * ego-items, potions, scrolls, books, rods, wands, staves, amulets, rings,
  1340. * and "enchanted" items of the "good" variety.
  1341. *
  1342. * It can probably be argued that this function is now too powerful.
  1343. */
  1344. bool detect_objects_magic(int range, bool show)
  1345. {
  1346. int i, y, x, tv;
  1347. int py = p_ptr->py;
  1348. int px = p_ptr->px;
  1349. bool detect = FALSE;
  1350. int num = 0;
  1351. /* Hack - flash the effected region on the current panel */
  1352. if (show)
  1353. animate_detect(range);
  1354. /* Scan all objects */
  1355. for (i = 1; i < o_max; i++) {
  1356. object_type *o_ptr = &o_list[i];
  1357. /* Skip dead objects */
  1358. if (!o_ptr->k_idx)
  1359. continue;
  1360. /* Skip held objects */
  1361. if (o_ptr->held_m_idx)
  1362. continue;
  1363. /* Location */
  1364. y = o_ptr->iy;
  1365. x = o_ptr->ix;
  1366. /* check range */
  1367. if (distance(py, px, y, x) > range)
  1368. continue;
  1369. /* Examine the tval */
  1370. tv = o_ptr->tval;
  1371. /* Artifacts, misc magic items, or enchanted wearables */
  1372. if (artifact_p(o_ptr) || ego_item_p(o_ptr) || (tv == TV_AMULET)
  1373. || (tv == TV_RING) || (tv == TV_STAFF) || (tv == TV_WAND)
  1374. || (tv == TV_ROD) || (tv == TV_SCROLL) || (tv == TV_POTION)
  1375. || (tv == TV_MAGIC_BOOK) || (tv == TV_PRAYER_BOOK)
  1376. || (tv == TV_DRUID_BOOK) || (tv == TV_NECRO_BOOK)
  1377. || ((o_ptr->to_a > 0) || (o_ptr->to_h + o_ptr->to_d > 0))) {
  1378. /* Memorize the item */
  1379. o_ptr->marked = TRUE;
  1380. /* Redraw */
  1381. light_spot(y, x);
  1382. /* increment number found */
  1383. if (!squelch_hide_item(o_ptr))
  1384. num++;
  1385. }
  1386. }
  1387. /* Found some */
  1388. if (num > 0) {
  1389. /* Obvious */
  1390. detect = TRUE;
  1391. /* Print success message */
  1392. msg("You detect magic objects.");
  1393. }
  1394. /* Return result */
  1395. return (detect);
  1396. }
  1397. /**
  1398. * Detect all "normal" monsters within range
  1399. */
  1400. bool detect_monsters_normal(int range, bool show)
  1401. {
  1402. int i, y, x;
  1403. int py = p_ptr->py;
  1404. int px = p_ptr->px;
  1405. bool flag = FALSE;
  1406. int num = 0;
  1407. int num_off = 0;
  1408. /* Hack - flash the effected region on the current panel */
  1409. if (show)
  1410. animate_detect(range);
  1411. /* Scan monsters */
  1412. for (i = 1; i < m_max; i++) {
  1413. monster_type *m_ptr = &m_list[i];
  1414. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1415. /* Skip dead monsters */
  1416. if (!m_ptr->r_idx)
  1417. continue;
  1418. /* Location */
  1419. y = m_ptr->fy;
  1420. x = m_ptr->fx;
  1421. /* check range */
  1422. if (distance(py, px, y, x) > range)
  1423. continue;
  1424. /* Detect all non-invisible monsters */
  1425. if (!(rf_has(r_ptr->flags, RF_INVISIBLE))) {
  1426. /* Optimize -- Repair flags */
  1427. repair_mflag_mark = repair_mflag_show = TRUE;
  1428. /* Hack -- Detect the monster */
  1429. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  1430. /* Update the monster */
  1431. update_mon(i, FALSE);
  1432. /* increment number found */
  1433. num++;
  1434. /* increment number found offscreen */
  1435. if (!panel_contains(y, x))
  1436. num_off++;
  1437. }
  1438. }
  1439. /* Found some */
  1440. if (num > 0) {
  1441. /* Obvious */
  1442. flag = TRUE;
  1443. /* Print success message */
  1444. if (num_off > 0)
  1445. msg("You detect monsters (%i offscreen).", num_off);
  1446. else
  1447. msg("You detect monsters.");
  1448. }
  1449. /* Result */
  1450. return (flag);
  1451. }
  1452. /**
  1453. * Detect all "invisible" monsters within range
  1454. */
  1455. bool detect_monsters_invis(int range, bool show)
  1456. {
  1457. int i, y, x;
  1458. int py = p_ptr->py;
  1459. int px = p_ptr->px;
  1460. bool flag = FALSE;
  1461. int num = 0;
  1462. int num_off = 0;
  1463. /* Hack - flash the effected region on the current panel */
  1464. if (show)
  1465. animate_detect(range);
  1466. /* Scan monsters */
  1467. for (i = 1; i < m_max; i++) {
  1468. monster_type *m_ptr = &m_list[i];
  1469. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1470. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  1471. /* Skip dead monsters */
  1472. if (!m_ptr->r_idx)
  1473. continue;
  1474. /* Location */
  1475. y = m_ptr->fy;
  1476. x = m_ptr->fx;
  1477. /* check range */
  1478. if (distance(py, px, y, x) > range)
  1479. continue;
  1480. /* Detect invisible monsters */
  1481. if (rf_has(r_ptr->flags, RF_INVISIBLE)) {
  1482. /* Take note that they are invisible */
  1483. rf_on(l_ptr->flags, RF_INVISIBLE);
  1484. /* Update monster recall window */
  1485. if (p_ptr->monster_race_idx == m_ptr->r_idx) {
  1486. /* Redraw stuff */
  1487. p_ptr->redraw |= (PR_MONSTER);
  1488. }
  1489. /* Optimize -- Repair flags */
  1490. repair_mflag_mark = repair_mflag_show = TRUE;
  1491. /* Hack -- Detect the monster */
  1492. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  1493. /* Update the monster */
  1494. update_mon(i, FALSE);
  1495. /* increment number found */
  1496. num++;
  1497. /* increment number found offscreen */
  1498. if (!panel_contains(y, x))
  1499. num_off++;
  1500. }
  1501. }
  1502. /* Found some */
  1503. if (num > 0) {
  1504. /* Obvious */
  1505. flag = TRUE;
  1506. /* Print success message */
  1507. if (num_off > 0)
  1508. msg("You detect invisible creatures (%i offscreen).", num_off);
  1509. else
  1510. msg("You detect invisible creatures.");
  1511. }
  1512. /* Result */
  1513. return (flag);
  1514. }
  1515. /**
  1516. * Detect all "evil" monsters within range
  1517. */
  1518. bool detect_monsters_evil(int range, bool show)
  1519. {
  1520. int i, y, x;
  1521. int py = p_ptr->py;
  1522. int px = p_ptr->px;
  1523. bool flag = FALSE;
  1524. int num = 0;
  1525. int num_off = 0;
  1526. /* Hack - flash the effected region on the current panel */
  1527. if (show)
  1528. animate_detect(range);
  1529. /* Scan monsters */
  1530. for (i = 1; i < m_max; i++) {
  1531. monster_type *m_ptr = &m_list[i];
  1532. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1533. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  1534. /* Skip dead monsters */
  1535. if (!m_ptr->r_idx)
  1536. continue;
  1537. /* Location */
  1538. y = m_ptr->fy;
  1539. x = m_ptr->fx;
  1540. /* check range */
  1541. if (distance(py, px, y, x) > range)
  1542. continue;
  1543. /* Detect evil monsters */
  1544. if (rf_has(r_ptr->flags, RF_EVIL)) {
  1545. /* Take note that they are evil */
  1546. rf_on(l_ptr->flags, RF_EVIL);
  1547. /* Update monster recall window */
  1548. if (p_ptr->monster_race_idx == m_ptr->r_idx) {
  1549. /* Redraw stuff */
  1550. p_ptr->redraw |= (PR_MONSTER);
  1551. }
  1552. /* Optimize -- Repair flags */
  1553. repair_mflag_mark = repair_mflag_show = TRUE;
  1554. /* Detect the monster */
  1555. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  1556. /* Update the monster */
  1557. update_mon(i, FALSE);
  1558. /* increment number found */
  1559. num++;
  1560. /* increment number found offscreen */
  1561. if (!panel_contains(y, x))
  1562. num_off++;
  1563. }
  1564. }
  1565. /* Found some */
  1566. if (num > 0) {
  1567. /* Obvious */
  1568. flag = TRUE;
  1569. /* Print success message */
  1570. if (num_off > 0)
  1571. msg("You detect evil creatures (%i offscreen).", num_off);
  1572. else
  1573. msg("You detect evil creatures.");
  1574. }
  1575. /* Result */
  1576. return (flag);
  1577. }
  1578. /**
  1579. * Detect all "living" monsters within range.
  1580. */
  1581. bool detect_monsters_living(int range, bool show)
  1582. {
  1583. int i, y, x;
  1584. int py = p_ptr->py;
  1585. int px = p_ptr->px;
  1586. bool flag = FALSE;
  1587. int num = 0;
  1588. int num_off = 0;
  1589. /* Hack - flash the effected region on the current panel */
  1590. if (show)
  1591. animate_detect(range);
  1592. /* Scan monsters */
  1593. for (i = 1; i < m_max; i++) {
  1594. monster_type *m_ptr = &m_list[i];
  1595. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1596. /* Skip dead monsters */
  1597. if (!m_ptr->r_idx)
  1598. continue;
  1599. /* Location */
  1600. y = m_ptr->fy;
  1601. x = m_ptr->fx;
  1602. /* check range */
  1603. if (distance(py, px, y, x) > range)
  1604. continue;
  1605. /* Hack -- Detect all living monsters. */
  1606. if ((!strchr("Egv", r_ptr->d_char))
  1607. && (!(rf_has(r_ptr->flags, RF_UNDEAD)))) {
  1608. /* Optimize -- Repair flags */
  1609. repair_mflag_mark = repair_mflag_show = TRUE;
  1610. /* Hack -- Detect the monster */
  1611. m_ptr->mflag |= (MFLAG_MARK | MFLAG_SHOW);
  1612. /* Update the monster */
  1613. update_mon(i, FALSE);
  1614. /* increment number found */
  1615. num++;
  1616. /* increment number found offscreen */
  1617. if (!panel_contains(y, x))
  1618. num_off++;
  1619. }
  1620. }
  1621. /* Found some */
  1622. if (num > 0) {
  1623. /* Obvious */
  1624. flag = TRUE;
  1625. /* Print success message */
  1626. if (num_off > 0)
  1627. msg("You detect living creatures (%i offscreen).", num_off);
  1628. else
  1629. msg("You detect living creatures.");
  1630. }
  1631. /* Now detect trees */
  1632. num = 0;
  1633. /* Scan the maximal area of mapping */
  1634. for (y = py - range; y <= py + range; y++) {
  1635. for (x = px - range; x <= px + range; x++) {
  1636. feature_type *f_ptr = &f_info[cave_feat[y][x]];
  1637. /* Ignore "illegal" locations */
  1638. if (!in_bounds(y, x))
  1639. continue;
  1640. /* Enforce a "circular" area */
  1641. if (distance(py, px, y, x) > range)
  1642. continue;
  1643. /* Notice trees */
  1644. if (tf_has(f_ptr->flags, TF_TREE)) {
  1645. /* Mark it */
  1646. cave_on(cave_info[y][x], CAVE_MARK);
  1647. /* Count it */
  1648. num++;
  1649. }
  1650. }
  1651. }
  1652. /* Found some */
  1653. if (num > 0) {
  1654. flag = TRUE;
  1655. /* Print message */
  1656. msg("You detect trees.");
  1657. /* Update */
  1658. p_ptr->redraw |= PR_MAP;
  1659. redraw_stuff(p_ptr);
  1660. }
  1661. /* Result */
  1662. return (flag);
  1663. }
  1664. /**
  1665. * Detect everything
  1666. */
  1667. bool detect_all(int range, bool show)
  1668. {
  1669. bool detect = FALSE;
  1670. /* Hack - flash the effected region on the current panel */
  1671. if (show)
  1672. animate_detect(range);
  1673. /* Detect everything */
  1674. /* Do not 'show' the affected region for each detect individually */
  1675. if (detect_traps(range, FALSE))
  1676. detect = TRUE;
  1677. if (detect_doors(range, FALSE))
  1678. detect = TRUE;
  1679. if (detect_stairs(range, FALSE))
  1680. detect = TRUE;
  1681. if (detect_treasure(range, FALSE))
  1682. detect = TRUE;
  1683. if (detect_objects_gold(range, FALSE))
  1684. detect = TRUE;
  1685. if (detect_objects_normal(range, FALSE))
  1686. detect = TRUE;
  1687. if (detect_monsters_invis(range, FALSE))
  1688. detect = TRUE;
  1689. if (detect_monsters_normal(range, FALSE))
  1690. detect = TRUE;
  1691. /* Result */
  1692. return (detect);
  1693. }
  1694. /**
  1695. * Create stairs at the player location
  1696. */
  1697. void stair_creation(void)
  1698. {
  1699. int py = p_ptr->py;
  1700. int px = p_ptr->px;
  1701. /* XXX XXX XXX */
  1702. if (!cave_valid_bold(py, px)) {
  1703. msg("The object resists the spell.");
  1704. return;
  1705. }
  1706. /* Doesn't work outside caves */
  1707. if (chunk_list[p_ptr->stage].z_pos == 0) {
  1708. msg("You can only create stairs in caves!");
  1709. return;
  1710. }
  1711. /* XXX XXX XXX */
  1712. delete_object(py, px);
  1713. /* Create a staircase */
  1714. if (is_quest(p_ptr->stage) || (chunk_list[p_ptr->stage].z_pos == 127)) {
  1715. cave_set_feat(py, px, FEAT_LESS);
  1716. } else if (chunk_list[p_ptr->stage].z_pos == 0) {
  1717. cave_set_feat(py, px, FEAT_MORE);
  1718. } else if (randint0(100) < 50) {
  1719. cave_set_feat(py, px, FEAT_MORE);
  1720. } else {
  1721. cave_set_feat(py, px, FEAT_LESS);
  1722. }
  1723. }
  1724. /**
  1725. * Hook to specify "weapon"
  1726. */
  1727. static bool item_tester_hook_weapon(const object_type * o_ptr)
  1728. {
  1729. switch (o_ptr->tval) {
  1730. case TV_SWORD:
  1731. case TV_HAFTED:
  1732. case TV_POLEARM:
  1733. case TV_DIGGING:
  1734. case TV_BOW:
  1735. case TV_BOLT:
  1736. case TV_ARROW:
  1737. case TV_SHOT:
  1738. {
  1739. return (TRUE);
  1740. }
  1741. }
  1742. return (FALSE);
  1743. }
  1744. /**
  1745. * Hook to specify "ammunition"
  1746. */
  1747. static bool item_tester_hook_ammo(const object_type * o_ptr)
  1748. {
  1749. switch (o_ptr->tval) {
  1750. case TV_BOLT:
  1751. case TV_ARROW:
  1752. case TV_SHOT:
  1753. {
  1754. return (TRUE);
  1755. }
  1756. }
  1757. return (FALSE);
  1758. }
  1759. /**
  1760. * Hook to specify "armour"
  1761. */
  1762. static bool item_tester_hook_armour(const object_type * o_ptr)
  1763. {
  1764. switch (o_ptr->tval) {
  1765. case TV_DRAG_ARMOR:
  1766. case TV_HARD_ARMOR:
  1767. case TV_SOFT_ARMOR:
  1768. case TV_SHIELD:
  1769. case TV_CLOAK:
  1770. case TV_CROWN:
  1771. case TV_HELM:
  1772. case TV_BOOTS:
  1773. case TV_GLOVES:
  1774. {
  1775. return (TRUE);
  1776. }
  1777. }
  1778. return (FALSE);
  1779. }
  1780. static bool item_tester_unknown(const object_type * o_ptr)
  1781. {
  1782. if (object_known_p(o_ptr))
  1783. return FALSE;
  1784. else
  1785. return TRUE;
  1786. }
  1787. static bool item_tester_unknown_curse(const object_type * o_ptr)
  1788. {
  1789. if (object_known_p(o_ptr) && (o_ptr->ident & IDENT_KNOW_CURSES))
  1790. return FALSE;
  1791. else
  1792. return TRUE;
  1793. }
  1794. static bool item_tester_unproofed(const object_type * o_ptr)
  1795. {
  1796. if (o_ptr->number != 1)
  1797. return FALSE;
  1798. if (of_is_subset(o_ptr->flags_obj, el_to_proof))
  1799. return FALSE;
  1800. else
  1801. return TRUE;
  1802. }
  1803. /**
  1804. * Enchant an item
  1805. *
  1806. * Revamped! Now takes item pointer, number of times to try enchanting,
  1807. * and a flag of what to try enchanting. Artifacts resist enchantment
  1808. * some of the time, and successful enchantment to at least +0 might
  1809. * break a curse on the item. -CFT
  1810. *
  1811. * Note that an item can technically be enchanted all the way to +15 if
  1812. * you wait a very, very, long time. Going from +9 to +10 only works
  1813. * about 5% of the time, and from +10 to +11 only about 1% of the time.
  1814. *
  1815. * Note that this function can now be used on "piles" of items, and
  1816. * the larger the pile, the lower the chance of success.
  1817. */
  1818. bool enchant(object_type * o_ptr, int n, int eflag)
  1819. {
  1820. int i, chance, prob;
  1821. bool res = FALSE;
  1822. bool a = artifact_p(o_ptr);
  1823. /* Large piles resist enchantment */
  1824. prob = o_ptr->number * 100;
  1825. /* Missiles are easy to enchant */
  1826. if ((o_ptr->tval == TV_BOLT) || (o_ptr->tval == TV_ARROW)
  1827. || (o_ptr->tval == TV_SHOT)) {
  1828. prob = prob / 35;
  1829. }
  1830. /* Try "n" times */
  1831. for (i = 0; i < n; i++) {
  1832. /* Hack -- Roll for pile resistance */
  1833. if ((prob > 100) && (randint0(prob) >= 100))
  1834. continue;
  1835. /* Enchant to hit */
  1836. if (eflag & (ENCH_TOHIT)) {
  1837. if (o_ptr->to_h < 0)
  1838. chance = 0;
  1839. else if (o_ptr->to_h > 15)
  1840. chance = 1000;
  1841. else
  1842. chance = enchant_table[o_ptr->to_h];
  1843. /* Attempt to enchant */
  1844. if ((randint1(1000) > chance) && (!a || (randint0(100) < 50))) {
  1845. res = TRUE;
  1846. /* Enchant */
  1847. o_ptr->to_h++;
  1848. }
  1849. }
  1850. /* Enchant to damage */
  1851. if (eflag & (ENCH_TODAM)) {
  1852. if (o_ptr->to_d < 0)
  1853. chance = 0;
  1854. else if (o_ptr->to_d > 15)
  1855. chance = 1000;
  1856. else
  1857. chance = enchant_table[o_ptr->to_d];
  1858. if ((randint1(1000) > chance) && (!a || (randint0(100) < 50))) {
  1859. res = TRUE;
  1860. /* Enchant */
  1861. o_ptr->to_d++;
  1862. }
  1863. }
  1864. /* Enchant to armor class */
  1865. if (eflag & (ENCH_TOAC)) {
  1866. if (o_ptr->to_a < 0)
  1867. chance = 0;
  1868. else if (o_ptr->to_a > 15)
  1869. chance = 1000;
  1870. else
  1871. chance = enchant_table[o_ptr->to_a];
  1872. if ((randint1(1000) > chance) && (!a || (randint0(100) < 50))) {
  1873. res = TRUE;
  1874. /* Enchant */
  1875. o_ptr->to_a++;
  1876. }
  1877. }
  1878. }
  1879. /* Failure */
  1880. if (!res)
  1881. return (FALSE);
  1882. /* Recalculate bonuses */
  1883. p_ptr->update |= (PU_BONUS);
  1884. /* Combine / Reorder the pack (later) */
  1885. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  1886. /* Redraw stuff */
  1887. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  1888. /* Success */
  1889. return (TRUE);
  1890. }
  1891. /**
  1892. * Enchant an item (in the inventory or on the floor)
  1893. * Note that "num_ac" requires armour, else weapon
  1894. * Returns TRUE if attempted, FALSE if cancelled
  1895. */
  1896. bool enchant_spell(int num_hit, int num_dam, int num_ac)
  1897. {
  1898. int item;
  1899. bool okay = FALSE;
  1900. object_type *o_ptr;
  1901. char o_name[120];
  1902. const char *q, *s;
  1903. /* Assume enchant weapon */
  1904. item_tester_hook = item_tester_hook_weapon;
  1905. /* Don't restrict choices */
  1906. item_tester_tval = 0;
  1907. /* Enchant armor if requested */
  1908. if (num_ac)
  1909. item_tester_hook = item_tester_hook_armour;
  1910. /* Get an item */
  1911. q = "Enchant which item? ";
  1912. s = "You have nothing to enchant.";
  1913. if (!get_item
  1914. (&item, q, s, CMD_NULL, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
  1915. return (FALSE);
  1916. /* Get the item (in the pack) */
  1917. if (item >= 0) {
  1918. o_ptr = &p_ptr->inventory[item];
  1919. }
  1920. /* Get the item (on the floor) */
  1921. else {
  1922. o_ptr = &o_list[0 - item];
  1923. }
  1924. /* Description */
  1925. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  1926. /* Describe */
  1927. msg("%s %s glow%s brightly!", ((item >= 0) ? "Your" : "The"), o_name,
  1928. ((o_ptr->number > 1) ? "" : "s"));
  1929. /* Enchant */
  1930. if (enchant(o_ptr, num_hit, ENCH_TOHIT))
  1931. okay = TRUE;
  1932. if (enchant(o_ptr, num_dam, ENCH_TODAM))
  1933. okay = TRUE;
  1934. if (enchant(o_ptr, num_ac, ENCH_TOAC))
  1935. okay = TRUE;
  1936. /* Failure */
  1937. if (!okay) {
  1938. /* Flush */
  1939. if (OPT(flush_failure))
  1940. flush();
  1941. /* Message */
  1942. msg("The enchantment failed.");
  1943. }
  1944. /* Something happened */
  1945. return (TRUE);
  1946. }
  1947. /**
  1948. * Enchant some missiles and give them an elemental brand
  1949. *
  1950. * Combines the old brand_bolts and brand_missiles routines.
  1951. *
  1952. * ammo_type is the tval of the relevant ammunition.
  1953. * If set to 0, any ammunition is enchantable.
  1954. *
  1955. * Brand type is the EGO flag for the relevant type element.
  1956. * If set to 0, a non-poison brand is picked randomly.
  1957. *
  1958. */
  1959. bool brand_missile(int ammo_type, int brand_type)
  1960. {
  1961. int item, choice;
  1962. object_type *o_ptr;
  1963. const char *q, *s;
  1964. bool status;
  1965. /* Restrict choices Hack - check for restricted choice */
  1966. if ((ammo_type >= TV_SHOT) && (ammo_type <= TV_BOLT))
  1967. item_tester_tval = ammo_type;
  1968. /* Otherwise any ammo will do */
  1969. else
  1970. item_tester_hook = item_tester_hook_ammo;
  1971. /* Get an item */
  1972. q = "Enchant which ammunition? ";
  1973. s = "You have no ammunition to brand.";
  1974. status = get_item(&item, q, s, 0, (USE_EQUIP | USE_INVEN | USE_FLOOR));
  1975. /* Hack - if failed, return, but only after resetting the ammo hack */
  1976. if (!status)
  1977. return (FALSE);
  1978. if (item >= 0) {
  1979. o_ptr = &p_ptr->inventory[item];
  1980. }
  1981. /* Get the item (on the floor) */
  1982. else {
  1983. o_ptr = &o_list[0 - item];
  1984. }
  1985. /*
  1986. * Don't enchant artifacts or ego-items
  1987. */
  1988. if (artifact_p(o_ptr) || ego_item_p(o_ptr)) {
  1989. /* Flush */
  1990. if (OPT(flush_failure))
  1991. flush();
  1992. /* Fail */
  1993. msg("The ammunition enchantment failed.");
  1994. /* Notice */
  1995. return (TRUE);
  1996. }
  1997. /* Type of brand may be restricted */
  1998. if (brand_type)
  1999. choice = brand_type;
  2000. /* Otherwise choose randomly Hack - Never get poison brand randomly */
  2001. else
  2002. choice = randint0(4) + EGO_ACIDIC;
  2003. switch (choice) {
  2004. case EGO_FLAME:
  2005. {
  2006. /* Print message and fire brand missiles. */
  2007. msg("Your missiles are covered in a fiery aura!");
  2008. break;
  2009. }
  2010. case EGO_FROST:
  2011. {
  2012. /* Print message and frost brand missiles. */
  2013. msg("Your missiles are covered in a frosty sheath!");
  2014. break;
  2015. }
  2016. case EGO_ACIDIC:
  2017. {
  2018. /* Print message and acid brand missiles. */
  2019. msg("Your missiles sizzle with acid!");
  2020. break;
  2021. }
  2022. case EGO_ELECT:
  2023. {
  2024. /* Print message and electric brand missiles. */
  2025. msg("Your missiles are covered in sparks!");
  2026. break;
  2027. }
  2028. case EGO_POISON:
  2029. {
  2030. /* Print message and poison brand missiles. */
  2031. msg("Your missiles drip with deadly poison!");
  2032. break;
  2033. }
  2034. default:
  2035. {
  2036. /* Oops */
  2037. return (FALSE);
  2038. }
  2039. }
  2040. /* Brand */
  2041. o_ptr->name2 = choice;
  2042. o_ptr->multiple_brand[choice - EGO_ACIDIC] = BRAND_BOOST_NORMAL;
  2043. /* Known now */
  2044. identify_object(o_ptr);
  2045. /* Enchant */
  2046. enchant(o_ptr, randint0(4) + 3, ENCH_TOHIT | ENCH_TODAM);
  2047. /* Prevent money-making. */
  2048. o_ptr->discount = 80;
  2049. /* Notice */
  2050. return (TRUE);
  2051. }
  2052. /**
  2053. * Set a temporary elemental brand. Clear all other brands. Print status
  2054. * messages. -LM-
  2055. */
  2056. void set_ele_attack(u32b attack_type, int duration)
  2057. {
  2058. /* Clear all elemental attacks (only one is allowed at a time). */
  2059. if ((p_ptr->special_attack & (ATTACK_ACID))
  2060. && (attack_type != ATTACK_ACID)) {
  2061. p_ptr->special_attack &= ~(ATTACK_ACID);
  2062. clear_timed(TMD_ATT_ACID, TRUE);
  2063. }
  2064. if ((p_ptr->special_attack & (ATTACK_ELEC))
  2065. && (attack_type != ATTACK_ELEC)) {
  2066. p_ptr->special_attack &= ~(ATTACK_ELEC);
  2067. clear_timed(TMD_ATT_ELEC, TRUE);
  2068. }
  2069. if ((p_ptr->special_attack & (ATTACK_FIRE))
  2070. && (attack_type != ATTACK_FIRE)) {
  2071. p_ptr->special_attack &= ~(ATTACK_FIRE);
  2072. clear_timed(TMD_ATT_FIRE, TRUE);
  2073. }
  2074. if ((p_ptr->special_attack & (ATTACK_COLD))
  2075. && (attack_type != ATTACK_COLD)) {
  2076. p_ptr->special_attack &= ~(ATTACK_COLD);
  2077. clear_timed(TMD_ATT_COLD, TRUE);
  2078. }
  2079. if ((p_ptr->special_attack & (ATTACK_POIS))
  2080. && (attack_type != ATTACK_POIS)) {
  2081. p_ptr->special_attack &= ~(ATTACK_POIS);
  2082. clear_timed(TMD_ATT_POIS, TRUE);
  2083. }
  2084. if ((duration) && (attack_type)) {
  2085. int type;
  2086. /* Set attack type. */
  2087. p_ptr->special_attack |= (attack_type);
  2088. switch (attack_type) {
  2089. case ATTACK_ACID:{
  2090. type = TMD_ATT_ACID;
  2091. break;
  2092. }
  2093. case ATTACK_ELEC:{
  2094. type = TMD_ATT_ELEC;
  2095. break;
  2096. }
  2097. case ATTACK_FIRE:{
  2098. type = TMD_ATT_FIRE;
  2099. break;
  2100. }
  2101. case ATTACK_COLD:{
  2102. type = TMD_ATT_COLD;
  2103. break;
  2104. }
  2105. case ATTACK_POIS:{
  2106. type = TMD_ATT_POIS;
  2107. break;
  2108. }
  2109. default:{
  2110. return;
  2111. }
  2112. }
  2113. /* Set duration. */
  2114. inc_timed(type, duration, TRUE);
  2115. }
  2116. }
  2117. /**
  2118. * Proof an object against an element
  2119. */
  2120. bool el_proof(bitflag * flag)
  2121. {
  2122. object_type *o_ptr;
  2123. int item;
  2124. const char *q, *s;
  2125. /* Set the element */
  2126. of_wipe(el_to_proof);
  2127. of_copy(el_to_proof, flag);
  2128. /* Only unproofed items */
  2129. item_tester_hook = item_tester_unproofed;
  2130. /* Don't restrict choices */
  2131. item_tester_tval = 0;
  2132. /* Get an item */
  2133. q = "Proof which single item? ";
  2134. s = "You have no single item to proof.";
  2135. if (!get_item(&item, q, s, 0, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
  2136. return (FALSE);
  2137. /* Get the item (in the pack) */
  2138. if (item >= 0) {
  2139. o_ptr = &p_ptr->inventory[item];
  2140. }
  2141. /* Get the item (on the floor) */
  2142. else {
  2143. o_ptr = &o_list[0 - item];
  2144. }
  2145. /* Proof it */
  2146. of_union(o_ptr->flags_obj, flag);
  2147. of_union(o_ptr->id_obj, flag);
  2148. /* Done */
  2149. return (TRUE);
  2150. }
  2151. /**
  2152. * Curse the players armor
  2153. */
  2154. bool curse_armor(void)
  2155. {
  2156. object_type *o_ptr;
  2157. char o_name[120];
  2158. int slot = INVEN_BODY;
  2159. /* Curse the body armor */
  2160. o_ptr = &p_ptr->inventory[INVEN_BODY];
  2161. /* Nothing to curse */
  2162. if (!o_ptr->k_idx)
  2163. return (FALSE);
  2164. /* Describe */
  2165. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL);
  2166. /* Attempt a saving throw for artifacts */
  2167. if (artifact_p(o_ptr) && (randint0(100) < 50)) {
  2168. /* Cool */
  2169. msg("A %s tries to %s, but your %s resists the effects!",
  2170. "terrible black aura", "surround your armor", o_name);
  2171. }
  2172. /* not artifact or failed save... */
  2173. else {
  2174. int i, feel;
  2175. bool heavy = FALSE;
  2176. /* Oops */
  2177. msg("A terrible black aura blasts your %s!", o_name);
  2178. /* Try every curse */
  2179. for (i = FLAG_START; i < CF_MAX; i++) {
  2180. if (randint0(100) < 10) {
  2181. /* Try once */
  2182. (void) cf_on(o_ptr->flags_curse, i);
  2183. }
  2184. }
  2185. /* Hack - no sticky curses on permacursed things */
  2186. if (of_has(o_ptr->flags_obj, OF_PERMA_CURSE)) {
  2187. (void) cf_off(o_ptr->flags_curse, CF_STICKY_WIELD);
  2188. (void) cf_off(o_ptr->flags_curse, CF_STICKY_CARRY);
  2189. }
  2190. /* Not uncursed */
  2191. o_ptr->ident &= ~(IDENT_UNCURSED | IDENT_KNOW_CURSES);
  2192. /* Heavy sensing */
  2193. heavy = (player_has(PF_PSEUDO_ID_HEAVY));
  2194. /* Type of feeling */
  2195. feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
  2196. /* Redo feeling */
  2197. if (!(o_ptr->feel == feel)) {
  2198. /* Get an object description */
  2199. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  2200. msg("You feel the %s (%c) you are %s %s now %s...", o_name,
  2201. index_to_label(slot), describe_use(slot),
  2202. ((o_ptr->number == 1) ? "is" : "are"), feel_text[feel]);
  2203. /* We have "felt" it */
  2204. o_ptr->ident |= (IDENT_SENSE);
  2205. /* Inscribe it textually */
  2206. o_ptr->feel = feel;
  2207. /* Set squelch flag as appropriate */
  2208. p_ptr->notice |= PN_SQUELCH;
  2209. }
  2210. /* Recalculate bonuses */
  2211. p_ptr->update |= (PU_BONUS);
  2212. /* Recalculate mana */
  2213. p_ptr->update |= (PU_MANA);
  2214. /* Redraw stuff */
  2215. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  2216. }
  2217. return (TRUE);
  2218. }
  2219. /**
  2220. * Curse the players weapon
  2221. */
  2222. bool curse_weapon(void)
  2223. {
  2224. object_type *o_ptr;
  2225. char o_name[120];
  2226. int slot = INVEN_WIELD;
  2227. /* Curse the weapon */
  2228. o_ptr = &p_ptr->inventory[INVEN_WIELD];
  2229. /* Nothing to curse */
  2230. if (!o_ptr->k_idx)
  2231. return (FALSE);
  2232. /* Describe */
  2233. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_FULL);
  2234. /* Attempt a saving throw */
  2235. if (artifact_p(o_ptr) && (randint0(100) < 50)) {
  2236. /* Cool */
  2237. msg("A %s tries to %s, but your %s resists the effects!",
  2238. "terrible black aura", "surround your weapon", o_name);
  2239. }
  2240. /* not artifact or failed save... */
  2241. else {
  2242. int i, feel;
  2243. bool heavy = FALSE;
  2244. /* Oops */
  2245. msg("A terrible black aura blasts your %s!", o_name);
  2246. /* Try every curse */
  2247. for (i = FLAG_START; i < CF_MAX; i++) {
  2248. if (randint0(100) < 10) {
  2249. /* Try once */
  2250. (void) cf_on(o_ptr->flags_curse, i);
  2251. }
  2252. }
  2253. /* Hack - no sticky curses on permacursed things */
  2254. if (of_has(o_ptr->flags_obj, OF_PERMA_CURSE)) {
  2255. (void) cf_off(o_ptr->flags_curse, CF_STICKY_WIELD);
  2256. (void) cf_off(o_ptr->flags_curse, CF_STICKY_CARRY);
  2257. }
  2258. /* Not uncursed */
  2259. o_ptr->ident &= ~(IDENT_UNCURSED | IDENT_KNOW_CURSES);
  2260. /* Heavy sensing */
  2261. heavy = (player_has(PF_PSEUDO_ID_HEAVY));
  2262. /* Type of feeling */
  2263. feel = (heavy ? value_check_aux1(o_ptr) : value_check_aux2(o_ptr));
  2264. /* Redo feeling */
  2265. if (!(o_ptr->feel == feel)) {
  2266. /* Get an object description */
  2267. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  2268. msg("You feel the %s (%c) you are %s %s now %s...", o_name,
  2269. index_to_label(slot), describe_use(slot),
  2270. ((o_ptr->number == 1) ? "is" : "are"), feel_text[feel]);
  2271. /* We have "felt" it */
  2272. o_ptr->ident |= (IDENT_SENSE);
  2273. /* Inscribe it textually */
  2274. o_ptr->feel = feel;
  2275. /* Set squelch flag as appropriate */
  2276. p_ptr->notice |= PN_SQUELCH;
  2277. }
  2278. /* Recalculate bonuses */
  2279. p_ptr->update |= (PU_BONUS);
  2280. /* Recalculate mana */
  2281. p_ptr->update |= (PU_MANA);
  2282. /* Redraw stuff */
  2283. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  2284. }
  2285. /* Notice */
  2286. return (TRUE);
  2287. }
  2288. /**
  2289. * Identify an object in the inventory, apart from curses.
  2290. *
  2291. * This routine returns TRUE if an item was identified.
  2292. */
  2293. bool ident_spell(void)
  2294. {
  2295. int item;
  2296. int squelch = 0;
  2297. object_type *o_ptr;
  2298. char o_name[120];
  2299. const char *q, *s;
  2300. /* Only un-id'ed items */
  2301. item_tester_hook = item_tester_unknown;
  2302. /* Don't restrict choices */
  2303. item_tester_tval = 0;
  2304. /* Get an item. */
  2305. q = "Identify which item? ";
  2306. s = "You have nothing to identify.";
  2307. if (!get_item(&item, q, s, 0, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
  2308. return (FALSE);
  2309. /* Get the item (in the pack) */
  2310. if (item >= 0) {
  2311. o_ptr = &p_ptr->inventory[item];
  2312. }
  2313. /* Get the item (on the floor) */
  2314. else {
  2315. o_ptr = &o_list[0 - item];
  2316. }
  2317. /* Identify it */
  2318. identify_object(o_ptr);
  2319. /* Recalculate bonuses */
  2320. p_ptr->update |= (PU_BONUS);
  2321. /* Combine / Reorder the pack (later) */
  2322. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  2323. /* Redraw stuff */
  2324. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  2325. /* Handle stuff */
  2326. handle_stuff(p_ptr);
  2327. /* Description */
  2328. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_PREFIX | ODESC_FULL);
  2329. /* Possibly play a sound depending on object quality. */
  2330. if (o_ptr->name1 != 0) {
  2331. /* We have a good artifact. */
  2332. sound(MSG_IDENT_ART);
  2333. } else if (o_ptr->name2 != 0) {
  2334. /* We have a good ego item. */
  2335. sound(MSG_IDENT_EGO);
  2336. }
  2337. /* Describe */
  2338. if (item >= INVEN_WIELD) {
  2339. char *m = format("%s: %s (%c).", describe_use(item), o_name,
  2340. index_to_label(item));
  2341. my_strcap(m);
  2342. msg(m);
  2343. } else if (item >= 0) {
  2344. msg("In your pack: %s (%c). %s", o_name, index_to_label(item),
  2345. ((squelch ==
  2346. 1) ? "(Squelch)" : ((squelch ==
  2347. -1) ? "(Squelch Failed)" : "")));
  2348. } else {
  2349. msg("On the ground: %s. %s", o_name,
  2350. ((squelch ==
  2351. 1) ? "(Squelch)" : ((squelch ==
  2352. -1) ? "(Squelch Failed)" : "")));
  2353. }
  2354. /* If artifact, check for Set Item */
  2355. if (o_ptr->name1) {
  2356. artifact_type *a_ptr = &a_info[o_ptr->name1];
  2357. if (a_ptr->set_no != 0) {
  2358. msg("This item is part of a set!");
  2359. }
  2360. }
  2361. /* Success */
  2362. return (TRUE);
  2363. }
  2364. /**
  2365. * Identify an object in the inventory, including curses.
  2366. *
  2367. * This routine returns TRUE if an item was identified.
  2368. */
  2369. bool identify_fully(void)
  2370. {
  2371. int item;
  2372. object_type *o_ptr;
  2373. const char *q, *s;
  2374. char header[120];
  2375. textblock *tb;
  2376. region area = { 0, 0, 0, 0 };
  2377. /* Only un-*id*'ed items */
  2378. item_tester_hook = item_tester_unknown_curse;
  2379. /* Don't restrict choices */
  2380. item_tester_tval = 0;
  2381. /* Get an item. */
  2382. q = "Reveal curses on which item? ";
  2383. s = "You have nothing to reveal curses on.";
  2384. if (!get_item(&item, q, s, 0, (USE_EQUIP | USE_INVEN | USE_FLOOR)))
  2385. return (FALSE);
  2386. /* Get the item (in the pack) */
  2387. if (item >= 0) {
  2388. o_ptr = &p_ptr->inventory[item];
  2389. }
  2390. /* Get the item (on the floor) */
  2391. else {
  2392. o_ptr = &o_list[0 - item];
  2393. }
  2394. /* Identify it */
  2395. identify_object(o_ptr);
  2396. /* Know the curses */
  2397. cf_copy(o_ptr->id_curse, o_ptr->flags_curse);
  2398. o_ptr->ident |= IDENT_KNOW_CURSES;
  2399. if (cf_is_empty(o_ptr->flags_curse)) {
  2400. o_ptr->ident |= IDENT_UNCURSED;
  2401. msg("This item has no curses.");
  2402. } else {
  2403. tb = object_info(o_ptr, OINFO_FULL);
  2404. object_desc(header, sizeof(header), o_ptr,
  2405. ODESC_PREFIX | ODESC_FULL);
  2406. textui_textblock_show(tb, area, header);
  2407. textblock_free(tb);
  2408. }
  2409. /* Recalculate bonuses */
  2410. p_ptr->update |= (PU_BONUS);
  2411. /* Combine / Reorder the pack (later) */
  2412. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  2413. /* Redraw stuff */
  2414. p_ptr->redraw |= (PR_INVEN | PR_EQUIP);
  2415. /* Handle stuff */
  2416. handle_stuff(p_ptr);
  2417. /* Success */
  2418. return (TRUE);
  2419. }
  2420. /**
  2421. * Hook for "get_item()". Determine if something is rechargable.
  2422. */
  2423. static bool item_tester_hook_recharge(const object_type * o_ptr)
  2424. {
  2425. /* Recharge staffs */
  2426. if (o_ptr->tval == TV_STAFF)
  2427. return (TRUE);
  2428. /* Recharge wands */
  2429. if (o_ptr->tval == TV_WAND)
  2430. return (TRUE);
  2431. /* Recharge rods */
  2432. if (o_ptr->tval == TV_ROD)
  2433. return (TRUE);
  2434. /* Nope */
  2435. return (FALSE);
  2436. }
  2437. /**
  2438. * Recharge a wand/staff/rod from the pack or on the floor.
  2439. * This function has been rewritten in Oangband. -LM-
  2440. *
  2441. * Mage -- Recharge I --> recharge(85)
  2442. * Mage -- Recharge II --> recharge(150)
  2443. * Mage -- Recharge III --> recharge(220)
  2444. *
  2445. * Druid -- Infusion --> recharge(125)
  2446. *
  2447. * Priest or Necromancer -- Recharge --> recharge(140)
  2448. *
  2449. * Scroll of recharging --> recharge(130)
  2450. * Scroll of *recharging* --> recharge(200)
  2451. *
  2452. * It is harder to recharge high level, and highly charged wands,
  2453. * staffs, and rods. The more wands in a stack, the more easily and
  2454. * strongly they recharge. Staffs, however, each get fewer charges if
  2455. * stacked.
  2456. *
  2457. * XXX XXX XXX Beware of "sliding index errors".
  2458. */
  2459. bool recharge(int power)
  2460. {
  2461. int item, lev;
  2462. int recharge_strength, recharge_amount;
  2463. object_type *o_ptr;
  2464. object_kind *k_ptr;
  2465. bool fail = FALSE;
  2466. byte fail_type = 1;
  2467. const char *q, *s;
  2468. char o_name[120];
  2469. /* Only accept legal items */
  2470. item_tester_hook = item_tester_hook_recharge;
  2471. /* Don't restrict choices */
  2472. item_tester_tval = 0;
  2473. /* Get an item */
  2474. q = "Recharge which item? ";
  2475. s = "You have nothing to recharge.";
  2476. if (!get_item(&item, q, s, 0, (USE_INVEN | USE_FLOOR)))
  2477. return (FALSE);
  2478. /* Get the item (in the pack) */
  2479. if (item >= 0) {
  2480. o_ptr = &p_ptr->inventory[item];
  2481. }
  2482. /* Get the item (on the floor) */
  2483. else {
  2484. o_ptr = &o_list[0 - item];
  2485. }
  2486. /* Get the object kind. */
  2487. k_ptr = &k_info[o_ptr->k_idx];
  2488. /* Extract the object "level" */
  2489. lev = k_info[o_ptr->k_idx].level;
  2490. /* Recharge a rod */
  2491. if (o_ptr->tval == TV_ROD) {
  2492. /* Extract a recharge strength by comparing object level to power. */
  2493. recharge_strength = ((power > lev) ? (power - lev) : 0) / 5;
  2494. /* Back-fire */
  2495. if (randint0(recharge_strength) == 0) {
  2496. /* Activate the failure code. */
  2497. fail = TRUE;
  2498. }
  2499. /* Recharge */
  2500. else {
  2501. /* Recharge amount */
  2502. recharge_amount = (power * damroll(3, 2));
  2503. /* Recharge by that amount */
  2504. if (o_ptr->timeout > recharge_amount)
  2505. o_ptr->timeout -= recharge_amount;
  2506. else
  2507. o_ptr->timeout = 0;
  2508. }
  2509. }
  2510. /* Recharge wand/staff */
  2511. else {
  2512. /* Extract a recharge strength by comparing object level to power.
  2513. * Divide up a stack of wands' charges to calculate charge penalty. */
  2514. if (((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF)) &&
  2515. (o_ptr->number > 1))
  2516. recharge_strength =
  2517. (100 + power - lev -
  2518. (8 * o_ptr->pval / o_ptr->number)) / 15;
  2519. /* All unstacked staffs, wands. */
  2520. else
  2521. recharge_strength =
  2522. (100 + power - lev - (8 * o_ptr->pval)) / 15;
  2523. /* Back-fire */
  2524. if ((recharge_strength < 0) || (randint0(recharge_strength) == 0)) {
  2525. /* Activate the failure code. */
  2526. fail = TRUE;
  2527. }
  2528. /* If the spell didn't backfire, recharge the wand or staff. */
  2529. else {
  2530. /* Recharge based on the standard number of charges. */
  2531. recharge_amount =
  2532. randint1(1 + randcalc(k_ptr->pval, lev, RANDOMISE) / 2);
  2533. /* Multiple wands in a stack increase recharging somewhat. */
  2534. if ((o_ptr->tval == TV_WAND) && (o_ptr->number > 1)) {
  2535. recharge_amount +=
  2536. (randint1(recharge_amount * (o_ptr->number - 1))) / 2;
  2537. if (recharge_amount < 1)
  2538. recharge_amount = 1;
  2539. if (recharge_amount > 12)
  2540. recharge_amount = 12;
  2541. }
  2542. /* But each staff in a stack gets fewer additional charges,
  2543. * although always at least one. */
  2544. if ((o_ptr->tval == TV_STAFF) && (o_ptr->number > 1)) {
  2545. recharge_amount /= o_ptr->number;
  2546. if (recharge_amount < 1)
  2547. recharge_amount = 1;
  2548. }
  2549. /* Recharge the wand or staff. */
  2550. o_ptr->pval += recharge_amount;
  2551. /* Artifacts have a maximum # of charges. */
  2552. if (artifact_p(o_ptr) && (o_ptr->pval > k_ptr->pval.base))
  2553. o_ptr->pval = k_ptr->pval.base;
  2554. /* We no longer think the item is empty */
  2555. o_ptr->ident &= ~(IDENT_EMPTY);
  2556. }
  2557. }
  2558. /* Inflict the penalties for failing a recharge. */
  2559. if (fail) {
  2560. /* Artifacts are never destroyed. */
  2561. if (artifact_p(o_ptr)) {
  2562. object_desc(o_name, sizeof(o_name), o_ptr,
  2563. ODESC_PREFIX | ODESC_BASE);
  2564. msg("The recharging backfires - %s is completely drained!",
  2565. o_name);
  2566. /* Artifact rods. */
  2567. if ((o_ptr->tval == TV_ROD) && (o_ptr->timeout < 10000))
  2568. o_ptr->timeout = (o_ptr->timeout + 100) * 2;
  2569. /* Artifact wands and staffs. */
  2570. else if ((o_ptr->tval == TV_WAND) || (o_ptr->tval == TV_STAFF))
  2571. o_ptr->pval = 0;
  2572. } else {
  2573. /* Get the object description */
  2574. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  2575. /*** Determine Seriousness of Failure ***/
  2576. /* Mages recharge objects more safely. */
  2577. if (player_has(PF_DEVICE_EXPERT)) {
  2578. /* 10% chance to blow up one rod, otherwise draining. */
  2579. if (o_ptr->tval == TV_ROD) {
  2580. if (randint1(10) == 1)
  2581. fail_type = 2;
  2582. else
  2583. fail_type = 1;
  2584. }
  2585. /* 67% chance to blow up one wand, otherwise draining. */
  2586. else if (o_ptr->tval == TV_WAND) {
  2587. if (randint1(3) != 1)
  2588. fail_type = 2;
  2589. else
  2590. fail_type = 1;
  2591. }
  2592. /* 50% chance to blow up one staff, otherwise no effect. */
  2593. else if (o_ptr->tval == TV_STAFF) {
  2594. if (randint1(2) == 1)
  2595. fail_type = 2;
  2596. else
  2597. fail_type = 0;
  2598. }
  2599. }
  2600. /* All other classes get no special favors. */
  2601. else {
  2602. /* 33% chance to blow up one rod, otherwise draining. */
  2603. if (o_ptr->tval == TV_ROD) {
  2604. if (randint1(3) == 1)
  2605. fail_type = 2;
  2606. else
  2607. fail_type = 1;
  2608. }
  2609. /* 20% chance of the entire stack, else destroy one wand. */
  2610. else if (o_ptr->tval == TV_WAND) {
  2611. if (randint1(5) == 1)
  2612. fail_type = 3;
  2613. else
  2614. fail_type = 2;
  2615. }
  2616. /* Blow up one staff. */
  2617. else if (o_ptr->tval == TV_STAFF) {
  2618. fail_type = 2;
  2619. }
  2620. }
  2621. /*** Apply draining and destruction. ***/
  2622. /* Drain object or stack of objects. */
  2623. if (fail_type == 1) {
  2624. if (o_ptr->tval == TV_ROD) {
  2625. msg("The recharge backfires, draining the rod further!");
  2626. if (o_ptr->timeout < 10000)
  2627. o_ptr->timeout = (o_ptr->timeout + 100) * 2;
  2628. } else if (o_ptr->tval == TV_WAND) {
  2629. msg("You save your %s from destruction, but all charges are lost.", o_name);
  2630. o_ptr->pval = 0;
  2631. }
  2632. /* Staffs aren't drained. */
  2633. }
  2634. /* Destroy an object or one in a stack of objects. */
  2635. if (fail_type == 2) {
  2636. if (o_ptr->number > 1)
  2637. msg("Wild magic consumes one of your %s!", o_name);
  2638. else
  2639. msg("Wild magic consumes your %s!", o_name);
  2640. /* Reduce rod stack maximum timeout, drain wands. */
  2641. if (o_ptr->tval == TV_WAND)
  2642. o_ptr->pval = 0;
  2643. /* Reduce the charges of rods/wands/staves */
  2644. reduce_charges(o_ptr, 1);
  2645. /* Reduce and describe inventory */
  2646. if (item >= 0) {
  2647. inven_item_increase(item, -1);
  2648. inven_item_describe(item);
  2649. inven_item_optimize(item);
  2650. }
  2651. /* Reduce and describe floor item */
  2652. else {
  2653. floor_item_increase(0 - item, -1);
  2654. floor_item_describe(0 - item);
  2655. floor_item_optimize(0 - item);
  2656. }
  2657. }
  2658. /* Destroy some members of a stack of objects. */
  2659. if (fail_type == 3) {
  2660. int num_gone = -2;
  2661. if (o_ptr->number > 1)
  2662. msg("Wild magic consumes some of your %s!", o_name);
  2663. else
  2664. msg("Wild magic consumes your %s!", o_name);
  2665. /* At least 2 gone, roll for others */
  2666. while ((o_ptr->number + num_gone) > 0)
  2667. if (randint0(4) == 0)
  2668. num_gone--;
  2669. /* Reduce the charges of rods/wands/staves */
  2670. reduce_charges(o_ptr, num_gone);
  2671. /* Reduce and describe inventory */
  2672. if (item >= 0) {
  2673. inven_item_increase(item, num_gone);
  2674. inven_item_describe(item);
  2675. inven_item_optimize(item);
  2676. }
  2677. /* Reduce and describe floor item */
  2678. else {
  2679. floor_item_increase(0 - item, num_gone);
  2680. floor_item_describe(0 - item);
  2681. floor_item_optimize(0 - item);
  2682. }
  2683. }
  2684. }
  2685. }
  2686. /* Combine / Reorder the pack (later) */
  2687. p_ptr->notice |= (PN_COMBINE | PN_REORDER);
  2688. /* Redraw stuff */
  2689. p_ptr->redraw |= (PR_INVEN);
  2690. /* Something was done */
  2691. return (TRUE);
  2692. }
  2693. /**
  2694. * Mages can get mana from magical objects at need. -LM-
  2695. */
  2696. void tap_magical_energy(void)
  2697. {
  2698. int item, lev;
  2699. int energy = 0;
  2700. object_type *o_ptr;
  2701. const char *q, *s;
  2702. char *item_name = "";
  2703. /* Only accept legal items */
  2704. item_tester_hook = item_tester_hook_recharge;
  2705. /* Get an item */
  2706. q = "Drain charges from which item? ";
  2707. s = "You have nothing to drain charges from.";
  2708. if (!get_item(&item, q, s, 0, (USE_INVEN | USE_FLOOR)))
  2709. return;
  2710. /* Get the item (in the pack) */
  2711. if (item >= 0) {
  2712. o_ptr = &p_ptr->inventory[item];
  2713. }
  2714. /* Get the item (on the floor) */
  2715. else {
  2716. o_ptr = &o_list[0 - item];
  2717. }
  2718. /* Extract the object "level" */
  2719. lev = k_info[o_ptr->k_idx].level;
  2720. /* Extract the object's energy and get its generic name. */
  2721. if (o_ptr->tval == TV_ROD) {
  2722. /* Rods have little usable energy, for obvious balance reasons... */
  2723. energy = (lev * o_ptr->number * 2) / 3;
  2724. /* No tapping rods with instant recharge */
  2725. if (!(o_ptr->pval))
  2726. energy = 0;
  2727. /* Modify Based on charged-ness */
  2728. if (o_ptr->pval)
  2729. energy =
  2730. (energy * (o_ptr->pval - o_ptr->timeout)) / o_ptr->pval;
  2731. item_name = "rod";
  2732. }
  2733. if (o_ptr->tval == TV_STAFF) {
  2734. energy = (5 + lev) * o_ptr->pval;
  2735. item_name = "staff";
  2736. }
  2737. if (o_ptr->tval == TV_WAND) {
  2738. energy = (5 + lev) * 3 * o_ptr->pval / 2;
  2739. item_name = "wand";
  2740. }
  2741. /* Turn energy into mana. */
  2742. /* Require a resonable amount of energy */
  2743. if (energy < 36) {
  2744. /* Notify of failure. */
  2745. msg("That %s had no useable energy", item_name);
  2746. } else {
  2747. /* If mana below maximum, increase mana and drain object. */
  2748. if (p_ptr->csp < p_ptr->msp) {
  2749. /* Drain the object. */
  2750. if (o_ptr->tval == TV_ROD)
  2751. o_ptr->timeout = o_ptr->pval;
  2752. else
  2753. o_ptr->pval = 0;
  2754. /* Combine / Reorder the pack (later) */
  2755. p_ptr->notice |= (PN_COMBINE | PN_REORDER);
  2756. /* Redraw stuff */
  2757. p_ptr->redraw |= (PR_INVEN);
  2758. /* Increase mana. */
  2759. p_ptr->csp += energy / 12;
  2760. p_ptr->csp_frac = 0;
  2761. if (p_ptr->csp > p_ptr->msp)
  2762. (p_ptr->csp = p_ptr->msp);
  2763. msg("You feel your head clear.");
  2764. p_ptr->redraw |= (PR_MANA);
  2765. }
  2766. /* Player is a smart cookie. */
  2767. else {
  2768. my_strcap(item_name);
  2769. msg("Your mana was already at its maximum. %s not drained.",
  2770. item_name);
  2771. }
  2772. }
  2773. }
  2774. /**
  2775. * Special code for staff of starlight and the Staff of Gandalf. Most
  2776. * effective against monsters that start out in darkness, and against
  2777. * those who hate light. -LM-
  2778. */
  2779. void do_starlight(int burst_number, int dam, bool strong)
  2780. {
  2781. int i, j, y, x;
  2782. feature_type *f_ptr;
  2783. /* Is the player in a square already magically lit? */
  2784. bool player_lit = cave_has(cave_info[p_ptr->py][p_ptr->px], CAVE_GLOW);
  2785. for (i = 0; i < burst_number; i++) {
  2786. /* First, we find the spot. */
  2787. for (j = 0; j < 20; j++) {
  2788. /* Pick a (scattered) distance. */
  2789. int d = 2 + randint0(4);
  2790. /* Admit failure. Switch to Plan B. */
  2791. if (j == 19) {
  2792. y = p_ptr->py;
  2793. x = p_ptr->px;
  2794. break;
  2795. }
  2796. /* Pick a location */
  2797. scatter(&y, &x, p_ptr->py, p_ptr->px, d, 0);
  2798. /* Not on top of the player. */
  2799. if (cave_m_idx[y][x] < 0)
  2800. continue;
  2801. /* Require passable terrain */
  2802. f_ptr = &f_info[cave_feat[y][x]];
  2803. if (!tf_has(f_ptr->flags, TF_PASSABLE))
  2804. continue;
  2805. /* Spot chosen. */
  2806. break;
  2807. }
  2808. /* Then we hit the spot. */
  2809. /* Confusing to be suddenly lit up. */
  2810. if (!cave_has(cave_info[y][x], CAVE_GLOW))
  2811. fire_meteor(-1, GF_CONFU, y, x, dam, strong ? 1 : 0, FALSE);
  2812. /* The actual burst of light. */
  2813. fire_meteor(-1, GF_LIGHT_WEAK, y, x, dam, strong ? 2 : 1, FALSE);
  2814. fire_meteor(-1, GF_LIGHT, y, x, dam, strong ? 1 : 0, FALSE);
  2815. /* Hack - assume that the player's square is typical of the area, and
  2816. * only light those squares that weren't already magically lit
  2817. * temporarily. */
  2818. if (!player_lit)
  2819. fire_meteor(-1, GF_DARK_WEAK, y, x, 0, strong ? 2 : 1, FALSE);
  2820. }
  2821. /* Hard not to notice. */
  2822. add_wakeup_chance = 10000;
  2823. }
  2824. /**
  2825. * Find some animals on the current dungeon level, and magic map the dungeon
  2826. * near them. Learn about traps on the entire level if at least one natural
  2827. * creature is found. -LM-
  2828. */
  2829. bool listen_to_natural_creatures(void)
  2830. {
  2831. int i, y, x;
  2832. int count = 0;
  2833. /* Check all the monsters */
  2834. for (i = 1; i < m_max; i++) {
  2835. monster_type *m_ptr = &m_list[i];
  2836. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  2837. /* Paranoia -- skip "dead" monsters */
  2838. if (!m_ptr->r_idx)
  2839. continue;
  2840. /* Only natural creatures are eligible, and some don't feel like
  2841. * talking. */
  2842. if ((rf_has(r_ptr->flags, RF_ANIMAL)) && (randint0(2) == 0)) {
  2843. /* Learn about their surroundings. */
  2844. map_area(m_ptr->fy, m_ptr->fx, FALSE);
  2845. /* increment the count. */
  2846. count++;
  2847. }
  2848. /* Avoid excessive processing time. */
  2849. if (count > 15)
  2850. break;
  2851. }
  2852. /* No natural allies. */
  2853. if (!count)
  2854. return (FALSE);
  2855. /* Find every trap on the level. */
  2856. /* Scan all normal grids */
  2857. for (y = 1; y < ARENA_HGT - 1; y++) {
  2858. /* Scan all normal grids */
  2859. for (x = 1; x < ARENA_WID - 1; x++) {
  2860. /* Detect invisible traps */
  2861. if (cave_invisible_trap(y, x)) {
  2862. (void) reveal_trap(y, x, 100, FALSE);
  2863. }
  2864. }
  2865. }
  2866. /* Report success. */
  2867. return (TRUE);
  2868. }
  2869. /**
  2870. * Grow some trees and grass in player's line of sight
  2871. */
  2872. void grow_trees_and_grass(bool powerful)
  2873. {
  2874. int y, x;
  2875. int py = p_ptr->py, px = p_ptr->px;
  2876. /* Check everything in line of sight */
  2877. for (y = py - 20; y <= py + 20; y++)
  2878. for (x = px - 20; x <= px + 20; x++) {
  2879. int dist = distance(py, px, y, x);
  2880. /* Skip distant grids */
  2881. if (dist > 20)
  2882. continue;
  2883. /* Skip grids the player can't see */
  2884. if (!player_has_los_bold(y, x))
  2885. continue;
  2886. /* Skip grids with objects */
  2887. if ((cave_o_idx[y][x] > 0) && (!powerful))
  2888. continue;
  2889. /* Skip grids that aren't floor or road */
  2890. if ((cave_feat[y][x] != FEAT_FLOOR) &&
  2891. (cave_feat[y][x] != FEAT_ROAD))
  2892. continue;
  2893. /* Skip grids that have monsters */
  2894. if ((cave_m_idx[y][x] > 0) && (!powerful))
  2895. continue;
  2896. /* Maybe grow something */
  2897. if ((randint0(dist + 2) != 0) && (!powerful))
  2898. continue;
  2899. /* Probably grass, otherwise a tree */
  2900. if ((randint0(4) == 0) || powerful) {
  2901. if (p_ptr->danger < 40)
  2902. cave_set_feat(y, x, FEAT_TREE);
  2903. else
  2904. cave_set_feat(y, x, FEAT_TREE2);
  2905. } else
  2906. cave_set_feat(y, x, FEAT_GRASS);
  2907. }
  2908. return;
  2909. }
  2910. /**
  2911. * Only the bold and the desperate dare to unleash chaos. -LM-
  2912. */
  2913. void unmake(int dir)
  2914. {
  2915. byte chaotic_effect;
  2916. int i;
  2917. bool repeat = TRUE;
  2918. while (repeat) {
  2919. /* Pick an effect. */
  2920. chaotic_effect = (byte) randint0(18);
  2921. switch (chaotic_effect) {
  2922. /* Massive chaos bolt. */
  2923. case 0:
  2924. case 1:
  2925. case 2:
  2926. case 3:
  2927. case 4:
  2928. case 5:
  2929. case 6:
  2930. case 7:
  2931. {
  2932. fire_bolt(GF_CHAOS, dir, randint1(500));
  2933. break;
  2934. }
  2935. /* Chaos balls in every directioon */
  2936. case 8:
  2937. case 9:
  2938. {
  2939. for (i = 0; i < 8; i++)
  2940. fire_ball(GF_CHAOS, ddd[i], randint1(400), 2, FALSE);
  2941. break;
  2942. }
  2943. /* Tear up the dungeon. */
  2944. case 10:
  2945. {
  2946. destroy_area(p_ptr->py, p_ptr->px, 5 + randint1(20), TRUE);
  2947. break;
  2948. }
  2949. /* Chaos cloud right on top of the poor caster. */
  2950. case 11:
  2951. {
  2952. fire_cloud(GF_CHAOS, 0, randint1(400), 6);
  2953. break;
  2954. }
  2955. /* Chaos spray. */
  2956. case 12:
  2957. case 13:
  2958. case 14:
  2959. case 15:
  2960. case 16:
  2961. {
  2962. fire_arc(GF_CHAOS, dir, randint1(600), 8, 90);
  2963. break;
  2964. }
  2965. /* Unmake the caster. */
  2966. case 17:
  2967. {
  2968. (void) dec_stat(A_STR, 20, (randint0(3) == 0));
  2969. (void) dec_stat(A_INT, 20, (randint0(3) == 0));
  2970. (void) dec_stat(A_WIS, 20, (randint0(3) == 0));
  2971. (void) dec_stat(A_DEX, 20, (randint0(3) == 0));
  2972. (void) dec_stat(A_CON, 20, (randint0(3) == 0));
  2973. (void) dec_stat(A_CHR, 20, (randint0(3) == 0));
  2974. break;
  2975. }
  2976. }
  2977. /* Chaos, once unleashed, likes to stay... */
  2978. if (randint0(4) == 0)
  2979. repeat = TRUE;
  2980. else
  2981. repeat = FALSE;
  2982. }
  2983. }
  2984. /**
  2985. * Unleash the wrath of the beings of Air. -LM-
  2986. */
  2987. void ele_air_smite(void)
  2988. {
  2989. byte i, j;
  2990. int y, x;
  2991. feature_type *f_ptr;
  2992. /* Due warning. */
  2993. msg("The powers of Air rain down destruction!");
  2994. /* Multiple gravity, light, and electricity balls. */
  2995. for (i = 0; i < 8; i++) {
  2996. /* Select a legal nearby location at random. */
  2997. for (j = 0; j < 20; j++) {
  2998. /* Pick a (short) distance. */
  2999. int d = randint1(3);
  3000. /* Admit failure. Switch to Plan B. */
  3001. if (j == 19) {
  3002. y = p_ptr->py;
  3003. x = p_ptr->px;
  3004. break;
  3005. }
  3006. /* Pick a location */
  3007. scatter(&y, &x, p_ptr->py, p_ptr->px, d, 0);
  3008. /* Not on top of the player. */
  3009. if (cave_m_idx[y][x] < 0)
  3010. continue;
  3011. /* Require passable terrain */
  3012. f_ptr = &f_info[cave_feat[y][x]];
  3013. if (!tf_has(f_ptr->flags, TF_PASSABLE))
  3014. continue;
  3015. /* Slight preference for actual monsters. */
  3016. if (cave_m_idx[y][x] > 0)
  3017. break;
  3018. /* Will accept any passable grid after a few tries. */
  3019. else if (j > 3)
  3020. break;
  3021. }
  3022. if (randint0(3) == 0)
  3023. (void) fire_meteor(-1, GF_GRAVITY, y, x, 100, 1, FALSE);
  3024. else if (randint0(2) == 0)
  3025. (void) fire_meteor(-1, GF_LIGHT, y, x, 100, 1, FALSE);
  3026. else
  3027. (void) fire_meteor(-1, GF_ELEC, y, x, 100, 1, FALSE);
  3028. /* This is a bombardment. Make it look like one. */
  3029. Term_xtra(TERM_XTRA_DELAY, 10);
  3030. }
  3031. /* I would /probably/ be awake at this point... */
  3032. add_wakeup_chance = 10000;
  3033. }
  3034. /**
  3035. * Apply a "project()" directly to all monsters in view of a certain spot.
  3036. *
  3037. * Note that affected monsters are NOT auto-tracked by this usage.
  3038. *
  3039. * This function is not optimized for efficieny. It should only be used
  3040. * in non-bottleneck functions such as spells. It should not be used in
  3041. * functions that are major code bottlenecks such as process monster
  3042. * or update_view. -JG
  3043. */
  3044. bool project_los_not_player(int y1, int x1, int dam, int typ)
  3045. {
  3046. int i, x, y;
  3047. u32b flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
  3048. bool obvious = FALSE;
  3049. /* Affect all (nearby) monsters */
  3050. for (i = 1; i < m_max; i++) {
  3051. monster_type *m_ptr = &m_list[i];
  3052. /* Paranoia -- Skip dead monsters */
  3053. if (!m_ptr->r_idx)
  3054. continue;
  3055. /* Location */
  3056. y = m_ptr->fy;
  3057. x = m_ptr->fx;
  3058. /* The LOS function doesn't do well with long distances */
  3059. if (distance(y1, x1, y, x) > MAX_RANGE)
  3060. continue;
  3061. /* Require line of sight or the monster being right on the square */
  3062. if ((y != y1) || (x != x1)) {
  3063. if (!los(y1, x1, y, x))
  3064. continue;
  3065. }
  3066. /* Jump directly to the target monster */
  3067. if (project(-1, 0, y, x, dam, typ, flg, 0, 0))
  3068. obvious = TRUE;
  3069. }
  3070. /* Result */
  3071. return (obvious);
  3072. }
  3073. /**
  3074. * Apply a "project()" directly to all viewable monsters
  3075. *
  3076. * Note that affected monsters are NOT auto-tracked by this usage.
  3077. */
  3078. static bool project_hack(int typ, int dam)
  3079. {
  3080. int i, x, y;
  3081. int flg = PROJECT_JUMP | PROJECT_KILL | PROJECT_HIDE;
  3082. bool obvious = FALSE;
  3083. /* Affect all (nearby) monsters */
  3084. for (i = 1; i < m_max; i++) {
  3085. monster_type *m_ptr = &m_list[i];
  3086. /* Paranoia -- Skip dead monsters */
  3087. if (!m_ptr->r_idx)
  3088. continue;
  3089. /* Location */
  3090. y = m_ptr->fy;
  3091. x = m_ptr->fx;
  3092. /* Require line of sight */
  3093. if (!player_has_los_bold(y, x))
  3094. continue;
  3095. /* Jump directly to the target monster */
  3096. if (project(-1, 0, y, x, dam, typ, flg, 0, 0))
  3097. obvious = TRUE;
  3098. }
  3099. /* Result */
  3100. return (obvious);
  3101. }
  3102. /**
  3103. * Speed monsters
  3104. */
  3105. bool speed_monsters(void)
  3106. {
  3107. return (project_hack(GF_OLD_SPEED, p_ptr->lev));
  3108. }
  3109. /**
  3110. * Slow monsters
  3111. */
  3112. bool slow_monsters(int dam)
  3113. {
  3114. return (project_hack(GF_OLD_SLOW, dam));
  3115. }
  3116. /**
  3117. * Sleep monsters
  3118. */
  3119. bool sleep_monsters(int dam)
  3120. {
  3121. return (project_hack(GF_OLD_SLEEP, dam));
  3122. }
  3123. /**
  3124. * Frighten monsters. -LM-
  3125. */
  3126. bool fear_monsters(int dam)
  3127. {
  3128. return (project_hack(GF_TURN_ALL, dam));
  3129. }
  3130. /**
  3131. * Confuse monsters. -LM-
  3132. */
  3133. bool confu_monsters(int dam)
  3134. {
  3135. return (project_hack(GF_OLD_CONF, dam));
  3136. }
  3137. /**
  3138. * Banish evil monsters
  3139. */
  3140. bool banish_evil(int dist)
  3141. {
  3142. return (project_hack(GF_AWAY_EVIL, dist));
  3143. }
  3144. /**
  3145. * Turn undead
  3146. */
  3147. bool turn_undead(int dam)
  3148. {
  3149. return (project_hack(GF_TURN_UNDEAD, dam));
  3150. }
  3151. /**
  3152. * Turn evil. -LM-
  3153. */
  3154. bool turn_evil(int dam)
  3155. {
  3156. return (project_hack(GF_TURN_EVIL, dam));
  3157. }
  3158. /**
  3159. * Dispel undead monsters
  3160. */
  3161. bool dispel_undead(int dam)
  3162. {
  3163. return (project_hack(GF_DISP_UNDEAD, dam));
  3164. }
  3165. /**
  3166. * Dispel evil monsters
  3167. */
  3168. bool dispel_evil(int dam)
  3169. {
  3170. return (project_hack(GF_DISP_EVIL, dam));
  3171. }
  3172. /**
  3173. * Dispel demons
  3174. */
  3175. bool dispel_demons(int dam)
  3176. {
  3177. return (project_hack(GF_DISP_DEMON, dam));
  3178. }
  3179. /**
  3180. * Dispel non-evil monsters
  3181. */
  3182. bool dispel_not_evil(int dam)
  3183. {
  3184. return (project_hack(GF_DISP_NOT_EVIL, dam));
  3185. }
  3186. /**
  3187. * Dispel all monsters
  3188. */
  3189. bool dispel_monsters(int dam)
  3190. {
  3191. return (project_hack(GF_DISP_ALL, dam));
  3192. }
  3193. /**
  3194. * Dispel all small monsters
  3195. */
  3196. bool dispel_small_monsters(int dam)
  3197. {
  3198. return (project_hack(GF_DISP_SMALL_ALL, dam));
  3199. }
  3200. /**
  3201. * Dispel all living creatures. From Sangband.
  3202. */
  3203. bool dispel_living(int dam)
  3204. {
  3205. return (project_hack(GF_SPIRIT, dam));
  3206. }
  3207. /**
  3208. * Dispel monsters who can't stand bright light. -LM-
  3209. */
  3210. bool dispel_light_hating(int dam)
  3211. {
  3212. return (project_hack(GF_LIGHT_WEAK, dam));
  3213. }
  3214. /**
  3215. * Trees and grass hurt monsters
  3216. */
  3217. bool nature_strike(int dam)
  3218. {
  3219. return (fire_meteor
  3220. (-1, GF_NATURE, p_ptr->py, p_ptr->px, dam, 5, FALSE));
  3221. }
  3222. /**
  3223. * Put undead monsters into stasis. -LM-
  3224. */
  3225. bool hold_undead(void)
  3226. {
  3227. return (project_hack(GF_HOLD_UNDEAD, 0));
  3228. }
  3229. /**
  3230. * Put all monsters into stasis.
  3231. */
  3232. bool hold_all(void)
  3233. {
  3234. return (project_hack(GF_HOLD, 0));
  3235. }
  3236. /**
  3237. * Put all monsters into stasis.
  3238. */
  3239. bool poly_all(int dam)
  3240. {
  3241. return (project_hack(GF_OLD_POLY, dam));
  3242. }
  3243. /**
  3244. * Put all monsters into stasis.
  3245. */
  3246. bool teleport_all(int dam)
  3247. {
  3248. return (project_hack(GF_AWAY_ALL, dam));
  3249. }
  3250. /**
  3251. * Sound blast monsters in line of sight.
  3252. */
  3253. bool cacophony(int dam)
  3254. {
  3255. return (project_hack(GF_SOUND, dam));
  3256. }
  3257. /**
  3258. * Wake up all monsters, and speed up "los" monsters.
  3259. */
  3260. bool aggravate_monsters(int who, bool the_entire_level)
  3261. {
  3262. int i;
  3263. bool sleep = FALSE;
  3264. bool known = FALSE;
  3265. /* Aggravate everyone nearby */
  3266. for (i = 1; i < m_max; i++) {
  3267. monster_type *m_ptr = &m_list[i];
  3268. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3269. /* Paranoia -- Skip dead monsters */
  3270. if (!m_ptr->r_idx)
  3271. continue;
  3272. /* Skip aggravating monster (or player) */
  3273. if (i == who)
  3274. continue;
  3275. /* Wake up and hasten all monsters. No additional messages. */
  3276. if (the_entire_level) {
  3277. /* Wake up */
  3278. if (m_ptr->csleep) {
  3279. /* Wake up */
  3280. m_ptr->csleep = 0;
  3281. }
  3282. /* Go active */
  3283. m_ptr->mflag |= (MFLAG_ACTV);
  3284. /* Get mad. */
  3285. if (m_ptr->mspeed < r_ptr->speed + 10)
  3286. m_ptr->mspeed = r_ptr->speed + 10;
  3287. }
  3288. /* Standard aggravation */
  3289. else {
  3290. /* Wake up nearby sleeping monsters */
  3291. if (m_ptr->cdis <
  3292. (p_ptr->themed_level ? MAX_SIGHT : MAX_SIGHT * 2)) {
  3293. /* Wake up */
  3294. if (m_ptr->csleep) {
  3295. /* Wake up */
  3296. m_ptr->csleep = 0;
  3297. sleep = TRUE;
  3298. /* Do not necessarily go active */
  3299. }
  3300. /* Random equipment aggravation */
  3301. else if (p_ptr->state.rand_aggro) {
  3302. /* Go active */
  3303. m_ptr->mflag |= (MFLAG_ACTV);
  3304. /* Get mad. */
  3305. if (m_ptr->mspeed < r_ptr->speed + 10)
  3306. m_ptr->mspeed = r_ptr->speed + 10;
  3307. }
  3308. /* Know we've aggravated */
  3309. known = TRUE;
  3310. }
  3311. }
  3312. }
  3313. /* Messages */
  3314. if (sleep)
  3315. msg("You hear a sudden stirring in the distance!");
  3316. return (known);
  3317. }
  3318. /**
  3319. * Delete all non-unique monsters of a given "type" from the level
  3320. */
  3321. bool genocide(void)
  3322. {
  3323. int i;
  3324. struct keypress typ;
  3325. /* Mega-Hack -- Get a monster symbol */
  3326. if (!get_com("Choose a monster race (by symbol) to genocide: ", &typ))
  3327. return (FALSE);
  3328. /* Delete the monsters of that "type" */
  3329. for (i = 1; i < m_max; i++) {
  3330. monster_type *m_ptr = &m_list[i];
  3331. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3332. /* Paranoia -- Skip dead monsters */
  3333. if (!m_ptr->r_idx)
  3334. continue;
  3335. /* Hack -- Skip Unique Monsters */
  3336. if (rf_has(r_ptr->flags, RF_UNIQUE))
  3337. continue;
  3338. /* Skip "wrong" monsters */
  3339. if ((unsigned char) r_ptr->d_char != typ.code)
  3340. continue;
  3341. /* Ignore monsters in icky squares */
  3342. if (cave_has(cave_info[m_ptr->fy][m_ptr->fx], CAVE_ICKY))
  3343. continue;
  3344. /* Delete the monster */
  3345. delete_monster_idx(i);
  3346. /* Take some damage */
  3347. take_hit(randint1(4), "the strain of casting Genocide");
  3348. }
  3349. /* Update monster list window */
  3350. p_ptr->redraw |= PR_MONLIST;
  3351. return (TRUE);
  3352. }
  3353. /**
  3354. * Delete all nearby (non-unique) monsters
  3355. */
  3356. bool mass_genocide(void)
  3357. {
  3358. int i;
  3359. /* Delete the (nearby) monsters */
  3360. for (i = 1; i < m_max; i++) {
  3361. monster_type *m_ptr = &m_list[i];
  3362. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3363. /* Paranoia -- Skip dead monsters */
  3364. if (!m_ptr->r_idx)
  3365. continue;
  3366. /* Hack -- Skip unique monsters */
  3367. if (rf_has(r_ptr->flags, RF_UNIQUE))
  3368. continue;
  3369. /* Skip distant monsters */
  3370. if (m_ptr->cdis > MAX_SIGHT)
  3371. continue;
  3372. /* Ignore monsters in icky squares */
  3373. if (cave_has(cave_info[m_ptr->fy][m_ptr->fx], CAVE_ICKY))
  3374. continue;
  3375. /* Delete the monster */
  3376. delete_monster_idx(i);
  3377. /* Take some damage */
  3378. take_hit(randint1(3), "the strain of casting Mass Genocide");
  3379. }
  3380. /* Update monster list window */
  3381. p_ptr->redraw |= PR_MONLIST;
  3382. return (TRUE);
  3383. }
  3384. /**
  3385. * Probe nearby monsters
  3386. */
  3387. bool probing(void)
  3388. {
  3389. int i;
  3390. bool probe = FALSE;
  3391. /* Probe all (nearby) monsters */
  3392. for (i = 1; i < m_max; i++) {
  3393. monster_type *m_ptr = &m_list[i];
  3394. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3395. /* Paranoia -- Skip dead monsters */
  3396. if (!m_ptr->r_idx)
  3397. continue;
  3398. /* Require line of sight */
  3399. if (!player_has_los_bold(m_ptr->fy, m_ptr->fx))
  3400. continue;
  3401. /* Probe visible monsters */
  3402. if (m_ptr->ml) {
  3403. char m_name[80];
  3404. /* Start the message */
  3405. if (!probe)
  3406. msg("Probing...");
  3407. /* Get "the monster" or "something" */
  3408. monster_desc(m_name, sizeof(m_name), m_ptr, 0x104);
  3409. /* Describe the monster */
  3410. if (!(r_ptr->mana))
  3411. msg("%s has %d hit points.", m_name, m_ptr->hp);
  3412. else
  3413. msg("%s has %d hit points and %d mana.", m_name,
  3414. m_ptr->hp, m_ptr->mana);
  3415. /* Learn all of the non-spell, non-treasure flags */
  3416. lore_do_probe(i);
  3417. /* Probe worked */
  3418. probe = TRUE;
  3419. }
  3420. }
  3421. /* Done */
  3422. if (probe) {
  3423. msg("That's all.");
  3424. }
  3425. /* Result */
  3426. return (probe);
  3427. }
  3428. /**
  3429. * The spell of destruction
  3430. *
  3431. * This spell "deletes" monsters (instead of "killing" them).
  3432. *
  3433. * Later we may use one function for both "destruction" and
  3434. * "earthquake" by using the "full" to select "destruction".
  3435. */
  3436. void destroy_area(int y1, int x1, int r, bool full)
  3437. {
  3438. int y, x, k, t;
  3439. bool flag = FALSE;
  3440. /* XXX XXX */
  3441. full = full ? full : 0;
  3442. /* Big area of affect */
  3443. for (y = (y1 - r); y <= (y1 + r); y++) {
  3444. for (x = (x1 - r); x <= (x1 + r); x++) {
  3445. /* Skip illegal grids */
  3446. if (!in_bounds_fully(y, x))
  3447. continue;
  3448. /* Extract the distance */
  3449. k = distance(y1, x1, y, x);
  3450. /* Stay in the circle of death */
  3451. if (k > r)
  3452. continue;
  3453. /* Ignore icky squares */
  3454. if (cave_has(cave_info[y][x], CAVE_ICKY))
  3455. continue;
  3456. /* Lose room */
  3457. cave_off(cave_info[y][x], CAVE_ROOM);
  3458. /* Lose light and knowledge */
  3459. cave_off(cave_info[y][x], CAVE_MARK);
  3460. cave_off(cave_info[y][x], CAVE_GLOW);
  3461. /* Hack -- Notice player affect */
  3462. if (cave_m_idx[y][x] < 0) {
  3463. /* Hurt the player later */
  3464. flag = TRUE;
  3465. /* Do not hurt this grid */
  3466. continue;
  3467. }
  3468. /* Hack -- Skip the epicenter */
  3469. if ((y == y1) && (x == x1))
  3470. continue;
  3471. /* Delete the monster (if any) */
  3472. delete_monster(y, x);
  3473. /* Destroy "valid" grids */
  3474. if (cave_valid_bold(y, x)) {
  3475. int feat = outside ? FEAT_ROAD : FEAT_FLOOR;
  3476. /* Delete objects */
  3477. delete_object(y, x);
  3478. /* Decrement the trap or rune count. */
  3479. (void) remove_trap(y, x, FALSE, -1);
  3480. /* Wall (or floor) type */
  3481. t = randint0(200);
  3482. /* Granite */
  3483. if (t < 20) {
  3484. /* Create granite wall */
  3485. feat = FEAT_WALL_EXTRA;
  3486. }
  3487. /* Quartz */
  3488. else if (t < 70) {
  3489. /* Create quartz vein */
  3490. feat = FEAT_QUARTZ;
  3491. }
  3492. /* Magma */
  3493. else if (t < 100) {
  3494. /* Create magma vein */
  3495. feat = FEAT_MAGMA;
  3496. }
  3497. /* Change the feature */
  3498. cave_set_feat(y, x, feat);
  3499. }
  3500. }
  3501. }
  3502. /* Hack -- Affect player */
  3503. if (flag) {
  3504. /* Message */
  3505. msg("There is a searing blast of light!");
  3506. /* Blind the player */
  3507. if (!p_ptr->state.no_blind && !p_resist_good(P_RES_LIGHT)) {
  3508. /* Become blind */
  3509. (void) inc_timed(TMD_BLIND, 10 + randint1(10), TRUE);
  3510. } else {
  3511. notice_other(IF_RES_LIGHT, 0);
  3512. notice_obj(OF_SEEING, 0);
  3513. }
  3514. }
  3515. /* Fully update the visuals */
  3516. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  3517. /* Redraw map */
  3518. p_ptr->redraw |= (PR_MAP);
  3519. /* Redraw monster list */
  3520. p_ptr->redraw |= (PR_MONLIST | PR_ITEMLIST);
  3521. }
  3522. /**
  3523. * Induce an "earthquake" of the given radius at the given location.
  3524. *
  3525. * This will turn some walls into floors and some floors into walls.
  3526. *
  3527. * The player will take damage and "jump" into a safe grid if possible,
  3528. * otherwise, he will "tunnel" through the rubble instantaneously.
  3529. *
  3530. * Monsters will take damage, and "jump" into a safe grid if possible,
  3531. * otherwise they will be "buried" in the rubble, disappearing from
  3532. * the level in the same way that they do when genocided.
  3533. *
  3534. * Note that players and monsters (except eaters of walls and passers
  3535. * through walls) will never occupy the same grid as a wall (or door).
  3536. */
  3537. void earthquake(int cy, int cx, int r, bool volcano)
  3538. {
  3539. int py = p_ptr->py;
  3540. int px = p_ptr->px;
  3541. int i, t, y, x, yy, xx, dy, dx;
  3542. int damage = 0;
  3543. int sn = 0, sy = 0, sx = 0;
  3544. int lava = 0, water = 0, abyss = 0, total = 0;
  3545. bool hurt = FALSE;
  3546. bool map[32][32];
  3547. /* Paranoia -- Enforce maximum range */
  3548. if (r > 12)
  3549. r = 12;
  3550. /* Clear the "maximal blast" area */
  3551. for (y = 0; y < 32; y++) {
  3552. for (x = 0; x < 32; x++) {
  3553. map[y][x] = FALSE;
  3554. }
  3555. }
  3556. /* Check around the epicenter */
  3557. for (dy = -r; dy <= r; dy++) {
  3558. for (dx = -r; dx <= r; dx++) {
  3559. /* Measure of terrain stability */
  3560. int unstable = 0;
  3561. /* Extract the location */
  3562. yy = cy + dy;
  3563. xx = cx + dx;
  3564. /* Skip illegal grids */
  3565. if (!in_bounds_fully(yy, xx))
  3566. continue;
  3567. /* Skip distant grids */
  3568. if (distance(cy, cx, yy, xx) > r)
  3569. continue;
  3570. /* Lose room */
  3571. cave_off(cave_info[yy][xx], CAVE_ROOM);
  3572. /* Lose light and knowledge */
  3573. cave_off(cave_info[yy][xx], CAVE_MARK);
  3574. cave_off(cave_info[yy][xx], CAVE_GLOW);
  3575. /* Count total, water, lava and void grids */
  3576. total++;
  3577. if (cave_feat[yy][xx] == FEAT_WATER) {
  3578. water++;
  3579. unstable++;
  3580. }
  3581. if (cave_feat[yy][xx] == FEAT_LAVA) {
  3582. lava++;
  3583. unstable++;
  3584. }
  3585. if (cave_feat[yy][xx] == FEAT_VOID) {
  3586. abyss++;
  3587. unstable++;
  3588. }
  3589. /* Skip the epicenter */
  3590. if (!dx && !dy)
  3591. continue;
  3592. /* Skip most grids, less if unstable */
  3593. if (randint0(100) < (75 - (50 * unstable) / total))
  3594. continue;
  3595. /* Damage this grid */
  3596. map[16 + yy - cy][16 + xx - cx] = TRUE;
  3597. /* Hack -- Take note of player damage */
  3598. if ((yy == py) && (xx == px))
  3599. hurt = TRUE;
  3600. }
  3601. }
  3602. /* First, affect the player (if necessary) */
  3603. if (hurt) {
  3604. /* Check around the player */
  3605. for (i = 0; i < 8; i++) {
  3606. /* Access the grid */
  3607. y = py + ddy_ddd[i];
  3608. x = px + ddx_ddd[i];
  3609. /* Skip non-empty grids */
  3610. if (!cave_empty_bold(y, x))
  3611. continue;
  3612. /* Important -- Skip "quake" grids */
  3613. if (map[16 + y - cy][16 + x - cx])
  3614. continue;
  3615. /* Count "safe" grids, apply the randomizer */
  3616. if ((++sn > 1) && (randint0(sn) != 0))
  3617. continue;
  3618. /* Save the safe location */
  3619. sy = y;
  3620. sx = x;
  3621. }
  3622. if (chunk_list[p_ptr->stage].z_pos != 0) {
  3623. /* Random message */
  3624. switch (randint1(3)) {
  3625. case 1:
  3626. {
  3627. msg("The cave ceiling collapses!");
  3628. break;
  3629. }
  3630. case 2:
  3631. {
  3632. msg("The cave floor twists in an unnatural way!");
  3633. break;
  3634. }
  3635. default:
  3636. {
  3637. msg("The cave quakes!");
  3638. msg("You are pummeled with debris!");
  3639. break;
  3640. }
  3641. }
  3642. } else {
  3643. /* Random message */
  3644. switch (randint1(3)) {
  3645. case 1:
  3646. {
  3647. msg("There is a mighty upheaval of the earth!");
  3648. break;
  3649. }
  3650. case 2:
  3651. {
  3652. msg("The ground twists in an unnatural way!");
  3653. break;
  3654. }
  3655. default:
  3656. {
  3657. msg("The ground quakes!");
  3658. msg("You are pummeled with debris!");
  3659. break;
  3660. }
  3661. }
  3662. }
  3663. /* Hurt the player a lot */
  3664. if (!sn) {
  3665. /* Message and damage */
  3666. msg("You are severely crushed!");
  3667. damage = damroll(5, 80);
  3668. }
  3669. /* Destroy the grid, and push the player to safety */
  3670. else {
  3671. /* Calculate results */
  3672. switch (randint1(3)) {
  3673. case 1:
  3674. {
  3675. msg("You nimbly dodge the blast!");
  3676. damage = 0;
  3677. break;
  3678. }
  3679. case 2:
  3680. {
  3681. msg("You are bashed by rubble!");
  3682. damage = damroll(10, 4);
  3683. (void) inc_timed(TMD_STUN, randint1(50), TRUE);
  3684. break;
  3685. }
  3686. case 3:
  3687. {
  3688. /* Chance of falling */
  3689. if (abyss > randint1(total)) {
  3690. fall_off_cliff(0);
  3691. } else {
  3692. msg("You are crushed!");
  3693. damage = damroll(10, 8);
  3694. (void) inc_timed(TMD_STUN, randint1(50), TRUE);
  3695. break;
  3696. }
  3697. }
  3698. }
  3699. /* Move player */
  3700. monster_swap(py, px, sy, sx);
  3701. }
  3702. /* Take some damage */
  3703. if (damage)
  3704. take_hit(damage, "an earthquake");
  3705. }
  3706. /* Examine the quaked region */
  3707. for (dy = -r; dy <= r; dy++) {
  3708. for (dx = -r; dx <= r; dx++) {
  3709. /* Extract the location */
  3710. yy = cy + dy;
  3711. xx = cx + dx;
  3712. /* Skip unaffected grids */
  3713. if (!map[16 + yy - cy][16 + xx - cx])
  3714. continue;
  3715. /* Process monsters */
  3716. if (cave_m_idx[yy][xx] > 0) {
  3717. monster_type *m_ptr = &m_list[cave_m_idx[yy][xx]];
  3718. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3719. /* Most monsters cannot co-exist with rock */
  3720. if (!(rf_has(r_ptr->flags, RF_KILL_WALL))
  3721. && !(rf_has(r_ptr->flags, RF_PASS_WALL))) {
  3722. char m_name[80];
  3723. /* Assume not safe */
  3724. sn = 0;
  3725. /* Monster can move to escape the wall */
  3726. if (!(rf_has(r_ptr->flags, RF_NEVER_MOVE))) {
  3727. /* Look for safety */
  3728. for (i = 0; i < 8; i++) {
  3729. /* Access the grid */
  3730. y = yy + ddy_ddd[i];
  3731. x = xx + ddx_ddd[i];
  3732. /* Skip non-empty grids */
  3733. if (!cave_empty_bold(y, x))
  3734. continue;
  3735. /* Hack -- no safety on glyph of warding */
  3736. if (cave_trap_specific(y, x, RUNE_PROTECT))
  3737. continue;
  3738. /* Important -- Skip "quake" grids */
  3739. if (map[16 + y - cy][16 + x - cx])
  3740. continue;
  3741. /* Count "safe" grids, apply the randomizer */
  3742. if ((++sn > 1) && (randint0(sn) != 0))
  3743. continue;
  3744. /* Save the safe grid */
  3745. sy = y;
  3746. sx = x;
  3747. }
  3748. }
  3749. /* Describe the monster */
  3750. monster_desc(m_name, sizeof(m_name), m_ptr, 0x100);
  3751. /* Scream in pain */
  3752. msg("%s wails out in pain!", m_name);
  3753. /* Take damage from the quake */
  3754. damage = (sn ? damroll(4, 8) : damroll(5, 80));
  3755. /* Monster is certainly awake */
  3756. m_ptr->csleep = 0;
  3757. /* Go active */
  3758. m_ptr->mflag |= (MFLAG_ACTV);
  3759. /* Apply damage directly */
  3760. m_ptr->hp -= damage;
  3761. /* Delete (not kill) "dead" monsters */
  3762. if (m_ptr->hp < 0) {
  3763. /* Message */
  3764. msg("%s is embedded in the rock!", m_name);
  3765. /* Delete the monster */
  3766. delete_monster(yy, xx);
  3767. /* No longer safe */
  3768. sn = 0;
  3769. }
  3770. /* Hack -- Escape from the rock */
  3771. if (sn) {
  3772. /* Move the monster */
  3773. monster_swap(yy, xx, sy, sx);
  3774. }
  3775. }
  3776. }
  3777. }
  3778. }
  3779. /* XXX XXX XXX */
  3780. /* New location */
  3781. py = p_ptr->py;
  3782. px = p_ptr->px;
  3783. /* Important -- no wall on player */
  3784. map[16 + py - cy][16 + px - cx] = FALSE;
  3785. /* Examine the quaked region */
  3786. for (dy = -r; dy <= r; dy++) {
  3787. for (dx = -r; dx <= r; dx++) {
  3788. /* Extract the location */
  3789. yy = cy + dy;
  3790. xx = cx + dx;
  3791. /* Skip unaffected grids */
  3792. if (!map[16 + yy - cy][16 + xx - cx])
  3793. continue;
  3794. /* Paranoia -- never affect player */
  3795. if ((yy == py) && (xx == px))
  3796. continue;
  3797. /* Destroy location (if valid). Increment trap/glyph count. */
  3798. if (cave_valid_bold(yy, xx)) {
  3799. int feat = outside ? FEAT_ROAD : FEAT_FLOOR;
  3800. monster_type *m_ptr = &m_list[cave_m_idx[yy][xx]];
  3801. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3802. feature_type *f_ptr = &f_info[cave_feat[yy][xx]];
  3803. bool floor = tf_has(f_ptr->flags, TF_FLOOR);
  3804. /* Allow more things to be destroyed outside */
  3805. if (chunk_list[p_ptr->stage].z_pos == 0)
  3806. floor = TRUE;
  3807. /* Delete objects */
  3808. delete_object(yy, xx);
  3809. /* Delete traps */
  3810. (void) remove_trap(yy, xx, FALSE, -1);
  3811. /* Wall (or floor) type */
  3812. t = (floor ? randint0(120) : 200);
  3813. /* Granite (rubble if monster is present) */
  3814. if (t < 20) {
  3815. /* Dump rubble on top of monsters. */
  3816. if (cave_m_idx[yy][xx] > 0)
  3817. feat = FEAT_RUBBLE;
  3818. /* Otherwise, create granite wall */
  3819. else
  3820. feat = FEAT_WALL_EXTRA;
  3821. }
  3822. /* Quartz */
  3823. else if (t < 55) {
  3824. /* Dump rubble on top of monsters. */
  3825. if (cave_m_idx[yy][xx] > 0)
  3826. feat = FEAT_RUBBLE;
  3827. /* If this was a volcanic eruption, create lava near
  3828. * center. -LM- */
  3829. else if ((volcano) && (distance(cy, cx, yy, xx) < 3))
  3830. feat = FEAT_LAVA;
  3831. /* Otherwise, create quartz vein */
  3832. else
  3833. feat = FEAT_QUARTZ;
  3834. }
  3835. /* Magma */
  3836. else if (t < 90) {
  3837. /* Dump rubble on top of monsters. */
  3838. if (cave_m_idx[yy][xx] > 0)
  3839. feat = FEAT_RUBBLE;
  3840. /* If this was a volcanic eruption, create lava near
  3841. * center. -LM- */
  3842. else if ((volcano) && (distance(cy, cx, yy, xx) < 3))
  3843. feat = FEAT_LAVA;
  3844. /* Otherwise, create magma vein */
  3845. else
  3846. feat = FEAT_MAGMA;
  3847. }
  3848. /* Rubble. */
  3849. else if (t < 120) {
  3850. /* Create rubble */
  3851. feat = FEAT_RUBBLE;
  3852. }
  3853. /* Override with water/lava/void */
  3854. t *= total;
  3855. /* Water */
  3856. if (t < water * 150) {
  3857. /* Monster OK in water */
  3858. if ((rf_has(r_ptr->flags, RF_FLYING))
  3859. || !((rsf_has(r_ptr->flags, RSF_BRTH_FIRE))
  3860. || (strchr("uU", r_ptr->d_char))
  3861. || ((strchr("E", r_ptr->d_char))
  3862. && ((r_ptr->d_attr == TERM_RED)
  3863. || (r_ptr->d_attr == TERM_L_RED)))))
  3864. /* Create water */
  3865. feat = FEAT_WATER;
  3866. } else if (t < lava * 150) {
  3867. /* Monster OK in lava */
  3868. if ((rf_has(r_ptr->flags, RF_IM_FIRE))
  3869. || ((rf_has(r_ptr->flags, RF_FLYING))
  3870. && ((rf_has(r_ptr->flags, RF_FORCE_MAXHP)
  3871. ? (r_ptr->hdice *
  3872. r_ptr->hside) : (r_ptr->hdice *
  3873. (r_ptr->hside +
  3874. 1) / 2)) > 49)))
  3875. /* Create lava */
  3876. feat = FEAT_LAVA;
  3877. } else if (t < abyss * 150) {
  3878. /* Check for monsters */
  3879. if (cave_m_idx[yy][xx] > 0) {
  3880. /* Flying monsters survive */
  3881. if (!(rf_has(r_ptr->flags, RF_FLYING))) {
  3882. /* What was that again ? */
  3883. char m_name[80];
  3884. /* Extract monster name */
  3885. monster_desc(m_name, sizeof(m_name), m_ptr, 0);
  3886. /* There it goes... */
  3887. msg("%s falls into the dark!", m_name);
  3888. /* Gone, precious */
  3889. delete_monster(y, x);
  3890. }
  3891. }
  3892. /* Create void */
  3893. feat = FEAT_VOID;
  3894. }
  3895. /* Change the feature */
  3896. cave_set_feat(yy, xx, feat);
  3897. }
  3898. }
  3899. }
  3900. /* Fully update the visuals */
  3901. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  3902. /* Redraw map */
  3903. p_ptr->redraw |= (PR_MAP);
  3904. /* Update the health and mana bars */
  3905. p_ptr->redraw |= (PR_HEALTH | PR_MON_MANA);
  3906. /* Window stuff */
  3907. p_ptr->redraw |= (PR_MONLIST | PR_ITEMLIST);
  3908. }
  3909. /**
  3910. * Small targetable earthquake
  3911. */
  3912. bool tremor(void)
  3913. {
  3914. int ny, nx;
  3915. s16b ty, tx;
  3916. bool okay = FALSE;
  3917. bool valid_grid = FALSE;
  3918. /* Choose the epicentre */
  3919. while (!valid_grid) {
  3920. okay = target_set_interactive(TARGET_LOOK | TARGET_GRID, -1, -1);
  3921. if (!okay)
  3922. return (FALSE);
  3923. /* grab the target coords. */
  3924. target_get(&tx, &ty);
  3925. ny = ty;
  3926. nx = tx;
  3927. /* Test for empty floor and line of sight, forbid vaults */
  3928. if (cave_empty_bold(ny, nx)
  3929. && !cave_has(cave_info[ny][nx], CAVE_ICKY)
  3930. && (player_has_los_bold(ny, nx)))
  3931. valid_grid = TRUE;
  3932. }
  3933. /* Shake the Earth */
  3934. earthquake(ny, nx, 3, FALSE);
  3935. /* Success */
  3936. return (TRUE);
  3937. }
  3938. /**
  3939. * This routine clears the entire "temp" set.
  3940. *
  3941. * This routine will Perma-Light all "temp" grids.
  3942. *
  3943. * This routine is used (only) by "light_room()"
  3944. *
  3945. * Dark grids are illuminated.
  3946. *
  3947. * Also, process all affected monsters.
  3948. *
  3949. * SMART monsters always wake up when illuminated
  3950. * NORMAL monsters wake up 1/4 the time when illuminated
  3951. * STUPID monsters wake up 1/10 the time when illuminated
  3952. */
  3953. static void cave_temp_room_light(void)
  3954. {
  3955. int i;
  3956. /* Apply flag changes */
  3957. for (i = 0; i < temp_n; i++) {
  3958. int y = temp_y[i];
  3959. int x = temp_x[i];
  3960. /* No longer in the array */
  3961. cave_off(cave_info[y][x], CAVE_TEMP);
  3962. /* Perma-Light */
  3963. cave_on(cave_info[y][x], CAVE_GLOW);
  3964. }
  3965. /* Fully update the visuals */
  3966. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  3967. /* Update stuff */
  3968. update_stuff(p_ptr);
  3969. /* Process the grids */
  3970. for (i = 0; i < temp_n; i++) {
  3971. int y = temp_y[i];
  3972. int x = temp_x[i];
  3973. /* Redraw the grid */
  3974. light_spot(y, x);
  3975. /* Process affected monsters */
  3976. if (cave_m_idx[y][x] > 0) {
  3977. int chance = 25;
  3978. monster_type *m_ptr = &m_list[cave_m_idx[y][x]];
  3979. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  3980. /* Stupid monsters rarely wake up */
  3981. if (rf_has(r_ptr->flags, RF_STUPID))
  3982. chance = 10;
  3983. /* Smart monsters always wake up */
  3984. if (rf_has(r_ptr->flags, RF_SMART))
  3985. chance = 100;
  3986. /* Sometimes monsters wake up */
  3987. if (m_ptr->csleep && (randint0(100) < chance)) {
  3988. /* Wake up! */
  3989. m_ptr->csleep = 0;
  3990. /* Go active */
  3991. m_ptr->mflag |= (MFLAG_ACTV);
  3992. /* Notice the "waking up" */
  3993. if (m_ptr->ml) {
  3994. char m_name[80];
  3995. /* Acquire the monster name */
  3996. monster_desc(m_name, sizeof(m_name), m_ptr, 0x100);
  3997. /* Dump a message */
  3998. msg("%s wakes up.", m_name);
  3999. }
  4000. }
  4001. }
  4002. }
  4003. /* None left */
  4004. temp_n = 0;
  4005. }
  4006. /**
  4007. * This routine clears the entire "temp" set.
  4008. *
  4009. * This routine will "darken" all "temp" grids.
  4010. *
  4011. * In addition, some of these grids will be "unmarked".
  4012. *
  4013. * This routine is used (only) by "unlight_room()"
  4014. */
  4015. static void cave_temp_room_unlight(void)
  4016. {
  4017. int i;
  4018. /* Apply flag changes */
  4019. for (i = 0; i < temp_n; i++) {
  4020. int y = temp_y[i];
  4021. int x = temp_x[i];
  4022. feature_type *f_ptr = &f_info[cave_feat[y][x]];
  4023. /* No longer in the array */
  4024. cave_off(cave_info[y][x], CAVE_TEMP);
  4025. /* Darken the grid */
  4026. cave_off(cave_info[y][x], CAVE_GLOW);
  4027. /* Hack -- Forget "boring" grids */
  4028. if (tf_has(f_ptr->flags, TF_FLOOR) &&
  4029. !cave_has(cave_info[y][x], CAVE_TRAP)) {
  4030. /* Forget the grid */
  4031. cave_off(cave_info[y][x], CAVE_MARK);
  4032. }
  4033. }
  4034. /* Fully update the visuals */
  4035. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  4036. /* Update stuff */
  4037. update_stuff(p_ptr);
  4038. /* Process the grids */
  4039. for (i = 0; i < temp_n; i++) {
  4040. int y = temp_y[i];
  4041. int x = temp_x[i];
  4042. /* Redraw the grid */
  4043. light_spot(y, x);
  4044. }
  4045. /* None left */
  4046. temp_n = 0;
  4047. }
  4048. /**
  4049. * Aux function -- see below
  4050. */
  4051. static void cave_temp_room_aux(int y, int x)
  4052. {
  4053. /* Check in bounds - thanks George */
  4054. if (!in_bounds(y, x))
  4055. return;
  4056. /* Avoid infinite recursion */
  4057. if (cave_has(cave_info[y][x], CAVE_TEMP))
  4058. return;
  4059. /* Do not "leave" the current room */
  4060. if (!cave_has(cave_info[y][x], CAVE_ROOM))
  4061. return;
  4062. /* Paranoia -- verify space */
  4063. if (temp_n == TEMP_MAX)
  4064. return;
  4065. /* Mark the grid as "seen" */
  4066. cave_on(cave_info[y][x], CAVE_TEMP);
  4067. /* Add it to the "seen" set */
  4068. temp_y[temp_n] = y;
  4069. temp_x[temp_n] = x;
  4070. temp_n++;
  4071. }
  4072. /**
  4073. * Illuminate any room containing the given location.
  4074. */
  4075. void light_room(int y1, int x1)
  4076. {
  4077. int i, x, y;
  4078. feature_type *f_ptr = NULL;
  4079. /* Add the initial grid */
  4080. cave_temp_room_aux(y1, x1);
  4081. /* While grids are in the queue, add their neighbors */
  4082. for (i = 0; i < temp_n; i++) {
  4083. x = temp_x[i], y = temp_y[i];
  4084. /* Walls (but not trees) get lit, but stop light */
  4085. f_ptr = &f_info[cave_feat[y][x]];
  4086. if (!cave_project(y, x) && tf_has(f_ptr->flags, TF_TREE))
  4087. continue;
  4088. /* Spread adjacent */
  4089. cave_temp_room_aux(y + 1, x);
  4090. cave_temp_room_aux(y - 1, x);
  4091. cave_temp_room_aux(y, x + 1);
  4092. cave_temp_room_aux(y, x - 1);
  4093. /* Spread diagonal */
  4094. cave_temp_room_aux(y + 1, x + 1);
  4095. cave_temp_room_aux(y - 1, x - 1);
  4096. cave_temp_room_aux(y - 1, x + 1);
  4097. cave_temp_room_aux(y + 1, x - 1);
  4098. }
  4099. /* Now, light them all up at once */
  4100. cave_temp_room_light();
  4101. }
  4102. /**
  4103. * Darken all rooms containing the given location
  4104. */
  4105. void unlight_room(int y1, int x1)
  4106. {
  4107. int i, x, y;
  4108. /* Add the initial grid */
  4109. cave_temp_room_aux(y1, x1);
  4110. /* Spread, breadth first */
  4111. for (i = 0; i < temp_n; i++) {
  4112. x = temp_x[i], y = temp_y[i];
  4113. /* Walls get dark, but stop darkness */
  4114. if (!cave_project(y, x))
  4115. continue;
  4116. /* Spread adjacent */
  4117. cave_temp_room_aux(y + 1, x);
  4118. cave_temp_room_aux(y - 1, x);
  4119. cave_temp_room_aux(y, x + 1);
  4120. cave_temp_room_aux(y, x - 1);
  4121. /* Spread diagonal */
  4122. cave_temp_room_aux(y + 1, x + 1);
  4123. cave_temp_room_aux(y - 1, x - 1);
  4124. cave_temp_room_aux(y - 1, x + 1);
  4125. cave_temp_room_aux(y + 1, x - 1);
  4126. }
  4127. /* Now, darken them all at once */
  4128. cave_temp_room_unlight();
  4129. }
  4130. /**
  4131. * Hack -- call light around the player
  4132. * Affect all monsters in the projection radius
  4133. */
  4134. bool light_area(int dam, int rad)
  4135. {
  4136. int py = p_ptr->py;
  4137. int px = p_ptr->px;
  4138. int flg = PROJECT_GRID | PROJECT_KILL;
  4139. /* Hack -- Message */
  4140. if (!p_ptr->timed[TMD_BLIND]) {
  4141. msg("You are surrounded by a white light.");
  4142. }
  4143. /* Hook into the "project()" function */
  4144. (void) project(-1, rad, py, px, dam, GF_LIGHT_WEAK, flg, 0, 0);
  4145. /* Light up the room */
  4146. light_room(py, px);
  4147. /* Assume seen */
  4148. return (TRUE);
  4149. }
  4150. /**
  4151. * Hack -- call darkness around the player
  4152. * Affect all monsters in the projection radius
  4153. */
  4154. bool unlight_area(int dam, int rad)
  4155. {
  4156. int py = p_ptr->py;
  4157. int px = p_ptr->px;
  4158. int flg = PROJECT_GRID | PROJECT_KILL;
  4159. /* Hack -- Message */
  4160. if (!p_ptr->timed[TMD_BLIND]) {
  4161. msg("Darkness surrounds you.");
  4162. }
  4163. /* Hook into the "project()" function */
  4164. (void) project(-1, rad, py, px, dam, GF_DARK_WEAK, flg, 0, 0);
  4165. /* Light up the room */
  4166. unlight_room(py, px);
  4167. /* Assume seen */
  4168. return (TRUE);
  4169. }
  4170. /**
  4171. * Cast a ball spell
  4172. * Stop if we hit a monster, act as a "ball"
  4173. * Allow "target" mode to pass over monsters
  4174. * Allow "jump" option to remove the standard "trail" from the caster to
  4175. * the target. -LM-
  4176. * Affect grids, objects, and monsters
  4177. */
  4178. bool fire_ball(int typ, int dir, int dam, int rad, bool jump)
  4179. {
  4180. int py = p_ptr->py;
  4181. int px = p_ptr->px;
  4182. s16b ty, tx;
  4183. int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
  4184. if (jump)
  4185. flg |= PROJECT_JUMP;
  4186. /* Use the given direction */
  4187. ty = py + 99 * ddy[dir];
  4188. tx = px + 99 * ddx[dir];
  4189. /* Hack -- Use an actual "target" */
  4190. if ((dir == 5) && target_okay()) {
  4191. target_get(&tx, &ty);
  4192. flg &= ~(PROJECT_STOP);
  4193. }
  4194. /* Analyze the "dir" and the "target". Hurt items on floor. */
  4195. return (project(-1, rad, ty, tx, dam, typ, flg, 0, 0));
  4196. }
  4197. /**
  4198. * Fire a sphere, defined as a ball spell that does not lose strength with
  4199. * distance from the center, up to a given diameter. This spell is most
  4200. * often used to cast balls centered on the player with diameter 20, because
  4201. * it then offers "what you see is what you get" damage to adjacent monsters.
  4202. * It could also be used to cast pinpoints of extremely intense energy (use
  4203. * a diameter of 5 or even less) more "realistically" than ball spells of
  4204. * radius 0. -LM-
  4205. */
  4206. bool fire_sphere(int typ, int dir, int dam, int rad,
  4207. byte diameter_of_source)
  4208. {
  4209. int py = p_ptr->py;
  4210. int px = p_ptr->px;
  4211. s16b ty, tx;
  4212. int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
  4213. /* Use the given direction */
  4214. ty = py + 99 * ddy[dir];
  4215. tx = px + 99 * ddx[dir];
  4216. /* Hack -- Use an actual "target" */
  4217. if ((dir == 5) && target_okay()) {
  4218. target_get(&tx, &ty);
  4219. flg &= ~(PROJECT_STOP);
  4220. }
  4221. /* Analyze the "dir" and the "target". Hurt items on floor. */
  4222. return (project
  4223. (-1, rad, ty, tx, dam, typ, flg, 0, diameter_of_source));
  4224. }
  4225. /**
  4226. * Fire a cloud, defined as a ball spell that effects the player. -LM-
  4227. */
  4228. bool fire_cloud(int typ, int dir, int dam, int rad)
  4229. {
  4230. int py = p_ptr->py;
  4231. int px = p_ptr->px;
  4232. s16b ty, tx;
  4233. int flg =
  4234. PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL |
  4235. PROJECT_PLAY;
  4236. /* Use the given direction */
  4237. ty = py + 99 * ddy[dir];
  4238. tx = px + 99 * ddx[dir];
  4239. /* Hack -- Use an actual "target" */
  4240. if ((dir == 5) && target_okay()) {
  4241. target_get(&tx, &ty);
  4242. flg &= ~(PROJECT_STOP);
  4243. }
  4244. /* Analyze the "dir" and the "target". Hurt items on floor. */
  4245. return (project(-1, rad, ty, tx, dam, typ, flg, 0, 0));
  4246. }
  4247. /**
  4248. * Cast a meteor spell, defined as a ball spell cast by an arbitary monster,
  4249. * player, or outside source, that starts out at an arbitrary location, and
  4250. * that leaves no trail from the "caster" to the target. This function is
  4251. * especially useful for bombardments and similar. -LM-
  4252. *
  4253. * Option to hurt the player.
  4254. */
  4255. bool fire_meteor(int who, int typ, int y, int x, int dam, int rad,
  4256. bool hurt_player)
  4257. {
  4258. int flg =
  4259. PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL |
  4260. PROJECT_JUMP;
  4261. if (hurt_player)
  4262. flg |= PROJECT_PLAY;
  4263. /* Analyze the "target" and the caster. */
  4264. return (project(who, rad, y, x, dam, typ, flg, 0, 0));
  4265. }
  4266. /**
  4267. * Cast an arc-shaped spell. This is nothing more than a sphere spell
  4268. * centered on the caster with a value for degrees_of_arc (how many degrees
  4269. * wide the the arc is) that is not 360. The direction given will be the
  4270. * center of the arc, which travels outwards from the caster to a distance
  4271. * given by rad. -LM-
  4272. *
  4273. * Because all arcs start out as being one grid wide, arc spells with a
  4274. * value for degrees_of_arc less than (roughly) 60 do not dissipate as
  4275. * quickly. In the extreme case where degrees_of_arc is 0, the arc is
  4276. * actually a defined length beam, and loses no strength at all over the
  4277. * ranges found in the game.
  4278. */
  4279. bool fire_arc(int typ, int dir, int dam, int rad, int degrees_of_arc)
  4280. {
  4281. int py = p_ptr->py;
  4282. int px = p_ptr->px;
  4283. /* Diameter of source of energy is normally, but not always, 20. */
  4284. int diameter_of_source = 20;
  4285. s16b ty, tx;
  4286. int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL | PROJECT_ARC;
  4287. /* If a full circle is asked for, just cast a ball spell and have done. */
  4288. if (degrees_of_arc >= 360)
  4289. return (fire_sphere(typ, 0, dam, rad, 20));
  4290. /* Use the given direction */
  4291. ty = py + 99 * ddy[dir];
  4292. tx = px + 99 * ddx[dir];
  4293. /* Hack -- Use an actual "target" */
  4294. if ((dir == 5) && target_okay()) {
  4295. target_get(&tx, &ty);
  4296. flg &= ~(PROJECT_STOP);
  4297. }
  4298. /* Calculate the effective diameter of the energy source, if necessary. */
  4299. if (degrees_of_arc < 60) {
  4300. if (degrees_of_arc == 0)
  4301. diameter_of_source = rad * 10;
  4302. else
  4303. diameter_of_source = diameter_of_source * 60 / degrees_of_arc;
  4304. }
  4305. /* Max */
  4306. if (diameter_of_source > 250)
  4307. diameter_of_source = 250;
  4308. /* Analyze the "dir" and the "target". Use the given degrees of arc, and
  4309. * the calculated source diameter. */
  4310. return (project
  4311. (-1, rad, ty, tx, dam, typ, flg, degrees_of_arc,
  4312. (byte) diameter_of_source));
  4313. }
  4314. /**
  4315. * Hack -- apply a "projection()" in a direction (or at the target)
  4316. */
  4317. static bool project_hook(int typ, int dir, int dam, int flg)
  4318. {
  4319. int py = p_ptr->py;
  4320. int px = p_ptr->px;
  4321. s16b ty, tx;
  4322. /* Pass through the target if needed */
  4323. flg |= (PROJECT_THRU);
  4324. /* Use the given direction */
  4325. ty = py + ddy[dir];
  4326. tx = px + ddx[dir];
  4327. /* Hack -- Use an actual "target" */
  4328. if ((dir == 5) && target_okay())
  4329. target_get(&tx, &ty);
  4330. /* Analyze the "dir" and the "target", do NOT explode */
  4331. return (project(-1, 0, ty, tx, dam, typ, flg, 0, 0));
  4332. }
  4333. /**
  4334. * Cast a bolt spell
  4335. * Stop if we hit a monster, as a "bolt"
  4336. * Affect monsters (not grids or objects)
  4337. */
  4338. bool fire_bolt(int typ, int dir, int dam)
  4339. {
  4340. int flg = PROJECT_STOP | PROJECT_KILL;
  4341. return (project_hook(typ, dir, dam, flg));
  4342. }
  4343. /**
  4344. * Cast a beam spell
  4345. * Pass through monsters, as a "beam"
  4346. * Affect monsters (not grids or objects)
  4347. */
  4348. bool fire_beam(int typ, int dir, int dam)
  4349. {
  4350. int flg = PROJECT_BEAM | PROJECT_KILL;
  4351. return (project_hook(typ, dir, dam, flg));
  4352. }
  4353. /**
  4354. * Cast a bolt spell, or rarely, a beam spell
  4355. */
  4356. bool fire_bolt_or_beam(int prob, int typ, int dir, int dam)
  4357. {
  4358. if (randint0(100) < prob) {
  4359. return (fire_beam(typ, dir, dam));
  4360. } else {
  4361. return (fire_bolt(typ, dir, dam));
  4362. }
  4363. }
  4364. /**
  4365. * Some of the old functions
  4366. */
  4367. bool light_line(int dir)
  4368. {
  4369. int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_KILL;
  4370. return (project_hook(GF_LIGHT_WEAK, dir, damroll(4, 5), flg));
  4371. }
  4372. bool drain_life(int dir, int dam)
  4373. {
  4374. int flg = PROJECT_STOP | PROJECT_KILL;
  4375. return (project_hook(GF_OLD_DRAIN, dir, dam, flg));
  4376. }
  4377. bool wall_to_mud(int dir)
  4378. {
  4379. int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
  4380. return (project_hook(GF_KILL_WALL, dir, 20 + randint1(30), flg));
  4381. }
  4382. bool wall_to_mud_hack(int dir, int dam)
  4383. {
  4384. int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM | PROJECT_KILL;
  4385. return (project_hook(GF_KILL_WALL, dir, dam, flg));
  4386. }
  4387. bool destroy_door(int dir)
  4388. {
  4389. int flg = PROJECT_BEAM | PROJECT_GRID | PROJECT_ITEM;
  4390. return (project_hook(GF_KILL_DOOR, dir, 0, flg));
  4391. }
  4392. /**
  4393. * This function now casts a radius 0 ball spell on the adjacent square
  4394. * in whatever direction has been chosen. -LM-
  4395. */
  4396. bool disarm_trap(int dir)
  4397. {
  4398. /* Use the given direction */
  4399. int ty = p_ptr->py + ddy[dir];
  4400. int tx = p_ptr->px + ddx[dir];
  4401. int flg = PROJECT_STOP | PROJECT_GRID | PROJECT_ITEM;
  4402. return (project(-1, 0, ty, tx, 0, GF_KILL_TRAP, flg, 0, 0));
  4403. }
  4404. bool heal_monster(int dir)
  4405. {
  4406. int flg = PROJECT_STOP | PROJECT_KILL;
  4407. return (project_hook(GF_OLD_HEAL, dir, damroll(4, 6), flg));
  4408. }
  4409. bool speed_monster(int dir)
  4410. {
  4411. int flg = PROJECT_STOP | PROJECT_KILL;
  4412. return (project_hook(GF_OLD_SPEED, dir, p_ptr->lev, flg));
  4413. }
  4414. bool slow_monster(int dir, int dam)
  4415. {
  4416. int flg = PROJECT_STOP | PROJECT_KILL;
  4417. return (project_hook(GF_OLD_SLOW, dir, dam, flg));
  4418. }
  4419. bool sleep_monster(int dir, int dam)
  4420. {
  4421. int flg = PROJECT_STOP | PROJECT_KILL;
  4422. return (project_hook(GF_OLD_SLEEP, dir, dam, flg));
  4423. }
  4424. bool confuse_monster(int dir, int dam)
  4425. {
  4426. int flg = PROJECT_STOP | PROJECT_KILL;
  4427. return (project_hook(GF_OLD_CONF, dir, dam, flg));
  4428. }
  4429. bool poly_monster(int dir)
  4430. {
  4431. int flg = PROJECT_STOP | PROJECT_KILL;
  4432. return (project_hook(GF_OLD_POLY, dir, p_ptr->lev, flg));
  4433. }
  4434. bool clone_monster(int dir)
  4435. {
  4436. int flg = PROJECT_STOP | PROJECT_KILL;
  4437. return (project_hook(GF_OLD_CLONE, dir, 0, flg));
  4438. }
  4439. bool fear_monster(int dir, int dam)
  4440. {
  4441. int flg = PROJECT_STOP | PROJECT_KILL;
  4442. return (project_hook(GF_TURN_ALL, dir, dam, flg));
  4443. }
  4444. bool dispel_an_undead(int dir, int dam)
  4445. {
  4446. int flg = PROJECT_STOP | PROJECT_KILL;
  4447. return (project_hook(GF_DISP_UNDEAD, dir, dam, flg));
  4448. }
  4449. bool dispel_a_demon(int dir, int dam)
  4450. {
  4451. int flg = PROJECT_STOP | PROJECT_KILL;
  4452. return (project_hook(GF_DISP_DEMON, dir, dam, flg));
  4453. }
  4454. bool dispel_a_dragon(int dir, int dam)
  4455. {
  4456. int flg = PROJECT_STOP | PROJECT_KILL;
  4457. return (project_hook(GF_DISP_DRAGON, dir, dam, flg));
  4458. }
  4459. bool teleport_monster(int dir, int dist)
  4460. {
  4461. int flg = PROJECT_STOP | PROJECT_KILL;
  4462. return (project_hook(GF_AWAY_ALL, dir, dist, flg));
  4463. }
  4464. /**
  4465. * Hooks -- affect adjacent grids (radius 1 ball attack)
  4466. */
  4467. bool door_creation(void)
  4468. {
  4469. int py = p_ptr->py;
  4470. int px = p_ptr->px;
  4471. int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
  4472. return (project(-1, 1, py, px, 0, GF_MAKE_DOOR, flg, 0, 0));
  4473. }
  4474. bool trap_creation(void)
  4475. {
  4476. int py = p_ptr->py;
  4477. int px = p_ptr->px;
  4478. int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
  4479. /* Trap trees - projection doesn't work. */
  4480. int i;
  4481. for (i = 0; i < 8; i++) {
  4482. int y = py + ddy_ddd[i], x = px + ddx_ddd[i];
  4483. feature_type *f_ptr = &f_info[cave_feat[x][y]];
  4484. if (tf_has(f_ptr->flags, TF_TREE))
  4485. place_trap(y, x, -1, p_ptr->danger);
  4486. }
  4487. return (project(-1, 1, py, px, 0, GF_MAKE_TRAP, flg, 0, 0));
  4488. }
  4489. bool destroy_doors_touch(void)
  4490. {
  4491. int py = p_ptr->py;
  4492. int px = p_ptr->px;
  4493. int flg = PROJECT_GRID | PROJECT_ITEM | PROJECT_HIDE;
  4494. return (project(-1, 1, py, px, 0, GF_KILL_DOOR, flg, 0, 0));
  4495. }
  4496. bool sleep_monsters_touch(int dam)
  4497. {
  4498. int py = p_ptr->py;
  4499. int px = p_ptr->px;
  4500. int flg = PROJECT_KILL | PROJECT_HIDE;
  4501. return (project(-1, 1, py, px, dam, GF_OLD_SLEEP, flg, 0, 0));
  4502. }