PageRenderTime 64ms CodeModel.GetById 22ms RepoModel.GetById 1ms app.codeStats 0ms

/src/monster/monster2.c

https://bitbucket.org/ekolis/jackband
C | 3300 lines | 1568 code | 747 blank | 985 comment | 443 complexity | 11ea1f6dbbecd5d4374da025f10ebf8b MD5 | raw file

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

  1. /*
  2. * File: monster2.c
  3. * Purpose: Low-level monster manipulation
  4. *
  5. * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
  6. *
  7. * This work is free software; you can redistribute it and/or modify it
  8. * under the terms of either:
  9. *
  10. * a) the GNU General Public License as published by the Free Software
  11. * Foundation, version 2, or
  12. *
  13. * b) the "Angband licence":
  14. * This software may be copied and distributed for educational, research,
  15. * and not for profit purposes provided that this copyright and statement
  16. * are included in all such copies. Other copyrights may also apply.
  17. */
  18. #include "angband.h"
  19. #include "object/tvalsval.h"
  20. /*
  21. * Delete a monster by index.
  22. *
  23. * When a monster is deleted, all of its objects are deleted.
  24. */
  25. void delete_monster_idx(int i)
  26. {
  27. int x, y;
  28. monster_type *m_ptr = &mon_list[i];
  29. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  30. s16b this_o_idx, next_o_idx = 0;
  31. /* Get location */
  32. y = m_ptr->fy;
  33. x = m_ptr->fx;
  34. /* Hack -- Reduce the racial counter */
  35. r_ptr->cur_num--;
  36. /* Hack -- count the number of "reproducers" */
  37. if (rf_has(r_ptr->flags, RF_MULTIPLY)) num_repro--;
  38. /* Hack -- remove target monster */
  39. if (target_get_monster() == i) target_set_monster(0);
  40. /* Hack -- remove tracked monster */
  41. if (p_ptr->health_who == i) health_track(0);
  42. /* Monster is gone */
  43. cave_m_idx[y][x] = 0;
  44. /* Delete objects */
  45. for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
  46. {
  47. object_type *o_ptr;
  48. /* Get the object */
  49. o_ptr = &o_list[this_o_idx];
  50. /* Get the next object */
  51. next_o_idx = o_ptr->next_o_idx;
  52. /* Hack -- efficiency */
  53. o_ptr->held_m_idx = 0;
  54. /* Delete the object */
  55. delete_object_idx(this_o_idx);
  56. }
  57. /* Wipe the Monster */
  58. (void)WIPE(m_ptr, monster_type);
  59. /* Count monsters */
  60. mon_cnt--;
  61. /* Visual update */
  62. light_spot(y, x);
  63. }
  64. /*
  65. * Delete the monster, if any, at a given location
  66. */
  67. void delete_monster(int y, int x)
  68. {
  69. /* Paranoia */
  70. if (!in_bounds(y, x)) return;
  71. /* Delete the monster (if any) */
  72. if (cave_m_idx[y][x] > 0) delete_monster_idx(cave_m_idx[y][x]);
  73. }
  74. /*
  75. * Move an object from index i1 to index i2 in the object list
  76. */
  77. static void compact_monsters_aux(int i1, int i2)
  78. {
  79. int y, x;
  80. monster_type *m_ptr;
  81. s16b this_o_idx, next_o_idx = 0;
  82. /* Do nothing */
  83. if (i1 == i2) return;
  84. /* Old monster */
  85. m_ptr = &mon_list[i1];
  86. /* Location */
  87. y = m_ptr->fy;
  88. x = m_ptr->fx;
  89. /* Update the cave */
  90. cave_m_idx[y][x] = i2;
  91. /* Repair objects being carried by monster */
  92. for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
  93. {
  94. object_type *o_ptr;
  95. /* Get the object */
  96. o_ptr = &o_list[this_o_idx];
  97. /* Get the next object */
  98. next_o_idx = o_ptr->next_o_idx;
  99. /* Reset monster pointer */
  100. o_ptr->held_m_idx = i2;
  101. }
  102. /* Hack -- Update the target */
  103. if (target_get_monster() == i1) target_set_monster(i2);
  104. /* Hack -- Update the health bar */
  105. if (p_ptr->health_who == i1) p_ptr->health_who = i2;
  106. /* Hack -- move monster */
  107. COPY(&mon_list[i2], &mon_list[i1], monster_type);
  108. /* Hack -- wipe hole */
  109. (void)WIPE(&mon_list[i1], monster_type);
  110. }
  111. /*
  112. * Compact and Reorder the monster list
  113. *
  114. * This function can be very dangerous, use with caution!
  115. *
  116. * When actually "compacting" monsters, we base the saving throw
  117. * on a combination of monster level, distance from player, and
  118. * current "desperation".
  119. *
  120. * After "compacting" (if needed), we "reorder" the monsters into a more
  121. * compact order, and we reset the allocation info, and the "live" array.
  122. */
  123. void compact_monsters(int size)
  124. {
  125. int i, num, cnt;
  126. int cur_lev, cur_dis, chance;
  127. /* Message (only if compacting) */
  128. if (size) msg_print("Compacting monsters...");
  129. /* Compact at least 'size' objects */
  130. for (num = 0, cnt = 1; num < size; cnt++)
  131. {
  132. /* Get more vicious each iteration */
  133. cur_lev = 5 * cnt;
  134. /* Get closer each iteration */
  135. cur_dis = 5 * (20 - cnt);
  136. /* Check all the monsters */
  137. for (i = 1; i < mon_max; i++)
  138. {
  139. monster_type *m_ptr = &mon_list[i];
  140. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  141. /* Paranoia -- skip "dead" monsters */
  142. if (!m_ptr->r_idx) continue;
  143. /* Hack -- High level monsters start out "immune" */
  144. if (r_ptr->level > cur_lev) continue;
  145. /* Ignore nearby monsters */
  146. if ((cur_dis > 0) && (m_ptr->cdis < cur_dis)) continue;
  147. /* Saving throw chance */
  148. chance = 90;
  149. /* Only compact "Quest" Monsters in emergencies */
  150. if (rf_has(r_ptr->flags, RF_QUESTOR) && (cnt < 1000)) chance = 100;
  151. /* Try not to compact Unique Monsters */
  152. if (rf_has(r_ptr->flags, RF_UNIQUE)) chance = 99;
  153. /* All monsters get a saving throw */
  154. if (randint0(100) < chance) continue;
  155. /* Delete the monster */
  156. delete_monster_idx(i);
  157. /* Count the monster */
  158. num++;
  159. }
  160. }
  161. /* Excise dead monsters (backwards!) */
  162. for (i = mon_max - 1; i >= 1; i--)
  163. {
  164. /* Get the i'th monster */
  165. monster_type *m_ptr = &mon_list[i];
  166. /* Skip real monsters */
  167. if (m_ptr->r_idx) continue;
  168. /* Move last monster into open hole */
  169. compact_monsters_aux(mon_max - 1, i);
  170. /* Compress "mon_max" */
  171. mon_max--;
  172. }
  173. }
  174. /*
  175. * Delete/Remove all the monsters when the player leaves the level
  176. *
  177. * This is an efficient method of simulating multiple calls to the
  178. * "delete_monster()" function, with no visual effects.
  179. */
  180. void wipe_mon_list(void)
  181. {
  182. int i;
  183. /* Delete all the monsters */
  184. for (i = mon_max - 1; i >= 1; i--)
  185. {
  186. monster_type *m_ptr = &mon_list[i];
  187. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  188. /* Skip dead monsters */
  189. if (!m_ptr->r_idx) continue;
  190. /* Mega-Hack -- preserve Unique's XXX XXX XXX */
  191. /* Hack -- Reduce the racial counter */
  192. r_ptr->cur_num--;
  193. /* Monster is gone */
  194. cave_m_idx[m_ptr->fy][m_ptr->fx] = 0;
  195. /* Wipe the Monster */
  196. (void)WIPE(m_ptr, monster_type);
  197. }
  198. /* Reset "mon_max" */
  199. mon_max = 1;
  200. /* Reset "mon_cnt" */
  201. mon_cnt = 0;
  202. /* Hack -- reset "reproducer" count */
  203. num_repro = 0;
  204. /* Hack -- no more target */
  205. target_set_monster(0);
  206. /* Hack -- no more tracking */
  207. health_track(0);
  208. }
  209. /*
  210. * Get and return the index of a "free" monster.
  211. *
  212. * This routine should almost never fail, but it *can* happen.
  213. */
  214. s16b mon_pop(void)
  215. {
  216. int i;
  217. /* Normal allocation */
  218. if (mon_max < z_info->m_max)
  219. {
  220. /* Get the next hole */
  221. i = mon_max;
  222. /* Expand the array */
  223. mon_max++;
  224. /* Count monsters */
  225. mon_cnt++;
  226. /* Return the index */
  227. return (i);
  228. }
  229. /* Recycle dead monsters */
  230. for (i = 1; i < mon_max; i++)
  231. {
  232. monster_type *m_ptr;
  233. /* Get the monster */
  234. m_ptr = &mon_list[i];
  235. /* Skip live monsters */
  236. if (m_ptr->r_idx) continue;
  237. /* Count monsters */
  238. mon_cnt++;
  239. /* Use this monster */
  240. return (i);
  241. }
  242. /* Warn the player (except during dungeon creation) */
  243. if (character_dungeon) msg_print("Too many monsters!");
  244. /* Try not to crash */
  245. return (0);
  246. }
  247. /*
  248. * Apply a "monster restriction function" to the "monster allocation table"
  249. */
  250. void get_mon_num_prep(void)
  251. {
  252. int i;
  253. /* Scan the allocation table */
  254. for (i = 0; i < alloc_race_size; i++)
  255. {
  256. /* Get the entry */
  257. alloc_entry *entry = &alloc_race_table[i];
  258. /* Accept monsters which pass the restriction, if any */
  259. if (!get_mon_num_hook || (*get_mon_num_hook)(entry->index))
  260. {
  261. /* Accept this monster */
  262. entry->prob2 = entry->prob1;
  263. }
  264. /* Do not use this monster */
  265. else
  266. {
  267. /* Decline this monster */
  268. entry->prob2 = 0;
  269. }
  270. }
  271. /* Success */
  272. return;
  273. }
  274. /*
  275. * Choose a monster race that seems "appropriate" to the given level
  276. *
  277. * This function uses the "prob2" field of the "monster allocation table",
  278. * and various local information, to calculate the "prob3" field of the
  279. * same table, which is then used to choose an "appropriate" monster, in
  280. * a relatively efficient manner.
  281. *
  282. * Note that "town" monsters will *only* be created in the town, and
  283. * "normal" monsters will *never* be created in the town, unless the
  284. * "level" is "modified", for example, by polymorph or summoning.
  285. *
  286. * There is a small chance (1/50) of "boosting" the given depth by
  287. * a small amount (up to four levels), except in the town.
  288. *
  289. * It is (slightly) more likely to acquire a monster of the given level
  290. * than one of a lower level. This is done by choosing several monsters
  291. * appropriate to the given level and keeping the "hardest" one.
  292. *
  293. * Note that if no monsters are "appropriate", then this function will
  294. * fail, and return zero, but this should *almost* never happen.
  295. */
  296. s16b get_mon_num(int level)
  297. {
  298. int i, j, p;
  299. int r_idx;
  300. long value, total;
  301. monster_race *r_ptr;
  302. alloc_entry *table = alloc_race_table;
  303. /* Occasionally produce a nastier monster in the dungeon */
  304. if (level > 0 && one_in_(NASTY_MON))
  305. level += MIN(level / 4 + 2, MON_OOD_MAX);
  306. /* Reset total */
  307. total = 0L;
  308. /* Process probabilities */
  309. for (i = 0; i < alloc_race_size; i++)
  310. {
  311. /* Monsters are sorted by depth */
  312. if (table[i].level > level) break;
  313. /* Default */
  314. table[i].prob3 = 0;
  315. /* Hack -- No town monsters in dungeon */
  316. if ((level > 0) && (table[i].level <= 0)) continue;
  317. /* Get the "r_idx" of the chosen monster */
  318. r_idx = table[i].index;
  319. /* Get the actual race */
  320. r_ptr = &r_info[r_idx];
  321. /* Hack -- "unique" monsters must be "unique" */
  322. if (rf_has(r_ptr->flags, RF_UNIQUE) &&
  323. r_ptr->cur_num >= r_ptr->max_num)
  324. {
  325. continue;
  326. }
  327. /* Depth Monsters never appear out of depth */
  328. if (rf_has(r_ptr->flags, RF_FORCE_DEPTH) && r_ptr->level > p_ptr->depth)
  329. {
  330. continue;
  331. }
  332. /* Accept */
  333. table[i].prob3 = table[i].prob2;
  334. /* Total */
  335. total += table[i].prob3;
  336. }
  337. /* No legal monsters */
  338. if (total <= 0) return (0);
  339. /* Pick a monster */
  340. value = randint0(total);
  341. /* Find the monster */
  342. for (i = 0; i < alloc_race_size; i++)
  343. {
  344. /* Found the entry */
  345. if (value < table[i].prob3) break;
  346. /* Decrement */
  347. value = value - table[i].prob3;
  348. }
  349. /* Power boost */
  350. p = randint0(100);
  351. /* Try for a "harder" monster once (50%) or twice (10%) */
  352. if (p < 60)
  353. {
  354. /* Save old */
  355. j = i;
  356. /* Pick a monster */
  357. value = randint0(total);
  358. /* Find the monster */
  359. for (i = 0; i < alloc_race_size; i++)
  360. {
  361. /* Found the entry */
  362. if (value < table[i].prob3) break;
  363. /* Decrement */
  364. value = value - table[i].prob3;
  365. }
  366. /* Keep the "best" one */
  367. if (table[i].level < table[j].level) i = j;
  368. }
  369. /* Try for a "harder" monster twice (10%) */
  370. if (p < 10)
  371. {
  372. /* Save old */
  373. j = i;
  374. /* Pick a monster */
  375. value = randint0(total);
  376. /* Find the monster */
  377. for (i = 0; i < alloc_race_size; i++)
  378. {
  379. /* Found the entry */
  380. if (value < table[i].prob3) break;
  381. /* Decrement */
  382. value = value - table[i].prob3;
  383. }
  384. /* Keep the "best" one */
  385. if (table[i].level < table[j].level) i = j;
  386. }
  387. /* Result */
  388. return (table[i].index);
  389. }
  390. /*
  391. * Display visible monsters in a window
  392. */
  393. void display_monlist(void)
  394. {
  395. size_t i, j, k;
  396. int max;
  397. int line = 1, x = 0;
  398. int cur_x;
  399. unsigned total_count = 0, disp_count = 0, type_count = 0, los_count = 0;
  400. byte attr;
  401. char *m_name;
  402. char buf[80];
  403. monster_type *m_ptr;
  404. monster_race *r_ptr;
  405. monster_race *r2_ptr;
  406. monster_vis *list;
  407. u16b *order;
  408. bool in_term = (Term != angband_term[0]);
  409. /* Hallucination is weird */
  410. if (p_ptr->timed[TMD_IMAGE])
  411. {
  412. if (in_term)
  413. clear_from(0);
  414. Term_gotoxy(0, 0);
  415. text_out_to_screen(TERM_ORANGE,
  416. "Your hallucinations are too wild to see things clearly.");
  417. return;
  418. }
  419. /* Clear the term if in a subwindow, set x otherwise */
  420. if (in_term)
  421. {
  422. clear_from(0);
  423. max = Term->hgt - 1;
  424. }
  425. else
  426. {
  427. x = 13;
  428. max = Term->hgt - 2;
  429. }
  430. /* Allocate the primary array */
  431. list = C_ZNEW(z_info->r_max, monster_vis);
  432. /* Scan the list of monsters on the level */
  433. for (i = 1; i < (size_t)mon_max; i++)
  434. {
  435. monster_vis *v;
  436. m_ptr = &mon_list[i];
  437. r_ptr = &r_info[m_ptr->r_idx];
  438. /* Only consider visible monsters */
  439. if (!m_ptr->ml) continue;
  440. /* Take a pointer to this monster visibility entry */
  441. v = &list[m_ptr->r_idx];
  442. /* Note each monster type and save its display attr (color) */
  443. if (!v->count) type_count++;
  444. if (!v->attr) v->attr = m_ptr->attr ? m_ptr->attr : r_ptr->x_attr;
  445. /* Check for LOS
  446. * Hack - we should use (m_ptr->mflag & (MFLAG_VIEW)) here,
  447. * but this does not catch monsters detected by ESP which are
  448. * targetable, so we cheat and use projectable() instead
  449. */
  450. if (projectable(p_ptr->py, p_ptr->px, m_ptr->fy, m_ptr->fx,
  451. PROJECT_NONE))
  452. {
  453. /* Increment the total number of in-LOS monsters */
  454. los_count++;
  455. /* Increment the LOS count for this monster type */
  456. v->los++;
  457. /* Check if asleep and increment accordingly */
  458. if (m_ptr->csleep) v->los_asleep++;
  459. }
  460. /* Not in LOS so increment if asleep */
  461. else if (m_ptr->csleep) v->asleep++;
  462. /* Bump the count for this race, and the total count */
  463. v->count++;
  464. total_count++;
  465. }
  466. /* Note no visible monsters at all */
  467. if (!total_count)
  468. {
  469. /* Clear display and print note */
  470. c_prt(TERM_SLATE, "You see no monsters.", 0, 0);
  471. if (!in_term)
  472. Term_addstr(-1, TERM_WHITE, " (Press any key to continue.)");
  473. /* Free up memory */
  474. FREE(list);
  475. /* Done */
  476. return;
  477. }
  478. /* Allocate the secondary array */
  479. order = C_ZNEW(type_count, u16b);
  480. /* Sort, because we cannot rely on monster.txt being ordered */
  481. /* Populate the ordered array, starting at 1 to ignore @ */
  482. for (i = 1; i < z_info->r_max; i++)
  483. {
  484. /* No monsters of this race are visible */
  485. if (!list[i].count) continue;
  486. /* Get the monster info */
  487. r_ptr = &r_info[i];
  488. /* Fit this monster into the sorted array */
  489. for (j = 0; j < type_count; j++)
  490. {
  491. /* If we get to the end of the list, put this one in */
  492. if (!order[j])
  493. {
  494. order[j] = i;
  495. break;
  496. }
  497. /* Get the monster info for comparison */
  498. r2_ptr = &r_info[order[j]];
  499. /* Monsters are sorted by depth */
  500. /* Monsters of same depth are sorted by power */
  501. if ((r_ptr->level > r2_ptr->level) ||
  502. ((r_ptr->level == r2_ptr->level) &&
  503. (r_ptr->power > r2_ptr->power)))
  504. {
  505. /* Move weaker monsters down the array */
  506. for (k = type_count - 1; k > j; k--)
  507. {
  508. order[k] = order[k - 1];
  509. }
  510. /* Put current monster in the right place */
  511. order[j] = i;
  512. break;
  513. }
  514. }
  515. }
  516. /* Message for monsters in LOS - even if there are none */
  517. if (!los_count) prt(format("You can see no monsters."), 0, 0);
  518. else prt(format("You can see %d monster%s", los_count, (los_count == 1
  519. ? ":" : "s:")), 0, 0);
  520. /* Print out in-LOS monsters in descending order */
  521. for (i = 0; (i < type_count) && (line < max); i++)
  522. {
  523. /* Skip if there are none of these in LOS */
  524. if (!list[order[i]].los) continue;
  525. /* Reset position */
  526. cur_x = x;
  527. /* Note that these have been displayed */
  528. disp_count += list[order[i]].los;
  529. /* Get monster race and name */
  530. r_ptr = &r_info[order[i]];
  531. m_name = r_name + r_ptr->name;
  532. /* Display uniques in a special colour */
  533. if (rf_has(r_ptr->flags, RF_UNIQUE))
  534. attr = TERM_VIOLET;
  535. else if (r_ptr->level > p_ptr->depth)
  536. attr = TERM_RED;
  537. else
  538. attr = TERM_WHITE;
  539. /* Build the monster name */
  540. if (list[order[i]].los == 1)
  541. strnfmt(buf, sizeof(buf), (list[order[i]].los_asleep ==
  542. 1 ? "%s (asleep) " : "%s "), m_name);
  543. else strnfmt(buf, sizeof(buf), (list[order[i]].los_asleep > 0 ?
  544. "%s (x%d, %d asleep) " : "%s (x%d)"), m_name,
  545. list[order[i]].los, list[order[i]].los_asleep);
  546. /* Display the pict */
  547. Term_putch(cur_x++, line, list[order[i]].attr, r_ptr->x_char);
  548. if (use_bigtile) Term_putch(cur_x++, line, 255, -1);
  549. Term_putch(cur_x++, line, TERM_WHITE, ' ');
  550. /* Print and bump line counter */
  551. c_prt(attr, buf, line, cur_x);
  552. line++;
  553. /* Page wrap */
  554. if (!in_term && (line == max) && disp_count != total_count)
  555. {
  556. prt("-- more --", line, x);
  557. anykey();
  558. /* Clear the screen */
  559. for (line = 1; line <= max; line++)
  560. prt("", line, 0);
  561. /* Reprint Message */
  562. prt(format("You can see %d monster%s",
  563. los_count, (los_count > 0 ? (los_count == 1 ?
  564. ":" : "s:") : "s.")), 0, 0);
  565. /* Reset */
  566. line = 1;
  567. }
  568. }
  569. /* Message for monsters outside LOS, if there are any */
  570. if (total_count > los_count)
  571. {
  572. /* Leave a blank line */
  573. line++;
  574. prt(format("You are aware of %d %smonster%s",
  575. (total_count - los_count), (los_count > 0 ? "other " : ""),
  576. ((total_count - los_count) == 1 ? ":" : "s:")), line++, 0);
  577. }
  578. /* Print out non-LOS monsters in descending order */
  579. for (i = 0; (i < type_count) && (line < max); i++)
  580. {
  581. /* Skip if there are none of these out of LOS */
  582. if (list[order[i]].count == list[order[i]].los) continue;
  583. /* Reset position */
  584. cur_x = x;
  585. /* Note that these have been displayed */
  586. disp_count += (list[order[i]].count - list[order[i]].los);
  587. /* Get monster race and name */
  588. r_ptr = &r_info[order[i]];
  589. m_name = r_name + r_ptr->name;
  590. /* Display uniques in a special colour */
  591. if (rf_has(r_ptr->flags, RF_UNIQUE))
  592. attr = TERM_VIOLET;
  593. else if (r_ptr->level > p_ptr->depth)
  594. attr = TERM_RED;
  595. else
  596. attr = TERM_WHITE;
  597. /* Build the monster name */
  598. if ((list[order[i]].count - list[order[i]].los) == 1)
  599. strnfmt(buf, sizeof(buf), (list[order[i]].asleep ==
  600. 1 ? "%s (asleep) " : "%s "), m_name);
  601. else strnfmt(buf, sizeof(buf), (list[order[i]].asleep > 0 ?
  602. "%s (x%d, %d asleep) " : "%s (x%d) "), m_name,
  603. (list[order[i]].count - list[order[i]].los),
  604. list[order[i]].asleep);
  605. /* Display the pict */
  606. Term_putch(cur_x++, line, list[order[i]].attr, r_ptr->x_char);
  607. if (use_bigtile) Term_putch(cur_x++, line, 255, -1);
  608. Term_putch(cur_x++, line, TERM_WHITE, ' ');
  609. /* Print and bump line counter */
  610. c_prt(attr, buf, line, cur_x);
  611. line++;
  612. /* Page wrap */
  613. if (!in_term && (line == max) && disp_count != total_count)
  614. {
  615. prt("-- more --", line, x);
  616. anykey();
  617. /* Clear the screen */
  618. for (line = 1; line <= max; line++)
  619. prt("", line, 0);
  620. /* Reprint Message */
  621. prt(format("You are aware of %d %smonster%s",
  622. (total_count - los_count), (los_count > 0 ?
  623. "other " : ""), ((total_count - los_count) > 0
  624. ? ((total_count - los_count) == 1 ? ":" : "s:")
  625. : "s.")), 0, 0);
  626. /* Reset */
  627. line = 1;
  628. }
  629. }
  630. /* Print "and others" message if we've run out of space */
  631. if (disp_count != total_count)
  632. {
  633. strnfmt(buf, sizeof buf, " ...and %d others.", total_count - disp_count);
  634. c_prt(TERM_WHITE, buf, line, x);
  635. }
  636. /* Otherwise clear a line at the end, for main-term display */
  637. else
  638. {
  639. prt("", line, x);
  640. }
  641. if (!in_term)
  642. Term_addstr(-1, TERM_WHITE, " (Press any key to continue.)");
  643. /* Free the arrays */
  644. FREE(list);
  645. FREE(order);
  646. }
  647. /*
  648. * Build a string describing a monster in some way.
  649. *
  650. * We can correctly describe monsters based on their visibility.
  651. * We can force all monsters to be treated as visible or invisible.
  652. * We can build nominatives, objectives, possessives, or reflexives.
  653. * We can selectively pronominalize hidden, visible, or all monsters.
  654. * We can use definite or indefinite descriptions for hidden monsters.
  655. * We can use definite or indefinite descriptions for visible monsters.
  656. *
  657. * Pronominalization involves the gender whenever possible and allowed,
  658. * so that by cleverly requesting pronominalization / visibility, you
  659. * can get messages like "You hit someone. She screams in agony!".
  660. *
  661. * Reflexives are acquired by requesting Objective plus Possessive.
  662. *
  663. * I am assuming that no monster name is more than 65 characters long,
  664. * so that "char desc[80];" is sufficiently large for any result, even
  665. * when the "offscreen" notation is added.
  666. *
  667. * Note that the "possessive" for certain unique monsters will look
  668. * really silly, as in "Morgoth, King of Darkness's". We should
  669. * perhaps add a flag to "remove" any "descriptives" in the name.
  670. *
  671. * Note that "offscreen" monsters will get a special "(offscreen)"
  672. * notation in their name if they are visible but offscreen. This
  673. * may look silly with possessives, as in "the rat's (offscreen)".
  674. * Perhaps the "offscreen" descriptor should be abbreviated.
  675. *
  676. * Mode Flags:
  677. * 0x01 --> Objective (or Reflexive)
  678. * 0x02 --> Possessive (or Reflexive)
  679. * 0x04 --> Use indefinites for hidden monsters ("something")
  680. * 0x08 --> Use indefinites for visible monsters ("a kobold")
  681. * 0x10 --> Pronominalize hidden monsters
  682. * 0x20 --> Pronominalize visible monsters
  683. * 0x40 --> Assume the monster is hidden
  684. * 0x80 --> Assume the monster is visible
  685. *
  686. * Useful Modes:
  687. * 0x00 --> Full nominative name ("the kobold") or "it"
  688. * 0x04 --> Full nominative name ("the kobold") or "something"
  689. * 0x80 --> Banishment resistance name ("the kobold")
  690. * 0x88 --> Killing name ("a kobold")
  691. * 0x22 --> Possessive, genderized if visable ("his") or "its"
  692. * 0x23 --> Reflexive, genderized if visable ("himself") or "itself"
  693. */
  694. void monster_desc(char *desc, size_t max, const monster_type *m_ptr, int mode)
  695. {
  696. cptr res;
  697. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  698. cptr name = (r_name + r_ptr->name);
  699. bool seen, pron;
  700. /* Can we "see" it (forced, or not hidden + visible) */
  701. seen = ((mode & (0x80)) || (!(mode & (0x40)) && m_ptr->ml));
  702. /* Sexed Pronouns (seen and forced, or unseen and allowed) */
  703. pron = ((seen && (mode & (0x20))) || (!seen && (mode & (0x10))));
  704. /* First, try using pronouns, or describing hidden monsters */
  705. if (!seen || pron)
  706. {
  707. /* an encoding of the monster "sex" */
  708. int kind = 0x00;
  709. /* Extract the gender (if applicable) */
  710. if (rf_has(r_ptr->flags, RF_FEMALE)) kind = 0x20;
  711. else if (rf_has(r_ptr->flags, RF_MALE)) kind = 0x10;
  712. /* Ignore the gender (if desired) */
  713. if (!m_ptr || !pron) kind = 0x00;
  714. /* Assume simple result */
  715. res = "it";
  716. /* Brute force: split on the possibilities */
  717. switch (kind + (mode & 0x07))
  718. {
  719. /* Neuter, or unknown */
  720. case 0x00: res = "it"; break;
  721. case 0x01: res = "it"; break;
  722. case 0x02: res = "its"; break;
  723. case 0x03: res = "itself"; break;
  724. case 0x04: res = "something"; break;
  725. case 0x05: res = "something"; break;
  726. case 0x06: res = "something's"; break;
  727. case 0x07: res = "itself"; break;
  728. /* Male (assume human if vague) */
  729. case 0x10: res = "he"; break;
  730. case 0x11: res = "him"; break;
  731. case 0x12: res = "his"; break;
  732. case 0x13: res = "himself"; break;
  733. case 0x14: res = "someone"; break;
  734. case 0x15: res = "someone"; break;
  735. case 0x16: res = "someone's"; break;
  736. case 0x17: res = "himself"; break;
  737. /* Female (assume human if vague) */
  738. case 0x20: res = "she"; break;
  739. case 0x21: res = "her"; break;
  740. case 0x22: res = "her"; break;
  741. case 0x23: res = "herself"; break;
  742. case 0x24: res = "someone"; break;
  743. case 0x25: res = "someone"; break;
  744. case 0x26: res = "someone's"; break;
  745. case 0x27: res = "herself"; break;
  746. }
  747. /* Copy the result */
  748. my_strcpy(desc, res, max);
  749. }
  750. /* Handle visible monsters, "reflexive" request */
  751. else if ((mode & 0x02) && (mode & 0x01))
  752. {
  753. /* The monster is visible, so use its gender */
  754. if (rf_has(r_ptr->flags, RF_FEMALE)) my_strcpy(desc, "herself", max);
  755. else if (rf_has(r_ptr->flags, RF_MALE)) my_strcpy(desc, "himself", max);
  756. else my_strcpy(desc, "itself", max);
  757. }
  758. /* Handle all other visible monster requests */
  759. else
  760. {
  761. /* It could be a Unique */
  762. if (rf_has(r_ptr->flags, RF_UNIQUE))
  763. {
  764. /* Start with the name (thus nominative and objective) */
  765. my_strcpy(desc, name, max);
  766. }
  767. /* It could be an indefinite monster */
  768. else if (mode & 0x08)
  769. {
  770. /* XXX Check plurality for "some" */
  771. /* Indefinite monsters need an indefinite article */
  772. my_strcpy(desc, is_a_vowel(name[0]) ? "an " : "a ", max);
  773. my_strcat(desc, name, max);
  774. }
  775. /* It could be a normal, definite, monster */
  776. else
  777. {
  778. /* Definite monsters need a definite article */
  779. my_strcpy(desc, "the ", max);
  780. my_strcat(desc, name, max);
  781. }
  782. /* Handle the Possessive as a special afterthought */
  783. if (mode & 0x02)
  784. {
  785. /* XXX Check for trailing "s" */
  786. /* Simply append "apostrophe" and "s" */
  787. my_strcat(desc, "'s", max);
  788. }
  789. /* Mention "offscreen" monsters XXX XXX */
  790. if (!panel_contains(m_ptr->fy, m_ptr->fx))
  791. {
  792. /* Append special notation */
  793. my_strcat(desc, " (offscreen)", max);
  794. }
  795. }
  796. }
  797. /*
  798. * Learn about a monster (by "probing" it)
  799. */
  800. void lore_do_probe(int m_idx)
  801. {
  802. monster_type *m_ptr = &mon_list[m_idx];
  803. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  804. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  805. unsigned i;
  806. /* Know various things */
  807. rsf_setall(l_ptr->flags);
  808. rsf_copy(l_ptr->spell_flags, r_ptr->spell_flags);
  809. for (i = 0; i < MONSTER_BLOW_MAX; i++)
  810. l_ptr->blows[i] = MAX_UCHAR;
  811. /* Update monster recall window */
  812. if (p_ptr->monster_race_idx == m_ptr->r_idx)
  813. p_ptr->redraw |= (PR_MONSTER);
  814. }
  815. /*
  816. * Take note that the given monster just dropped some treasure
  817. *
  818. * Note that learning the "GOOD"/"GREAT" flags gives information
  819. * about the treasure (even when the monster is killed for the first
  820. * time, such as uniques, and the treasure has not been examined yet).
  821. *
  822. * This "indirect" method is used to prevent the player from learning
  823. * exactly how much treasure a monster can drop from observing only
  824. * a single example of a drop. This method actually observes how much
  825. * gold and items are dropped, and remembers that information to be
  826. * described later by the monster recall code.
  827. */
  828. void lore_treasure(int m_idx, int num_item, int num_gold)
  829. {
  830. monster_type *m_ptr = &mon_list[m_idx];
  831. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  832. /* Note the number of things dropped */
  833. if (num_item > l_ptr->drop_item) l_ptr->drop_item = num_item;
  834. if (num_gold > l_ptr->drop_gold) l_ptr->drop_gold = num_gold;
  835. /* Learn about drop quality */
  836. rf_on(l_ptr->flags, RF_DROP_GOOD);
  837. rf_on(l_ptr->flags, RF_DROP_GREAT);
  838. /* Update monster recall window */
  839. if (p_ptr->monster_race_idx == m_ptr->r_idx)
  840. {
  841. /* Window stuff */
  842. p_ptr->redraw |= (PR_MONSTER);
  843. }
  844. }
  845. /*
  846. * This function updates the monster record of the given monster
  847. *
  848. * This involves extracting the distance to the player (if requested),
  849. * and then checking for visibility (natural, infravision, see-invis,
  850. * telepathy), updating the monster visibility flag, redrawing (or
  851. * erasing) the monster when its visibility changes, and taking note
  852. * of any interesting monster flags (cold-blooded, invisible, etc).
  853. *
  854. * Note the new "mflag" field which encodes several monster state flags,
  855. * including "view" for when the monster is currently in line of sight,
  856. * and "mark" for when the monster is currently visible via detection.
  857. *
  858. * The only monster fields that are changed here are "cdis" (the
  859. * distance from the player), "ml" (visible to the player), and
  860. * "mflag" (to maintain the "MFLAG_VIEW" flag).
  861. *
  862. * Note the special "update_monsters()" function which can be used to
  863. * call this function once for every monster.
  864. *
  865. * Note the "full" flag which requests that the "cdis" field be updated,
  866. * this is only needed when the monster (or the player) has moved.
  867. *
  868. * Every time a monster moves, we must call this function for that
  869. * monster, and update the distance, and the visibility. Every time
  870. * the player moves, we must call this function for every monster, and
  871. * update the distance, and the visibility. Whenever the player "state"
  872. * changes in certain ways ("blindness", "infravision", "telepathy",
  873. * and "see invisible"), we must call this function for every monster,
  874. * and update the visibility.
  875. *
  876. * Routines that change the "illumination" of a grid must also call this
  877. * function for any monster in that grid, since the "visibility" of some
  878. * monsters may be based on the illumination of their grid.
  879. *
  880. * Note that this function is called once per monster every time the
  881. * player moves. When the player is running, this function is one
  882. * of the primary bottlenecks, along with "update_view()" and the
  883. * "process_monsters()" code, so efficiency is important.
  884. *
  885. * Note the optimized "inline" version of the "distance()" function.
  886. *
  887. * A monster is "visible" to the player if (1) it has been detected
  888. * by the player, (2) it is close to the player and the player has
  889. * telepathy, or (3) it is close to the player, and in line of sight
  890. * of the player, and it is "illuminated" by some combination of
  891. * infravision, torch light, or permanent light (invisible monsters
  892. * are only affected by "light" if the player can see invisible).
  893. *
  894. * Monsters which are not on the current panel may be "visible" to
  895. * the player, and their descriptions will include an "offscreen"
  896. * reference. Currently, offscreen monsters cannot be targeted
  897. * or viewed directly, but old targets will remain set. XXX XXX
  898. *
  899. * The player can choose to be disturbed by several things, including
  900. * "OPT(disturb_move)" (monster which is viewable moves in some way), and
  901. * "OPT(disturb_near)" (monster which is "easily" viewable moves in some
  902. * way). Note that "moves" includes "appears" and "disappears".
  903. */
  904. void update_mon(int m_idx, bool full)
  905. {
  906. monster_type *m_ptr = &mon_list[m_idx];
  907. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  908. monster_lore *l_ptr = &l_list[m_ptr->r_idx];
  909. int d;
  910. /* Current location */
  911. int fy = m_ptr->fy;
  912. int fx = m_ptr->fx;
  913. /* Seen at all */
  914. bool flag = FALSE;
  915. /* Seen by vision */
  916. bool easy = FALSE;
  917. /* Compute distance */
  918. if (full)
  919. {
  920. int py = p_ptr->py;
  921. int px = p_ptr->px;
  922. /* Distance components */
  923. int dy = (py > fy) ? (py - fy) : (fy - py);
  924. int dx = (px > fx) ? (px - fx) : (fx - px);
  925. /* Approximate distance */
  926. d = (dy > dx) ? (dy + (dx>>1)) : (dx + (dy>>1));
  927. /* Restrict distance */
  928. if (d > 255) d = 255;
  929. /* Save the distance */
  930. m_ptr->cdis = d;
  931. }
  932. /* Extract distance */
  933. else
  934. {
  935. /* Extract the distance */
  936. d = m_ptr->cdis;
  937. }
  938. /* Detected */
  939. if (m_ptr->mflag & (MFLAG_MARK)) flag = TRUE;
  940. /* Nearby */
  941. if (d <= MAX_SIGHT)
  942. {
  943. /* Basic telepathy */
  944. if (p_ptr->state.telepathy)
  945. {
  946. /* Empty mind, no telepathy */
  947. if (rf_has(r_ptr->flags, RF_EMPTY_MIND))
  948. {
  949. /* Nothing! */
  950. }
  951. /* Weird mind, occasional telepathy */
  952. else if (rf_has(r_ptr->flags, RF_WEIRD_MIND))
  953. {
  954. /* One in ten individuals are detectable */
  955. if ((m_idx % 10) == 5)
  956. {
  957. /* Detectable */
  958. flag = TRUE;
  959. /* Check for LOS so that MFLAG_VIEW is set later */
  960. if (player_has_los_bold(fy, fx)) easy = TRUE;
  961. }
  962. }
  963. /* Normal mind, allow telepathy */
  964. else
  965. {
  966. /* Detectable */
  967. flag = TRUE;
  968. /* Check for LOS to that MFLAG_VIEW is set later */
  969. if (player_has_los_bold(fy, fx)) easy = TRUE;
  970. }
  971. }
  972. /* Normal line of sight, and not blind */
  973. if (player_has_los_bold(fy, fx) && !p_ptr->timed[TMD_BLIND])
  974. {
  975. /* Use "infravision" */
  976. if (d <= p_ptr->state.see_infra)
  977. {
  978. /* Learn about warm/cold blood */
  979. rf_on(l_ptr->flags, RF_COLD_BLOOD);
  980. /* Handle "warm blooded" monsters */
  981. if (!rf_has(r_ptr->flags, RF_COLD_BLOOD))
  982. {
  983. /* Easy to see */
  984. easy = flag = TRUE;
  985. }
  986. }
  987. /* See if the monster is emitting lite */
  988. /*if (rf_has(r_ptr->flags, RF_HAS_LITE)) easy = flag = TRUE;*/
  989. /* Use "illumination" */
  990. if (player_can_see_bold(fy, fx))
  991. {
  992. /* Learn it emits light */
  993. rf_on(l_ptr->flags, RF_HAS_LITE);
  994. /* Learn about invisibility */
  995. rf_on(l_ptr->flags, RF_INVISIBLE);
  996. /* Handle "invisible" monsters */
  997. if (rf_has(r_ptr->flags, RF_INVISIBLE))
  998. {
  999. /* See invisible */
  1000. if (p_ptr->state.see_inv)
  1001. {
  1002. /* Easy to see */
  1003. easy = flag = TRUE;
  1004. }
  1005. }
  1006. /* Handle "normal" monsters */
  1007. else
  1008. {
  1009. /* Easy to see */
  1010. easy = flag = TRUE;
  1011. }
  1012. }
  1013. }
  1014. }
  1015. /* The monster is now visible */
  1016. if (flag)
  1017. {
  1018. /* Learn about the monster's mind */
  1019. if (p_ptr->state.telepathy)
  1020. {
  1021. flags_set(l_ptr->flags, RF_SIZE, RF_EMPTY_MIND, RF_WEIRD_MIND, RF_SMART, RF_STUPID, FLAG_END);
  1022. }
  1023. /* It was previously unseen */
  1024. if (!m_ptr->ml)
  1025. {
  1026. /* Mark as visible */
  1027. m_ptr->ml = TRUE;
  1028. /* Draw the monster */
  1029. light_spot(fy, fx);
  1030. /* Update health bar as needed */
  1031. if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
  1032. /* Hack -- Count "fresh" sightings */
  1033. if (l_ptr->sights < MAX_SHORT) l_ptr->sights++;
  1034. /* Disturb on appearance */
  1035. if (OPT(disturb_move)) disturb(1, 0);
  1036. /* Window stuff */
  1037. p_ptr->redraw |= PR_MONLIST;
  1038. }
  1039. }
  1040. /* The monster is not visible */
  1041. else
  1042. {
  1043. /* It was previously seen */
  1044. if (m_ptr->ml)
  1045. {
  1046. /* Mark as not visible */
  1047. m_ptr->ml = FALSE;
  1048. /* Erase the monster */
  1049. light_spot(fy, fx);
  1050. /* Update health bar as needed */
  1051. if (p_ptr->health_who == m_idx) p_ptr->redraw |= (PR_HEALTH);
  1052. /* Disturb on disappearance */
  1053. if (OPT(disturb_move)) disturb(1, 0);
  1054. /* Window stuff */
  1055. p_ptr->redraw |= PR_MONLIST;
  1056. }
  1057. }
  1058. /* The monster is now easily visible */
  1059. if (easy)
  1060. {
  1061. /* Change */
  1062. if (!(m_ptr->mflag & (MFLAG_VIEW)))
  1063. {
  1064. /* Mark as easily visible */
  1065. m_ptr->mflag |= (MFLAG_VIEW);
  1066. /* Disturb on appearance */
  1067. if (OPT(disturb_near)) disturb(1, 0);
  1068. /* Re-draw monster window */
  1069. p_ptr->redraw |= PR_MONLIST;
  1070. }
  1071. }
  1072. /* The monster is not easily visible */
  1073. else
  1074. {
  1075. /* Change */
  1076. if (m_ptr->mflag & (MFLAG_VIEW))
  1077. {
  1078. /* Mark as not easily visible */
  1079. m_ptr->mflag &= ~(MFLAG_VIEW);
  1080. /* Disturb on disappearance */
  1081. if (OPT(disturb_near)) disturb(1, 0);
  1082. /* Re-draw monster list window */
  1083. p_ptr->redraw |= PR_MONLIST;
  1084. }
  1085. }
  1086. }
  1087. /*
  1088. * This function simply updates all the (non-dead) monsters (see above).
  1089. */
  1090. void update_monsters(bool full)
  1091. {
  1092. int i;
  1093. /* Update each (live) monster */
  1094. for (i = 1; i < mon_max; i++)
  1095. {
  1096. monster_type *m_ptr = &mon_list[i];
  1097. /* Skip dead monsters */
  1098. if (!m_ptr->r_idx) continue;
  1099. /* Update the monster */
  1100. update_mon(i, full);
  1101. }
  1102. }
  1103. /*
  1104. * Make a monster carry an object
  1105. */
  1106. s16b monster_carry(int m_idx, object_type *j_ptr)
  1107. {
  1108. s16b o_idx;
  1109. s16b this_o_idx, next_o_idx = 0;
  1110. monster_type *m_ptr = &mon_list[m_idx];
  1111. /* Scan objects already being held for combination */
  1112. for (this_o_idx = m_ptr->hold_o_idx; this_o_idx; this_o_idx = next_o_idx)
  1113. {
  1114. object_type *o_ptr;
  1115. /* Get the object */
  1116. o_ptr = &o_list[this_o_idx];
  1117. /* Get the next object */
  1118. next_o_idx = o_ptr->next_o_idx;
  1119. /* Check for combination */
  1120. if (object_similar(o_ptr, j_ptr))
  1121. {
  1122. /* Combine the items */
  1123. object_absorb(o_ptr, j_ptr);
  1124. /* Result */
  1125. return (this_o_idx);
  1126. }
  1127. }
  1128. /* Make an object */
  1129. o_idx = o_pop();
  1130. /* Success */
  1131. if (o_idx)
  1132. {
  1133. object_type *o_ptr;
  1134. /* Get new object */
  1135. o_ptr = &o_list[o_idx];
  1136. /* Copy object */
  1137. object_copy(o_ptr, j_ptr);
  1138. /* Forget mark */
  1139. o_ptr->marked = FALSE;
  1140. /* Forget location */
  1141. o_ptr->iy = o_ptr->ix = 0;
  1142. /* Link the object to the monster */
  1143. o_ptr->held_m_idx = m_idx;
  1144. /* Link the object to the pile */
  1145. o_ptr->next_o_idx = m_ptr->hold_o_idx;
  1146. /* Link the monster to the object */
  1147. m_ptr->hold_o_idx = o_idx;
  1148. }
  1149. /* Result */
  1150. return (o_idx);
  1151. }
  1152. /*
  1153. * Swap the players/monsters (if any) at two locations XXX XXX XXX
  1154. */
  1155. void monster_swap(int y1, int x1, int y2, int x2)
  1156. {
  1157. int m1, m2;
  1158. monster_type *m_ptr;
  1159. monster_race *r_ptr;
  1160. /* Monsters */
  1161. m1 = cave_m_idx[y1][x1];
  1162. m2 = cave_m_idx[y2][x2];
  1163. /* Update grids */
  1164. cave_m_idx[y1][x1] = m2;
  1165. cave_m_idx[y2][x2] = m1;
  1166. /* Monster 1 */
  1167. if (m1 > 0)
  1168. {
  1169. m_ptr = &mon_list[m1];
  1170. /* Move monster */
  1171. m_ptr->fy = y2;
  1172. m_ptr->fx = x2;
  1173. /* Update monster */
  1174. update_mon(m1, TRUE);
  1175. /* Radiate light? */
  1176. r_ptr = &r_info[m_ptr->r_idx];
  1177. if (rf_has(r_ptr->flags, RF_HAS_LITE)) p_ptr->redraw |= PU_UPDATE_VIEW;
  1178. /* Redraw monster list */
  1179. p_ptr->redraw |= (PR_MONLIST);
  1180. }
  1181. /* Player 1 */
  1182. else if (m1 < 0)
  1183. {
  1184. /* Move player */
  1185. p_ptr->py = y2;
  1186. p_ptr->px = x2;
  1187. /* Update the trap detection status */
  1188. p_ptr->redraw |= (PR_DTRAP);
  1189. /* Update the panel */
  1190. p_ptr->update |= (PU_PANEL);
  1191. /* Update the visuals (and monster distances) */
  1192. p_ptr->update |= (PU_UPDATE_VIEW | PU_DISTANCE);
  1193. /* Update the flow */
  1194. p_ptr->update |= (PU_UPDATE_FLOW);
  1195. /* Redraw monster list */
  1196. p_ptr->redraw |= (PR_MONLIST);
  1197. }
  1198. /* Monster 2 */
  1199. if (m2 > 0)
  1200. {
  1201. m_ptr = &mon_list[m2];
  1202. /* Move monster */
  1203. m_ptr->fy = y1;
  1204. m_ptr->fx = x1;
  1205. /* Update monster */
  1206. update_mon(m2, TRUE);
  1207. /* Radiate light? */
  1208. r_ptr = &r_info[m_ptr->r_idx];
  1209. if (rf_has(r_ptr->flags, RF_HAS_LITE)) p_ptr->update |= PU_UPDATE_VIEW;
  1210. /* Redraw monster list */
  1211. p_ptr->redraw |= (PR_MONLIST);
  1212. }
  1213. /* Player 2 */
  1214. else if (m2 < 0)
  1215. {
  1216. /* Move player */
  1217. p_ptr->py = y1;
  1218. p_ptr->px = x1;
  1219. /* Update the trap detection status */
  1220. p_ptr->redraw |= (PR_DTRAP);
  1221. /* Update the panel */
  1222. p_ptr->update |= (PU_PANEL);
  1223. /* Update the visuals (and monster distances) */
  1224. p_ptr->update |= (PU_UPDATE_VIEW | PU_DISTANCE);
  1225. /* Update the flow */
  1226. p_ptr->update |= (PU_UPDATE_FLOW);
  1227. /* Redraw monster list */
  1228. p_ptr->redraw |= (PR_MONLIST);
  1229. }
  1230. /* Redraw */
  1231. light_spot(y1, x1);
  1232. light_spot(y2, x2);
  1233. }
  1234. /*
  1235. * Place the player in the dungeon XXX XXX
  1236. */
  1237. s16b player_place(int y, int x)
  1238. {
  1239. /* Paranoia XXX XXX */
  1240. if (cave_m_idx[y][x] != 0) return (0);
  1241. /* Save player location */
  1242. p_ptr->py = y;
  1243. p_ptr->px = x;
  1244. /* Mark cave grid */
  1245. cave_m_idx[y][x] = -1;
  1246. /* Success */
  1247. return (-1);
  1248. }
  1249. /*
  1250. * Place a copy of a monster in the dungeon XXX XXX
  1251. */
  1252. s16b monster_place(int y, int x, monster_type *n_ptr)
  1253. {
  1254. s16b m_idx;
  1255. monster_type *m_ptr;
  1256. monster_race *r_ptr;
  1257. /* Paranoia XXX XXX */
  1258. if (cave_m_idx[y][x] != 0) return (0);
  1259. /* Get a new record */
  1260. m_idx = mon_pop();
  1261. /* Oops */
  1262. if (m_idx)
  1263. {
  1264. /* Make a new monster */
  1265. cave_m_idx[y][x] = m_idx;
  1266. /* Get the new monster */
  1267. m_ptr = &mon_list[m_idx];
  1268. /* Copy the monster XXX */
  1269. COPY(m_ptr, n_ptr, monster_type);
  1270. /* Location */
  1271. m_ptr->fy = y;
  1272. m_ptr->fx = x;
  1273. /* Update the monster */
  1274. update_mon(m_idx, TRUE);
  1275. /* Get the new race */
  1276. r_ptr = &r_info[m_ptr->r_idx];
  1277. /* Hack -- Notice new multi-hued monsters */
  1278. if (rf_has(r_ptr->flags, RF_ATTR_MULTI)) shimmer_monsters = TRUE;
  1279. /* Hack -- Count the number of "reproducers" */
  1280. if (rf_has(r_ptr->flags, RF_MULTIPLY)) num_repro++;
  1281. /* Count racial occurances */
  1282. r_ptr->cur_num++;
  1283. }
  1284. /* Result */
  1285. return (m_idx);
  1286. }
  1287. /*
  1288. * Attempt to place a monster of the given race at the given location.
  1289. *
  1290. * To give the player a sporting chance, any monster that appears in
  1291. * line-of-sight and is extremely dangerous can be marked as
  1292. * "FORCE_SLEEP", which will cause them to be placed with low energy,
  1293. * which often (but not always) lets the player move before they do.
  1294. *
  1295. * This routine refuses to place out-of-depth "FORCE_DEPTH" monsters.
  1296. *
  1297. * XXX XXX XXX Use special "here" and "dead" flags for unique monsters,
  1298. * remove old "cur_num" and "max_num" fields.
  1299. *
  1300. * XXX XXX XXX Actually, do something similar for artifacts, to simplify
  1301. * the "preserve" mode, and to make the "what artifacts" flag more useful.
  1302. *
  1303. * This is the only function which may place a monster in the dungeon,
  1304. * except for the savefile loading code.
  1305. */
  1306. static bool place_monster_one(int y, int x, int r_idx, bool slp)
  1307. {
  1308. int i;
  1309. monster_race *r_ptr;
  1310. monster_type *n_ptr;
  1311. monster_type monster_type_body;
  1312. cptr name;
  1313. /* Paranoia */
  1314. if (!in_bounds(y, x)) return (FALSE);
  1315. /* Require empty space */
  1316. if (!cave_empty_bold(y, x)) return (FALSE);
  1317. /* Hack -- no creation on glyph of warding */
  1318. if (cave_feat[y][x] == FEAT_GLYPH) return (FALSE);
  1319. /* Paranoia */
  1320. if (!r_idx) return (FALSE);
  1321. /* Race */
  1322. r_ptr = &r_info[r_idx];
  1323. /* Paranoia */
  1324. if (!r_ptr->name) return (FALSE);
  1325. /* Name */
  1326. name = (r_name + r_ptr->name);
  1327. /* Hack -- "unique" monsters must be "unique" */
  1328. if (rf_has(r_ptr->flags, RF_UNIQUE) && r_ptr->cur_num >= r_ptr->max_num)
  1329. {
  1330. /* Cannot create */
  1331. return (FALSE);
  1332. }
  1333. /* Depth monsters may NOT be created out of depth */
  1334. if (rf_has(r_ptr->flags, RF_FORCE_DEPTH) && p_ptr->depth < r_ptr->level)
  1335. {
  1336. /* Cannot create */
  1337. return (FALSE);
  1338. }
  1339. /* Powerful monster */
  1340. if (r_ptr->level > p_ptr->depth)
  1341. {
  1342. /* Unique monsters */
  1343. if (rf_has(r_ptr->flags, RF_UNIQUE))
  1344. {
  1345. /* Message for cheaters */
  1346. if (OPT(cheat_hear)) msg_format("Deep Unique (%s).", name);
  1347. /* Boost rating by twice delta-depth */
  1348. rating += (r_ptr->level - p_ptr->depth) * 2;
  1349. }
  1350. /* Normal monsters */
  1351. else
  1352. {
  1353. /* Message for cheaters */
  1354. if (OPT(cheat_hear)) msg_format("Deep Monster (%s).", name);
  1355. /* Boost rating by delta-depth */
  1356. rating += (r_ptr->level - p_ptr->depth);
  1357. }
  1358. }
  1359. /* Note the monster */
  1360. else if (rf_has(r_ptr->flags, RF_UNIQUE))
  1361. {
  1362. /* Unique monsters induce message */
  1363. if (OPT(cheat_hear)) msg_format("Unique (%s).", name);
  1364. }
  1365. /* Get local monster */
  1366. n_ptr = &monster_type_body;
  1367. /* Clean out the monster */
  1368. (void)WIPE(n_ptr, monster_type);
  1369. /* Save the race */
  1370. n_ptr->r_idx = r_idx;
  1371. /* Enforce sleeping if needed */
  1372. if (slp && r_ptr->sleep)
  1373. {
  1374. int val = r_ptr->sleep;
  1375. n_ptr->csleep = ((val * 2) + randint1(val * 10));
  1376. }
  1377. /* Uniques get a fixed amount of HP */
  1378. if (rf_has(r_ptr->flags, RF_UNIQUE))
  1379. {
  1380. n_ptr->maxhp = r_ptr->avg_hp;
  1381. }
  1382. else
  1383. {
  1384. int std_dev = (((r_ptr->avg_hp * 10) / 8) + 5) / 10;
  1385. if (r_ptr->avg_hp > 1) std_dev++;
  1386. n_ptr->maxhp = Rand_normal(r_ptr->avg_hp, std_dev);
  1387. n_ptr->maxhp = MAX(n_ptr->maxhp, 1);
  1388. }
  1389. /* And start out fully healthy */
  1390. n_ptr->hp = n_ptr->maxhp;
  1391. /* Extract the monster base speed */
  1392. n_ptr->mspeed = r_ptr->speed;
  1393. /* Hack -- small racial variety */
  1394. if (!rf_has(r_ptr->flags, RF_UNIQUE))
  1395. {
  1396. /* Allow some small variation per monster */
  1397. i = extract_energy[r_ptr->speed] / 10;
  1398. if (i) n_ptr->mspeed += rand_spread(0, i);
  1399. }
  1400. /* Give a random starting energy */
  1401. n_ptr->energy = (byte)randint0(50);
  1402. /* Force monster to wait for player */
  1403. if (rf_has(r_ptr->flags, RF_FORCE_SLEEP))
  1404. {
  1405. /* Monster is still being nice */
  1406. n_ptr->mflag |= (MFLAG_NICE);
  1407. /* Optimize -- Repair flags */
  1408. repair_mflag_nice = TRUE;
  1409. }
  1410. /* Radiate light? */
  1411. if (rf_has(r_ptr->flags, RF_HAS_LITE)) p_ptr->update |= PU_UPDATE_VIEW;
  1412. /* Place the monster in the dungeon */
  1413. if (!monster_place(y, x, n_ptr)) return (FALSE);
  1414. /* Success */
  1415. return (TRUE);
  1416. }
  1417. /*
  1418. * Maximum size of a group of monsters
  1419. */
  1420. #define GROUP_MAX 32
  1421. /*
  1422. * Attempt to place a "group" of monsters around the given location
  1423. */
  1424. static bool place_monster_group(int y, int x, int r_idx, bool slp)
  1425. {
  1426. monster_race *r_ptr = &r_info[r_idx];
  1427. int old, n, i;
  1428. int total, extra = 0;
  1429. int hack_n;
  1430. byte hack_y[GROUP_MAX];
  1431. byte hack_x[GROUP_MAX];
  1432. /* Pick a group size */
  1433. total = randint1(13);
  1434. /* Hard monsters, small groups */
  1435. if (r_ptr->level > p_ptr->depth)
  1436. {
  1437. extra = r_ptr->level - p_ptr->depth;
  1438. extra = 0 - randint1(extra);
  1439. }
  1440. /* Easy monsters, large groups */
  1441. else if (r_ptr->level < p_ptr->depth)
  1442. {
  1443. extra = p_ptr->depth - r_ptr->level;
  1444. extra = randint1(extra);
  1445. }
  1446. /* Hack -- limit group reduction */
  1447. if (extra > 12) extra = 12;
  1448. /* Modify the group size */
  1449. total += extra;
  1450. /* Minimum size */
  1451. if (total < 1) total = 1;
  1452. /* Maximum size */
  1453. if (total > GROUP_MAX) total = GROUP_MAX;
  1454. /* Save the rating */
  1455. old = rating;
  1456. /* Start on the monster */
  1457. hack_n = 1;
  1458. hack_x[0] = x;
  1459. hack_y[0] = y;
  1460. /* Puddle monsters, breadth first, up to total */
  1461. for (n = 0; (n < hack_n) && (hack_n < total); n++)
  1462. {
  1463. /* Grab the location */
  1464. int hx = hack_x[n];
  1465. int hy = hack_y[n];
  1466. /* Check each direction, up to total */
  1467. for (i = 0; (i < 8) && (hack_n < total); i++)
  1468. {
  1469. int mx = hx + ddx_ddd[i];
  1470. int my = hy + ddy_ddd[i];
  1471. /* Walls and Monsters block flow */
  1472. if (!cave_empty_bold(my, mx)) continue;
  1473. /* Attempt to place another monster */
  1474. if (place_monster_one(my, mx, r_idx, slp))
  1475. {
  1476. /* Add it to the "hack" set */
  1477. hack_y[hack_n] = my;
  1478. hack_x[hack_n] = mx;
  1479. hack_n++;
  1480. }
  1481. }
  1482. }
  1483. /* Hack -- restore the rating */
  1484. rating = old;
  1485. /* Success */
  1486. return (TRUE);
  1487. }
  1488. /*
  1489. * Hack -- help pick an escort type
  1490. */
  1491. static int place_monster_idx = 0;
  1492. /*
  1493. * Hack -- help pick an escort type
  1494. */
  1495. static bool place_monster_okay(int r_idx)
  1496. {
  1497. monster_race *r_ptr = &r_info[place_monster_idx];
  1498. monster_race *z_ptr = &r_info[r_idx];
  1499. /* Require similar "race" */
  1500. if (z_ptr->d_char != r_ptr->d_char) return (FALSE);
  1501. /* Skip more advanced monsters */
  1502. if (z_ptr->level > r_ptr->level) return (FALSE);
  1503. /* Skip unique monsters */
  1504. if (rf_has(z_ptr->flags, RF_UNIQUE)) return (FALSE);
  1505. /* Paranoia -- Skip identical monsters */
  1506. if (place_monster_idx == r_idx) return (FALSE);
  1507. /* Okay */
  1508. return (TRUE);
  1509. }
  1510. /*
  1511. * Attempt to place a monster of the given race at the given location
  1512. *
  1513. * Note that certain monsters are now marked as requiring "friends".
  1514. * These monsters, if successfully placed, and if the "grp" parameter
  1515. * is TRUE, will be surrounded by a "group" of identical monsters.
  1516. *
  1517. * Note that certain monsters are now marked as requiring an "escort",
  1518. * which is a collection of monsters with similar "race" but lower level.
  1519. *
  1520. * Some monsters induce a fake "group" flag on their escorts.
  1521. *
  1522. * Note the "bizarre" use of non-recursion to prevent annoying output
  1523. * when running a code profiler.
  1524. *
  1525. * Note the use of the new "monster allocation table" code to restrict
  1526. * the "get_mon_num()" function to "legal" escort types.
  1527. */
  1528. bool place_monster_aux(int y, int x, int r_idx, bool slp, bool grp)
  1529. {
  1530. int i;
  1531. monster_race *r_ptr = &r_info[r_idx];
  1532. /* Place one monster, or fail */
  1533. if (!place_monster_one(y, x, r_idx, slp)) return (FALSE);
  1534. /* Require the "group" flag */
  1535. if (!grp) return (TRUE);
  1536. /* Friends for certain monsters */
  1537. if (rf_has(r_ptr->flags, RF_FRIENDS))
  1538. {
  1539. /* Attempt to place a group */
  1540. (void)place_monster_group(y, x, r_idx, slp);
  1541. }
  1542. /* Escorts for certain monsters */
  1543. if (rf_has(r_ptr->flags, RF_ESCORT))
  1544. {
  1545. /* Try to place several "escorts" */
  1546. for (i = 0; i < 50; i++)
  1547. {
  1548. int nx, ny, z, d = 3;
  1549. /* Pick a location */
  1550. scatter(&ny, &nx, y, x, d, 0);
  1551. /* Require empty grids */
  1552. if (!cave_empty_bold(ny, nx)) continue;
  1553. /* Set the escort index */
  1554. place_monster_idx = r_idx;
  1555. /* Set the escort hook */
  1556. get_mon_num_hook = place_monster_okay;
  1557. /* Prepare allocation table */
  1558. get_mon_num_prep();
  1559. /* Pick a random race */
  1560. z = get_mon_num(r_ptr->level);
  1561. /* Remove restriction */
  1562. get_mon_num_hook = NULL;
  1563. /* Prepare allocation table */
  1564. get_mon_num_prep();
  1565. /* Handle failure */
  1566. if (!z) break;
  1567. /* Place a single escort */
  1568. (void)place_monster_one(ny, nx, z, slp);
  1569. /* Place a "group" of escorts if needed */
  1570. if (rf_has(r_info[z].flags, RF_FRIENDS) ||
  1571. rf_has(r_ptr->flags, RF_ESCORTS))
  1572. {
  1573. /* Place a group of monsters */
  1574. (void)place_monster_group(ny, nx, z, slp);
  1575. }
  1576. }
  1577. }
  1578. /* Success */
  1579. return (TRUE);
  1580. }
  1581. /*
  1582. * Hack -- attempt to place a monster at the given location
  1583. *
  1584. * Attempt to find a monster appropriate to the given depth
  1585. */
  1586. bool place_monster(int y, int x, int depth, bool slp, bool grp)
  1587. {
  1588. int r_idx;
  1589. /* Pick a monster */
  1590. r_idx = get_mon_num(depth);
  1591. /* Handle failure */
  1592. if (!r_idx) return (FALSE);
  1593. /* Attempt to place the monster */
  1594. if (place_monster_aux(y, x, r_idx, slp, grp)) return (TRUE);
  1595. /* Oops */
  1596. return (FALSE);
  1597. }
  1598. /*
  1599. * XXX XXX XXX Player Ghosts are such a hack, they have been completely
  1600. * removed.
  1601. *
  1602. * An idea for reintroducing them is to create a small number of
  1603. * "unique" monsters which will serve as the "player ghosts".
  1604. * Each will have a place holder for the "name" of a deceased player,
  1605. * which will be extracted from a "bone" file, or replaced with a
  1606. * "default" name if a real name is not available. Each ghost will
  1607. * appear exactly once and will not induce a special feeling.
  1608. *
  1609. * Possible methods:
  1610. * (s) 1 Skeleton
  1611. * (z) 1 Zombie …

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