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

/src/cave.c

https://bitbucket.org/ekolis/jackband
C | 3993 lines | 1654 code | 736 blank | 1603 comment | 438 complexity | 427748e19cbc3ca6ac9a5ad570f643b5 MD5 | raw file
  1. /*
  2. * File: cave.c
  3. * Purpose: Lighting and update functions
  4. *
  5. * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
  6. *
  7. * This work is free software; you can redistribute it and/or modify it
  8. * under the terms of either:
  9. *
  10. * a) the GNU General Public License as published by the Free Software
  11. * Foundation, version 2, or
  12. *
  13. * b) the "Angband licence":
  14. * This software may be copied and distributed for educational, research,
  15. * and not for profit purposes provided that this copyright and statement
  16. * are included in all such copies. Other copyrights may also apply.
  17. */
  18. #include "angband.h"
  19. #include "object/tvalsval.h"
  20. #include "game-event.h"
  21. #include "game-cmd.h"
  22. /*
  23. * Support for Adam Bolt's tileset, lighting and transparency effects
  24. * by Robert Ruehlmann (rr9@thangorodrim.net)
  25. */
  26. /*
  27. * Approximate distance between two points.
  28. *
  29. * When either the X or Y component dwarfs the other component,
  30. * this function is almost perfect, and otherwise, it tends to
  31. * over-estimate about one grid per fifteen grids of distance.
  32. *
  33. * Algorithm: hypot(dy,dx) = max(dy,dx) + min(dy,dx) / 2
  34. */
  35. int distance(int y1, int x1, int y2, int x2)
  36. {
  37. /* Find the absolute y/x distance components */
  38. int ay = abs(y2 - y1);
  39. int ax = abs(x2 - x1);
  40. /* Approximate the distance */
  41. return ay > ax ? ay + (ax>>1) : ax + (ay>>1);
  42. }
  43. /*
  44. * A simple, fast, integer-based line-of-sight algorithm. By Joseph Hall,
  45. * 4116 Brewster Drive, Raleigh NC 27606. Email to jnh@ecemwl.ncsu.edu.
  46. *
  47. * This function returns TRUE if a "line of sight" can be traced from the
  48. * center of the grid (x1,y1) to the center of the grid (x2,y2), with all
  49. * of the grids along this path (except for the endpoints) being non-wall
  50. * grids. Actually, the "chess knight move" situation is handled by some
  51. * special case code which allows the grid diagonally next to the player
  52. * to be obstructed, because this yields better gameplay semantics. This
  53. * algorithm is totally reflexive, except for "knight move" situations.
  54. *
  55. * Because this function uses (short) ints for all calculations, overflow
  56. * may occur if dx and dy exceed 90.
  57. *
  58. * Once all the degenerate cases are eliminated, we determine the "slope"
  59. * ("m"), and we use special "fixed point" mathematics in which we use a
  60. * special "fractional component" for one of the two location components
  61. * ("qy" or "qx"), which, along with the slope itself, are "scaled" by a
  62. * scale factor equal to "abs(dy*dx*2)" to keep the math simple. Then we
  63. * simply travel from start to finish along the longer axis, starting at
  64. * the border between the first and second tiles (where the y offset is
  65. * thus half the slope), using slope and the fractional component to see
  66. * when motion along the shorter axis is necessary. Since we assume that
  67. * vision is not blocked by "brushing" the corner of any grid, we must do
  68. * some special checks to avoid testing grids which are "brushed" but not
  69. * actually "entered".
  70. *
  71. * Angband three different "line of sight" type concepts, including this
  72. * function (which is used almost nowhere), the "project()" method (which
  73. * is used for determining the paths of projectables and spells and such),
  74. * and the "update_view()" concept (which is used to determine which grids
  75. * are "viewable" by the player, which is used for many things, such as
  76. * determining which grids are illuminated by the player's torch, and which
  77. * grids and monsters can be "seen" by the player, etc).
  78. */
  79. bool los(int y1, int x1, int y2, int x2)
  80. {
  81. /* Delta */
  82. int dx, dy;
  83. /* Absolute */
  84. int ax, ay;
  85. /* Signs */
  86. int sx, sy;
  87. /* Fractions */
  88. int qx, qy;
  89. /* Scanners */
  90. int tx, ty;
  91. /* Scale factors */
  92. int f1, f2;
  93. /* Slope, or 1/Slope, of LOS */
  94. int m;
  95. /* Extract the offset */
  96. dy = y2 - y1;
  97. dx = x2 - x1;
  98. /* Extract the absolute offset */
  99. ay = ABS(dy);
  100. ax = ABS(dx);
  101. /* Handle adjacent (or identical) grids */
  102. if ((ax < 2) && (ay < 2)) return (TRUE);
  103. /* Directly South/North */
  104. if (!dx)
  105. {
  106. /* South -- check for walls */
  107. if (dy > 0)
  108. {
  109. for (ty = y1 + 1; ty < y2; ty++)
  110. {
  111. if (!cave_floor_bold(ty, x1)) return (FALSE);
  112. }
  113. }
  114. /* North -- check for walls */
  115. else
  116. {
  117. for (ty = y1 - 1; ty > y2; ty--)
  118. {
  119. if (!cave_floor_bold(ty, x1)) return (FALSE);
  120. }
  121. }
  122. /* Assume los */
  123. return (TRUE);
  124. }
  125. /* Directly East/West */
  126. if (!dy)
  127. {
  128. /* East -- check for walls */
  129. if (dx > 0)
  130. {
  131. for (tx = x1 + 1; tx < x2; tx++)
  132. {
  133. if (!cave_floor_bold(y1, tx)) return (FALSE);
  134. }
  135. }
  136. /* West -- check for walls */
  137. else
  138. {
  139. for (tx = x1 - 1; tx > x2; tx--)
  140. {
  141. if (!cave_floor_bold(y1, tx)) return (FALSE);
  142. }
  143. }
  144. /* Assume los */
  145. return (TRUE);
  146. }
  147. /* Extract some signs */
  148. sx = (dx < 0) ? -1 : 1;
  149. sy = (dy < 0) ? -1 : 1;
  150. /* Vertical "knights" */
  151. if (ax == 1)
  152. {
  153. if (ay == 2)
  154. {
  155. if (cave_floor_bold(y1 + sy, x1)) return (TRUE);
  156. }
  157. }
  158. /* Horizontal "knights" */
  159. else if (ay == 1)
  160. {
  161. if (ax == 2)
  162. {
  163. if (cave_floor_bold(y1, x1 + sx)) return (TRUE);
  164. }
  165. }
  166. /* Calculate scale factor div 2 */
  167. f2 = (ax * ay);
  168. /* Calculate scale factor */
  169. f1 = f2 << 1;
  170. /* Travel horizontally */
  171. if (ax >= ay)
  172. {
  173. /* Let m = dy / dx * 2 * (dy * dx) = 2 * dy * dy */
  174. qy = ay * ay;
  175. m = qy << 1;
  176. tx = x1 + sx;
  177. /* Consider the special case where slope == 1. */
  178. if (qy == f2)
  179. {
  180. ty = y1 + sy;
  181. qy -= f1;
  182. }
  183. else
  184. {
  185. ty = y1;
  186. }
  187. /* Note (below) the case (qy == f2), where */
  188. /* the LOS exactly meets the corner of a tile. */
  189. while (x2 - tx)
  190. {
  191. if (!cave_floor_bold(ty, tx)) return (FALSE);
  192. qy += m;
  193. if (qy < f2)
  194. {
  195. tx += sx;
  196. }
  197. else if (qy > f2)
  198. {
  199. ty += sy;
  200. if (!cave_floor_bold(ty, tx)) return (FALSE);
  201. qy -= f1;
  202. tx += sx;
  203. }
  204. else
  205. {
  206. ty += sy;
  207. qy -= f1;
  208. tx += sx;
  209. }
  210. }
  211. }
  212. /* Travel vertically */
  213. else
  214. {
  215. /* Let m = dx / dy * 2 * (dx * dy) = 2 * dx * dx */
  216. qx = ax * ax;
  217. m = qx << 1;
  218. ty = y1 + sy;
  219. if (qx == f2)
  220. {
  221. tx = x1 + sx;
  222. qx -= f1;
  223. }
  224. else
  225. {
  226. tx = x1;
  227. }
  228. /* Note (below) the case (qx == f2), where */
  229. /* the LOS exactly meets the corner of a tile. */
  230. while (y2 - ty)
  231. {
  232. if (!cave_floor_bold(ty, tx)) return (FALSE);
  233. qx += m;
  234. if (qx < f2)
  235. {
  236. ty += sy;
  237. }
  238. else if (qx > f2)
  239. {
  240. tx += sx;
  241. if (!cave_floor_bold(ty, tx)) return (FALSE);
  242. qx -= f1;
  243. ty += sy;
  244. }
  245. else
  246. {
  247. tx += sx;
  248. qx -= f1;
  249. ty += sy;
  250. }
  251. }
  252. }
  253. /* Assume los */
  254. return (TRUE);
  255. }
  256. /*
  257. * Returns true if the player's grid is dark
  258. */
  259. bool no_light(void)
  260. {
  261. return (!player_can_see_bold(p_ptr->py, p_ptr->px));
  262. }
  263. /*
  264. * Determine if a given location may be "destroyed"
  265. *
  266. * Used by destruction spells, and for placing stairs, etc.
  267. */
  268. bool cave_valid_bold(int y, int x)
  269. {
  270. object_type *o_ptr;
  271. /* Forbid perma-grids */
  272. if (cave_perma_bold(y, x)) return (FALSE);
  273. /* Check objects */
  274. for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr))
  275. {
  276. /* Forbid artifact grids */
  277. if (artifact_p(o_ptr)) return (FALSE);
  278. }
  279. /* Accept */
  280. return (TRUE);
  281. }
  282. /*
  283. * Hack -- Hallucinatory monster
  284. */
  285. static u16b hallucinatory_monster(void)
  286. {
  287. monster_race *r_ptr;
  288. byte a;
  289. char c;
  290. while (1)
  291. {
  292. /* Select a random monster */
  293. r_ptr = &r_info[randint0(z_info->r_max)];
  294. /* Skip non-entries */
  295. if (!r_ptr->name) continue;
  296. /* Retrieve attr/char */
  297. a = r_ptr->x_attr;
  298. c = r_ptr->x_char;
  299. /* Encode */
  300. return (PICT(a,c));
  301. }
  302. }
  303. /*
  304. * Hack -- Hallucinatory object
  305. */
  306. static u16b hallucinatory_object(void)
  307. {
  308. object_kind *k_ptr;
  309. byte a;
  310. char c;
  311. while (1)
  312. {
  313. /* Select a random object */
  314. k_ptr = &k_info[randint0(z_info->k_max - 1) + 1];
  315. /* Skip non-entries */
  316. if (!k_ptr->name) continue;
  317. /* Retrieve attr/char (HACK - without flavors) */
  318. a = k_ptr->x_attr;
  319. c = k_ptr->x_char;
  320. /* HACK - Skip empty entries */
  321. if ((a == 0) || (c == 0)) continue;
  322. /* Encode */
  323. return (PICT(a,c));
  324. }
  325. }
  326. /*
  327. * The 16x16 tile of the terrain supports lighting
  328. */
  329. bool feat_supports_lighting(int feat)
  330. {
  331. /* Pseudo graphics don't support lighting */
  332. if (use_graphics == GRAPHICS_PSEUDO) return FALSE;
  333. if ((use_graphics != GRAPHICS_DAVID_GERVAIS) &&
  334. (feat >= FEAT_TRAP_HEAD) && (feat <= FEAT_TRAP_TAIL))
  335. {
  336. return TRUE;
  337. }
  338. switch (feat)
  339. {
  340. case FEAT_FLOOR:
  341. case FEAT_INVIS:
  342. case FEAT_SECRET:
  343. case FEAT_MAGMA:
  344. case FEAT_QUARTZ:
  345. case FEAT_MAGMA_H:
  346. case FEAT_QUARTZ_H:
  347. case FEAT_WALL_EXTRA:
  348. case FEAT_WALL_INNER:
  349. case FEAT_WALL_OUTER:
  350. case FEAT_WALL_SOLID:
  351. case FEAT_PERM_EXTRA:
  352. case FEAT_PERM_INNER:
  353. case FEAT_PERM_OUTER:
  354. case FEAT_PERM_SOLID:
  355. return TRUE;
  356. default:
  357. return FALSE;
  358. }
  359. }
  360. /*
  361. * Translate text colours.
  362. *
  363. * This translates a color based on the attribute. We use this to set terrain to
  364. * be lighter or darker, make metallic monsters shimmer, highlight text under the
  365. * mouse, and reduce the colours on mono colour or 16 colour terms to the correct
  366. * colour space.
  367. *
  368. * TODO: Honour the attribute for the term (full color, mono, 16 color) but ensure
  369. * that e.g. the lighter version of yellow becomes white in a 16 color term, but
  370. * light yellow in a full colour term.
  371. */
  372. byte get_color(byte a, int attr, int n)
  373. {
  374. /* Accept any graphical attr (high bit set) */
  375. if (a & (0x80)) return (a);
  376. /* TODO: Honour the attribute for the term (full color, mono, 16 color) */
  377. if (!attr) return(a);
  378. /* Translate the color N times */
  379. while (n > 0)
  380. {
  381. a = color_table[a].color_translate[attr];
  382. n--;
  383. }
  384. /* Return the modified color */
  385. return (a);
  386. }
  387. /*
  388. * This function modifies the attr/char pair for an empty floor space
  389. * to reflect the various lighting options available.
  390. *
  391. * For text, this means changing the colouring for OPT(view_yellow_light) or
  392. * OPT(view_bright_light), and for graphics it means modifying the char to
  393. * use a different tile in the tileset. These modifications are different
  394. * for different sets, depending on the tiles available, and their position
  395. * in the set.
  396. */
  397. static void special_lighting_floor(byte *a, char *c, enum grid_light_level lighting, bool in_view)
  398. {
  399. /* The floor starts off "lit" - i.e. rendered in white or the default
  400. * tile. */
  401. if (lighting == LIGHT_TORCH && OPT(view_yellow_light))
  402. {
  403. /*
  404. * OPT(view_yellow_light) distinguishes between torchlit and
  405. * permanently-lit areas
  406. */
  407. switch (use_graphics)
  408. {
  409. case GRAPHICS_NONE:
  410. case GRAPHICS_PSEUDO:
  411. /* Use "yellow" */
  412. if (*a == TERM_WHITE) *a = TERM_YELLOW;
  413. break;
  414. case GRAPHICS_ADAM_BOLT:
  415. *c += 2;
  416. break;
  417. case GRAPHICS_DAVID_GERVAIS:
  418. *c -= 1;
  419. break;
  420. }
  421. }
  422. else if (lighting == LIGHT_DARK)
  423. {
  424. /* Use a dark tile */
  425. switch (use_graphics)
  426. {
  427. case GRAPHICS_NONE:
  428. case GRAPHICS_PSEUDO:
  429. /* Use "dark gray" */
  430. if (*a == TERM_WHITE) *a = TERM_L_DARK;
  431. break;
  432. case GRAPHICS_ADAM_BOLT:
  433. case GRAPHICS_DAVID_GERVAIS:
  434. *c += 1;
  435. break;
  436. }
  437. }
  438. else
  439. {
  440. /*
  441. * OPT(view_bright_light) makes tiles that aren't in the "eyeline"
  442. * of the player show up dimmer than those that are.
  443. */
  444. if (OPT(view_bright_light) && !in_view)
  445. {
  446. switch (use_graphics)
  447. {
  448. case GRAPHICS_NONE:
  449. case GRAPHICS_PSEUDO:
  450. /* Use "gray" */
  451. if (*a == TERM_WHITE) *a = TERM_SLATE;
  452. else if (*a == TERM_L_GREEN) *a = TERM_GREEN;
  453. break;
  454. case GRAPHICS_ADAM_BOLT:
  455. case GRAPHICS_DAVID_GERVAIS:
  456. *c += 1;
  457. break;
  458. }
  459. }
  460. }
  461. }
  462. /*
  463. * This function modifies the attr/char pair for a wall (or other "interesting"
  464. * grids to show them as more-or-less lit. Note that how walls are drawn
  465. * isn't directly related to how they are lit - walls are always "lit".
  466. * The lighting effects we use are as a visual cue to emphasise blindness
  467. * and to show field-of-view (OPT(view_bright_light)).
  468. *
  469. * For text, we change the attr and for graphics we modify the char to
  470. * use a different tile in the tileset. These modifications are different
  471. * for different sets, depending on the tiles available, and their position
  472. * in the set.
  473. */
  474. static void special_wall_display(byte *a, char *c, bool in_view, int feat)
  475. {
  476. /* Grids currently in view are left alone, rendered as "white" */
  477. if (in_view) return;
  478. /* When blind, we make walls and other "white" things dark */
  479. if (p_ptr->timed[TMD_BLIND])
  480. {
  481. switch (use_graphics)
  482. {
  483. case GRAPHICS_NONE:
  484. case GRAPHICS_PSEUDO:
  485. /* Use "dark gray" */
  486. if (*a == TERM_WHITE) *a = TERM_L_DARK;
  487. break;
  488. case GRAPHICS_ADAM_BOLT:
  489. case GRAPHICS_DAVID_GERVAIS:
  490. if (feat_supports_lighting(feat)) *c += 1;
  491. break;
  492. }
  493. }
  494. /* Handle "OPT(view_bright_light)" by dimming walls not "in view" */
  495. else if (OPT(view_bright_light))
  496. {
  497. switch (use_graphics)
  498. {
  499. case GRAPHICS_NONE:
  500. case GRAPHICS_PSEUDO:
  501. /* Use "gray" */
  502. if (*a == TERM_WHITE) *a = TERM_SLATE;
  503. break;
  504. case GRAPHICS_ADAM_BOLT:
  505. case GRAPHICS_DAVID_GERVAIS:
  506. if (feat_supports_lighting(feat)) *c += 1;
  507. break;
  508. }
  509. }
  510. else
  511. {
  512. /* Use a brightly lit tile */
  513. switch (use_graphics)
  514. {
  515. case GRAPHICS_ADAM_BOLT:
  516. if (feat_supports_lighting(feat)) *c += 2;
  517. break;
  518. case GRAPHICS_DAVID_GERVAIS:
  519. if (feat_supports_lighting(feat)) *c -= 1;
  520. break;
  521. }
  522. }
  523. }
  524. /*
  525. * Checks if a square is at the (inner) edge of a trap detect area
  526. */
  527. bool dtrap_edge(int y, int x)
  528. {
  529. /* Check if the square is a dtrap in the first place */
  530. if (!cave_info2[y][x] & CAVE2_DTRAP) return FALSE;
  531. /* Check for non-dtrap adjacent grids */
  532. if (in_bounds_fully(y + 1, x ) && (!cave_info2[y + 1][x ] & CAVE2_DTRAP)) return TRUE;
  533. if (in_bounds_fully(y , x + 1) && (!cave_info2[y ][x + 1] & CAVE2_DTRAP)) return TRUE;
  534. if (in_bounds_fully(y - 1, x ) && (!cave_info2[y - 1][x ] & CAVE2_DTRAP)) return TRUE;
  535. if (in_bounds_fully(y , x - 1) && (!cave_info2[y ][x - 1] & CAVE2_DTRAP)) return TRUE;
  536. return FALSE;
  537. }
  538. /*
  539. * This function takes a pointer to a grid info struct describing the
  540. * contents of a grid location (as obtained through the function map_info)
  541. * and fills in the character and attr pairs for display.
  542. *
  543. * ap and cp are filled with the attr/char pair for the monster, object or
  544. * floor tile that is at the "top" of the grid (monsters covering objects,
  545. * which cover floor, assuming all are present).
  546. *
  547. * tap and tcp are filled with the attr/char pair for the floor, regardless
  548. * of what is on it. This can be used by graphical displays with
  549. * transparency to place an object onto a floor tile, is desired.
  550. *
  551. * Any lighting effects are also applied to these pairs, clear monsters allow
  552. * the underlying colour or feature to show through (ATTR_CLEAR and
  553. * CHAR_CLEAR), multi-hued colour-changing (ATTR_MULTI) is applied, and so on.
  554. * Technically, the flag "CHAR_MULTI" is supposed to indicate that a monster
  555. * looks strange when examined, but this flag is currently ignored.
  556. *
  557. * NOTES:
  558. * This is called pretty frequently, whenever a grid on the map display
  559. * needs updating, so don't overcomplicate it.
  560. *
  561. * The "zero" entry in the feature/object/monster arrays are
  562. * used to provide "special" attr/char codes, with "monster zero" being
  563. * used for the player attr/char, "object zero" being used for the "pile"
  564. * attr/char, and "feature zero" being used for the "darkness" attr/char.
  565. *
  566. * TODO:
  567. * The transformations for tile colors, or brightness for the 16x16
  568. * tiles should be handled differently. One possibility would be to
  569. * extend feature_type with attr/char definitions for the different states.
  570. * This will probably be done outside of the current text->graphics mappings
  571. * though.
  572. */
  573. void grid_data_as_text(grid_data *g, byte *ap, char *cp, byte *tap, char *tcp)
  574. {
  575. byte a;
  576. char c;
  577. feature_type *f_ptr = &f_info[g->f_idx];
  578. /* Normal attr and char */
  579. a = f_ptr->x_attr;
  580. c = f_ptr->x_char;
  581. /* Check for trap detection boundaries */
  582. if (g->trapborder && g->f_idx == FEAT_FLOOR &&
  583. (use_graphics == GRAPHICS_NONE ||
  584. use_graphics == GRAPHICS_PSEUDO))
  585. a = TERM_L_GREEN;
  586. /* Special lighting effects */
  587. if (g->f_idx <= FEAT_INVIS && OPT(view_special_light))
  588. special_lighting_floor(&a, &c, g->lighting, g->in_view);
  589. /* Special lighting effects (walls only) */
  590. if (g->f_idx > FEAT_INVIS && OPT(view_granite_light))
  591. special_wall_display(&a, &c, g->in_view, g->f_idx);
  592. /* Save the terrain info for the transparency effects */
  593. (*tap) = a;
  594. (*tcp) = c;
  595. /* If there's an object, deal with that. */
  596. if (g->first_k_idx)
  597. {
  598. if (g->hallucinate)
  599. {
  600. /* Just pick a random object to display. */
  601. int i = hallucinatory_object();
  602. a = PICT_A(i);
  603. c = PICT_C(i);
  604. }
  605. else
  606. {
  607. object_kind *k_ptr = &k_info[g->first_k_idx];
  608. /* Normal attr and char */
  609. a = object_kind_attr(g->first_k_idx);
  610. c = object_kind_char(g->first_k_idx);
  611. if (OPT(show_piles) && g->multiple_objects)
  612. {
  613. /* Get the "pile" feature instead */
  614. k_ptr = &k_info[0];
  615. a = k_ptr->x_attr;
  616. c = k_ptr->x_char;
  617. }
  618. }
  619. }
  620. /* If there's a monster */
  621. if (g->m_idx > 0)
  622. {
  623. if (g->hallucinate)
  624. {
  625. /* Just pick a random monster to display. */
  626. int i = hallucinatory_monster();
  627. a = PICT_A(i);
  628. c = PICT_C(i);
  629. }
  630. else
  631. {
  632. monster_type *m_ptr = &mon_list[g->m_idx];
  633. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  634. byte da;
  635. char dc;
  636. /* Desired attr & char*/
  637. da = r_ptr->x_attr;
  638. dc = r_ptr->x_char;
  639. /* Special attr/char codes */
  640. if ((da & 0x80) && (dc & 0x80))
  641. {
  642. /* Use attr */
  643. a = da;
  644. /* Use char */
  645. c = dc;
  646. }
  647. /* Multi-hued monster */
  648. else if (rf_has(r_ptr->flags, RF_ATTR_MULTI) ||
  649. rf_has(r_ptr->flags, RF_ATTR_FLICKER))
  650. {
  651. /* Multi-hued attr */
  652. a = m_ptr->attr ? m_ptr->attr : 1;
  653. /* Normal char */
  654. c = dc;
  655. }
  656. /* Normal monster (not "clear" in any way) */
  657. else if (!flags_test(r_ptr->flags, RF_SIZE, RF_ATTR_CLEAR,
  658. RF_CHAR_CLEAR, FLAG_END))
  659. {
  660. /* Use attr */
  661. a = da;
  662. /* Desired attr & char */
  663. da = r_ptr->x_attr;
  664. dc = r_ptr->x_char;
  665. /* Use char */
  666. c = dc;
  667. }
  668. /* Hack -- Bizarre grid under monster */
  669. else if ((a & 0x80) || (c & 0x80))
  670. {
  671. /* Use attr */
  672. a = da;
  673. /* Use char */
  674. c = dc;
  675. }
  676. /* Normal char, Clear attr, monster */
  677. else if (!rf_has(r_ptr->flags, RF_CHAR_CLEAR))
  678. {
  679. /* Normal char */
  680. c = dc;
  681. }
  682. /* Normal attr, Clear char, monster */
  683. else if (!rf_has(r_ptr->flags, RF_ATTR_CLEAR))
  684. {
  685. /* Normal attr */
  686. a = da;
  687. }
  688. /* Store the drawing attr so we can use it other places too */
  689. m_ptr->attr = a;
  690. }
  691. }
  692. /* Handle "player" */
  693. else if (g->is_player)
  694. {
  695. monster_race *r_ptr = &r_info[0];
  696. /* Get the "player" attr */
  697. a = r_ptr->x_attr;
  698. if ((OPT(hp_changes_color)) && (arg_graphics == GRAPHICS_NONE))
  699. {
  700. switch(p_ptr->chp * 10 / p_get_mhp())
  701. {
  702. case 10:
  703. case 9:
  704. {
  705. a = TERM_WHITE;
  706. break;
  707. }
  708. case 8:
  709. case 7:
  710. {
  711. a = TERM_YELLOW;
  712. break;
  713. }
  714. case 6:
  715. case 5:
  716. {
  717. a = TERM_ORANGE;
  718. break;
  719. }
  720. case 4:
  721. case 3:
  722. {
  723. a = TERM_L_RED;
  724. break;
  725. }
  726. case 2:
  727. case 1:
  728. case 0:
  729. {
  730. a = TERM_RED;
  731. break;
  732. }
  733. default:
  734. {
  735. a = TERM_WHITE;
  736. break;
  737. }
  738. }
  739. }
  740. /* Get the "player" char */
  741. c = r_ptr->x_char;
  742. }
  743. /* Result */
  744. (*ap) = a;
  745. (*cp) = c;
  746. }
  747. /*
  748. * This function takes a grid location (x, y) and extracts information the
  749. * player is allowed to know about it, filling in the grid_data structure
  750. * passed in 'g'.
  751. *
  752. * The information filled in is as follows:
  753. * - g->f_idx is filled in with the terrain's feature type, or FEAT_NONE
  754. * if the player doesn't know anything about the grid. The function
  755. * makes use of the "mimic" field in terrain in order to allow one
  756. * feature to look like another (hiding secret doors, invisible traps,
  757. * etc). This will return the terrain type the player "Knows" about,
  758. * not necessarily the real terrain.
  759. * - g->m_idx is set to the monster index, or 0 if there is none (or the
  760. * player doesn't know it).
  761. * - g->first_k_idx is set to the index of the first object in a grid
  762. * that the player knows (and cares, as per OPT(hide_squelchable)) about,
  763. * or zero for no object in the grid.
  764. * - g->muliple_objects is TRUE if there is more than one object in the
  765. * grid that the player knows and cares about (to facilitate any special
  766. * floor stack symbol that might be used).
  767. * - g->in_view is TRUE if the player can currently see the grid - this can
  768. * be used to indicate field-of-view, such as through the OPT(view_bright_light)
  769. * option.
  770. * - g->lighting is set to indicate the lighting level for the grid:
  771. * LIGHT_DARK for unlit grids, LIGHT_TORCH for those lit by the player's
  772. * light source, and LIGHT_GLOW for inherently light grids (lit rooms, etc).
  773. * Note that lighting is always LIGHT_GLOW for known "interesting" grids
  774. * like walls.
  775. * - g->is_player is TRUE if the player is on the given grid.
  776. * - g->hallucinate is TRUE if the player is hallucinating something "strange"
  777. * for this grid - this should pick a random monster to show if the m_idx
  778. * is non-zero, and a random object if first_k_idx is non-zero.
  779. *
  780. * NOTES:
  781. * This is called pretty frequently, whenever a grid on the map display
  782. * needs updating, so don't overcomplicate it.
  783. *
  784. * Terrain is remembered separately from objects and monsters, so can be
  785. * shown even when the player can't "see" it. This leads to things like
  786. * doors out of the player's view still change from closed to open and so on.
  787. *
  788. * TODO:
  789. * Hallucination is currently disabled (it was a display-level hack before,
  790. * and we need it to be a knowledge-level hack). The idea is that objects
  791. * may turn into different objects, monsters into different monsters, and
  792. * terrain may be objects, monsters, or stay the same.
  793. */
  794. void map_info(unsigned y, unsigned x, grid_data *g)
  795. {
  796. object_type *o_ptr;
  797. byte info, info2;
  798. assert(x < DUNGEON_WID);
  799. assert(y < DUNGEON_HGT);
  800. info = cave_info[y][x];
  801. info2 = cave_info2[y][x];
  802. /* Default "clear" values, others will be set later where appropriate. */
  803. g->first_k_idx = 0;
  804. g->multiple_objects = FALSE;
  805. g->lighting = LIGHT_GLOW;
  806. /* Set things we can work out right now */
  807. g->f_idx = cave_feat[y][x];
  808. g->in_view = (info & CAVE_SEEN) ? TRUE : FALSE;
  809. g->is_player = (cave_m_idx[y][x] < 0) ? TRUE : FALSE;
  810. g->m_idx = (g->is_player) ? 0 : cave_m_idx[y][x];
  811. g->hallucinate = p_ptr->timed[TMD_IMAGE] ? TRUE : FALSE;
  812. g->trapborder = (dtrap_edge(y, x)) ? TRUE : FALSE;
  813. /* If the grid is memorised or can currently be seen */
  814. if ((info & CAVE_MARK) || (info & CAVE_SEEN))
  815. {
  816. /* Apply "mimic" field */
  817. g->f_idx = f_info[g->f_idx].mimic;
  818. /* Boring grids (floors, etc) */
  819. if (g->f_idx <= FEAT_INVIS)
  820. {
  821. /* Get the floor feature */
  822. g->f_idx = FEAT_FLOOR;
  823. /* Handle currently visible grids */
  824. if (info & CAVE_SEEN)
  825. {
  826. /* Only lit by "torch" light */
  827. if (info & CAVE_GLOW)
  828. g->lighting = LIGHT_GLOW;
  829. else
  830. g->lighting = LIGHT_TORCH;
  831. }
  832. /* Handle "dark" grids and "blindness" */
  833. else if (p_ptr->timed[TMD_BLIND] || !(info & CAVE_GLOW))
  834. g->lighting = LIGHT_DARK;
  835. }
  836. }
  837. /* Unknown */
  838. else
  839. {
  840. g->f_idx = FEAT_NONE;
  841. }
  842. /* Objects */
  843. for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr))
  844. {
  845. /* Memorized objects */
  846. if (o_ptr->marked && !squelch_hide_item(o_ptr))
  847. {
  848. /* First item found */
  849. if (g->first_k_idx == 0)
  850. {
  851. g->first_k_idx = o_ptr->k_idx;
  852. }
  853. else
  854. {
  855. g->multiple_objects = TRUE;
  856. /* And we know all we need to know. */
  857. break;
  858. }
  859. }
  860. }
  861. /* Monsters */
  862. if (g->m_idx > 0)
  863. {
  864. /* If the monster isn't "visible", make sure we don't list it.*/
  865. monster_type *m_ptr = &mon_list[g->m_idx];
  866. if (!m_ptr->ml) g->m_idx = 0;
  867. }
  868. /* Rare random hallucination on non-outer walls */
  869. if (g->hallucinate && g->m_idx == 0 && g->first_k_idx == 0)
  870. {
  871. if (one_in_(256) && (g->f_idx < FEAT_PERM_SOLID))
  872. {
  873. /* Normally, make an imaginary monster */
  874. if (randint0(100) < 75)
  875. {
  876. g->m_idx = 1;
  877. }
  878. /* Otherwise, an imaginary object */
  879. else
  880. {
  881. g->first_k_idx = 1;
  882. }
  883. }
  884. else
  885. {
  886. g->hallucinate = FALSE;
  887. }
  888. }
  889. assert(g->f_idx <= FEAT_PERM_SOLID);
  890. assert(g->m_idx < (u32b) mon_max);
  891. assert(g->first_k_idx < z_info->k_max);
  892. /* All other g fields are 'flags', mostly booleans. */
  893. }
  894. /*
  895. * Move the cursor to a given map location.
  896. */
  897. static void move_cursor_relative_map(int y, int x)
  898. {
  899. int ky, kx;
  900. term *old;
  901. int j;
  902. /* Scan windows */
  903. for (j = 0; j < ANGBAND_TERM_MAX; j++)
  904. {
  905. term *t = angband_term[j];
  906. /* No window */
  907. if (!t) continue;
  908. /* No relevant flags */
  909. if (!(op_ptr->window_flag[j] & (PW_MAP))) continue;
  910. /* Location relative to panel */
  911. ky = y - t->offset_y;
  912. /* Verify location */
  913. if ((ky < 0) || (ky >= t->hgt)) continue;
  914. /* Location relative to panel */
  915. kx = x - t->offset_x;
  916. if (use_bigtile) kx += kx;
  917. /* Verify location */
  918. if ((kx < 0) || (kx >= t->wid)) continue;
  919. /* Go there */
  920. old = Term;
  921. Term_activate(t);
  922. (void)Term_gotoxy(kx, ky);
  923. Term_activate(old);
  924. }
  925. }
  926. /*
  927. * Move the cursor to a given map location.
  928. *
  929. * The main screen will always be at least 24x80 in size.
  930. */
  931. void move_cursor_relative(int y, int x)
  932. {
  933. int ky, kx;
  934. int vy, vx;
  935. /* Move the cursor on map sub-windows */
  936. move_cursor_relative_map(y, x);
  937. /* Location relative to panel */
  938. ky = y - Term->offset_y;
  939. /* Verify location */
  940. if ((ky < 0) || (ky >= SCREEN_HGT)) return;
  941. /* Location relative to panel */
  942. kx = x - Term->offset_x;
  943. /* Verify location */
  944. if ((kx < 0) || (kx >= SCREEN_WID)) return;
  945. /* Location in window */
  946. vy = ky + ROW_MAP;
  947. /* Location in window */
  948. vx = kx + COL_MAP;
  949. if (use_bigtile) vx += kx;
  950. /* Go there */
  951. (void)Term_gotoxy(vx, vy);
  952. }
  953. /*
  954. * Display an attr/char pair at the given map location
  955. *
  956. * Note the inline use of "panel_contains()" for efficiency.
  957. *
  958. * Note the use of "Term_queue_char()" for efficiency.
  959. */
  960. static void print_rel_map(char c, byte a, int y, int x)
  961. {
  962. int ky, kx;
  963. int j;
  964. /* Scan windows */
  965. for (j = 0; j < ANGBAND_TERM_MAX; j++)
  966. {
  967. term *t = angband_term[j];
  968. /* No window */
  969. if (!t) continue;
  970. /* No relevant flags */
  971. if (!(op_ptr->window_flag[j] & (PW_MAP))) continue;
  972. /* Location relative to panel */
  973. ky = y - t->offset_y;
  974. /* Verify location */
  975. if ((ky < 0) || (ky >= t->hgt)) continue;
  976. /* Location relative to panel */
  977. kx = x - t->offset_x;
  978. if (use_bigtile)
  979. {
  980. kx += kx;
  981. if (kx + 1 >= t->wid) continue;
  982. }
  983. /* Verify location */
  984. if ((kx < 0) || (kx >= t->wid)) continue;
  985. /* Hack -- Queue it */
  986. Term_queue_char(t, kx, ky, a, c, 0, 0);
  987. if (use_bigtile)
  988. {
  989. /* Mega-Hack : Queue dummy char */
  990. if (a & 0x80)
  991. Term_queue_char(t, kx+1, ky, 255, -1, 0, 0);
  992. else
  993. Term_queue_char(t, kx+1, ky, TERM_WHITE, ' ', 0, 0);
  994. }
  995. }
  996. }
  997. /*
  998. * Display an attr/char pair at the given map location
  999. *
  1000. * Note the inline use of "panel_contains()" for efficiency.
  1001. *
  1002. * Note the use of "Term_queue_char()" for efficiency.
  1003. *
  1004. * The main screen will always be at least 24x80 in size.
  1005. */
  1006. void print_rel(char c, byte a, int y, int x)
  1007. {
  1008. int ky, kx;
  1009. int vy, vx;
  1010. /* Print on map sub-windows */
  1011. print_rel_map(c, a, y, x);
  1012. /* Location relative to panel */
  1013. ky = y - Term->offset_y;
  1014. /* Verify location */
  1015. if ((ky < 0) || (ky >= SCREEN_HGT)) return;
  1016. /* Location relative to panel */
  1017. kx = x - Term->offset_x;
  1018. /* Verify location */
  1019. if ((kx < 0) || (kx >= SCREEN_WID)) return;
  1020. /* Location in window */
  1021. vy = ky + ROW_MAP;
  1022. /* Location in window */
  1023. vx = kx + COL_MAP;
  1024. if (use_bigtile) vx += kx;
  1025. /* Hack -- Queue it */
  1026. Term_queue_char(Term, vx, vy, a, c, 0, 0);
  1027. if (use_bigtile)
  1028. {
  1029. /* Mega-Hack : Queue dummy char */
  1030. if (a & 0x80)
  1031. Term_queue_char(Term, vx+1, vy, 255, -1, 0, 0);
  1032. else
  1033. Term_queue_char(Term, vx+1, vy, TERM_WHITE, ' ', 0, 0);
  1034. }
  1035. }
  1036. /*
  1037. * Memorize interesting viewable object/features in the given grid
  1038. *
  1039. * This function should only be called on "legal" grids.
  1040. *
  1041. * This function will memorize the object and/or feature in the given grid,
  1042. * if they are (1) see-able and (2) interesting. Note that all objects are
  1043. * interesting, all terrain features except floors (and invisible traps) are
  1044. * interesting, and floors (and invisible traps) are interesting sometimes
  1045. * (depending on various options involving the illumination of floor grids).
  1046. *
  1047. * The automatic memorization of all objects and non-floor terrain features
  1048. * as soon as they are displayed allows incredible amounts of optimization
  1049. * in various places, especially "map_info()" and this function itself.
  1050. *
  1051. * Note that the memorization of objects is completely separate from the
  1052. * memorization of terrain features, preventing annoying floor memorization
  1053. * when a detected object is picked up from a dark floor, and object
  1054. * memorization when an object is dropped into a floor grid which is
  1055. * memorized but out-of-sight.
  1056. *
  1057. * This function should be called every time the "memorization" of a grid
  1058. * (or the object in a grid) is called into question, such as when an object
  1059. * is created in a grid, when a terrain feature "changes" from "floor" to
  1060. * "non-floor", and when any grid becomes "see-able" for any reason.
  1061. *
  1062. * This function is called primarily from the "update_view()" function, for
  1063. * each grid which becomes newly "see-able".
  1064. */
  1065. void note_spot(int y, int x)
  1066. {
  1067. byte info;
  1068. object_type *o_ptr;
  1069. /* Get cave info */
  1070. info = cave_info[y][x];
  1071. /* Require "seen" flag */
  1072. if (!(info & (CAVE_SEEN))) return;
  1073. /* Hack -- memorize objects */
  1074. for (o_ptr = get_first_object(y, x); o_ptr; o_ptr = get_next_object(o_ptr))
  1075. {
  1076. /* Memorize objects */
  1077. o_ptr->marked = TRUE;
  1078. }
  1079. /* Hack -- memorize grids */
  1080. if (!(info & (CAVE_MARK)))
  1081. {
  1082. /* Memorize some "boring" grids */
  1083. if (cave_feat[y][x] <= FEAT_INVIS)
  1084. {
  1085. /* Option -- memorize certain floors */
  1086. if (((info & (CAVE_GLOW)) && OPT(view_perma_grids)) ||
  1087. OPT(view_torch_grids))
  1088. {
  1089. /* Memorize */
  1090. cave_info[y][x] |= (CAVE_MARK);
  1091. }
  1092. }
  1093. /* Memorize all "interesting" grids */
  1094. else
  1095. {
  1096. /* Memorize */
  1097. cave_info[y][x] |= (CAVE_MARK);
  1098. }
  1099. }
  1100. }
  1101. /*
  1102. * Redraw (on the screen) a given map location
  1103. *
  1104. * This function should only be called on "legal" grids.
  1105. */
  1106. void light_spot(int y, int x)
  1107. {
  1108. event_signal_point(EVENT_MAP, x, y);
  1109. }
  1110. static void prt_map_aux(void)
  1111. {
  1112. byte a;
  1113. char c;
  1114. byte ta;
  1115. char tc;
  1116. grid_data g;
  1117. int y, x;
  1118. int vy, vx;
  1119. int ty, tx;
  1120. int j;
  1121. /* Scan windows */
  1122. for (j = 0; j < ANGBAND_TERM_MAX; j++)
  1123. {
  1124. term *t = angband_term[j];
  1125. /* No window */
  1126. if (!t) continue;
  1127. /* No relevant flags */
  1128. if (!(op_ptr->window_flag[j] & (PW_MAP))) continue;
  1129. /* Assume screen */
  1130. ty = t->offset_y + t->hgt;
  1131. tx = t->offset_x + t->wid;
  1132. if (use_bigtile) tx = t->offset_x + (t->wid / 2);
  1133. /* Dump the map */
  1134. for (y = t->offset_y, vy = 0; y < ty; vy++, y++)
  1135. {
  1136. for (x = t->offset_x, vx = 0; x < tx; vx++, x++)
  1137. {
  1138. /* Check bounds */
  1139. if (!in_bounds(y, x)) continue;
  1140. if (use_bigtile && (vx + 1 >= t->wid)) continue;
  1141. /* Determine what is there */
  1142. map_info(y, x, &g);
  1143. grid_data_as_text(&g, &a, &c, &ta, &tc);
  1144. Term_queue_char(t, vx, vy, a, c, ta, tc);
  1145. if (use_bigtile)
  1146. {
  1147. vx++;
  1148. /* Mega-Hack : Queue dummy char */
  1149. if (a & 0x80)
  1150. Term_queue_char(t, vx, vy, 255, -1, 0, 0);
  1151. else
  1152. Term_queue_char(t, vx, vy, TERM_WHITE, ' ', TERM_WHITE, ' ');
  1153. }
  1154. }
  1155. }
  1156. }
  1157. }
  1158. /*
  1159. * Redraw (on the screen) the current map panel
  1160. *
  1161. * Note the inline use of "light_spot()" for efficiency.
  1162. *
  1163. * The main screen will always be at least 24x80 in size.
  1164. */
  1165. void prt_map(void)
  1166. {
  1167. byte a;
  1168. char c;
  1169. byte ta;
  1170. char tc;
  1171. grid_data g;
  1172. int y, x;
  1173. int vy, vx;
  1174. int ty, tx;
  1175. /* Redraw map sub-windows */
  1176. prt_map_aux();
  1177. /* Assume screen */
  1178. ty = Term->offset_y + SCREEN_HGT;
  1179. tx = Term->offset_x + SCREEN_WID;
  1180. /* Dump the map */
  1181. for (y = Term->offset_y, vy = ROW_MAP; y < ty; vy++, y++)
  1182. {
  1183. for (x = Term->offset_x, vx = COL_MAP; x < tx; vx++, x++)
  1184. {
  1185. /* Check bounds */
  1186. if (!in_bounds(y, x)) continue;
  1187. /* Determine what is there */
  1188. map_info(y, x, &g);
  1189. grid_data_as_text(&g, &a, &c, &ta, &tc);
  1190. /* Hack -- Queue it */
  1191. Term_queue_char(Term, vx, vy, a, c, ta, tc);
  1192. if (use_bigtile)
  1193. {
  1194. vx++;
  1195. /* Mega-Hack : Queue dummy char */
  1196. if (a & 0x80)
  1197. Term_queue_char(Term, vx, vy, 255, -1, 0, 0);
  1198. else
  1199. Term_queue_char(Term, vx, vy, TERM_WHITE, ' ', TERM_WHITE, ' ');
  1200. }
  1201. }
  1202. }
  1203. }
  1204. /*
  1205. * Hack -- priority array (see below)
  1206. *
  1207. * Note that all "walls" always look like "secret doors" (see "map_info()").
  1208. */
  1209. static const int priority_table[14][2] =
  1210. {
  1211. /* Dark */
  1212. { FEAT_NONE, 2 },
  1213. /* Floors */
  1214. { FEAT_FLOOR, 5 },
  1215. /* Walls */
  1216. { FEAT_SECRET, 10 },
  1217. /* Quartz */
  1218. { FEAT_QUARTZ, 11 },
  1219. /* Magma */
  1220. { FEAT_MAGMA, 12 },
  1221. /* Rubble */
  1222. { FEAT_RUBBLE, 13 },
  1223. /* Open doors */
  1224. { FEAT_OPEN, 15 },
  1225. { FEAT_BROKEN, 15 },
  1226. /* Closed doors */
  1227. { FEAT_DOOR_HEAD + 0x00, 17 },
  1228. /* Hidden gold */
  1229. { FEAT_QUARTZ_K, 19 },
  1230. { FEAT_MAGMA_K, 19 },
  1231. /* Stairs */
  1232. { FEAT_LESS, 25 },
  1233. { FEAT_MORE, 25 },
  1234. /* End */
  1235. { 0, 0 }
  1236. };
  1237. /*
  1238. * Hack -- a priority function (see below)
  1239. */
  1240. static byte priority(byte a, char c)
  1241. {
  1242. int i, p0, p1;
  1243. feature_type *f_ptr;
  1244. /* Scan the table */
  1245. for (i = 0; TRUE; i++)
  1246. {
  1247. /* Priority level */
  1248. p1 = priority_table[i][1];
  1249. /* End of table */
  1250. if (!p1) break;
  1251. /* Feature index */
  1252. p0 = priority_table[i][0];
  1253. /* Get the feature */
  1254. f_ptr = &f_info[p0];
  1255. /* Check character and attribute, accept matches */
  1256. if ((f_ptr->x_char == c) && (f_ptr->x_attr == a)) return (p1);
  1257. }
  1258. /* Default */
  1259. return (20);
  1260. }
  1261. /*
  1262. * Display a "small-scale" map of the dungeon in the active Term.
  1263. *
  1264. * Note that this function must "disable" the special lighting effects so
  1265. * that the "priority" function will work.
  1266. *
  1267. * Note the use of a specialized "priority" function to allow this function
  1268. * to work with any graphic attr/char mappings, and the attempts to optimize
  1269. * this function where possible.
  1270. *
  1271. * If "cy" and "cx" are not NULL, then returns the screen location at which
  1272. * the player was displayed, so the cursor can be moved to that location,
  1273. * and restricts the horizontal map size to SCREEN_WID. Otherwise, nothing
  1274. * is returned (obviously), and no restrictions are enforced.
  1275. */
  1276. void display_map(int *cy, int *cx)
  1277. {
  1278. int py = p_ptr->py;
  1279. int px = p_ptr->px;
  1280. int map_hgt, map_wid;
  1281. int dungeon_hgt, dungeon_wid;
  1282. int row, col;
  1283. int x, y;
  1284. grid_data g;
  1285. byte ta;
  1286. char tc;
  1287. byte tp;
  1288. /* Large array on the stack */
  1289. byte mp[DUNGEON_HGT][DUNGEON_WID];
  1290. bool old_view_special_light;
  1291. bool old_view_granite_light;
  1292. monster_race *r_ptr = &r_info[0];
  1293. /* Desired map height */
  1294. map_hgt = Term->hgt - 2;
  1295. map_wid = Term->wid - 2;
  1296. dungeon_hgt = (p_ptr->depth == 0) ? TOWN_HGT : DUNGEON_HGT;
  1297. dungeon_wid = (p_ptr->depth == 0) ? TOWN_WID : DUNGEON_WID;
  1298. /* Prevent accidents */
  1299. if (map_hgt > dungeon_hgt) map_hgt = dungeon_hgt;
  1300. if (map_wid > dungeon_wid) map_wid = dungeon_wid;
  1301. /* Prevent accidents */
  1302. if ((map_wid < 1) || (map_hgt < 1)) return;
  1303. /* Save lighting effects */
  1304. old_view_special_light = OPT(view_special_light);
  1305. old_view_granite_light = OPT(view_granite_light);
  1306. /* Disable lighting effects */
  1307. OPT(view_special_light) = FALSE;
  1308. OPT(view_granite_light) = FALSE;
  1309. /* Nothing here */
  1310. ta = TERM_WHITE;
  1311. tc = ' ';
  1312. /* Clear the priorities */
  1313. for (y = 0; y < map_hgt; ++y)
  1314. {
  1315. for (x = 0; x < map_wid; ++x)
  1316. {
  1317. /* No priority */
  1318. mp[y][x] = 0;
  1319. }
  1320. }
  1321. /* Draw a box around the edge of the term */
  1322. window_make(0, 0, map_wid + 1, map_hgt + 1);
  1323. /* Analyze the actual map */
  1324. for (y = 0; y < dungeon_hgt; y++)
  1325. {
  1326. for (x = 0; x < dungeon_wid; x++)
  1327. {
  1328. row = (y * map_hgt / dungeon_hgt);
  1329. col = (x * map_wid / dungeon_wid);
  1330. if (use_bigtile)
  1331. col = col & ~1;
  1332. /* Get the attr/char at that map location */
  1333. map_info(y, x, &g);
  1334. grid_data_as_text(&g, &ta, &tc, &ta, &tc);
  1335. /* Get the priority of that attr/char */
  1336. tp = priority(ta, tc);
  1337. /* Save "best" */
  1338. if (mp[row][col] < tp)
  1339. {
  1340. /* Add the character */
  1341. Term_putch(col + 1, row + 1, ta, tc);
  1342. if (use_bigtile)
  1343. {
  1344. if (ta & 0x80)
  1345. Term_putch(col + 2, row + 1, 255, -1);
  1346. else
  1347. Term_putch(col + 2, row + 1, TERM_WHITE, ' ');
  1348. }
  1349. /* Save priority */
  1350. mp[row][col] = tp;
  1351. }
  1352. }
  1353. }
  1354. /* Player location */
  1355. row = (py * map_hgt / dungeon_hgt);
  1356. col = (px * map_wid / dungeon_wid);
  1357. if (use_bigtile)
  1358. col = col & ~1;
  1359. /*** Make sure the player is visible ***/
  1360. /* Get the "player" attr */
  1361. ta = r_ptr->x_attr;
  1362. /* Get the "player" char */
  1363. tc = r_ptr->x_char;
  1364. /* Draw the player */
  1365. Term_putch(col + 1, row + 1, ta, tc);
  1366. /* Return player location */
  1367. if (cy != NULL) (*cy) = row + 1;
  1368. if (cx != NULL) (*cx) = col + 1;
  1369. /* Restore lighting effects */
  1370. OPT(view_special_light) = old_view_special_light;
  1371. OPT(view_granite_light) = old_view_granite_light;
  1372. }
  1373. /*
  1374. * Display a "small-scale" map of the dungeon.
  1375. *
  1376. * Note that the "player" is always displayed on the map.
  1377. */
  1378. void do_cmd_view_map(void)
  1379. {
  1380. int cy, cx;
  1381. cptr prompt = "Hit any key to continue";
  1382. /* Save screen */
  1383. screen_save();
  1384. /* Note */
  1385. prt("Please wait...", 0, 0);
  1386. /* Flush */
  1387. Term_fresh();
  1388. /* Clear the screen */
  1389. Term_clear();
  1390. /* Display the map */
  1391. display_map(&cy, &cx);
  1392. /* Show the prompt */
  1393. put_str(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2);
  1394. /* Highlight the player */
  1395. Term_gotoxy(cx, cy);
  1396. /* Get any key */
  1397. (void)anykey();
  1398. /* Load screen */
  1399. screen_load();
  1400. }
  1401. /*
  1402. * Some comments on the dungeon related data structures and functions...
  1403. *
  1404. * Angband is primarily a dungeon exploration game, and it should come as
  1405. * no surprise that the internal representation of the dungeon has evolved
  1406. * over time in much the same way as the game itself, to provide semantic
  1407. * changes to the game itself, to make the code simpler to understand, and
  1408. * to make the executable itself faster or more efficient in various ways.
  1409. *
  1410. * There are a variety of dungeon related data structures, and associated
  1411. * functions, which store information about the dungeon, and provide methods
  1412. * by which this information can be accessed or modified.
  1413. *
  1414. * Some of this information applies to the dungeon as a whole, such as the
  1415. * list of unique monsters which are still alive. Some of this information
  1416. * only applies to the current dungeon level, such as the current depth, or
  1417. * the list of monsters currently inhabiting the level. And some of the
  1418. * information only applies to a single grid of the current dungeon level,
  1419. * such as whether the grid is illuminated, or whether the grid contains a
  1420. * monster, or whether the grid can be seen by the player. If Angband was
  1421. * to be turned into a multi-player game, some of the information currently
  1422. * associated with the dungeon should really be associated with the player,
  1423. * such as whether a given grid is viewable by a given player.
  1424. *
  1425. * One of the major bottlenecks in ancient versions of Angband was in the
  1426. * calculation of "line of sight" from the player to various grids, such
  1427. * as those containing monsters, using the relatively expensive "los()"
  1428. * function. This was such a nasty bottleneck that a lot of silly things
  1429. * were done to reduce the dependancy on "line of sight", for example, you
  1430. * could not "see" any grids in a lit room until you actually entered the
  1431. * room, at which point every grid in the room became "illuminated" and
  1432. * all of the grids in the room were "memorized" forever. Other major
  1433. * bottlenecks involved the determination of whether a grid was lit by the
  1434. * player's torch, and whether a grid blocked the player's line of sight.
  1435. * These bottlenecks led to the development of special new functions to
  1436. * optimize issues involved with "line of sight" and "torch lit grids".
  1437. * These optimizations led to entirely new additions to the game, such as
  1438. * the ability to display the player's entire field of view using different
  1439. * colors than were used for the "memorized" portions of the dungeon, and
  1440. * the ability to memorize dark floor grids, but to indicate by the way in
  1441. * which they are displayed that they are not actually illuminated. And
  1442. * of course many of them simply made the game itself faster or more fun.
  1443. * Also, over time, the definition of "line of sight" has been relaxed to
  1444. * allow the player to see a wider "field of view", which is slightly more
  1445. * realistic, and only slightly more expensive to maintain.
  1446. *
  1447. * Currently, a lot of the information about the dungeon is stored in ways
  1448. * that make it very efficient to access or modify the information, while
  1449. * still attempting to be relatively conservative about memory usage, even
  1450. * if this means that some information is stored in multiple places, or in
  1451. * ways which require the use of special code idioms. For example, each
  1452. * monster record in the monster array contains the location of the monster,
  1453. * and each cave grid has an index into the monster array, or a zero if no
  1454. * monster is in the grid. This allows the monster code to efficiently see
  1455. * where the monster is located, while allowing the dungeon code to quickly
  1456. * determine not only if a monster is present in a given grid, but also to
  1457. * find out which monster. The extra space used to store the information
  1458. * twice is inconsequential compared to the speed increase.
  1459. *
  1460. * Some of the information about the dungeon is used by functions which can
  1461. * constitute the "critical efficiency path" of the game itself, and so the
  1462. * way in which they are stored and accessed has been optimized in order to
  1463. * optimize the game itself. For example, the "update_view()" function was
  1464. * originally created to speed up the game itself (when the player was not
  1465. * running), but then it took on extra responsibility as the provider of the
  1466. * new "special effects lighting code", and became one of the most important
  1467. * bottlenecks when the player was running. So many rounds of optimization
  1468. * were performed on both the function itself, and the data structures which
  1469. * it uses, resulting eventually in a function which not only made the game
  1470. * faster than before, but which was responsible for even more calculations
  1471. * (including the determination of which grids are "viewable" by the player,
  1472. * which grids are illuminated by the player's torch, and which grids can be
  1473. * "seen" in some way by the player), as well as for providing the guts of
  1474. * the special effects lighting code, and for the efficient redisplay of any
  1475. * grids whose visual representation may have changed.
  1476. *
  1477. * Several pieces of information about each cave grid are stored in various
  1478. * two dimensional arrays, with one unit of information for each grid in the
  1479. * dungeon. Some of these arrays have been intentionally expanded by a small
  1480. * factor to make the two dimensional array accesses faster by allowing the
  1481. * use of shifting instead of multiplication.
  1482. *
  1483. * Several pieces of information about each cave grid are stored in the
  1484. * "cave_info" array, which is a special two dimensional array of bytes,
  1485. * one for each cave grid, each containing eight separate "flags" which
  1486. * describe some property of the cave grid. These flags can be checked and
  1487. * modified extremely quickly, especially when special idioms are used to
  1488. * force the compiler to keep a local register pointing to the base of the
  1489. * array. Special location offset macros can be used to minimize the number
  1490. * of computations which must be performed at runtime. Note that using a
  1491. * byte for each flag set may be slightly more efficient than using a larger
  1492. * unit, so if another flag (or two) is needed later, and it must be fast,
  1493. * then the two existing flags which do not have to be fast should be moved
  1494. * out into some other data structure and the new flags should take their
  1495. * place. This may require a few minor changes in the savefile code.
  1496. *
  1497. * The "CAVE_ROOM" flag is saved in the savefile and is used to determine
  1498. * which grids are part of "rooms", and thus which grids are affected by
  1499. * "illumination" spells. This flag does not have to be very fast.
  1500. *
  1501. * The "CAVE_ICKY" flag is saved in the savefile and is used to determine
  1502. * which grids are part of "vaults", and thus which grids cannot serve as
  1503. * the destinations of player teleportation. This flag does not have to
  1504. * be very fast.
  1505. *
  1506. * The "CAVE_MARK" flag is saved in the savefile and is used to determine
  1507. * which grids have been "memorized" by the player. This flag is used by
  1508. * the "map_info()" function to determine if a grid should be displayed.
  1509. * This flag is used in a few other places to determine if the player can
  1510. * "know" about a given grid. This flag must be very fast.
  1511. *
  1512. * The "CAVE_GLOW" flag is saved in the savefile and is used to determine
  1513. * which grids are "permanently illuminated". This flag is used by the
  1514. * "update_view()" function to help determine which viewable flags may
  1515. * be "seen" by the player. This flag is used by the "map_info" function
  1516. * to determine if a grid is only lit by the player's torch. This flag
  1517. * has special semantics for wall grids (see "update_view()"). This flag
  1518. * must be very fast.
  1519. *
  1520. * The "CAVE_WALL" flag is used to determine which grids block the player's
  1521. * line of sight. This flag is used by the "update_view()" function to
  1522. * determine which grids block line of sight, and to help determine which
  1523. * grids can be "seen" by the player. This flag must be very fast.
  1524. *
  1525. * The "CAVE_VIEW" flag is used to determine which grids are currently in
  1526. * line of sight of the player. This flag is set by (and used by) the
  1527. * "update_view()" function. This flag is used by any code which needs to
  1528. * know if the player can "view" a given grid. This flag is used by the
  1529. * "map_info()" function for some optional special lighting effects. The
  1530. * "player_has_los_bold()" macro wraps an abstraction around this flag, but
  1531. * certain code idioms are much more efficient. This flag is used to check
  1532. * if a modification to a terrain feature might affect the player's field of
  1533. * view. This flag is used to see if certain monsters are "visible" to the
  1534. * player. This flag is used to allow any monster in the player's field of
  1535. * view to "sense" the presence of the player. This flag must be very fast.
  1536. *
  1537. * The "CAVE_SEEN" flag is used to determine which grids are currently in
  1538. * line of sight of the player and also illuminated in some way. This flag
  1539. * is set by the "update_view()" function, using computations based on the
  1540. * "CAVE_VIEW" and "CAVE_WALL" and "CAVE_GLOW" flags of various grids. This
  1541. * flag is used by any code which needs to know if the player can "see" a
  1542. * given grid. This flag is used by the "map_info()" function both to see
  1543. * if a given "boring" grid can be seen by the player, and for some optional
  1544. * special lighting effects. The "player_can_see_bold()" macro wraps an
  1545. * abstraction around this flag, but certain code idioms are much more
  1546. * efficient. This flag is used to see if certain monsters are "visible" to
  1547. * the player. This flag is never set for a grid unless "CAVE_VIEW" is also
  1548. * set for the grid. Whenever the "CAVE_WALL" or "CAVE_GLOW" flag changes
  1549. * for a grid which has the "CAVE_VIEW" flag set, the "CAVE_SEEN" flag must
  1550. * be recalculated. The simplest way to do this is to call "forget_view()"
  1551. * and "update_view()" whenever the "CAVE_WALL" or "CAVE_GLOW" flags change
  1552. * for a grid which has "CAVE_VIEW" set. This flag must be very fast.
  1553. *
  1554. * The "CAVE_TEMP" flag is used for a variety of temporary purposes. This
  1555. * flag is used to determine if the "CAVE_SEEN" flag for a grid has changed
  1556. * during the "update_view()" function. This flag is used to "spread" light
  1557. * or darkness through a room. This flag is used by the "monster flow code".
  1558. * This flag must always be cleared by any code which sets it, often, this
  1559. * can be optimized by the use of the special "temp_g", "temp_y", "temp_x"
  1560. * arrays (and the special "temp_n" global). This flag must be very fast.
  1561. *
  1562. * Note that the "CAVE_MARK" flag is used for many reasons, some of which
  1563. * are strictly for optimization purposes. The "CAVE_MARK" flag means that
  1564. * even if the player cannot "see" the grid, he "knows" about the terrain in
  1565. * that grid. This is used to "memorize" grids when they are first "seen" by
  1566. * the player, and to allow certain grids to be "detected" by certain magic.
  1567. * Note that most grids are always memorized when they are first "seen", but
  1568. * "boring" grids (floor grids) are only memorized if the "OPT(view_torch_grids)"
  1569. * option is set, or if the "OPT(view_perma_grids)" option is set, and the grid
  1570. * in question has the "CAVE_GLOW" flag set.
  1571. *
  1572. * Objects are "memorized" in a different way, using a special "marked" flag
  1573. * on the object itself, which is set when an object is observed or detected.
  1574. * This allows objects to be "memorized" independant of the terrain features.
  1575. *
  1576. * The "update_view()" function is an extremely important function. It is
  1577. * called only when the player moves, significant terrain changes, or the
  1578. * player's blindness or torch radius changes. Note that when the player
  1579. * is resting, or performing any repeated actions (like digging, disarming,
  1580. * farming, etc), there is no need to call the "update_view()" function, so
  1581. * even if it was not very efficient, this would really only matter when the
  1582. * player was "running" through the dungeon. It sets the "CAVE_VIEW" flag
  1583. * on every cave grid in the player's field of view, and maintains an array
  1584. * of all such grids in the global "view_g" array. It also checks the torch
  1585. * radius of the player, and sets the "CAVE_SEEN" flag for every grid which
  1586. * is in the "field of view" of the player and which is also "illuminated",
  1587. * either by the players torch (if any) or by any permanent light source.
  1588. * It could use and help maintain information about multiple light sources,
  1589. * which would be helpful in a multi-player version of Angband.
  1590. *
  1591. * The "update_view()" function maintains the special "view_g" array, which
  1592. * contains exactly those grids which have the "CAVE_VIEW" flag set. This
  1593. * array is used by "update_view()" to (only) memorize grids which become
  1594. * newly "seen", and to (only) redraw grids whose "seen" value changes, which
  1595. * allows the use of some interesting (and very efficient) "special lighting
  1596. * effects". In addition, this array could be used elsewhere to quickly scan
  1597. * through all the grids which are in the player's field of view.
  1598. *
  1599. * Note that the "update_view()" function allows, among other things, a room
  1600. * to be "partially" seen as the player approaches it, with a growing cone
  1601. * of floor appearing as the player gets closer to the door. Also, by not
  1602. * turning on the "memorize perma-lit grids" option, the player will only
  1603. * "see" those floor grids which are actually in line of sight. And best
  1604. * of all, you can now activate the special lighting effects to indicate
  1605. * which grids are actually in the player's field of view by using dimmer
  1606. * colors for grids which are not in the player's field of view, and/or to
  1607. * indicate which grids are illuminated only by the player's torch by using
  1608. * the color yellow for those grids.
  1609. *
  1610. * The old "update_view()" algorithm uses the special "CAVE_EASY" flag as a
  1611. * temporary internal flag to mark those grids which are not only in view,
  1612. * but which are also "easily" in line of sight of the player. This flag
  1613. * is actually just the "CAVE_SEEN" flag, and the "update_view()" function
  1614. * makes sure to clear it for all old "CAVE_SEEN" grids, and then use it in
  1615. * the algorithm as "CAVE_EASY", and then clear it for all "CAVE_EASY" grids,
  1616. * and then reset it as appropriate for all new "CAVE_SEEN" grids. This is
  1617. * kind of messy, but it works. The old algorithm may disappear eventually.
  1618. *
  1619. * The new "update_view()" algorithm uses a faster and more mathematically
  1620. * correct algorithm, assisted by a large machine generated static array, to
  1621. * determine the "CAVE_VIEW" and "CAVE_SEEN" flags simultaneously. See below.
  1622. *
  1623. * It seems as though slight modifications to the "update_view()" functions
  1624. * would allow us to determine "reverse" line-of-sight as well as "normal"
  1625. * line-of-sight", which would allow monsters to have a more "correct" way
  1626. * to determine if they can "see" the player, since right now, they "cheat"
  1627. * somewhat and assume that if the player has "line of sight" to them, then
  1628. * they can "pretend" that they have "line of sight" to the player. But if
  1629. * such a change was attempted, the monsters would actually start to exhibit
  1630. * some undesirable behavior, such as "freezing" near the entrances to long
  1631. * hallways containing the player, and code would have to be added to make
  1632. * the monsters move around even if the player was not detectable, and to
  1633. * "remember" where the player was last seen, to avoid looking stupid.
  1634. *
  1635. * Note that the "CAVE_GLOW" flag means that a grid is permanently lit in
  1636. * some way. However, for the player to "see" the grid, as determined by
  1637. * the "CAVE_SEEN" flag, the player must not be blind, the grid must have
  1638. * the "CAVE_VIEW" flag set, and if the grid is a "wall" grid, and it is
  1639. * not lit by the player's torch, then it must touch a grid which does not
  1640. * have the "CAVE_WALL" flag set, but which does have both the "CAVE_GLOW"
  1641. * and "CAVE_VIEW" flags set. This last part about wall grids is induced
  1642. * by the semantics of "CAVE_GLOW" as applied to wall grids, and checking
  1643. * the technical requirements can be very expensive, especially since the
  1644. * grid may be touching some "illegal" grids. Luckily, it is more or less
  1645. * correct to restrict the "touching" grids from the eight "possible" grids
  1646. * to the (at most) three grids which are touching the grid, and which are
  1647. * closer to the player than the grid itself, which eliminates more than
  1648. * half of the work, including all of the potentially "illegal" grids, if
  1649. * at most one of the three grids is a "diagonal" grid. In addition, in
  1650. * almost every situation, it is possible to ignore the "CAVE_VIEW" flag
  1651. * on these three "touching" grids, for a variety of technical reasons.
  1652. * Finally, note that in most situations, it is only necessary to check
  1653. * a single "touching" grid, in fact, the grid which is strictly closest
  1654. * to the player of all the touching grids, and in fact, it is normally
  1655. * only necessary to check the "CAVE_GLOW" flag of that grid, again, for
  1656. * various technical reasons. However, one of the situations which does
  1657. * not work with this last reduction is the very common one in which the
  1658. * player approaches an illuminated room from a dark hallway, in which the
  1659. * two wall grids which form the "entrance" to the room would not be marked
  1660. * as "CAVE_SEEN", since of the three "touching" grids nearer to the player
  1661. * than each wall grid, only the farthest of these grids is itself marked
  1662. * "CAVE_GLOW".
  1663. *
  1664. *
  1665. * Here are some pictures of the legal "light source" radius values, in
  1666. * which the numbers indicate the "order" in which the grids could have
  1667. * been calculated, if desired. Note that the code will work with larger
  1668. * radiuses, though currently yields such a radius, and the game would
  1669. * become slower in some situations if it did.
  1670. *
  1671. * Rad=0 Rad=1 Rad=2 Rad=3
  1672. * No-Light Torch,etc Lantern Artifacts
  1673. *
  1674. * 333
  1675. * 333 43334
  1676. * 212 32123 3321233
  1677. * @ 1@1 31@13 331@133
  1678. * 212 32123 3321233
  1679. * 333 43334
  1680. * 333
  1681. *
  1682. *
  1683. * Here is an illustration of the two different "update_view()" algorithms,
  1684. * in which the grids marked "%" are pillars, and the grids marked "?" are
  1685. * not in line of sight of the player.
  1686. *
  1687. *
  1688. * Sample situation
  1689. *
  1690. * #####################
  1691. * ############.%.%.%.%#
  1692. * #...@..#####........#
  1693. * #............%.%.%.%#
  1694. * #......#####........#
  1695. * ############........#
  1696. * #####################
  1697. *
  1698. *
  1699. * New Algorithm Old Algorithm
  1700. *
  1701. * ########????????????? ########?????????????
  1702. * #...@..#????????????? #...@..#?????????????
  1703. * #...........????????? #.........???????????
  1704. * #......#####.....???? #......####??????????
  1705. * ########?????????...# ########?????????????
  1706. *
  1707. * ########????????????? ########?????????????
  1708. * #.@....#????????????? #.@....#?????????????
  1709. * #............%??????? #...........?????????
  1710. * #......#####........? #......#####?????????
  1711. * ########??????????..# ########?????????????
  1712. *
  1713. * ########????????????? ########?????%???????
  1714. * #......#####........# #......#####..???????
  1715. * #.@..........%??????? #.@..........%???????
  1716. * #......#####........# #......#####..???????
  1717. * ########????????????? ########?????????????
  1718. *
  1719. * ########??????????..# ########?????????????
  1720. * #......#####........? #......#####?????????
  1721. * #............%??????? #...........?????????
  1722. * #.@....#????????????? #.@....#?????????????
  1723. * ########????????????? ########?????????????
  1724. *
  1725. * ########?????????%??? ########?????????????
  1726. * #......#####.....???? #......####??????????
  1727. * #...........????????? #.........???????????
  1728. * #...@..#????????????? #...@..#?????????????
  1729. * ########????????????? ########?????????????
  1730. */
  1731. /*
  1732. * Maximum number of grids in a single octant
  1733. */
  1734. #define VINFO_MAX_GRIDS 161
  1735. /*
  1736. * Maximum number of slopes in a single octant
  1737. */
  1738. #define VINFO_MAX_SLOPES 126
  1739. /*
  1740. * Mask of bits used in a single octant
  1741. */
  1742. #define VINFO_BITS_3 0x3FFFFFFF
  1743. #define VINFO_BITS_2 0xFFFFFFFF
  1744. #define VINFO_BITS_1 0xFFFFFFFF
  1745. #define VINFO_BITS_0 0xFFFFFFFF
  1746. /*
  1747. * Forward declare
  1748. */
  1749. typedef struct vinfo_type vinfo_type;
  1750. /*
  1751. * The 'vinfo_type' structure
  1752. */
  1753. struct vinfo_type
  1754. {
  1755. s16b grid[8];
  1756. u32b bits_3;
  1757. u32b bits_2;
  1758. u32b bits_1;
  1759. u32b bits_0;
  1760. vinfo_type *next_0;
  1761. vinfo_type *next_1;
  1762. byte y;
  1763. byte x;
  1764. byte d;
  1765. byte r;
  1766. };
  1767. /*
  1768. * The array of "vinfo" objects, initialized by "vinfo_init()"
  1769. */
  1770. static vinfo_type vinfo[VINFO_MAX_GRIDS];
  1771. /*
  1772. * Slope scale factor
  1773. */
  1774. #define SCALE 100000L
  1775. /*
  1776. * The actual slopes (for reference)
  1777. */
  1778. /* Bit : Slope Grids */
  1779. /* --- : ----- ----- */
  1780. /* 0 : 2439 21 */
  1781. /* 1 : 2564 21 */
  1782. /* 2 : 2702 21 */
  1783. /* 3 : 2857 21 */
  1784. /* 4 : 3030 21 */
  1785. /* 5 : 3225 21 */
  1786. /* 6 : 3448 21 */
  1787. /* 7 : 3703 21 */
  1788. /* 8 : 4000 21 */
  1789. /* 9 : 4347 21 */
  1790. /* 10 : 4761 21 */
  1791. /* 11 : 5263 21 */
  1792. /* 12 : 5882 21 */
  1793. /* 13 : 6666 21 */
  1794. /* 14 : 7317 22 */
  1795. /* 15 : 7692 20 */
  1796. /* 16 : 8108 21 */
  1797. /* 17 : 8571 21 */
  1798. /* 18 : 9090 20 */
  1799. /* 19 : 9677 21 */
  1800. /* 20 : 10344 21 */
  1801. /* 21 : 11111 20 */
  1802. /* 22 : 12000 21 */
  1803. /* 23 : 12820 22 */
  1804. /* 24 : 13043 22 */
  1805. /* 25 : 13513 22 */
  1806. /* 26 : 14285 20 */
  1807. /* 27 : 15151 22 */
  1808. /* 28 : 15789 22 */
  1809. /* 29 : 16129 22 */
  1810. /* 30 : 17241 22 */
  1811. /* 31 : 17647 22 */
  1812. /* 32 : 17948 23 */
  1813. /* 33 : 18518 22 */
  1814. /* 34 : 18918 22 */
  1815. /* 35 : 20000 19 */
  1816. /* 36 : 21212 22 */
  1817. /* 37 : 21739 22 */
  1818. /* 38 : 22580 22 */
  1819. /* 39 : 23076 22 */
  1820. /* 40 : 23809 22 */
  1821. /* 41 : 24137 22 */
  1822. /* 42 : 24324 23 */
  1823. /* 43 : 25714 23 */
  1824. /* 44 : 25925 23 */
  1825. /* 45 : 26315 23 */
  1826. /* 46 : 27272 22 */
  1827. /* 47 : 28000 23 */
  1828. /* 48 : 29032 23 */
  1829. /* 49 : 29411 23 */
  1830. /* 50 : 29729 24 */
  1831. /* 51 : 30434 23 */
  1832. /* 52 : 31034 23 */
  1833. /* 53 : 31428 23 */
  1834. /* 54 : 33333 18 */
  1835. /* 55 : 35483 23 */
  1836. /* 56 : 36000 23 */
  1837. /* 57 : 36842 23 */
  1838. /* 58 : 37142 24 */
  1839. /* 59 : 37931 24 */
  1840. /* 60 : 38461 24 */
  1841. /* 61 : 39130 24 */
  1842. /* 62 : 39393 24 */
  1843. /* 63 : 40740 24 */
  1844. /* 64 : 41176 24 */
  1845. /* 65 : 41935 24 */
  1846. /* 66 : 42857 23 */
  1847. /* 67 : 44000 24 */
  1848. /* 68 : 44827 24 */
  1849. /* 69 : 45454 23 */
  1850. /* 70 : 46666 24 */
  1851. /* 71 : 47368 24 */
  1852. /* 72 : 47826 24 */
  1853. /* 73 : 48148 24 */
  1854. /* 74 : 48387 24 */
  1855. /* 75 : 51515 25 */
  1856. /* 76 : 51724 25 */
  1857. /* 77 : 52000 25 */
  1858. /* 78 : 52380 25 */
  1859. /* 79 : 52941 25 */
  1860. /* 80 : 53846 25 */
  1861. /* 81 : 54838 25 */
  1862. /* 82 : 55555 24 */
  1863. /* 83 : 56521 25 */
  1864. /* 84 : 57575 26 */
  1865. /* 85 : 57894 25 */
  1866. /* 86 : 58620 25 */
  1867. /* 87 : 60000 23 */
  1868. /* 88 : 61290 25 */
  1869. /* 89 : 61904 25 */
  1870. /* 90 : 62962 25 */
  1871. /* 91 : 63636 25 */
  1872. /* 92 : 64705 25 */
  1873. /* 93 : 65217 25 */
  1874. /* 94 : 65517 25 */
  1875. /* 95 : 67741 26 */
  1876. /* 96 : 68000 26 */
  1877. /* 97 : 68421 26 */
  1878. /* 98 : 69230 26 */
  1879. /* 99 : 70370 26 */
  1880. /* 100 : 71428 25 */
  1881. /* 101 : 72413 26 */
  1882. /* 102 : 73333 26 */
  1883. /* 103 : 73913 26 */
  1884. /* 104 : 74193 27 */
  1885. /* 105 : 76000 26 */
  1886. /* 106 : 76470 26 */
  1887. /* 107 : 77777 25 */
  1888. /* 108 : 78947 26 */
  1889. /* 109 : 79310 26 */
  1890. /* 110 : 80952 26 */
  1891. /* 111 : 81818 26 */
  1892. /* 112 : 82608 26 */
  1893. /* 113 : 84000 26 */
  1894. /* 114 : 84615 26 */
  1895. /* 115 : 85185 26 */
  1896. /* 116 : 86206 27 */
  1897. /* 117 : 86666 27 */
  1898. /* 118 : 88235 27 */
  1899. /* 119 : 89473 27 */
  1900. /* 120 : 90476 27 */
  1901. /* 121 : 91304 27 */
  1902. /* 122 : 92000 27 */
  1903. /* 123 : 92592 27 */
  1904. /* 124 : 93103 28 */
  1905. /* 125 : 100000 13 */
  1906. /*
  1907. * Forward declare
  1908. */
  1909. typedef struct vinfo_hack vinfo_hack;
  1910. /*
  1911. * Temporary data used by "vinfo_init()"
  1912. *
  1913. * - Number of grids
  1914. *
  1915. * - Number of slopes
  1916. *
  1917. * - Slope values
  1918. *
  1919. * - Slope range per grid
  1920. */
  1921. struct vinfo_hack {
  1922. int num_slopes;
  1923. long slopes[VINFO_MAX_SLOPES];
  1924. long slopes_min[MAX_SIGHT+1][MAX_SIGHT+1];
  1925. long slopes_max[MAX_SIGHT+1][MAX_SIGHT+1];
  1926. };
  1927. /*
  1928. * Sorting hook -- comp function -- array of long's (see below)
  1929. *
  1930. * We use "u" to point to an array of long integers.
  1931. */
  1932. static bool ang_sort_comp_hook_longs(const void *u, const void *v, int a, int b)
  1933. {
  1934. const long *x = u;
  1935. /* Unused parameter */
  1936. (void)v;
  1937. return (x[a] <= x[b]);
  1938. }
  1939. /*
  1940. * Sorting hook -- comp function -- array of long's (see below)
  1941. *
  1942. * We use "u" to point to an array of long integers.
  1943. */
  1944. static void ang_sort_swap_hook_longs(void *u, void *v, int a, int b)
  1945. {
  1946. long *x = (long *)(u);
  1947. long temp;
  1948. /* Unused parameter */
  1949. (void)v;
  1950. /* Swap */
  1951. temp = x[a];
  1952. x[a] = x[b];
  1953. x[b] = temp;
  1954. }
  1955. /*
  1956. * Save a slope
  1957. */
  1958. static void vinfo_init_aux(vinfo_hack *hack, int y, int x, long m)
  1959. {
  1960. int i;
  1961. /* Handle "legal" slopes */
  1962. if ((m > 0) && (m <= SCALE))
  1963. {
  1964. /* Look for that slope */
  1965. for (i = 0; i < hack->num_slopes; i++)
  1966. {
  1967. if (hack->slopes[i] == m) break;
  1968. }
  1969. /* New slope */
  1970. if (i == hack->num_slopes)
  1971. {
  1972. /* Paranoia */
  1973. if (hack->num_slopes >= VINFO_MAX_SLOPES)
  1974. {
  1975. quit_fmt("Too many slopes (%d)!",
  1976. VINFO_MAX_SLOPES);
  1977. }
  1978. /* Save the slope, and advance */
  1979. hack->slopes[hack->num_slopes++] = m;
  1980. }
  1981. }
  1982. /* Track slope range */
  1983. if (hack->slopes_min[y][x] > m) hack->slopes_min[y][x] = m;
  1984. if (hack->slopes_max[y][x] < m) hack->slopes_max[y][x] = m;
  1985. }
  1986. /*
  1987. * Initialize the "vinfo" array
  1988. *
  1989. * Full Octagon (radius 20), Grids=1149
  1990. *
  1991. * Quadrant (south east), Grids=308, Slopes=251
  1992. *
  1993. * Octant (east then south), Grids=161, Slopes=126
  1994. *
  1995. * This function assumes that VINFO_MAX_GRIDS and VINFO_MAX_SLOPES
  1996. * have the correct values, which can be derived by setting them to
  1997. * a number which is too high, running this function, and using the
  1998. * error messages to obtain the correct values.
  1999. */
  2000. errr vinfo_init(void)
  2001. {
  2002. int i, g;
  2003. int y, x;
  2004. long m;
  2005. vinfo_hack *hack;
  2006. int num_grids = 0;
  2007. int queue_head = 0;
  2008. int queue_tail = 0;
  2009. vinfo_type *queue[VINFO_MAX_GRIDS*2];
  2010. /* Make hack */
  2011. hack = ZNEW(vinfo_hack);
  2012. /* Analyze grids */
  2013. for (y = 0; y <= MAX_SIGHT; ++y)
  2014. {
  2015. for (x = y; x <= MAX_SIGHT; ++x)
  2016. {
  2017. /* Skip grids which are out of sight range */
  2018. if (distance(0, 0, y, x) > MAX_SIGHT) continue;
  2019. /* Default slope range */
  2020. hack->slopes_min[y][x] = 999999999;
  2021. hack->slopes_max[y][x] = 0;
  2022. /* Paranoia */
  2023. if (num_grids >= VINFO_MAX_GRIDS)
  2024. {
  2025. quit_fmt("Too many grids (%d >= %d)!",
  2026. num_grids, VINFO_MAX_GRIDS);
  2027. }
  2028. /* Count grids */
  2029. num_grids++;
  2030. /* Slope to the top right corner */
  2031. m = SCALE * (1000L * y - 500) / (1000L * x + 500);
  2032. /* Handle "legal" slopes */
  2033. vinfo_init_aux(hack, y, x, m);
  2034. /* Slope to top left corner */
  2035. m = SCALE * (1000L * y - 500) / (1000L * x - 500);
  2036. /* Handle "legal" slopes */
  2037. vinfo_init_aux(hack, y, x, m);
  2038. /* Slope to bottom right corner */
  2039. m = SCALE * (1000L * y + 500) / (1000L * x + 500);
  2040. /* Handle "legal" slopes */
  2041. vinfo_init_aux(hack, y, x, m);
  2042. /* Slope to bottom left corner */
  2043. m = SCALE * (1000L * y + 500) / (1000L * x - 500);
  2044. /* Handle "legal" slopes */
  2045. vinfo_init_aux(hack, y, x, m);
  2046. }
  2047. }
  2048. /* Enforce maximal efficiency */
  2049. if (num_grids < VINFO_MAX_GRIDS)
  2050. {
  2051. quit_fmt("Too few grids (%d < %d)!",
  2052. num_grids, VINFO_MAX_GRIDS);
  2053. }
  2054. /* Enforce maximal efficiency */
  2055. if (hack->num_slopes < VINFO_MAX_SLOPES)
  2056. {
  2057. quit_fmt("Too few slopes (%d < %d)!",
  2058. hack->num_slopes, VINFO_MAX_SLOPES);
  2059. }
  2060. /* Sort slopes numerically */
  2061. ang_sort_comp = ang_sort_comp_hook_longs;
  2062. /* Sort slopes numerically */
  2063. ang_sort_swap = ang_sort_swap_hook_longs;
  2064. /* Sort the (unique) slopes */
  2065. ang_sort(hack->slopes, NULL, hack->num_slopes);
  2066. /* Enqueue player grid */
  2067. queue[queue_tail++] = &vinfo[0];
  2068. /* Process queue */
  2069. while (queue_head < queue_tail)
  2070. {
  2071. int e;
  2072. /* Index */
  2073. e = queue_head++;
  2074. /* Main Grid */
  2075. g = vinfo[e].grid[0];
  2076. /* Location */
  2077. y = GRID_Y(g);
  2078. x = GRID_X(g);
  2079. /* Compute grid offsets */
  2080. vinfo[e].grid[0] = GRID(+y,+x);
  2081. vinfo[e].grid[1] = GRID(+x,+y);
  2082. vinfo[e].grid[2] = GRID(+x,-y);
  2083. vinfo[e].grid[3] = GRID(+y,-x);
  2084. vinfo[e].grid[4] = GRID(-y,-x);
  2085. vinfo[e].grid[5] = GRID(-x,-y);
  2086. vinfo[e].grid[6] = GRID(-x,+y);
  2087. vinfo[e].grid[7] = GRID(-y,+x);
  2088. /* Analyze slopes */
  2089. for (i = 0; i < hack->num_slopes; ++i)
  2090. {
  2091. m = hack->slopes[i];
  2092. /* Memorize intersection slopes (for non-player-grids) */
  2093. if ((e > 0) &&
  2094. (hack->slopes_min[y][x] < m) &&
  2095. (m < hack->slopes_max[y][x]))
  2096. {
  2097. switch (i / 32)
  2098. {
  2099. case 3: vinfo[e].bits_3 |= (1L << (i % 32)); break;
  2100. case 2: vinfo[e].bits_2 |= (1L << (i % 32)); break;
  2101. case 1: vinfo[e].bits_1 |= (1L << (i % 32)); break;
  2102. case 0: vinfo[e].bits_0 |= (1L << (i % 32)); break;
  2103. }
  2104. }
  2105. }
  2106. /* Default */
  2107. vinfo[e].next_0 = &vinfo[0];
  2108. /* Grid next child */
  2109. if (distance(0, 0, y, x+1) <= MAX_SIGHT)
  2110. {
  2111. g = GRID(y,x+1);
  2112. if (queue[queue_tail-1]->grid[0] != g)
  2113. {
  2114. vinfo[queue_tail].grid[0] = g;
  2115. queue[queue_tail] = &vinfo[queue_tail];
  2116. queue_tail++;
  2117. }
  2118. vinfo[e].next_0 = &vinfo[queue_tail - 1];
  2119. }
  2120. /* Default */
  2121. vinfo[e].next_1 = &vinfo[0];
  2122. /* Grid diag child */
  2123. if (distance(0, 0, y+1, x+1) <= MAX_SIGHT)
  2124. {
  2125. g = GRID(y+1,x+1);
  2126. if (queue[queue_tail-1]->grid[0] != g)
  2127. {
  2128. vinfo[queue_tail].grid[0] = g;
  2129. queue[queue_tail] = &vinfo[queue_tail];
  2130. queue_tail++;
  2131. }
  2132. vinfo[e].next_1 = &vinfo[queue_tail - 1];
  2133. }
  2134. /* Hack -- main diagonal has special children */
  2135. if (y == x) vinfo[e].next_0 = vinfo[e].next_1;
  2136. /* Extra values */
  2137. vinfo[e].y = y;
  2138. vinfo[e].x = x;
  2139. vinfo[e].d = ((y > x) ? (y + x/2) : (x + y/2));
  2140. vinfo[e].r = ((!y) ? x : (!x) ? y : (y == x) ? y : 0);
  2141. }
  2142. /* Verify maximal bits XXX XXX XXX */
  2143. if (((vinfo[1].bits_3 | vinfo[2].bits_3) != VINFO_BITS_3) ||
  2144. ((vinfo[1].bits_2 | vinfo[2].bits_2) != VINFO_BITS_2) ||
  2145. ((vinfo[1].bits_1 | vinfo[2].bits_1) != VINFO_BITS_1) ||
  2146. ((vinfo[1].bits_0 | vinfo[2].bits_0) != VINFO_BITS_0))
  2147. {
  2148. quit("Incorrect bit masks!");
  2149. }
  2150. /* Kill hack */
  2151. FREE(hack);
  2152. /* Success */
  2153. return (0);
  2154. }
  2155. /*
  2156. * Forget the "CAVE_VIEW" grids, redrawing as needed
  2157. */
  2158. void forget_view(void)
  2159. {
  2160. int i, g;
  2161. int fast_view_n = view_n;
  2162. u16b *fast_view_g = view_g;
  2163. byte *fast_cave_info = &cave_info[0][0];
  2164. /* None to forget */
  2165. if (!fast_view_n) return;
  2166. /* Clear them all */
  2167. for (i = 0; i < fast_view_n; i++)
  2168. {
  2169. int y, x;
  2170. /* Grid */
  2171. g = fast_view_g[i];
  2172. /* Location */
  2173. y = GRID_Y(g);
  2174. x = GRID_X(g);
  2175. /* Clear "CAVE_VIEW" and "CAVE_SEEN" flags */
  2176. fast_cave_info[g] &= ~(CAVE_VIEW | CAVE_SEEN);
  2177. /* Clear "CAVE_LIGHT" flag */
  2178. /* fast_cave_info[g] &= ~(CAVE_LIGHT); */
  2179. /* Redraw */
  2180. light_spot(y, x);
  2181. }
  2182. /* None left */
  2183. fast_view_n = 0;
  2184. /* Save 'view_n' */
  2185. view_n = fast_view_n;
  2186. }
  2187. /*
  2188. * Calculate the complete field of view using a new algorithm
  2189. *
  2190. * If "view_g" and "temp_g" were global pointers to arrays of grids, as
  2191. * opposed to actual arrays of grids, then we could be more efficient by
  2192. * using "pointer swapping".
  2193. *
  2194. * Note the following idiom, which is used in the function below.
  2195. * This idiom processes each "octant" of the field of view, in a
  2196. * clockwise manner, starting with the east strip, south side,
  2197. * and for each octant, allows a simple calculation to set "g"
  2198. * equal to the proper grids, relative to "pg", in the octant.
  2199. *
  2200. * for (o2 = 0; o2 < 8; o2++)
  2201. * ...
  2202. * g = pg + p->grid[o2];
  2203. * ...
  2204. *
  2205. *
  2206. * Normally, vision along the major axes is more likely than vision
  2207. * along the diagonal axes, so we check the bits corresponding to
  2208. * the lines of sight near the major axes first.
  2209. *
  2210. * We use the "temp_g" array (and the "CAVE_TEMP" flag) to keep track of
  2211. * which grids were previously marked "CAVE_SEEN", since only those grids
  2212. * whose "CAVE_SEEN" value changes during this routine must be redrawn.
  2213. *
  2214. * This function is now responsible for maintaining the "CAVE_SEEN"
  2215. * flags as well as the "CAVE_VIEW" flags, which is good, because
  2216. * the only grids which normally need to be memorized and/or redrawn
  2217. * are the ones whose "CAVE_SEEN" flag changes during this routine.
  2218. *
  2219. * Basically, this function divides the "octagon of view" into octants of
  2220. * grids (where grids on the main axes and diagonal axes are "shared" by
  2221. * two octants), and processes each octant one at a time, processing each
  2222. * octant one grid at a time, processing only those grids which "might" be
  2223. * viewable, and setting the "CAVE_VIEW" flag for each grid for which there
  2224. * is an (unobstructed) line of sight from the center of the player grid to
  2225. * any internal point in the grid (and collecting these "CAVE_VIEW" grids
  2226. * into the "view_g" array), and setting the "CAVE_SEEN" flag for the grid
  2227. * if, in addition, the grid is "illuminated" in some way.
  2228. *
  2229. * This function relies on a theorem (suggested and proven by Mat Hostetter)
  2230. * which states that in each octant of a field of view, a given grid will
  2231. * be "intersected" by one or more unobstructed "lines of sight" from the
  2232. * center of the player grid if and only if it is "intersected" by at least
  2233. * one such unobstructed "line of sight" which passes directly through some
  2234. * corner of some grid in the octant which is not shared by any other octant.
  2235. * The proof is based on the fact that there are at least three significant
  2236. * lines of sight involving any non-shared grid in any octant, one which
  2237. * intersects the grid and passes though the corner of the grid closest to
  2238. * the player, and two which "brush" the grid, passing through the "outer"
  2239. * corners of the grid, and that any line of sight which intersects a grid
  2240. * without passing through the corner of a grid in the octant can be "slid"
  2241. * slowly towards the corner of the grid closest to the player, until it
  2242. * either reaches it or until it brushes the corner of another grid which
  2243. * is closer to the player, and in either case, the existanc of a suitable
  2244. * line of sight is thus demonstrated.
  2245. *
  2246. * It turns out that in each octant of the radius 20 "octagon of view",
  2247. * there are 161 grids (with 128 not shared by any other octant), and there
  2248. * are exactly 126 distinct "lines of sight" passing from the center of the
  2249. * player grid through any corner of any non-shared grid in the octant. To
  2250. * determine if a grid is "viewable" by the player, therefore, you need to
  2251. * simply show that one of these 126 lines of sight intersects the grid but
  2252. * does not intersect any wall grid closer to the player. So we simply use
  2253. * a bit vector with 126 bits to represent the set of interesting lines of
  2254. * sight which have not yet been obstructed by wall grids, and then we scan
  2255. * all the grids in the octant, moving outwards from the player grid. For
  2256. * each grid, if any of the lines of sight which intersect that grid have not
  2257. * yet been obstructed, then the grid is viewable. Furthermore, if the grid
  2258. * is a wall grid, then all of the lines of sight which intersect the grid
  2259. * should be marked as obstructed for future reference. Also, we only need
  2260. * to check those grids for whom at least one of the "parents" was a viewable
  2261. * non-wall grid, where the parents include the two grids touching the grid
  2262. * but closer to the player grid (one adjacent, and one diagonal). For the
  2263. * bit vector, we simply use 4 32-bit integers. All of the static values
  2264. * which are needed by this function are stored in the large "vinfo" array
  2265. * (above), which is machine generated by another program. XXX XXX XXX
  2266. *
  2267. * Hack -- The queue must be able to hold more than VINFO_MAX_GRIDS grids
  2268. * because the grids at the edge of the field of view use "grid zero" as
  2269. * their children, and the queue must be able to hold several of these
  2270. * special grids. Because the actual number of required grids is bizarre,
  2271. * we simply allocate twice as many as we would normally need. XXX XXX XXX
  2272. */
  2273. void update_view(void)
  2274. {
  2275. int py = p_ptr->py;
  2276. int px = p_ptr->px;
  2277. int pg = GRID(py,px);
  2278. int i, j, k, g, o2;
  2279. int radius;
  2280. int fast_view_n = view_n;
  2281. u16b *fast_view_g = view_g;
  2282. int fast_temp_n = 0;
  2283. u16b *fast_temp_g = temp_g;
  2284. byte *fast_cave_info = &cave_info[0][0];
  2285. byte info;
  2286. /*** Step 0 -- Begin ***/
  2287. /* Save the old "view" grids for later */
  2288. for (i = 0; i < fast_view_n; i++)
  2289. {
  2290. /* Grid */
  2291. g = fast_view_g[i];
  2292. /* Get grid info */
  2293. info = fast_cave_info[g];
  2294. /* Save "CAVE_SEEN" grids */
  2295. if (info & (CAVE_SEEN))
  2296. {
  2297. /* Set "CAVE_TEMP" flag */
  2298. info |= (CAVE_TEMP);
  2299. /* Save grid for later */
  2300. fast_temp_g[fast_temp_n++] = g;
  2301. }
  2302. /* Clear "CAVE_VIEW" and "CAVE_SEEN" flags */
  2303. info &= ~(CAVE_VIEW | CAVE_SEEN);
  2304. /* Clear "CAVE_LIGHT" flag */
  2305. /* info &= ~(CAVE_LIGHT); */
  2306. /* Save cave info */
  2307. fast_cave_info[g] = info;
  2308. }
  2309. /* Reset the "view" array */
  2310. fast_view_n = 0;
  2311. /* Extract "radius" value */
  2312. radius = p_ptr->cur_light;
  2313. /* Handle real light */
  2314. if (radius > 0) ++radius;
  2315. /* Scan monster list and add monster lites */
  2316. for (k = 1; k < z_info->m_max; k++)
  2317. {
  2318. /* Check the k'th monster */
  2319. monster_type *m_ptr = &mon_list[k];
  2320. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  2321. /* Access the location */
  2322. int fx = m_ptr->fx;
  2323. int fy = m_ptr->fy;
  2324. /* Skip dead monsters */
  2325. if (!m_ptr->r_idx) continue;
  2326. /* Skip monsters not carrying lite */
  2327. if (!rf_has(r_ptr->flags, RF_HAS_LITE)) continue;
  2328. /* Light a 3x3 box centered on the monster */
  2329. for (i = -1; i <= 1; i++)
  2330. {
  2331. for (j = -1; j <= 1; j++)
  2332. {
  2333. int sy = fy + i;
  2334. int sx = fx + j;
  2335. /* Make sure the square is close enough and is in LOS */
  2336. if (distance(p_ptr->py, p_ptr->px, sy, sx) > MAX_SIGHT)
  2337. continue;
  2338. else if (!los(p_ptr->py, p_ptr->px, sy, sx))
  2339. continue;
  2340. g = GRID(sy, sx);
  2341. /* Mark the square lit and seen */
  2342. fast_cave_info[g] |= (CAVE_VIEW | CAVE_SEEN);
  2343. /* Save in array */
  2344. fast_view_g[fast_view_n++] = g;
  2345. }
  2346. }
  2347. }
  2348. /*** Step 1 -- player grid ***/
  2349. /* Player grid */
  2350. g = pg;
  2351. /* Get grid info */
  2352. info = fast_cave_info[g];
  2353. /* Assume viewable */
  2354. info |= (CAVE_VIEW);
  2355. /* Torch-lit grid */
  2356. if (0 < radius)
  2357. {
  2358. /* Mark as "CAVE_SEEN" */
  2359. info |= (CAVE_SEEN);
  2360. /* Mark as "CAVE_LIGHT" */
  2361. /* info |= (CAVE_LIGHT); */
  2362. }
  2363. /* Perma-lit grid */
  2364. else if (info & (CAVE_GLOW))
  2365. {
  2366. /* Mark as "CAVE_SEEN" */
  2367. info |= (CAVE_SEEN);
  2368. }
  2369. /* Save cave info */
  2370. fast_cave_info[g] = info;
  2371. /* Save in array */
  2372. fast_view_g[fast_view_n++] = g;
  2373. /*** Step 2 -- octants ***/
  2374. /* Scan each octant */
  2375. for (o2 = 0; o2 < 8; o2++)
  2376. {
  2377. vinfo_type *p;
  2378. /* Last added */
  2379. vinfo_type *last = &vinfo[0];
  2380. /* Grid queue */
  2381. int queue_head = 0;
  2382. int queue_tail = 0;
  2383. vinfo_type *queue[VINFO_MAX_GRIDS*2];
  2384. /* Slope bit vector */
  2385. u32b bits0 = VINFO_BITS_0;
  2386. u32b bits1 = VINFO_BITS_1;
  2387. u32b bits2 = VINFO_BITS_2;
  2388. u32b bits3 = VINFO_BITS_3;
  2389. /* Reset queue */
  2390. queue_head = queue_tail = 0;
  2391. /* Initial grids */
  2392. queue[queue_tail++] = &vinfo[1];
  2393. queue[queue_tail++] = &vinfo[2];
  2394. /* Process queue */
  2395. while (queue_head < queue_tail)
  2396. {
  2397. /* Dequeue next grid */
  2398. p = queue[queue_head++];
  2399. /* Check bits */
  2400. if ((bits0 & (p->bits_0)) ||
  2401. (bits1 & (p->bits_1)) ||
  2402. (bits2 & (p->bits_2)) ||
  2403. (bits3 & (p->bits_3)))
  2404. {
  2405. /* Extract grid value XXX XXX XXX */
  2406. g = pg + p->grid[o2];
  2407. /* Get grid info */
  2408. info = fast_cave_info[g];
  2409. /* Handle wall */
  2410. if (info & (CAVE_WALL))
  2411. {
  2412. /* Clear bits */
  2413. bits0 &= ~(p->bits_0);
  2414. bits1 &= ~(p->bits_1);
  2415. bits2 &= ~(p->bits_2);
  2416. bits3 &= ~(p->bits_3);
  2417. /* Newly viewable wall */
  2418. if (!(info & (CAVE_VIEW)))
  2419. {
  2420. /* Mark as viewable */
  2421. info |= (CAVE_VIEW);
  2422. /* Torch-lit grids */
  2423. if (p->d < radius)
  2424. {
  2425. /* Mark as "CAVE_SEEN" */
  2426. info |= (CAVE_SEEN);
  2427. /* Mark as "CAVE_LIGHT" */
  2428. /* info |= (CAVE_LIGHT); */
  2429. }
  2430. /* Perma-lit grids */
  2431. else if (info & (CAVE_GLOW))
  2432. {
  2433. int y = GRID_Y(g);
  2434. int x = GRID_X(g);
  2435. /* Hack -- move towards player */
  2436. int yy = (y < py) ? (y + 1) : (y > py) ? (y - 1) : y;
  2437. int xx = (x < px) ? (x + 1) : (x > px) ? (x - 1) : x;
  2438. /* Check for "simple" illumination */
  2439. if (cave_info[yy][xx] & (CAVE_GLOW))
  2440. {
  2441. /* Mark as seen */
  2442. info |= (CAVE_SEEN);
  2443. }
  2444. }
  2445. /* Save cave info */
  2446. fast_cave_info[g] = info;
  2447. /* Save in array */
  2448. fast_view_g[fast_view_n++] = g;
  2449. }
  2450. }
  2451. /* Handle non-wall */
  2452. else
  2453. {
  2454. /* Enqueue child */
  2455. if (last != p->next_0)
  2456. {
  2457. queue[queue_tail++] = last = p->next_0;
  2458. }
  2459. /* Enqueue child */
  2460. if (last != p->next_1)
  2461. {
  2462. queue[queue_tail++] = last = p->next_1;
  2463. }
  2464. /* Newly viewable non-wall */
  2465. if (!(info & (CAVE_VIEW)))
  2466. {
  2467. /* Mark as "viewable" */
  2468. info |= (CAVE_VIEW);
  2469. /* Torch-lit grids */
  2470. if (p->d < radius)
  2471. {
  2472. /* Mark as "CAVE_SEEN" */
  2473. info |= (CAVE_SEEN);
  2474. /* Mark as "CAVE_LIGHT" */
  2475. /* info |= (CAVE_LIGHT); */
  2476. }
  2477. /* Perma-lit grids */
  2478. else if (info & (CAVE_GLOW))
  2479. {
  2480. /* Mark as "CAVE_SEEN" */
  2481. info |= (CAVE_SEEN);
  2482. }
  2483. /* Save cave info */
  2484. fast_cave_info[g] = info;
  2485. /* Save in array */
  2486. fast_view_g[fast_view_n++] = g;
  2487. }
  2488. }
  2489. }
  2490. }
  2491. }
  2492. /*** Step 3 -- Complete the algorithm ***/
  2493. /* Handle blindness */
  2494. if (p_ptr->timed[TMD_BLIND])
  2495. {
  2496. /* Process "new" grids */
  2497. for (i = 0; i < fast_view_n; i++)
  2498. {
  2499. /* Grid */
  2500. g = fast_view_g[i];
  2501. /* Grid cannot be "CAVE_SEEN" */
  2502. fast_cave_info[g] &= ~(CAVE_SEEN);
  2503. }
  2504. }
  2505. /* Process "new" grids */
  2506. for (i = 0; i < fast_view_n; i++)
  2507. {
  2508. /* Grid */
  2509. g = fast_view_g[i];
  2510. /* Get grid info */
  2511. info = fast_cave_info[g];
  2512. /* Was not "CAVE_SEEN", is now "CAVE_SEEN" */
  2513. if ((info & (CAVE_SEEN)) && !(info & (CAVE_TEMP)))
  2514. {
  2515. int y, x;
  2516. /* Location */
  2517. y = GRID_Y(g);
  2518. x = GRID_X(g);
  2519. /* Note */
  2520. note_spot(y, x);
  2521. /* Redraw */
  2522. light_spot(y, x);
  2523. }
  2524. }
  2525. /* Process "old" grids */
  2526. for (i = 0; i < fast_temp_n; i++)
  2527. {
  2528. /* Grid */
  2529. g = fast_temp_g[i];
  2530. /* Get grid info */
  2531. info = fast_cave_info[g];
  2532. /* Clear "CAVE_TEMP" flag */
  2533. info &= ~(CAVE_TEMP);
  2534. /* Save cave info */
  2535. fast_cave_info[g] = info;
  2536. /* Was "CAVE_SEEN", is now not "CAVE_SEEN" */
  2537. if (!(info & (CAVE_SEEN)))
  2538. {
  2539. int y, x;
  2540. /* Location */
  2541. y = GRID_Y(g);
  2542. x = GRID_X(g);
  2543. /* Redraw */
  2544. light_spot(y, x);
  2545. }
  2546. }
  2547. /* Save 'view_n' */
  2548. view_n = fast_view_n;
  2549. }
  2550. /*
  2551. * Size of the circular queue used by "update_flow()"
  2552. */
  2553. #define FLOW_MAX 2048
  2554. /*
  2555. * Hack -- provide some "speed" for the "flow" code
  2556. * This entry is the "current index" for the "when" field
  2557. * Note that a "when" value of "zero" means "not used".
  2558. *
  2559. * Note that the "cost" indexes from 1 to 127 are for
  2560. * "old" data, and from 128 to 255 are for "new" data.
  2561. *
  2562. * This means that as long as the player does not "teleport",
  2563. * then any monster up to 128 + MONSTER_FLOW_DEPTH will be
  2564. * able to track down the player, and in general, will be
  2565. * able to track down either the player or a position recently
  2566. * occupied by the player.
  2567. */
  2568. static int flow_save = 0;
  2569. /*
  2570. * Hack -- forget the "flow" information
  2571. */
  2572. void forget_flow(void)
  2573. {
  2574. int x, y;
  2575. /* Nothing to forget */
  2576. if (!flow_save) return;
  2577. /* Check the entire dungeon */
  2578. for (y = 0; y < DUNGEON_HGT; y++)
  2579. {
  2580. for (x = 0; x < DUNGEON_WID; x++)
  2581. {
  2582. /* Forget the old data */
  2583. cave_cost[y][x] = 0;
  2584. cave_when[y][x] = 0;
  2585. }
  2586. }
  2587. /* Start over */
  2588. flow_save = 0;
  2589. }
  2590. /*
  2591. * Hack -- fill in the "cost" field of every grid that the player can
  2592. * "reach" with the number of steps needed to reach that grid. This
  2593. * also yields the "distance" of the player from every grid.
  2594. *
  2595. * In addition, mark the "when" of the grids that can reach the player
  2596. * with the incremented value of "flow_save".
  2597. *
  2598. * Hack -- use the local "flow_y" and "flow_x" arrays as a "circular
  2599. * queue" of cave grids.
  2600. *
  2601. * We do not need a priority queue because the cost from grid to grid
  2602. * is always "one" (even along diagonals) and we process them in order.
  2603. */
  2604. void update_flow(void)
  2605. {
  2606. int py = p_ptr->py;
  2607. int px = p_ptr->px;
  2608. int ty, tx;
  2609. int y, x;
  2610. int n, d;
  2611. int flow_n;
  2612. int flow_tail = 0;
  2613. int flow_head = 0;
  2614. byte flow_y[FLOW_MAX];
  2615. byte flow_x[FLOW_MAX];
  2616. /* Hack -- disabled */
  2617. if (!OPT(adult_ai_sound)) return;
  2618. /*** Cycle the flow ***/
  2619. /* Cycle the flow */
  2620. if (flow_save++ == 255)
  2621. {
  2622. /* Cycle the flow */
  2623. for (y = 0; y < DUNGEON_HGT; y++)
  2624. {
  2625. for (x = 0; x < DUNGEON_WID; x++)
  2626. {
  2627. int w = cave_when[y][x];
  2628. cave_when[y][x] = (w >= 128) ? (w - 128) : 0;
  2629. }
  2630. }
  2631. /* Restart */
  2632. flow_save = 128;
  2633. }
  2634. /* Local variable */
  2635. flow_n = flow_save;
  2636. /*** Player Grid ***/
  2637. /* Save the time-stamp */
  2638. cave_when[py][px] = flow_n;
  2639. /* Save the flow cost */
  2640. cave_cost[py][px] = 0;
  2641. /* Enqueue that entry */
  2642. flow_y[flow_head] = py;
  2643. flow_x[flow_head] = px;
  2644. /* Advance the queue */
  2645. ++flow_tail;
  2646. /*** Process Queue ***/
  2647. /* Now process the queue */
  2648. while (flow_head != flow_tail)
  2649. {
  2650. /* Extract the next entry */
  2651. ty = flow_y[flow_head];
  2652. tx = flow_x[flow_head];
  2653. /* Forget that entry (with wrap) */
  2654. if (++flow_head == FLOW_MAX) flow_head = 0;
  2655. /* Child cost */
  2656. n = cave_cost[ty][tx] + 1;
  2657. /* Hack -- Limit flow depth */
  2658. if (n == MONSTER_FLOW_DEPTH) continue;
  2659. /* Add the "children" */
  2660. for (d = 0; d < 8; d++)
  2661. {
  2662. int old_head = flow_tail;
  2663. /* Child location */
  2664. y = ty + ddy_ddd[d];
  2665. x = tx + ddx_ddd[d];
  2666. /* Ignore "pre-stamped" entries */
  2667. if (cave_when[y][x] == flow_n) continue;
  2668. /* Ignore "walls" and "rubble" */
  2669. if (cave_feat[y][x] >= FEAT_RUBBLE) continue;
  2670. /* Save the time-stamp */
  2671. cave_when[y][x] = flow_n;
  2672. /* Save the flow cost */
  2673. cave_cost[y][x] = n;
  2674. /* Enqueue that entry */
  2675. flow_y[flow_tail] = y;
  2676. flow_x[flow_tail] = x;
  2677. /* Advance the queue */
  2678. if (++flow_tail == FLOW_MAX) flow_tail = 0;
  2679. /* Hack -- Overflow by forgetting new entry */
  2680. if (flow_tail == flow_head) flow_tail = old_head;
  2681. }
  2682. }
  2683. }
  2684. /*
  2685. * Light up the dungeon using "claravoyance"
  2686. *
  2687. * This function "illuminates" every grid in the dungeon, memorizes all
  2688. * "objects", memorizes all grids as with magic mapping, and, under the
  2689. * standard option settings (OPT(view_perma_grids) but not OPT(view_torch_grids))
  2690. * memorizes all floor grids too.
  2691. *
  2692. * Note that if "OPT(view_perma_grids)" is not set, we do not memorize floor
  2693. * grids, since this would defeat the purpose of "OPT(view_perma_grids)", not
  2694. * that anyone seems to play without this option.
  2695. *
  2696. * Note that if "OPT(view_torch_grids)" is set, we do not memorize floor grids,
  2697. * since this would prevent the use of "OPT(view_torch_grids)" as a method to
  2698. * keep track of what grids have been observed directly.
  2699. */
  2700. void wiz_light(void)
  2701. {
  2702. int i, y, x;
  2703. /* Memorize objects */
  2704. for (i = 1; i < o_max; i++)
  2705. {
  2706. object_type *o_ptr = &o_list[i];
  2707. /* Skip dead objects */
  2708. if (!o_ptr->k_idx) continue;
  2709. /* Skip held objects */
  2710. if (o_ptr->held_m_idx) continue;
  2711. /* Memorize */
  2712. o_ptr->marked = TRUE;
  2713. }
  2714. /* Scan all normal grids */
  2715. for (y = 1; y < DUNGEON_HGT-1; y++)
  2716. {
  2717. /* Scan all normal grids */
  2718. for (x = 1; x < DUNGEON_WID-1; x++)
  2719. {
  2720. /* Process all non-walls */
  2721. if (cave_feat[y][x] < FEAT_SECRET)
  2722. {
  2723. /* Scan all neighbors */
  2724. for (i = 0; i < 9; i++)
  2725. {
  2726. int yy = y + ddy_ddd[i];
  2727. int xx = x + ddx_ddd[i];
  2728. /* Perma-light the grid */
  2729. cave_info[yy][xx] |= (CAVE_GLOW);
  2730. /* Memorize normal features */
  2731. if (cave_feat[yy][xx] > FEAT_INVIS)
  2732. {
  2733. /* Memorize the grid */
  2734. cave_info[yy][xx] |= (CAVE_MARK);
  2735. }
  2736. /* Normally, memorize floors (see above) */
  2737. if (OPT(view_perma_grids) && !OPT(view_torch_grids))
  2738. {
  2739. /* Memorize the grid */
  2740. cave_info[yy][xx] |= (CAVE_MARK);
  2741. }
  2742. }
  2743. }
  2744. }
  2745. }
  2746. /* Fully update the visuals */
  2747. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  2748. /* Redraw whole map, monster list */
  2749. p_ptr->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
  2750. }
  2751. /*
  2752. * Forget the dungeon map (ala "Thinking of Maud...").
  2753. */
  2754. void wiz_dark(void)
  2755. {
  2756. int i, y, x;
  2757. /* Forget every grid */
  2758. for (y = 0; y < DUNGEON_HGT; y++)
  2759. {
  2760. for (x = 0; x < DUNGEON_WID; x++)
  2761. {
  2762. /* Process the grid */
  2763. cave_info[y][x] &= ~(CAVE_MARK);
  2764. cave_info2[y][x] &= ~(CAVE2_DTRAP);
  2765. }
  2766. }
  2767. /* Forget all objects */
  2768. for (i = 1; i < o_max; i++)
  2769. {
  2770. object_type *o_ptr = &o_list[i];
  2771. /* Skip dead objects */
  2772. if (!o_ptr->k_idx) continue;
  2773. /* Skip held objects */
  2774. if (o_ptr->held_m_idx) continue;
  2775. /* Forget the object */
  2776. o_ptr->marked = FALSE;
  2777. }
  2778. /* Fully update the visuals */
  2779. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  2780. /* Redraw map, monster list */
  2781. p_ptr->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
  2782. }
  2783. /*
  2784. * Light or Darken the town
  2785. */
  2786. void town_illuminate(bool daytime)
  2787. {
  2788. int y, x, i;
  2789. /* Apply light or darkness */
  2790. for (y = 0; y < TOWN_HGT; y++)
  2791. {
  2792. for (x = 0; x < TOWN_WID; x++)
  2793. {
  2794. /* Interesting grids */
  2795. if (cave_feat[y][x] > FEAT_INVIS)
  2796. {
  2797. /* Illuminate the grid */
  2798. cave_info[y][x] |= (CAVE_GLOW);
  2799. /* Memorize the grid */
  2800. cave_info[y][x] |= (CAVE_MARK);
  2801. }
  2802. /* Boring grids (light) */
  2803. else if (daytime)
  2804. {
  2805. /* Illuminate the grid */
  2806. cave_info[y][x] |= (CAVE_GLOW);
  2807. /* Hack -- Memorize grids */
  2808. if (OPT(view_perma_grids))
  2809. {
  2810. cave_info[y][x] |= (CAVE_MARK);
  2811. }
  2812. }
  2813. /* Boring grids (dark) */
  2814. else
  2815. {
  2816. /* Darken the grid */
  2817. cave_info[y][x] &= ~(CAVE_GLOW);
  2818. /* Hack -- Forget grids */
  2819. if (OPT(view_perma_grids))
  2820. {
  2821. cave_info[y][x] &= ~(CAVE_MARK);
  2822. }
  2823. }
  2824. }
  2825. }
  2826. /* Handle shop doorways */
  2827. for (y = 0; y < TOWN_HGT; y++)
  2828. {
  2829. for (x = 0; x < TOWN_WID; x++)
  2830. {
  2831. /* Track shop doorways */
  2832. if ((cave_feat[y][x] >= FEAT_SHOP_HEAD) &&
  2833. (cave_feat[y][x] <= FEAT_SHOP_TAIL))
  2834. {
  2835. for (i = 0; i < 8; i++)
  2836. {
  2837. int yy = y + ddy_ddd[i];
  2838. int xx = x + ddx_ddd[i];
  2839. /* Illuminate the grid */
  2840. cave_info[yy][xx] |= (CAVE_GLOW);
  2841. /* Hack -- Memorize grids */
  2842. if (OPT(view_perma_grids))
  2843. {
  2844. cave_info[yy][xx] |= (CAVE_MARK);
  2845. }
  2846. }
  2847. }
  2848. }
  2849. }
  2850. /* Fully update the visuals */
  2851. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_MONSTERS);
  2852. /* Redraw map, monster list */
  2853. p_ptr->redraw |= (PR_MAP | PR_MONLIST | PR_ITEMLIST);
  2854. }
  2855. /*
  2856. * Change the "feat" flag for a grid, and notice/redraw the grid
  2857. */
  2858. void cave_set_feat(int y, int x, int feat)
  2859. {
  2860. /* Change the feature */
  2861. cave_feat[y][x] = feat;
  2862. /* Handle "wall/door" grids */
  2863. if (feat >= FEAT_DOOR_HEAD)
  2864. {
  2865. cave_info[y][x] |= (CAVE_WALL);
  2866. }
  2867. /* Handle "floor"/etc grids */
  2868. else
  2869. {
  2870. cave_info[y][x] &= ~(CAVE_WALL);
  2871. }
  2872. /* Notice/Redraw */
  2873. if (character_dungeon)
  2874. {
  2875. /* Notice */
  2876. note_spot(y, x);
  2877. /* Redraw */
  2878. light_spot(y, x);
  2879. }
  2880. }
  2881. /*
  2882. * Determine the path taken by a projection.
  2883. *
  2884. * The projection will always start from the grid (y1,x1), and will travel
  2885. * towards the grid (y2,x2), touching one grid per unit of distance along
  2886. * the major axis, and stopping when it enters the destination grid or a
  2887. * wall grid, or has travelled the maximum legal distance of "range".
  2888. *
  2889. * Note that "distance" in this function (as in the "update_view()" code)
  2890. * is defined as "MAX(dy,dx) + MIN(dy,dx)/2", which means that the player
  2891. * actually has an "octagon of projection" not a "circle of projection".
  2892. *
  2893. * The path grids are saved into the grid array pointed to by "gp", and
  2894. * there should be room for at least "range" grids in "gp". Note that
  2895. * due to the way in which distance is calculated, this function normally
  2896. * uses fewer than "range" grids for the projection path, so the result
  2897. * of this function should never be compared directly to "range". Note
  2898. * that the initial grid (y1,x1) is never saved into the grid array, not
  2899. * even if the initial grid is also the final grid. XXX XXX XXX
  2900. *
  2901. * The "flg" flags can be used to modify the behavior of this function.
  2902. *
  2903. * In particular, the "PROJECT_STOP" and "PROJECT_THRU" flags have the same
  2904. * semantics as they do for the "project" function, namely, that the path
  2905. * will stop as soon as it hits a monster, or that the path will continue
  2906. * through the destination grid, respectively.
  2907. *
  2908. * The "PROJECT_JUMP" flag, which for the "project()" function means to
  2909. * start at a special grid (which makes no sense in this function), means
  2910. * that the path should be "angled" slightly if needed to avoid any wall
  2911. * grids, allowing the player to "target" any grid which is in "view".
  2912. * This flag is non-trivial and has not yet been implemented, but could
  2913. * perhaps make use of the "vinfo" array (above). XXX XXX XXX
  2914. *
  2915. * This function returns the number of grids (if any) in the path. This
  2916. * function will return zero if and only if (y1,x1) and (y2,x2) are equal.
  2917. *
  2918. * This algorithm is similar to, but slightly different from, the one used
  2919. * by "update_view_los()", and very different from the one used by "los()".
  2920. */
  2921. int project_path(u16b *gp, int range, int y1, int x1, int y2, int x2, int flg)
  2922. {
  2923. int y, x;
  2924. int n = 0;
  2925. int k = 0;
  2926. /* Absolute */
  2927. int ay, ax;
  2928. /* Offsets */
  2929. int sy, sx;
  2930. /* Fractions */
  2931. int frac;
  2932. /* Scale factors */
  2933. int full, half;
  2934. /* Slope */
  2935. int m;
  2936. /* No path necessary (or allowed) */
  2937. if ((x1 == x2) && (y1 == y2)) return (0);
  2938. /* Analyze "dy" */
  2939. if (y2 < y1)
  2940. {
  2941. ay = (y1 - y2);
  2942. sy = -1;
  2943. }
  2944. else
  2945. {
  2946. ay = (y2 - y1);
  2947. sy = 1;
  2948. }
  2949. /* Analyze "dx" */
  2950. if (x2 < x1)
  2951. {
  2952. ax = (x1 - x2);
  2953. sx = -1;
  2954. }
  2955. else
  2956. {
  2957. ax = (x2 - x1);
  2958. sx = 1;
  2959. }
  2960. /* Number of "units" in one "half" grid */
  2961. half = (ay * ax);
  2962. /* Number of "units" in one "full" grid */
  2963. full = half << 1;
  2964. /* Vertical */
  2965. if (ay > ax)
  2966. {
  2967. /* Start at tile edge */
  2968. frac = ax * ax;
  2969. /* Let m = ((dx/dy) * full) = (dx * dx * 2) = (frac * 2) */
  2970. m = frac << 1;
  2971. /* Start */
  2972. y = y1 + sy;
  2973. x = x1;
  2974. /* Create the projection path */
  2975. while (1)
  2976. {
  2977. /* Save grid */
  2978. gp[n++] = GRID(y,x);
  2979. /* Hack -- Check maximum range */
  2980. if ((n + (k >> 1)) >= range) break;
  2981. /* Sometimes stop at destination grid */
  2982. if (!(flg & (PROJECT_THRU)))
  2983. {
  2984. if ((x == x2) && (y == y2)) break;
  2985. }
  2986. /* Always stop at non-initial wall grids */
  2987. if ((n > 0) && !cave_floor_bold(y, x)) break;
  2988. /* Sometimes stop at non-initial monsters/players */
  2989. if (flg & (PROJECT_STOP))
  2990. {
  2991. if ((n > 0) && (cave_m_idx[y][x] != 0)) break;
  2992. }
  2993. /* Slant */
  2994. if (m)
  2995. {
  2996. /* Advance (X) part 1 */
  2997. frac += m;
  2998. /* Horizontal change */
  2999. if (frac >= half)
  3000. {
  3001. /* Advance (X) part 2 */
  3002. x += sx;
  3003. /* Advance (X) part 3 */
  3004. frac -= full;
  3005. /* Track distance */
  3006. k++;
  3007. }
  3008. }
  3009. /* Advance (Y) */
  3010. y += sy;
  3011. }
  3012. }
  3013. /* Horizontal */
  3014. else if (ax > ay)
  3015. {
  3016. /* Start at tile edge */
  3017. frac = ay * ay;
  3018. /* Let m = ((dy/dx) * full) = (dy * dy * 2) = (frac * 2) */
  3019. m = frac << 1;
  3020. /* Start */
  3021. y = y1;
  3022. x = x1 + sx;
  3023. /* Create the projection path */
  3024. while (1)
  3025. {
  3026. /* Save grid */
  3027. gp[n++] = GRID(y,x);
  3028. /* Hack -- Check maximum range */
  3029. if ((n + (k >> 1)) >= range) break;
  3030. /* Sometimes stop at destination grid */
  3031. if (!(flg & (PROJECT_THRU)))
  3032. {
  3033. if ((x == x2) && (y == y2)) break;
  3034. }
  3035. /* Always stop at non-initial wall grids */
  3036. if ((n > 0) && !cave_floor_bold(y, x)) break;
  3037. /* Sometimes stop at non-initial monsters/players */
  3038. if (flg & (PROJECT_STOP))
  3039. {
  3040. if ((n > 0) && (cave_m_idx[y][x] != 0)) break;
  3041. }
  3042. /* Slant */
  3043. if (m)
  3044. {
  3045. /* Advance (Y) part 1 */
  3046. frac += m;
  3047. /* Vertical change */
  3048. if (frac >= half)
  3049. {
  3050. /* Advance (Y) part 2 */
  3051. y += sy;
  3052. /* Advance (Y) part 3 */
  3053. frac -= full;
  3054. /* Track distance */
  3055. k++;
  3056. }
  3057. }
  3058. /* Advance (X) */
  3059. x += sx;
  3060. }
  3061. }
  3062. /* Diagonal */
  3063. else
  3064. {
  3065. /* Start */
  3066. y = y1 + sy;
  3067. x = x1 + sx;
  3068. /* Create the projection path */
  3069. while (1)
  3070. {
  3071. /* Save grid */
  3072. gp[n++] = GRID(y,x);
  3073. /* Hack -- Check maximum range */
  3074. if ((n + (n >> 1)) >= range) break;
  3075. /* Sometimes stop at destination grid */
  3076. if (!(flg & (PROJECT_THRU)))
  3077. {
  3078. if ((x == x2) && (y == y2)) break;
  3079. }
  3080. /* Always stop at non-initial wall grids */
  3081. if ((n > 0) && !cave_floor_bold(y, x)) break;
  3082. /* Sometimes stop at non-initial monsters/players */
  3083. if (flg & (PROJECT_STOP))
  3084. {
  3085. if ((n > 0) && (cave_m_idx[y][x] != 0)) break;
  3086. }
  3087. /* Advance (Y) */
  3088. y += sy;
  3089. /* Advance (X) */
  3090. x += sx;
  3091. }
  3092. }
  3093. /* Length */
  3094. return (n);
  3095. }
  3096. /*
  3097. * Determine if a bolt spell cast from (y1,x1) to (y2,x2) will arrive
  3098. * at the final destination, assuming that no monster gets in the way,
  3099. * using the "project_path()" function to check the projection path.
  3100. *
  3101. * Note that no grid is ever "projectable()" from itself.
  3102. *
  3103. * This function is used to determine if the player can (easily) target
  3104. * a given grid, and if a monster can target the player.
  3105. */
  3106. bool projectable(int y1, int x1, int y2, int x2, int flg)
  3107. {
  3108. int y, x;
  3109. int grid_n = 0;
  3110. u16b grid_g[512];
  3111. /* Check the projection path */
  3112. grid_n = project_path(grid_g, MAX_RANGE, y1, x1, y2, x2, flg);
  3113. /* No grid is ever projectable from itself */
  3114. if (!grid_n) return (FALSE);
  3115. /* Final grid */
  3116. y = GRID_Y(grid_g[grid_n-1]);
  3117. x = GRID_X(grid_g[grid_n-1]);
  3118. /* May not end in a wall grid */
  3119. if (!cave_floor_bold(y, x)) return (FALSE);
  3120. /* May not end in an unrequested grid */
  3121. if ((y != y2) || (x != x2)) return (FALSE);
  3122. /* Assume okay */
  3123. return (TRUE);
  3124. }
  3125. /*
  3126. * Standard "find me a location" function
  3127. *
  3128. * Obtains a legal location within the given distance of the initial
  3129. * location, and with "los()" from the source to destination location.
  3130. *
  3131. * This function is often called from inside a loop which searches for
  3132. * locations while increasing the "d" distance.
  3133. *
  3134. * Currently the "m" parameter is unused.
  3135. */
  3136. void scatter(int *yp, int *xp, int y, int x, int d, int m)
  3137. {
  3138. int nx, ny;
  3139. /* Unused parameter */
  3140. (void)m;
  3141. /* Pick a location */
  3142. while (TRUE)
  3143. {
  3144. /* Pick a new location */
  3145. ny = rand_spread(y, d);
  3146. nx = rand_spread(x, d);
  3147. /* Ignore annoying locations */
  3148. if (!in_bounds_fully(ny, nx)) continue;
  3149. /* Ignore "excessively distant" locations */
  3150. if ((d > 1) && (distance(y, x, ny, nx) > d)) continue;
  3151. /* Require "line of sight" */
  3152. if (los(y, x, ny, nx)) break;
  3153. }
  3154. /* Save the location */
  3155. (*yp) = ny;
  3156. (*xp) = nx;
  3157. }
  3158. /*
  3159. * Track a new monster
  3160. */
  3161. void health_track(int m_idx)
  3162. {
  3163. /* Track a new guy */
  3164. p_ptr->health_who = m_idx;
  3165. /* Redraw (later) */
  3166. p_ptr->redraw |= (PR_HEALTH);
  3167. }
  3168. /*
  3169. * Hack -- track the given monster race
  3170. */
  3171. void monster_race_track(int r_idx)
  3172. {
  3173. /* Save this monster ID */
  3174. p_ptr->monster_race_idx = r_idx;
  3175. /* Window stuff */
  3176. p_ptr->redraw |= (PR_MONSTER);
  3177. }
  3178. /*
  3179. * Hack -- track the given object kind
  3180. */
  3181. void track_object(int item)
  3182. {
  3183. p_ptr->object_idx = item;
  3184. p_ptr->object_kind_idx = 0;
  3185. p_ptr->redraw |= (PR_OBJECT);
  3186. }
  3187. void track_object_kind(int k_idx)
  3188. {
  3189. p_ptr->object_idx = 0;
  3190. p_ptr->object_kind_idx = k_idx;
  3191. p_ptr->redraw |= (PR_OBJECT);
  3192. }
  3193. /*
  3194. * Something has happened to disturb the player.
  3195. *
  3196. * The first arg indicates a major disturbance, which affects search.
  3197. *
  3198. * The second arg is currently unused, but could induce output flush.
  3199. *
  3200. * All disturbance cancels repeated commands, resting, and running.
  3201. */
  3202. void disturb(int stop_search, int unused_flag)
  3203. {
  3204. /* Unused parameter */
  3205. (void)unused_flag;
  3206. /* Cancel auto-commands */
  3207. /* p_ptr->command_new = 0; */
  3208. /* Cancel repeated commands */
  3209. cmd_cancel_repeat();
  3210. /* Cancel Resting */
  3211. if (p_ptr->resting)
  3212. {
  3213. /* Cancel */
  3214. p_ptr->resting = 0;
  3215. /* Redraw the state (later) */
  3216. p_ptr->redraw |= (PR_STATE);
  3217. }
  3218. /* Cancel running */
  3219. if (p_ptr->running)
  3220. {
  3221. /* Cancel */
  3222. p_ptr->running = 0;
  3223. /* Check for new panel if appropriate */
  3224. if (OPT(center_player)) verify_panel();
  3225. /* Calculate torch radius */
  3226. p_ptr->update |= (PU_TORCH);
  3227. }
  3228. /* Cancel searching if requested */
  3229. if (stop_search && p_ptr->searching)
  3230. {
  3231. /* Cancel */
  3232. p_ptr->searching = FALSE;
  3233. /* Recalculate bonuses */
  3234. p_ptr->update |= (PU_BONUS);
  3235. /* Redraw the state */
  3236. p_ptr->redraw |= (PR_STATE);
  3237. }
  3238. /* Flush the input if requested */
  3239. if (OPT(flush_disturb)) flush();
  3240. }
  3241. /*
  3242. * Hack -- Check if a level is a "quest" level
  3243. */
  3244. bool is_quest(int level)
  3245. {
  3246. int i;
  3247. /* Town is never a quest */
  3248. if (!level) return (FALSE);
  3249. /* Check quests */
  3250. for (i = 0; i < MAX_Q_IDX; i++)
  3251. {
  3252. /* Check for quest */
  3253. if (q_list[i].level == level) return (TRUE);
  3254. }
  3255. /* Nope */
  3256. return (FALSE);
  3257. }