PageRenderTime 96ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/src/dungeon.c

https://bitbucket.org/ekolis/jackband
C | 1951 lines | 984 code | 452 blank | 515 comment | 291 complexity | 8655a0b6604f4941f5bb2cc30197e9df MD5 | raw file
  1. /*
  2. * File: dungeon.c
  3. * Purpose: The game core bits, shared across platforms.
  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 "cmds.h"
  21. #include "game-event.h"
  22. /*
  23. * Change dungeon level - e.g. by going up stairs or with WoR.
  24. */
  25. void dungeon_change_level(int dlev)
  26. {
  27. /* New depth */
  28. p_ptr->depth = dlev;
  29. /* If we're returning to town, update the store contents
  30. according to how long we've been away */
  31. if (!dlev && daycount)
  32. {
  33. if (OPT(cheat_xtra)) msg_print("Updating Shops...");
  34. while (daycount--)
  35. {
  36. int n;
  37. /* Maintain each shop (except home) */
  38. for (n = 0; n < MAX_STORES; n++)
  39. {
  40. /* Skip the home */
  41. if (n == STORE_HOME) continue;
  42. /* Maintain */
  43. store_maint(n);
  44. }
  45. /* Sometimes, shuffle the shop-keepers */
  46. if (one_in_(STORE_SHUFFLE))
  47. {
  48. /* Message */
  49. if (OPT(cheat_xtra)) msg_print("Shuffling a Shopkeeper...");
  50. /* Pick a random shop (except home) */
  51. while (1)
  52. {
  53. n = randint0(MAX_STORES);
  54. if (n != STORE_HOME) break;
  55. }
  56. /* Shuffle it */
  57. store_shuffle(n);
  58. }
  59. }
  60. daycount = 0;
  61. if (OPT(cheat_xtra)) msg_print("Done.");
  62. }
  63. /* Leaving */
  64. p_ptr->leaving = TRUE;
  65. /* Save the game when we arrive on the new level. */
  66. p_ptr->autosave = TRUE;
  67. }
  68. /*
  69. * Regenerate hit points
  70. */
  71. static void regenhp(int percent)
  72. {
  73. s32b new_chp, new_chp_frac;
  74. int old_chp;
  75. /* Save the old hitpoints */
  76. old_chp = p_ptr->chp;
  77. /* Extract the new hitpoints */
  78. new_chp = ((long)p_get_mhp()) * percent + PY_REGEN_HPBASE;
  79. p_ptr->chp += (s16b)(new_chp >> 16); /* div 65536 */
  80. /* check for overflow */
  81. if ((p_ptr->chp < 0) && (old_chp > 0)) p_ptr->chp = MAX_SHORT;
  82. new_chp_frac = (new_chp & 0xFFFF) + p_ptr->chp_frac; /* mod 65536 */
  83. if (new_chp_frac >= 0x10000L)
  84. {
  85. p_ptr->chp_frac = (u16b)(new_chp_frac - 0x10000L);
  86. p_ptr->chp++;
  87. }
  88. else
  89. {
  90. p_ptr->chp_frac = (u16b)new_chp_frac;
  91. }
  92. /* Fully healed */
  93. if (p_ptr->chp >= p_get_mhp())
  94. {
  95. p_ptr->chp = p_get_mhp();
  96. p_ptr->chp_frac = 0;
  97. }
  98. /* Notice changes */
  99. if (old_chp != p_ptr->chp)
  100. {
  101. /* Redraw */
  102. p_ptr->redraw |= (PR_HP);
  103. wieldeds_notice_flag(OF_REGEN);
  104. wieldeds_notice_flag(OF_IMPAIR_HP);
  105. }
  106. }
  107. /*
  108. * Regenerate mana points
  109. */
  110. static void regenmana(int percent)
  111. {
  112. s32b new_mana, new_mana_frac;
  113. int old_csp;
  114. old_csp = p_ptr->csp;
  115. new_mana = ((long)p_get_msp()) * percent + PY_REGEN_MNBASE;
  116. p_ptr->csp += (s16b)(new_mana >> 16); /* div 65536 */
  117. /* check for overflow */
  118. if ((p_ptr->csp < 0) && (old_csp > 0))
  119. {
  120. p_ptr->csp = MAX_SHORT;
  121. }
  122. new_mana_frac = (new_mana & 0xFFFF) + p_ptr->csp_frac; /* mod 65536 */
  123. if (new_mana_frac >= 0x10000L)
  124. {
  125. p_ptr->csp_frac = (u16b)(new_mana_frac - 0x10000L);
  126. p_ptr->csp++;
  127. }
  128. else
  129. {
  130. p_ptr->csp_frac = (u16b)new_mana_frac;
  131. }
  132. /* Must set frac to zero even if equal */
  133. if (p_ptr->csp >= p_get_msp())
  134. {
  135. p_ptr->csp = p_get_msp();
  136. p_ptr->csp_frac = 0;
  137. }
  138. /* Redraw mana */
  139. if (old_csp != p_ptr->csp)
  140. {
  141. /* Redraw */
  142. p_ptr->redraw |= (PR_MANA);
  143. wieldeds_notice_flag(OF_REGEN);
  144. wieldeds_notice_flag(OF_IMPAIR_MANA);
  145. }
  146. }
  147. /*
  148. * Regenerate the monsters (once per 100 game turns)
  149. *
  150. * XXX XXX XXX Should probably be done during monster turns.
  151. */
  152. static void regen_monsters(void)
  153. {
  154. int i, frac;
  155. /* Regenerate everyone */
  156. for (i = 1; i < mon_max; i++)
  157. {
  158. /* Check the i'th monster */
  159. monster_type *m_ptr = &mon_list[i];
  160. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  161. /* Skip dead monsters */
  162. if (!m_ptr->r_idx) continue;
  163. /* Allow regeneration (if needed) */
  164. if (m_ptr->hp < m_ptr->maxhp)
  165. {
  166. /* Hack -- Base regeneration */
  167. frac = m_ptr->maxhp / 100;
  168. /* Hack -- Minimal regeneration rate */
  169. if (!frac) frac = 1;
  170. /* Hack -- Some monsters regenerate quickly */
  171. if (rf_has(r_ptr->flags, RF_REGENERATE)) frac *= 2;
  172. /* Hack -- Regenerate */
  173. m_ptr->hp += frac;
  174. /* Do not over-regenerate */
  175. if (m_ptr->hp > m_ptr->maxhp) m_ptr->hp = m_ptr->maxhp;
  176. /* Redraw (later) if needed */
  177. if (p_ptr->health_who == i) p_ptr->redraw |= (PR_HEALTH);
  178. }
  179. }
  180. }
  181. /*
  182. * If player has inscribed the object with "!!", let him know when it's
  183. * recharged. -LM-
  184. * Also inform player when first item of a stack has recharged. -HK-
  185. * Notify all recharges w/o inscription if notify_recharge option set -WP-
  186. */
  187. static void recharged_notice(const object_type *o_ptr, bool all)
  188. {
  189. char o_name[120];
  190. cptr s;
  191. bool notify = FALSE;
  192. if (OPT(notify_recharge))
  193. {
  194. notify = TRUE;
  195. }
  196. else if (o_ptr->note)
  197. {
  198. /* Find a '!' */
  199. s = strchr(quark_str(o_ptr->note), '!');
  200. /* Process notification request */
  201. while (s)
  202. {
  203. /* Find another '!' */
  204. if (s[1] == '!')
  205. {
  206. notify = TRUE;
  207. break;
  208. }
  209. /* Keep looking for '!'s */
  210. s = strchr(s + 1, '!');
  211. }
  212. }
  213. if (!notify) return;
  214. /* Describe (briefly) */
  215. object_desc(o_name, sizeof(o_name), o_ptr, ODESC_BASE);
  216. /* Disturb the player */
  217. disturb(0, 0);
  218. /* Notify the player */
  219. if (o_ptr->number > 1)
  220. {
  221. if (all) msg_format("Your %s have recharged.", o_name);
  222. else msg_format("One of your %s has recharged.", o_name);
  223. }
  224. /* Artifacts */
  225. else if (o_ptr->name1)
  226. {
  227. msg_format("The %s has recharged.", o_name);
  228. }
  229. /* Single, non-artifact items */
  230. else msg_format("Your %s has recharged.", o_name);
  231. }
  232. /*
  233. * Recharge activatable objects in the player's equipment
  234. * and rods in the inventory and on the ground.
  235. */
  236. static void recharge_objects(void)
  237. {
  238. int i;
  239. bool charged = FALSE, discharged_stack;
  240. object_type *o_ptr;
  241. object_kind *k_ptr;
  242. /*** Recharge equipment ***/
  243. for (i = INVEN_WIELD; i < INVEN_TOTAL; i++)
  244. {
  245. /* Get the object */
  246. o_ptr = &inventory[i];
  247. /* Skip non-objects */
  248. if (!o_ptr->k_idx) continue;
  249. /* Recharge activatable objects */
  250. if (recharge_timeout(o_ptr))
  251. {
  252. charged = TRUE;
  253. /* Message if an item recharged */
  254. recharged_notice(o_ptr, TRUE);
  255. }
  256. }
  257. /* Notice changes */
  258. if (charged)
  259. {
  260. /* Window stuff */
  261. p_ptr->redraw |= (PR_EQUIP);
  262. }
  263. charged = FALSE;
  264. /*** Recharge the inventory ***/
  265. for (i = 0; i < INVEN_PACK; i++)
  266. {
  267. o_ptr = &inventory[i];
  268. k_ptr = &k_info[o_ptr->k_idx];
  269. /* Skip non-objects */
  270. if (!o_ptr->k_idx) continue;
  271. discharged_stack = (number_charging(o_ptr) == o_ptr->number) ? TRUE : FALSE;
  272. /* Recharge rods, and update if any rods are recharged */
  273. if (o_ptr->tval == TV_ROD && recharge_timeout(o_ptr))
  274. {
  275. charged = TRUE;
  276. /* Entire stack is recharged */
  277. if (o_ptr->timeout == 0)
  278. {
  279. recharged_notice(o_ptr, TRUE);
  280. }
  281. /* Previously exhausted stack has acquired a charge */
  282. else if (discharged_stack)
  283. {
  284. recharged_notice(o_ptr, FALSE);
  285. }
  286. }
  287. }
  288. /* Notice changes */
  289. if (charged)
  290. {
  291. /* Combine pack */
  292. p_ptr->notice |= (PN_COMBINE);
  293. /* Redraw stuff */
  294. p_ptr->redraw |= (PR_INVEN);
  295. }
  296. /*** Recharge the ground ***/
  297. for (i = 1; i < o_max; i++)
  298. {
  299. /* Get the object */
  300. o_ptr = &o_list[i];
  301. /* Skip dead objects */
  302. if (!o_ptr->k_idx) continue;
  303. /* Recharge rods on the ground */
  304. if (o_ptr->tval == TV_ROD)
  305. recharge_timeout(o_ptr);
  306. }
  307. }
  308. static void play_ambient_sound(void)
  309. {
  310. /* Town sound */
  311. if (p_ptr->depth == 0)
  312. {
  313. /* Hack - is it daytime or nighttime? */
  314. if (turn % (10L * TOWN_DAWN) < TOWN_DAWN / 2)
  315. {
  316. /* It's day. */
  317. sound(MSG_AMBIENT_DAY);
  318. }
  319. else
  320. {
  321. /* It's night. */
  322. sound(MSG_AMBIENT_NITE);
  323. }
  324. }
  325. /* Dungeon level 1-20 */
  326. else if (p_ptr->depth <= 20)
  327. {
  328. sound(MSG_AMBIENT_DNG1);
  329. }
  330. /* Dungeon level 21-40 */
  331. else if (p_ptr->depth <= 40)
  332. {
  333. sound(MSG_AMBIENT_DNG2);
  334. }
  335. /* Dungeon level 41-60 */
  336. else if (p_ptr->depth <= 60)
  337. {
  338. sound(MSG_AMBIENT_DNG3);
  339. }
  340. /* Dungeon level 61-80 */
  341. else if (p_ptr->depth <= 80)
  342. {
  343. sound(MSG_AMBIENT_DNG4);
  344. }
  345. /* Dungeon level 80- */
  346. else
  347. {
  348. sound(MSG_AMBIENT_DNG5);
  349. }
  350. }
  351. /*
  352. * Helper for process_world -- decrement p_ptr->timed[] fields.
  353. */
  354. static void decrease_timeouts(void)
  355. {
  356. int adjust = (adj_con_fix[p_ptr->state.stat_ind[A_CON]] + 1);
  357. int i;
  358. /* Decrement all effects that can be done simply */
  359. for (i = 0; i < TMD_MAX; i++)
  360. {
  361. int decr = 1;
  362. if (!p_ptr->timed[i])
  363. continue;
  364. switch (i)
  365. {
  366. case TMD_CUT:
  367. {
  368. /* Hack -- check for truly "mortal" wound */
  369. decr = (p_ptr->timed[i] > 1000) ? 0 : adjust;
  370. break;
  371. }
  372. case TMD_POISONED:
  373. case TMD_STUN:
  374. {
  375. decr = adjust;
  376. break;
  377. }
  378. }
  379. /* Decrement the effect */
  380. dec_timed(i, decr, FALSE);
  381. }
  382. return;
  383. }
  384. /*
  385. * Handle certain things once every 10 game turns
  386. */
  387. static void process_world(void)
  388. {
  389. int i;
  390. int regen_amount;
  391. int pcidx;
  392. object_type *o_ptr;
  393. /* Every 10 game turns */
  394. if (turn % 10) return;
  395. /*** Check the Time ***/
  396. /* Play an ambient sound at regular intervals. */
  397. if (!(turn % ((10L * TOWN_DAWN) / 4)))
  398. {
  399. play_ambient_sound();
  400. }
  401. /*** Handle the "town" (stores and sunshine) ***/
  402. /* While in town */
  403. if (!p_ptr->depth)
  404. {
  405. /* Hack -- Daybreak/Nighfall in town */
  406. if (!(turn % ((10L * TOWN_DAWN) / 2)))
  407. {
  408. bool dawn;
  409. /* Check for dawn */
  410. dawn = (!(turn % (10L * TOWN_DAWN)));
  411. /* Day breaks */
  412. if (dawn)
  413. msg_print("The sun has risen.");
  414. /* Night falls */
  415. else
  416. msg_print("The sun has fallen.");
  417. /* Illuminate */
  418. town_illuminate(dawn);
  419. }
  420. }
  421. /* While in the dungeon */
  422. else
  423. {
  424. /* Update the stores once a day (while in the dungeon).
  425. The changes are not actually made until return to town,
  426. to avoid giving details away in the knowledge menu. */
  427. if (!(turn % (10L * STORE_TURNS))) daycount++;
  428. }
  429. /*** Process the monsters ***/
  430. /* Check for creature generation */
  431. if (one_in_(MAX_M_ALLOC_CHANCE))
  432. {
  433. /* Make a new monster */
  434. (void)alloc_monster(MAX_SIGHT + 5, FALSE, p_ptr->depth);
  435. }
  436. /* Hack -- Check for creature regeneration */
  437. if (!(turn % 100)) regen_monsters();
  438. /*** Damage over Time ***/
  439. /* Take damage from poison */
  440. if (p_ptr->timed[TMD_POISONED])
  441. {
  442. /* Take damage */
  443. take_hit(1, "poison");
  444. }
  445. /* Take damage from cuts */
  446. if (p_ptr->timed[TMD_CUT])
  447. {
  448. /* Mortal wound or Deep Gash */
  449. if (p_ptr->timed[TMD_CUT] > 200)
  450. i = 3;
  451. /* Severe cut */
  452. else if (p_ptr->timed[TMD_CUT] > 100)
  453. i = 2;
  454. /* Other cuts */
  455. else
  456. i = 1;
  457. /* Take damage */
  458. take_hit(i, "a fatal wound");
  459. }
  460. /*** Check the Food, and Regenerate ***/
  461. /* Digest normally */
  462. if (p_ptr->food < PY_FOOD_MAX)
  463. {
  464. /* Every 100 game turns */
  465. if (!(turn % 100))
  466. {
  467. /* Basic digestion rate based on speed */
  468. i = extract_energy[p_ptr->state.speed] * 2;
  469. /* Regeneration takes more food */
  470. if (p_ptr->state.regenerate) i += 30;
  471. /* Slow digestion takes less food */
  472. if (p_ptr->state.slow_digest) i -= 10;
  473. /* Minimal digestion */
  474. if (i < 1) i = 1;
  475. /* Digest some food */
  476. (void)set_food(p_ptr->food - i);
  477. }
  478. }
  479. /* Digest quickly when gorged */
  480. else
  481. {
  482. /* Digest a lot of food */
  483. (void)set_food(p_ptr->food - 100);
  484. }
  485. /* Getting Faint */
  486. if (p_ptr->food < PY_FOOD_FAINT)
  487. {
  488. /* Faint occasionally */
  489. if (!p_ptr->timed[TMD_PARALYZED] && one_in_(10))
  490. {
  491. /* Message */
  492. msg_print("You faint from the lack of food.");
  493. disturb(1, 0);
  494. /* Hack -- faint (bypass free action) */
  495. (void)inc_timed(TMD_PARALYZED, 1 + randint0(5), TRUE);
  496. }
  497. }
  498. /* Starve to death (slowly) */
  499. if (p_ptr->food < PY_FOOD_STARVE)
  500. {
  501. /* Calculate damage */
  502. i = (PY_FOOD_STARVE - p_ptr->food) / 10;
  503. /* Take damage */
  504. take_hit(i, "starvation");
  505. }
  506. /** Regenerate HP **/
  507. /* Default regeneration */
  508. if (p_ptr->food >= PY_FOOD_WEAK)
  509. regen_amount = PY_REGEN_NORMAL;
  510. else if (p_ptr->food < PY_FOOD_STARVE)
  511. regen_amount = 0;
  512. else if (p_ptr->food < PY_FOOD_FAINT)
  513. regen_amount = PY_REGEN_FAINT;
  514. else /* if (p_ptr->food < PY_FOOD_WEAK) */
  515. regen_amount = PY_REGEN_WEAK;
  516. /* Various things speed up regeneration */
  517. if (p_ptr->state.regenerate)
  518. regen_amount *= 2;
  519. if (p_ptr->searching || p_ptr->resting)
  520. regen_amount *= 2;
  521. /* Some things slow it down */
  522. if (p_ptr->state.impair_hp)
  523. regen_amount /= 2;
  524. /* Various things interfere with physical healing */
  525. if (p_ptr->timed[TMD_PARALYZED]) regen_amount = 0;
  526. if (p_ptr->timed[TMD_POISONED]) regen_amount = 0;
  527. if (p_ptr->timed[TMD_STUN]) regen_amount = 0;
  528. if (p_ptr->timed[TMD_CUT]) regen_amount = 0;
  529. /* Regenerate Hit Points if needed */
  530. if (p_ptr->chp < p_get_mhp())
  531. regenhp(regen_amount);
  532. /** Regenerate SP **/
  533. /* Default regeneration */
  534. regen_amount = PY_REGEN_NORMAL;
  535. /* Various things speed up regeneration */
  536. if (p_ptr->state.regenerate)
  537. regen_amount *= 2;
  538. if (p_ptr->searching || p_ptr->resting)
  539. regen_amount *= 2;
  540. /* Some things slow it down */
  541. if (p_ptr->state.impair_mana)
  542. regen_amount /= 2;
  543. /* Regenerate mana */
  544. if (p_ptr->csp < p_get_msp())
  545. regenmana(regen_amount);
  546. /*** Timeout Various Things ***/
  547. decrease_timeouts();
  548. /*** Process Light ***/
  549. /* Check for light being wielded */
  550. o_ptr = &inventory[INVEN_LIGHT];
  551. /* Burn some fuel in the current light */
  552. if (o_ptr->tval == TV_LIGHT)
  553. {
  554. bitflag f[OF_SIZE];
  555. bool burn_fuel = TRUE;
  556. /* Get the object flags */
  557. object_flags(o_ptr, f);
  558. /* Turn off the wanton burning of light during the day in the town */
  559. if (!p_ptr->depth && ((turn % (10L * TOWN_DAWN)) < ((10L * TOWN_DAWN) / 2)))
  560. burn_fuel = FALSE;
  561. /* If the light has the NO_FUEL flag, well... */
  562. if (of_has(f, OF_NO_FUEL))
  563. burn_fuel = FALSE;
  564. /* Use some fuel (except on artifacts, or during the day) */
  565. if (burn_fuel && o_ptr->timeout > 0)
  566. {
  567. /* Decrease life-span */
  568. o_ptr->timeout--;
  569. /* Hack -- notice interesting fuel steps */
  570. if ((o_ptr->timeout < 100) || (!(o_ptr->timeout % 100)))
  571. {
  572. /* Redraw stuff */
  573. p_ptr->redraw |= (PR_EQUIP);
  574. }
  575. /* Hack -- Special treatment when blind */
  576. if (p_ptr->timed[TMD_BLIND])
  577. {
  578. /* Hack -- save some light for later */
  579. if (o_ptr->timeout == 0) o_ptr->timeout++;
  580. }
  581. /* The light is now out */
  582. else if (o_ptr->timeout == 0)
  583. {
  584. disturb(0, 0);
  585. msg_print("Your light has gone out!");
  586. }
  587. /* The light is getting dim */
  588. else if ((o_ptr->timeout < 100) && (!(o_ptr->timeout % 10)))
  589. {
  590. disturb(0, 0);
  591. msg_print("Your light is growing faint.");
  592. }
  593. }
  594. }
  595. /* Calculate torch radius */
  596. p_ptr->update |= (PU_TORCH);
  597. /*** Process Inventory ***/
  598. /* Handle experience draining */
  599. if (p_ptr->state.exp_drain)
  600. {
  601. for (pcidx = 0; pcidx < PY_MAX_CLASSES; pcidx++)
  602. {
  603. if ((pc_array[pcidx].exp > 0) && one_in_(10 * PY_MAX_CLASSES))
  604. {
  605. pc_array[pcidx].exp--;
  606. pc_array[pcidx].max_exp--;
  607. check_experience();
  608. }
  609. }
  610. wieldeds_notice_flag(OF_DRAIN_EXP);
  611. }
  612. /* Recharge activatable objects and rods */
  613. recharge_objects();
  614. /* Feel the inventory */
  615. sense_inventory();
  616. /*** Involuntary Movement ***/
  617. /* Random teleportation */
  618. if (p_ptr->state.teleport && one_in_(100))
  619. {
  620. wieldeds_notice_flag(OF_TELEPORT);
  621. teleport_player(40);
  622. disturb(0, 0);
  623. }
  624. /* Delayed Word-of-Recall */
  625. if (p_ptr->word_recall)
  626. {
  627. /* Count down towards recall */
  628. p_ptr->word_recall--;
  629. /* Activate the recall */
  630. if (!p_ptr->word_recall)
  631. {
  632. /* Disturbing! */
  633. disturb(0, 0);
  634. /* Determine the level */
  635. if (p_ptr->depth)
  636. {
  637. message_format(MSG_TPLEVEL, 0, "You feel yourself yanked upwards!");
  638. dungeon_change_level(0);
  639. }
  640. else
  641. {
  642. message_format(MSG_TPLEVEL, 0, "You feel yourself yanked downwards!");
  643. /* New depth - back to max depth or 1, whichever is deeper */
  644. dungeon_change_level(p_ptr->max_depth < 1 ? 1: p_ptr->max_depth);
  645. }
  646. }
  647. }
  648. }
  649. /*
  650. * Hack -- helper function for "process_player()"
  651. *
  652. * Check for changes in the "monster memory"
  653. */
  654. static void process_player_aux(void)
  655. {
  656. int i;
  657. bool changed = FALSE;
  658. static int old_monster_race_idx = 0;
  659. static bitflag old_flags[RF_SIZE];
  660. static bitflag old_spell_flags[RSF_SIZE];
  661. static byte old_blows[MONSTER_BLOW_MAX];
  662. static byte old_cast_innate = 0;
  663. static byte old_cast_spell = 0;
  664. /* Tracking a monster */
  665. if (p_ptr->monster_race_idx)
  666. {
  667. /* Get the monster lore */
  668. monster_lore *l_ptr = &l_list[p_ptr->monster_race_idx];
  669. for (i = 0; i < MONSTER_BLOW_MAX; i++)
  670. {
  671. if (old_blows[i] != l_ptr->blows[i])
  672. {
  673. changed = TRUE;
  674. break;
  675. }
  676. }
  677. /* Check for change of any kind */
  678. if (changed ||
  679. (old_monster_race_idx != p_ptr->monster_race_idx) ||
  680. !rf_is_equal(old_flags, l_ptr->flags) ||
  681. !rsf_is_equal(old_spell_flags, l_ptr->spell_flags) ||
  682. (old_cast_innate != l_ptr->cast_innate) ||
  683. (old_cast_spell != l_ptr->cast_spell))
  684. {
  685. /* Memorize old race */
  686. old_monster_race_idx = p_ptr->monster_race_idx;
  687. /* Memorize flags */
  688. rf_copy(old_flags, l_ptr->flags);
  689. rsf_copy(old_spell_flags, l_ptr->spell_flags);
  690. /* Memorize blows */
  691. memmove(old_blows, l_ptr->blows, sizeof(byte)*MONSTER_BLOW_MAX);
  692. /* Memorize castings */
  693. old_cast_innate = l_ptr->cast_innate;
  694. old_cast_spell = l_ptr->cast_spell;
  695. /* Redraw stuff */
  696. p_ptr->redraw |= (PR_MONSTER);
  697. redraw_stuff();
  698. }
  699. }
  700. }
  701. /*
  702. * Process the player
  703. *
  704. * Notice the annoying code to handle "pack overflow", which
  705. * must come first just in case somebody manages to corrupt
  706. * the savefiles by clever use of menu commands or something.
  707. *
  708. * Notice the annoying code to handle "monster memory" changes,
  709. * which allows us to avoid having to update the window flags
  710. * every time we change any internal monster memory field, and
  711. * also reduces the number of times that the recall window must
  712. * be redrawn.
  713. *
  714. * Note that the code to check for user abort during repeated commands
  715. * and running and resting can be disabled entirely with an option, and
  716. * even if not disabled, it will only check during every 128th game turn
  717. * while resting, for efficiency.
  718. */
  719. static void process_player(void)
  720. {
  721. int i;
  722. /*** Check for interrupts ***/
  723. /* Complete resting */
  724. if (p_ptr->resting < 0)
  725. {
  726. /* Basic resting */
  727. if (p_ptr->resting == REST_ALL_POINTS)
  728. {
  729. /* Stop resting */
  730. if ((p_ptr->chp == p_get_mhp()) &&
  731. (p_ptr->csp == p_get_msp()))
  732. {
  733. disturb(0, 0);
  734. }
  735. }
  736. /* Complete resting */
  737. else if (p_ptr->resting == REST_COMPLETE)
  738. {
  739. /* Stop resting */
  740. if ((p_ptr->chp == p_get_mhp()) &&
  741. (p_ptr->csp == p_get_msp()) &&
  742. !p_ptr->timed[TMD_BLIND] && !p_ptr->timed[TMD_CONFUSED] &&
  743. !p_ptr->timed[TMD_POISONED] && !p_ptr->timed[TMD_AFRAID] &&
  744. !p_ptr->timed[TMD_TERROR] &&
  745. !p_ptr->timed[TMD_STUN] && !p_ptr->timed[TMD_CUT] &&
  746. !p_ptr->timed[TMD_SLOW] && !p_ptr->timed[TMD_PARALYZED] &&
  747. !p_ptr->timed[TMD_IMAGE] && !p_ptr->word_recall)
  748. {
  749. disturb(0, 0);
  750. }
  751. }
  752. /* Rest until HP or SP are filled */
  753. else if (p_ptr->resting == REST_SOME_POINTS)
  754. {
  755. /* Stop resting */
  756. if ((p_ptr->chp == p_get_mhp()) ||
  757. (p_ptr->csp == p_get_msp()))
  758. {
  759. disturb(0, 0);
  760. }
  761. }
  762. }
  763. /* Check for "player abort" */
  764. if (p_ptr->running ||
  765. cmd_get_nrepeats() > 0 ||
  766. (p_ptr->resting && !(turn & 0x7F)))
  767. {
  768. /* Do not wait */
  769. inkey_scan = SCAN_INSTANT;
  770. /* Check for a key */
  771. if (inkey())
  772. {
  773. /* Flush input */
  774. flush();
  775. /* Disturb */
  776. disturb(0, 0);
  777. /* Hack -- Show a Message */
  778. msg_print("Cancelled.");
  779. }
  780. }
  781. /*** Handle actual user input ***/
  782. /* Repeat until energy is reduced */
  783. do
  784. {
  785. /* Notice stuff (if needed) */
  786. if (p_ptr->notice) notice_stuff();
  787. /* Update stuff (if needed) */
  788. if (p_ptr->update) update_stuff();
  789. /* Redraw stuff (if needed) */
  790. if (p_ptr->redraw) redraw_stuff();
  791. /* Place the cursor on the player */
  792. move_cursor_relative(p_ptr->py, p_ptr->px);
  793. /* Refresh (optional) */
  794. Term_fresh();
  795. /* Hack -- Pack Overflow */
  796. pack_overflow();
  797. /* Hack -- reset to inventory display */
  798. if (!p_ptr->command_new) p_ptr->command_wrk = USE_INVEN;
  799. /* Assume free turn */
  800. p_ptr->energy_use = 0;
  801. /* Dwarves detect treasure */
  802. if (player_has(PF_SEE_ORE))
  803. {
  804. /* Only if they are in good shape */
  805. if (!p_ptr->timed[TMD_IMAGE] &&
  806. !p_ptr->timed[TMD_CONFUSED] &&
  807. !p_ptr->timed[TMD_AMNESIA] &&
  808. !p_ptr->timed[TMD_STUN] &&
  809. !p_ptr->timed[TMD_PARALYZED] &&
  810. !p_ptr->timed[TMD_TERROR] &&
  811. !p_ptr->timed[TMD_AFRAID])
  812. detect_close_buried_treasure();
  813. }
  814. /* Paralyzed or Knocked Out */
  815. if ((p_ptr->timed[TMD_PARALYZED]) || (p_ptr->timed[TMD_STUN] >= 100))
  816. {
  817. /* Take a turn */
  818. p_ptr->energy_use = 100;
  819. }
  820. /* Picking up objects */
  821. else if (p_ptr->notice & PN_PICKUP)
  822. {
  823. /* Recursively call the pickup function, use energy */
  824. p_ptr->energy_use = py_pickup(0) * 10;
  825. if (p_ptr->energy_use > 100)
  826. p_ptr->energy_use = 100;
  827. p_ptr->notice &= ~(PN_PICKUP);
  828. }
  829. /* Resting */
  830. else if (p_ptr->resting)
  831. {
  832. /* Timed rest */
  833. if (p_ptr->resting > 0)
  834. {
  835. /* Reduce rest count */
  836. p_ptr->resting--;
  837. /* Redraw the state */
  838. p_ptr->redraw |= (PR_STATE);
  839. }
  840. /* Take a turn */
  841. p_ptr->energy_use = 100;
  842. }
  843. /* Running */
  844. else if (p_ptr->running)
  845. {
  846. /* Take a step */
  847. run_step(0);
  848. }
  849. /* Repeated command */
  850. else if (cmd_get_nrepeats() > 0)
  851. {
  852. /* Hack -- Assume messages were seen */
  853. msg_flag = FALSE;
  854. /* Clear the top line */
  855. prt("", 0, 0);
  856. /* Process the command */
  857. process_command(CMD_GAME, TRUE);
  858. }
  859. /* Normal command */
  860. else
  861. {
  862. /* Check monster recall */
  863. process_player_aux();
  864. /* Place the cursor on the player */
  865. move_cursor_relative(p_ptr->py, p_ptr->px);
  866. /* Get and process a command */
  867. process_command(CMD_GAME, FALSE);
  868. }
  869. /*** Clean up ***/
  870. /* Action is or was resting */
  871. if (p_ptr->resting)
  872. {
  873. /* Increment the resting counter */
  874. p_ptr->resting_turn++;
  875. }
  876. /* Significant */
  877. if (p_ptr->energy_use)
  878. {
  879. /* Use some energy */
  880. p_ptr->energy -= p_ptr->energy_use;
  881. /* Increment the player turn counter */
  882. p_ptr->player_turn++;
  883. /* Hack -- constant hallucination */
  884. if (p_ptr->timed[TMD_IMAGE])
  885. {
  886. p_ptr->redraw |= (PR_MAP);
  887. }
  888. /* Shimmer monsters if needed */
  889. if (shimmer_monsters)
  890. {
  891. /* Clear the flag */
  892. shimmer_monsters = FALSE;
  893. /* Shimmer multi-hued monsters */
  894. for (i = 1; i < mon_max; i++)
  895. {
  896. monster_type *m_ptr;
  897. monster_race *r_ptr;
  898. /* Get the monster */
  899. m_ptr = &mon_list[i];
  900. /* Skip dead monsters */
  901. if (!m_ptr->r_idx) continue;
  902. /* Get the monster race */
  903. r_ptr = &r_info[m_ptr->r_idx];
  904. /* Skip non-multi-hued monsters */
  905. if (!rf_has(r_ptr->flags, RF_ATTR_MULTI)) continue;
  906. /* Reset the flag */
  907. shimmer_monsters = TRUE;
  908. /* Redraw regardless */
  909. light_spot(m_ptr->fy, m_ptr->fx);
  910. }
  911. }
  912. /* Repair "nice" flags */
  913. if (repair_mflag_nice)
  914. {
  915. /* Clear flag */
  916. repair_mflag_nice = FALSE;
  917. /* Process monsters */
  918. for (i = 1; i < mon_max; i++)
  919. {
  920. monster_type *m_ptr;
  921. /* Get the monster */
  922. m_ptr = &mon_list[i];
  923. /* Skip dead monsters */
  924. /* if (!m_ptr->r_idx) continue; */
  925. /* Clear "nice" flag */
  926. m_ptr->mflag &= ~(MFLAG_NICE);
  927. }
  928. }
  929. /* Repair "mark" flags */
  930. if (repair_mflag_mark)
  931. {
  932. /* Reset the flag */
  933. repair_mflag_mark = FALSE;
  934. /* Process the monsters */
  935. for (i = 1; i < mon_max; i++)
  936. {
  937. monster_type *m_ptr;
  938. /* Get the monster */
  939. m_ptr = &mon_list[i];
  940. /* Skip dead monsters */
  941. /* if (!m_ptr->r_idx) continue; */
  942. /* Repair "mark" flag */
  943. if (m_ptr->mflag & (MFLAG_MARK))
  944. {
  945. /* Skip "show" monsters */
  946. if (m_ptr->mflag & (MFLAG_SHOW))
  947. {
  948. /* Repair "mark" flag */
  949. repair_mflag_mark = TRUE;
  950. /* Skip */
  951. continue;
  952. }
  953. /* Forget flag */
  954. m_ptr->mflag &= ~(MFLAG_MARK);
  955. /* Update the monster */
  956. update_mon(i, FALSE);
  957. }
  958. }
  959. }
  960. }
  961. /* Repair "show" flags */
  962. if (repair_mflag_show)
  963. {
  964. /* Reset the flag */
  965. repair_mflag_show = FALSE;
  966. /* Process the monsters */
  967. for (i = 1; i < mon_max; i++)
  968. {
  969. monster_type *m_ptr;
  970. /* Get the monster */
  971. m_ptr = &mon_list[i];
  972. /* Skip dead monsters */
  973. /* if (!m_ptr->r_idx) continue; */
  974. /* Clear "show" flag */
  975. m_ptr->mflag &= ~(MFLAG_SHOW);
  976. }
  977. }
  978. /* HACK: This will redraw the itemlist too frequently, but I'm don't
  979. know all the individual places it should go. */
  980. p_ptr->redraw |= PR_ITEMLIST;
  981. }
  982. while (!p_ptr->energy_use && !p_ptr->leaving);
  983. }
  984. byte flicker = 0;
  985. byte color_flicker[MAX_COLORS][3] =
  986. {
  987. {TERM_DARK, TERM_L_DARK, TERM_L_RED},
  988. {TERM_WHITE, TERM_L_WHITE, TERM_L_BLUE},
  989. {TERM_SLATE, TERM_WHITE, TERM_L_DARK},
  990. {TERM_ORANGE, TERM_YELLOW, TERM_L_RED},
  991. {TERM_RED, TERM_L_RED, TERM_L_PINK},
  992. {TERM_GREEN, TERM_L_GREEN, TERM_L_TEAL},
  993. {TERM_BLUE, TERM_L_BLUE, TERM_SLATE},
  994. {TERM_UMBER, TERM_L_UMBER, TERM_MUSTARD},
  995. {TERM_L_DARK, TERM_SLATE, TERM_L_VIOLET},
  996. {TERM_WHITE, TERM_SLATE, TERM_L_WHITE},
  997. {TERM_L_PURPLE, TERM_PURPLE, TERM_L_VIOLET},
  998. {TERM_YELLOW, TERM_L_YELLOW, TERM_MUSTARD},
  999. {TERM_L_RED, TERM_RED, TERM_L_PINK},
  1000. {TERM_L_GREEN, TERM_L_TEAL, TERM_GREEN},
  1001. {TERM_L_BLUE, TERM_DEEP_L_BLUE, TERM_BLUE_SLATE},
  1002. {TERM_L_UMBER, TERM_UMBER, TERM_MUD},
  1003. {TERM_PURPLE, TERM_VIOLET, TERM_MAGENTA},
  1004. {TERM_VIOLET, TERM_L_VIOLET, TERM_MAGENTA},
  1005. {TERM_TEAL, TERM_L_TEAL, TERM_L_GREEN},
  1006. {TERM_MUD, TERM_YELLOW, TERM_UMBER},
  1007. {TERM_L_YELLOW, TERM_WHITE, TERM_L_UMBER},
  1008. {TERM_MAGENTA, TERM_L_PINK, TERM_L_RED},
  1009. {TERM_L_TEAL, TERM_L_WHITE, TERM_TEAL},
  1010. {TERM_L_VIOLET, TERM_L_PURPLE, TERM_VIOLET},
  1011. {TERM_L_PINK, TERM_L_RED, TERM_L_WHITE},
  1012. {TERM_MUSTARD, TERM_YELLOW, TERM_UMBER},
  1013. {TERM_BLUE_SLATE, TERM_BLUE, TERM_SLATE},
  1014. {TERM_DEEP_L_BLUE, TERM_L_BLUE, TERM_BLUE},
  1015. };
  1016. byte get_flicker(byte a)
  1017. {
  1018. switch(flicker % 3)
  1019. {
  1020. case 1: return color_flicker[a][1];
  1021. case 2: return color_flicker[a][2];
  1022. }
  1023. return a;
  1024. }
  1025. /*
  1026. * This animates monsters and/or items as necessary.
  1027. */
  1028. void do_animation(void)
  1029. {
  1030. int i;
  1031. for (i = 1; i < mon_max; i++)
  1032. {
  1033. byte attr;
  1034. monster_type *m_ptr = &mon_list[i];
  1035. monster_race *r_ptr = &r_info[m_ptr->r_idx];
  1036. if (!m_ptr || !m_ptr->ml)
  1037. continue;
  1038. else if (rf_has(r_ptr->flags, RF_ATTR_MULTI))
  1039. attr = randint1(BASIC_COLORS - 1);
  1040. else if (rf_has(r_ptr->flags, RF_ATTR_FLICKER))
  1041. attr = get_flicker(r_ptr->x_attr);
  1042. else
  1043. continue;
  1044. m_ptr->attr = attr;
  1045. p_ptr->redraw |= (PR_MAP | PR_MONLIST);
  1046. }
  1047. flicker++;
  1048. }
  1049. /*
  1050. * This is used when the user is idle to allow for simple animations.
  1051. * Currently the only thing it really does is animate shimmering monsters.
  1052. */
  1053. void idle_update(void)
  1054. {
  1055. if (!character_dungeon) return;
  1056. if (!OPT(animate_flicker)) return;
  1057. /* Animate and redraw if necessary */
  1058. do_animation();
  1059. redraw_stuff();
  1060. /* Refresh the main screen */
  1061. Term_fresh();
  1062. }
  1063. /*
  1064. * Interact with the current dungeon level.
  1065. *
  1066. * This function will not exit until the level is completed,
  1067. * the user dies, or the game is terminated.
  1068. */
  1069. static void dungeon(void)
  1070. {
  1071. monster_type *m_ptr;
  1072. int i;
  1073. int pcidx;
  1074. /* Hack -- enforce illegal panel */
  1075. Term->offset_y = DUNGEON_HGT;
  1076. Term->offset_x = DUNGEON_WID;
  1077. /* Not leaving */
  1078. p_ptr->leaving = FALSE;
  1079. /* Reset the "command" vars */
  1080. p_ptr->command_cmd = 0;
  1081. p_ptr->command_new = 0;
  1082. p_ptr->command_arg = 0;
  1083. /* Cancel the target */
  1084. target_set_monster(0);
  1085. /* Cancel the health bar */
  1086. health_track(0);
  1087. /* Reset shimmer flags */
  1088. shimmer_monsters = TRUE;
  1089. shimmer_objects = TRUE;
  1090. /* Reset repair flags */
  1091. repair_mflag_nice = TRUE;
  1092. repair_mflag_show = TRUE;
  1093. repair_mflag_mark = TRUE;
  1094. /* Disturb */
  1095. disturb(1, 0);
  1096. /* Track maximum player level */
  1097. for (pcidx = 0; pcidx < PY_MAX_CLASSES; pcidx++)
  1098. {
  1099. if (pc_array[pcidx].max_lev < pc_array[pcidx].lev)
  1100. {
  1101. pc_array[pcidx].max_lev = pc_array[pcidx].lev;
  1102. }
  1103. }
  1104. /* Track maximum dungeon level */
  1105. if (p_ptr->max_depth < p_ptr->depth)
  1106. {
  1107. p_ptr->max_depth = p_ptr->depth;
  1108. }
  1109. /* If autosave is pending, do it now. */
  1110. if (p_ptr->autosave)
  1111. {
  1112. save_game();
  1113. p_ptr->autosave = FALSE;
  1114. }
  1115. /* Choose panel */
  1116. verify_panel();
  1117. /* Flush messages */
  1118. message_flush();
  1119. /* Hack -- Increase "xtra" depth */
  1120. character_xtra++;
  1121. /* Clear */
  1122. Term_clear();
  1123. /* Update stuff */
  1124. p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
  1125. /* Calculate torch radius */
  1126. p_ptr->update |= (PU_TORCH);
  1127. /* Update stuff */
  1128. update_stuff();
  1129. /* Fully update the visuals (and monster distances) */
  1130. p_ptr->update |= (PU_FORGET_VIEW | PU_UPDATE_VIEW | PU_DISTANCE);
  1131. /* Fully update the flow */
  1132. p_ptr->update |= (PU_FORGET_FLOW | PU_UPDATE_FLOW);
  1133. /* Redraw dungeon */
  1134. p_ptr->redraw |= (PR_BASIC | PR_EXTRA | PR_MAP);
  1135. /* Redraw "statusy" things */
  1136. p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_MONSTER | PR_MONLIST | PR_ITEMLIST);
  1137. /* Update stuff */
  1138. update_stuff();
  1139. /* Redraw stuff */
  1140. redraw_stuff();
  1141. /* Hack -- Decrease "xtra" depth */
  1142. character_xtra--;
  1143. /* Update stuff */
  1144. p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_SPELLS);
  1145. /* Combine / Reorder the pack */
  1146. p_ptr->notice |= (PN_COMBINE | PN_REORDER | PN_SORT_QUIVER);
  1147. /* Make basic mouse buttons */
  1148. (void) button_add("[ESC]", ESCAPE);
  1149. (void) button_add("[Ret]", '\r');
  1150. (void) button_add("[Spc]", ' ');
  1151. (void) button_add("[Rpt]", 'n');
  1152. (void) button_add("[Std]", ',');
  1153. /* Redraw buttons */
  1154. p_ptr->redraw |= (PR_BUTTONS);
  1155. /* Notice stuff */
  1156. notice_stuff();
  1157. /* Update stuff */
  1158. update_stuff();
  1159. /* Redraw stuff */
  1160. redraw_stuff();
  1161. /* Refresh */
  1162. Term_fresh();
  1163. /* Handle delayed death */
  1164. if (p_ptr->is_dead) return;
  1165. /* Announce (or repeat) the feeling */
  1166. if (p_ptr->depth) do_cmd_feeling();
  1167. /* Give player minimum energy to start a new level, but do not reduce higher value from savefile for level in progress */
  1168. if (p_ptr->energy < INITIAL_DUNGEON_ENERGY)
  1169. p_ptr->energy = INITIAL_DUNGEON_ENERGY;
  1170. /*** Process this dungeon level ***/
  1171. /* Main loop */
  1172. while (TRUE)
  1173. {
  1174. /* Hack -- Compact the monster list occasionally */
  1175. if (mon_cnt + 32 > z_info->m_max) compact_monsters(64);
  1176. /* Hack -- Compress the monster list occasionally */
  1177. if (mon_cnt + 32 < mon_max) compact_monsters(0);
  1178. /* Hack -- Compact the object list occasionally */
  1179. if (o_cnt + 32 > z_info->o_max) compact_objects(64);
  1180. /* Hack -- Compress the object list occasionally */
  1181. if (o_cnt + 32 < o_max) compact_objects(0);
  1182. /* Can the player move? */
  1183. while ((p_ptr->energy >= 100) && !p_ptr->leaving)
  1184. {
  1185. /* Do any necessary animations */
  1186. do_animation();
  1187. /* process monster with even more energy first */
  1188. process_monsters((byte)(p_ptr->energy + 1));
  1189. /* if still alive */
  1190. if (!p_ptr->leaving)
  1191. {
  1192. /* Process the player */
  1193. process_player();
  1194. }
  1195. }
  1196. /* Notice stuff */
  1197. if (p_ptr->notice) notice_stuff();
  1198. /* Update stuff */
  1199. if (p_ptr->update) update_stuff();
  1200. /* Redraw stuff */
  1201. if (p_ptr->redraw) redraw_stuff();
  1202. /* Hack -- Highlight the player */
  1203. move_cursor_relative(p_ptr->py, p_ptr->px);
  1204. /* Handle "leaving" */
  1205. if (p_ptr->leaving) break;
  1206. /* Process all of the monsters */
  1207. process_monsters(100);
  1208. /* Notice stuff */
  1209. if (p_ptr->notice) notice_stuff();
  1210. /* Update stuff */
  1211. if (p_ptr->update) update_stuff();
  1212. /* Redraw stuff */
  1213. if (p_ptr->redraw) redraw_stuff();
  1214. /* Hack -- Highlight the player */
  1215. move_cursor_relative(p_ptr->py, p_ptr->px);
  1216. /* Handle "leaving" */
  1217. if (p_ptr->leaving) break;
  1218. /* Process the world */
  1219. process_world();
  1220. /* Notice stuff */
  1221. if (p_ptr->notice) notice_stuff();
  1222. /* Update stuff */
  1223. if (p_ptr->update) update_stuff();
  1224. /* Redraw stuff */
  1225. if (p_ptr->redraw) redraw_stuff();
  1226. /* Hack -- Highlight the player */
  1227. move_cursor_relative(p_ptr->py, p_ptr->px);
  1228. /* Handle "leaving" */
  1229. if (p_ptr->leaving) break;
  1230. /*** Apply energy ***/
  1231. /* Give the player some energy */
  1232. p_ptr->energy += extract_energy[p_ptr->state.speed];
  1233. /* Give energy to all monsters */
  1234. for (i = mon_max - 1; i >= 1; i--)
  1235. {
  1236. /* Access the monster */
  1237. m_ptr = &mon_list[i];
  1238. /* Ignore "dead" monsters */
  1239. if (!m_ptr->r_idx) continue;
  1240. /* Give this monster some energy */
  1241. m_ptr->energy += extract_energy[m_ptr->mspeed];
  1242. }
  1243. /* Count game turns */
  1244. turn++;
  1245. }
  1246. }
  1247. /*
  1248. * Process some user pref files
  1249. */
  1250. static void process_some_user_pref_files(void)
  1251. {
  1252. char buf[1024];
  1253. /* Process the "user.prf" file */
  1254. (void)process_pref_file("user.prf");
  1255. /* Get the "PLAYER.prf" filename */
  1256. (void)strnfmt(buf, sizeof(buf), "%s.prf", op_ptr->base_name);
  1257. /* Process the "PLAYER.prf" file */
  1258. (void)process_pref_file(buf);
  1259. }
  1260. /*
  1261. * Actually play a game.
  1262. *
  1263. * This function is called from a variety of entry points, since both
  1264. * the standard "main.c" file, as well as several platform-specific
  1265. * "main-xxx.c" files, call this function to start a new game with a
  1266. * new savefile, start a new game with an existing savefile, or resume
  1267. * a saved game with an existing savefile.
  1268. *
  1269. * If the "new_game" parameter is true, and the savefile contains a
  1270. * living character, then that character will be killed, so that the
  1271. * player may start a new game with that savefile. This is only used
  1272. * by the "-n" option in "main.c".
  1273. *
  1274. * If the savefile does not exist, cannot be loaded, or contains a dead
  1275. * character, then a new game will be started.
  1276. *
  1277. * Several platforms (Windows, Macintosh, Amiga) start brand new games
  1278. * with "savefile" and "op_ptr->base_name" both empty, and initialize
  1279. * them later based on the player name. To prevent weirdness, we must
  1280. * initialize "op_ptr->base_name" to "PLAYER" if it is empty.
  1281. *
  1282. * Note that we load the RNG state from savefiles (2.8.0 or later) and
  1283. * so we only initialize it if we were unable to load it. The loading
  1284. * code marks successful loading of the RNG state using the "Rand_quick"
  1285. * flag, which is a hack, but which optimizes loading of savefiles.
  1286. */
  1287. void play_game(void)
  1288. {
  1289. bool existing_dead_save = FALSE;
  1290. /* Initialize */
  1291. bool new_game = init_angband();
  1292. /*** Do horrible, hacky things, to start the game off ***/
  1293. /* Hack -- Increase "icky" depth */
  1294. character_icky++;
  1295. /* Verify main term */
  1296. if (!term_screen)
  1297. quit("main window does not exist");
  1298. /* Make sure main term is active */
  1299. Term_activate(term_screen);
  1300. /* Verify minimum size */
  1301. if ((Term->hgt < 24) || (Term->wid < 80))
  1302. quit("main window is too small");
  1303. /* Hack -- Turn off the cursor */
  1304. (void)Term_set_cursor(FALSE);
  1305. /*** Try to load the savefile ***/
  1306. p_ptr->is_dead = TRUE;
  1307. if (savefile[0] && file_exists(savefile))
  1308. {
  1309. bool ok = old_load();
  1310. if (!ok) quit("broken savefile");
  1311. if (p_ptr->is_dead && arg_wizard)
  1312. {
  1313. p_ptr->is_dead = FALSE;
  1314. p_ptr->noscore |= NOSCORE_WIZARD;
  1315. }
  1316. else if (p_ptr->is_dead)
  1317. {
  1318. existing_dead_save = TRUE;
  1319. }
  1320. }
  1321. else
  1322. {
  1323. existing_dead_save = TRUE;
  1324. }
  1325. /* No living character loaded */
  1326. if (p_ptr->is_dead)
  1327. {
  1328. /* Make new player */
  1329. new_game = TRUE;
  1330. /* The dungeon is not ready */
  1331. character_dungeon = FALSE;
  1332. }
  1333. /* Hack -- Default base_name */
  1334. if (!op_ptr->base_name[0])
  1335. my_strcpy(op_ptr->base_name, "PLAYER", sizeof(op_ptr->base_name));
  1336. /* Init RNG */
  1337. if (Rand_quick)
  1338. {
  1339. u32b seed;
  1340. /* Basic seed */
  1341. seed = (time(NULL));
  1342. #ifdef SET_UID
  1343. /* Mutate the seed on Unix machines */
  1344. seed = ((seed >> 3) * (getpid() << 1));
  1345. #endif
  1346. /* Use the complex RNG */
  1347. Rand_quick = FALSE;
  1348. /* Seed the "complex" RNG */
  1349. Rand_state_init(seed);
  1350. }
  1351. /* Roll new character */
  1352. if (new_game)
  1353. {
  1354. /* The dungeon is not ready */
  1355. character_dungeon = FALSE;
  1356. /* Start in town */
  1357. p_ptr->depth = 0;
  1358. /* Hack -- seed for flavors */
  1359. seed_flavor = randint0(0x10000000);
  1360. /* Hack -- seed for town layout */
  1361. seed_town = randint0(0x10000000);
  1362. /* Hack -- seed for random artifacts */
  1363. seed_randart = randint0(0x10000000);
  1364. /* Roll up a new character. Quickstart is allowed if ht_birth is set */
  1365. player_birth(p_ptr->ht_birth ? TRUE : FALSE);
  1366. /* Randomize the artifacts */
  1367. if (OPT(adult_randarts))
  1368. do_randart(seed_randart, TRUE);
  1369. }
  1370. /* Normal machine (process player name) */
  1371. if (savefile[0])
  1372. process_player_name(FALSE);
  1373. /* Weird machine (process player name, pick savefile name) */
  1374. else
  1375. process_player_name(TRUE);
  1376. #if 0
  1377. /* Check if we're overwriting a savefile */
  1378. while (new_game && !existing_dead_save)
  1379. {
  1380. bool overwrite = get_check("Continuing will overwrite an existing savefile. Overwrite? ");
  1381. if (overwrite) break;
  1382. get_name(TRUE);
  1383. }
  1384. #endif
  1385. /* Stop the player being quite so dead */
  1386. p_ptr->is_dead = FALSE;
  1387. /* Flash a message */
  1388. prt("Please wait...", 0, 0);
  1389. /* Flush the message */
  1390. Term_fresh();
  1391. /* Flavor the objects */
  1392. flavor_init();
  1393. /* Reset visuals */
  1394. reset_visuals(TRUE);
  1395. /* Tell the UI we've started. */
  1396. event_signal(EVENT_ENTER_GAME);
  1397. /* Redraw stuff */
  1398. p_ptr->redraw |= (PR_INVEN | PR_EQUIP | PR_MONSTER | PR_MESSAGE);
  1399. redraw_stuff();
  1400. /* Process some user pref files */
  1401. process_some_user_pref_files();
  1402. /* React to changes */
  1403. Term_xtra(TERM_XTRA_REACT, 0);
  1404. /* Generate a dungeon level if needed */
  1405. if (!character_dungeon) generate_cave();
  1406. /* Character is now "complete" */
  1407. character_generated = TRUE;
  1408. /* Hack -- Decrease "icky" depth */
  1409. character_icky--;
  1410. /* Start playing */
  1411. p_ptr->playing = TRUE;
  1412. /* Save not required yet. */
  1413. p_ptr->autosave = FALSE;
  1414. /* Hack -- Enforce "delayed death" */
  1415. if (p_ptr->chp < 0) p_ptr->is_dead = TRUE;
  1416. /* Process */
  1417. while (TRUE)
  1418. {
  1419. /* Play ambient sound on change of level. */
  1420. play_ambient_sound();
  1421. /* Process the level */
  1422. dungeon();
  1423. /* Notice stuff */
  1424. if (p_ptr->notice) notice_stuff();
  1425. /* Update stuff */
  1426. if (p_ptr->update) update_stuff();
  1427. /* Redraw stuff */
  1428. if (p_ptr->redraw) redraw_stuff();
  1429. /* Cancel the target */
  1430. target_set_monster(0);
  1431. /* Cancel the health bar */
  1432. health_track(0);
  1433. /* Forget the view */
  1434. forget_view();
  1435. /* Handle "quit and save" */
  1436. if (!p_ptr->playing && !p_ptr->is_dead) break;
  1437. /* XXX XXX XXX */
  1438. message_flush();
  1439. /* Accidental Death */
  1440. if (p_ptr->playing && p_ptr->is_dead)
  1441. {
  1442. /* Mega-Hack -- Allow player to cheat death */
  1443. if ((p_ptr->wizard || OPT(cheat_live)) && !get_check("Die? "))
  1444. {
  1445. /* Mark social class, reset age, if needed */
  1446. if (p_ptr->sc) p_ptr->sc = p_ptr->age = 0;
  1447. /* Increase age */
  1448. p_ptr->age++;
  1449. /* Mark savefile */
  1450. p_ptr->noscore |= NOSCORE_WIZARD;
  1451. /* Message */
  1452. msg_print("You invoke wizard mode and cheat death.");
  1453. message_flush();
  1454. /* Cheat death */
  1455. p_ptr->is_dead = FALSE;
  1456. /* Restore hit points */
  1457. p_ptr->chp = p_get_mhp();
  1458. p_ptr->chp_frac = 0;
  1459. /* Restore spell points */
  1460. p_ptr->csp = p_get_msp();
  1461. p_ptr->csp_frac = 0;
  1462. /* Hack -- Healing */
  1463. (void)clear_timed(TMD_BLIND, TRUE);
  1464. (void)clear_timed(TMD_CONFUSED, TRUE);
  1465. (void)clear_timed(TMD_POISONED, TRUE);
  1466. (void)clear_timed(TMD_AFRAID, TRUE);
  1467. (void)clear_timed(TMD_PARALYZED, TRUE);
  1468. (void)clear_timed(TMD_IMAGE, TRUE);
  1469. (void)clear_timed(TMD_STUN, TRUE);
  1470. (void)clear_timed(TMD_CUT, TRUE);
  1471. /* Hack -- Prevent starvation */
  1472. (void)set_food(PY_FOOD_MAX - 1);
  1473. /* Hack -- cancel recall */
  1474. if (p_ptr->word_recall)
  1475. {
  1476. /* Message */
  1477. msg_print("A tension leaves the air around you...");
  1478. message_flush();
  1479. /* Hack -- Prevent recall */
  1480. p_ptr->word_recall = 0;
  1481. }
  1482. /* Note cause of death XXX XXX XXX */
  1483. my_strcpy(p_ptr->died_from, "Cheating death", sizeof(p_ptr->died_from));
  1484. /* New depth */
  1485. p_ptr->depth = 0;
  1486. /* Leaving */
  1487. p_ptr->leaving = TRUE;
  1488. }
  1489. }
  1490. /* Handle "death" */
  1491. if (p_ptr->is_dead) break;
  1492. /* Make a new level */
  1493. generate_cave();
  1494. }
  1495. /* Tell the UI we're done with the game state */
  1496. event_signal(EVENT_LEAVE_GAME);
  1497. /* Close stuff */
  1498. close_game();
  1499. }