PageRenderTime 51ms CodeModel.GetById 13ms RepoModel.GetById 0ms app.codeStats 1ms

/trunk/IronHellsOgre/src/ironhells/angband/birth.c

#
C | 1531 lines | 854 code | 292 blank | 385 comment | 186 complexity | 4d4ac96f562a46f5d67ae33864a73cd0 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, Apache-2.0
  1. /* $Id: birth.c 217 2004-11-12 14:22:13Z cipher $ */
  2. /*
  3. * Copyright (c) 1997 Ben Harrison, James E. Wilson, Robert A. Koeneke
  4. *
  5. * This software may be copied and distributed for educational, research,
  6. * and not for profit purposes provided that this copyright and statement
  7. * are included in all such copies. Other copyrights may also apply.
  8. */
  9. #include "angband.h"
  10. #include "script.h"
  11. /*
  12. * Forward declare
  13. */
  14. typedef struct birther birther;
  15. /*
  16. * A structure to hold "rolled" information
  17. */
  18. struct birther
  19. {
  20. s16b age;
  21. s16b wt;
  22. s16b ht;
  23. s16b sc;
  24. s32b au;
  25. s16b stat[A_MAX];
  26. char history[250];
  27. };
  28. /*
  29. * The last character displayed
  30. */
  31. static birther prev;
  32. /*
  33. * Current stats (when rolling a character).
  34. */
  35. static s16b stat_use[A_MAX];
  36. /*
  37. * Save the currently rolled data for later.
  38. */
  39. static void
  40. save_prev_data(void)
  41. {
  42. int i;
  43. /*** Save the current data ***/
  44. /* Save the data */
  45. prev.age = p_ptr->age;
  46. prev.wt = p_ptr->wt;
  47. prev.ht = p_ptr->ht;
  48. prev.sc = p_ptr->sc;
  49. prev.au = p_ptr->au;
  50. /* Save the stats */
  51. for(i = 0; i < A_MAX; i++)
  52. {
  53. prev.stat[i] = p_ptr->stat_max[i];
  54. }
  55. /* Save the history */
  56. my_strcpy(prev.history, p_ptr->history, sizeof(prev.history));
  57. }
  58. /*
  59. * Load the previously rolled data.
  60. */
  61. static void
  62. load_prev_data(void)
  63. {
  64. int i;
  65. birther temp;
  66. /*** Save the current data ***/
  67. /* Save the data */
  68. temp.age = p_ptr->age;
  69. temp.wt = p_ptr->wt;
  70. temp.ht = p_ptr->ht;
  71. temp.sc = p_ptr->sc;
  72. temp.au = p_ptr->au;
  73. /* Save the stats */
  74. for(i = 0; i < A_MAX; i++)
  75. {
  76. temp.stat[i] = p_ptr->stat_max[i];
  77. }
  78. /* Save the history */
  79. my_strcpy(temp.history, p_ptr->history, sizeof(temp.history));
  80. /*** Load the previous data ***/
  81. /* Load the data */
  82. p_ptr->age = prev.age;
  83. p_ptr->wt = prev.wt;
  84. p_ptr->ht = prev.ht;
  85. p_ptr->sc = prev.sc;
  86. p_ptr->au = prev.au;
  87. /* Load the stats */
  88. for(i = 0; i < A_MAX; i++)
  89. {
  90. p_ptr->stat_max[i] = prev.stat[i];
  91. p_ptr->stat_cur[i] = prev.stat[i];
  92. }
  93. /* Load the history */
  94. my_strcpy(p_ptr->history, prev.history, sizeof(p_ptr->history));
  95. /*** Save the current data ***/
  96. /* Save the data */
  97. prev.age = temp.age;
  98. prev.wt = temp.wt;
  99. prev.ht = temp.ht;
  100. prev.sc = temp.sc;
  101. prev.au = temp.au;
  102. /* Save the stats */
  103. for(i = 0; i < A_MAX; i++)
  104. {
  105. prev.stat[i] = temp.stat[i];
  106. }
  107. /* Save the history */
  108. my_strcpy(prev.history, temp.history, sizeof(prev.history));
  109. }
  110. /*
  111. * Adjust a stat by an amount.
  112. *
  113. * This just uses "modify_stat_value()" unless "maximize" mode is false,
  114. * and a positive bonus is being applied, in which case, a special hack
  115. * is used, with the "auto_roll" flag affecting the result.
  116. *
  117. * The "auto_roll" flag selects "maximal" changes for use with the
  118. * auto-roller initialization code. Otherwise, if "maximize" mode
  119. * is being used, the changes are fixed. Otherwise, semi-random
  120. * changes will occur, with larger changes at lower values.
  121. */
  122. static int
  123. adjust_stat(int value,
  124. int amount,
  125. int auto_roll)
  126. {
  127. /* Negative amounts or maximize mode */
  128. if((amount < 0) || adult_maximize)
  129. {
  130. return (modify_stat_value(value, amount));
  131. }
  132. /* Special hack */
  133. else
  134. {
  135. int i;
  136. /* Apply reward */
  137. for(i = 0; i < amount; i++)
  138. {
  139. if(value < 18)
  140. {
  141. value++;
  142. }
  143. else if(value < 18 + 70)
  144. {
  145. value += ((auto_roll ? 15 : randint(15)) + 5);
  146. }
  147. else if(value < 18 + 90)
  148. {
  149. value += ((auto_roll ? 6 : randint(6)) + 2);
  150. }
  151. else if(value < 18 + 100)
  152. {
  153. value++;
  154. }
  155. }
  156. }
  157. /* Return the result */
  158. return (value);
  159. }
  160. /*
  161. * Roll for a characters stats
  162. *
  163. * For efficiency, we include a chunk of "calc_bonuses()".
  164. */
  165. static void
  166. get_stats(void)
  167. {
  168. int i, j;
  169. int bonus;
  170. int dice[18];
  171. /* Roll and verify some stats */
  172. while(TRUE)
  173. {
  174. /* Roll some dice */
  175. for(j = i = 0; i < 18; i++)
  176. {
  177. /* Roll the dice */
  178. dice[i] = randint(3 + i % 3);
  179. /* Collect the maximum */
  180. j += dice[i];
  181. }
  182. /* Verify totals */
  183. if((j > 42) && (j < 54))
  184. break;
  185. }
  186. /* Roll the stats */
  187. for(i = 0; i < A_MAX; i++)
  188. {
  189. /* Extract 5 + 1d3 + 1d4 + 1d5 */
  190. j = 5 + dice[3 * i] + dice[3 * i + 1] + dice[3 * i + 2];
  191. /* Save that value */
  192. p_ptr->stat_max[i] = j;
  193. /* Obtain a "bonus" for "race" and "class" */
  194. bonus = rp_ptr->r_adj[i] + cp_ptr->c_adj[i];
  195. /* Variable stat maxes */
  196. if(adult_maximize)
  197. {
  198. /* Start fully healed */
  199. p_ptr->stat_cur[i] = p_ptr->stat_max[i];
  200. /* Efficiency -- Apply the racial/class bonuses */
  201. stat_use[i] = modify_stat_value(p_ptr->stat_max[i], bonus);
  202. }
  203. /* Fixed stat maxes */
  204. else
  205. {
  206. /* Apply the bonus to the stat (somewhat randomly) */
  207. stat_use[i] = adjust_stat(p_ptr->stat_max[i], bonus, FALSE);
  208. /* Save the resulting stat maximum */
  209. p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stat_use[i];
  210. }
  211. }
  212. }
  213. /*
  214. * Roll for some info that the auto-roller ignores
  215. */
  216. static void
  217. get_extra(void)
  218. {
  219. int i, j, min_value, max_value;
  220. /* Level one */
  221. p_ptr->max_lev = p_ptr->lev = 1;
  222. /* Experience factor */
  223. p_ptr->expfact = rp_ptr->r_exp + cp_ptr->c_exp;
  224. /* Hitdice */
  225. p_ptr->hitdie = rp_ptr->r_mhp + cp_ptr->c_mhp;
  226. /* Initial hitpoints */
  227. p_ptr->mhp = p_ptr->hitdie;
  228. /* Minimum hitpoints at highest level */
  229. min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8;
  230. min_value += PY_MAX_LEVEL;
  231. /* Maximum hitpoints at highest level */
  232. max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8;
  233. max_value += PY_MAX_LEVEL;
  234. /* Pre-calculate level 1 hitdice */
  235. p_ptr->player_hp[0] = p_ptr->hitdie;
  236. /* Roll out the hitpoints */
  237. while(TRUE)
  238. {
  239. /* Roll the hitpoint values */
  240. for(i = 1; i < PY_MAX_LEVEL; i++)
  241. {
  242. j = randint(p_ptr->hitdie);
  243. p_ptr->player_hp[i] = p_ptr->player_hp[i - 1] + j;
  244. }
  245. /* XXX Could also require acceptable "mid-level" hitpoints */
  246. /* Require "valid" hitpoints at highest level */
  247. if(p_ptr->player_hp[PY_MAX_LEVEL - 1] < min_value)
  248. continue;
  249. if(p_ptr->player_hp[PY_MAX_LEVEL - 1] > max_value)
  250. continue;
  251. /* Acceptable */
  252. break;
  253. }
  254. }
  255. /*
  256. * Get the racial history, and social class, using the "history charts".
  257. */
  258. static void
  259. get_history(void)
  260. {
  261. int i, chart, roll, social_class;
  262. /* Clear the previous history strings */
  263. p_ptr->history[0] = '\0';
  264. /* Initial social class */
  265. social_class = randint(4);
  266. /* Starting place */
  267. chart = rp_ptr->hist;
  268. /* Process the history */
  269. while(chart)
  270. {
  271. /* Start over */
  272. i = 0;
  273. /* Roll for nobility */
  274. roll = randint(100);
  275. /* Get the proper entry in the table */
  276. while((chart != h_info[i].chart) || (roll > h_info[i].roll))
  277. i++;
  278. /* Get the textual history */
  279. my_strcat(p_ptr->history, (h_text + h_info[i].text),
  280. sizeof(p_ptr->history));
  281. /* Add in the social class */
  282. social_class += (int) (h_info[i].bonus) - 50;
  283. /* Enter the next chart */
  284. chart = h_info[i].next;
  285. }
  286. /* Verify social class */
  287. if(social_class > 100)
  288. social_class = 100;
  289. else if(social_class < 1)
  290. social_class = 1;
  291. /* Save the social class */
  292. p_ptr->sc = social_class;
  293. }
  294. /*
  295. * Computes character's age, height, and weight
  296. */
  297. static void
  298. get_ahw(void)
  299. {
  300. /* Calculate the age */
  301. p_ptr->age = rp_ptr->b_age + randint(rp_ptr->m_age);
  302. /* Calculate the height/weight for males */
  303. if(p_ptr->psex == SEX_MALE)
  304. {
  305. p_ptr->ht = Rand_normal(rp_ptr->m_b_ht, rp_ptr->m_m_ht);
  306. p_ptr->wt = Rand_normal(rp_ptr->m_b_wt, rp_ptr->m_m_wt);
  307. }
  308. /* Calculate the height/weight for females */
  309. else if(p_ptr->psex == SEX_FEMALE)
  310. {
  311. p_ptr->ht = Rand_normal(rp_ptr->f_b_ht, rp_ptr->f_m_ht);
  312. p_ptr->wt = Rand_normal(rp_ptr->f_b_wt, rp_ptr->f_m_wt);
  313. }
  314. }
  315. /*
  316. * Get the player's starting money
  317. */
  318. static void
  319. get_money(void)
  320. {
  321. int i;
  322. int gold;
  323. /* Social Class determines starting gold */
  324. gold = (p_ptr->sc * 6) + randint(100) + 300;
  325. /* Process the stats */
  326. for(i = 0; i < A_MAX; i++)
  327. {
  328. /* Mega-Hack -- reduce gold for high stats */
  329. if(stat_use[i] >= 18 + 50)
  330. gold -= 300;
  331. else if(stat_use[i] >= 18 + 20)
  332. gold -= 200;
  333. else if(stat_use[i] > 18)
  334. gold -= 150;
  335. else
  336. gold -= (stat_use[i] - 8) * 10;
  337. }
  338. /* Minimum 100 gold */
  339. if(gold < 100)
  340. gold = 100;
  341. /* Save the gold */
  342. p_ptr->au = gold;
  343. }
  344. /*
  345. * Clear all the global "character" data
  346. */
  347. static void
  348. player_wipe(void)
  349. {
  350. int i;
  351. /* Wipe the player */
  352. (void) WIPE(p_ptr, player_type);
  353. /* Clear the inventory */
  354. for(i = 0; i < INVEN_TOTAL; i++)
  355. {
  356. object_wipe(&inventory[i]);
  357. }
  358. /* Start with no artifacts made yet */
  359. for(i = 0; i < z_info->a_max; i++)
  360. {
  361. artifact_type *a_ptr = &a_info[i];
  362. a_ptr->cur_num = 0;
  363. }
  364. /* Start with no quests */
  365. for(i = 0; i < MAX_Q_IDX; i++)
  366. {
  367. q_list[i].level = 0;
  368. }
  369. /* Add a special quest */
  370. q_list[0].level = 99;
  371. /* Add a second quest */
  372. q_list[1].level = 100;
  373. /* Reset the "objects" */
  374. for(i = 1; i < z_info->k_max; i++)
  375. {
  376. object_kind *k_ptr = &k_info[i];
  377. /* Reset "tried" */
  378. k_ptr->tried = FALSE;
  379. /* Reset "aware" */
  380. k_ptr->aware = FALSE;
  381. }
  382. /* Reset the "monsters" */
  383. for(i = 1; i < z_info->r_max; i++)
  384. {
  385. monster_race *r_ptr = &r_info[i];
  386. monster_lore *l_ptr = &l_list[i];
  387. /* Hack -- Reset the counter */
  388. r_ptr->cur_num = 0;
  389. /* Hack -- Reset the max counter */
  390. r_ptr->max_num = 100;
  391. /* Hack -- Reset the max counter */
  392. if(r_ptr->flags1 & (RF1_UNIQUE))
  393. r_ptr->max_num = 1;
  394. /* Clear player kills */
  395. l_ptr->pkills = 0;
  396. }
  397. /* Hack -- no ghosts */
  398. r_info[z_info->r_max - 1].max_num = 0;
  399. /* Hack -- Well fed player */
  400. p_ptr->food = PY_FOOD_FULL - 1;
  401. /* None of the spells have been learned yet */
  402. for(i = 0; i < PY_MAX_SPELLS; i++)
  403. p_ptr->spell_order[i] = 99;
  404. }
  405. /*
  406. * Init players with some belongings
  407. *
  408. * Having an item makes the player "aware" of its purpose.
  409. */
  410. static void
  411. player_outfit(void)
  412. {
  413. int i;
  414. const start_item *e_ptr;
  415. object_type *i_ptr;
  416. object_type object_type_body;
  417. /* Hack -- Give the player his equipment */
  418. for(i = 0; i < MAX_START_ITEMS; i++)
  419. {
  420. /* Access the item */
  421. e_ptr = &(cp_ptr->start_items[i]);
  422. /* Get local object */
  423. i_ptr = &object_type_body;
  424. /* Hack -- Give the player an object */
  425. if(e_ptr->tval > 0)
  426. {
  427. /* Get the object_kind */
  428. int k_idx =
  429. lookup_kind(e_ptr->tval, e_ptr->sval);
  430. /* Valid item? */
  431. if(!k_idx)
  432. continue;
  433. /* Prepare the item */
  434. object_prep(i_ptr, k_idx);
  435. i_ptr->number = (byte) rand_range(e_ptr->min, e_ptr->max);
  436. object_aware(i_ptr);
  437. object_known(i_ptr);
  438. (void) inven_carry(i_ptr);
  439. }
  440. }
  441. }
  442. /*
  443. * Helper function for 'player_birth()'.
  444. *
  445. * This function allows the player to select a sex, race, and class, and
  446. * modify options (including the birth options).
  447. */
  448. static bool
  449. player_birth_aux_1(void)
  450. {
  451. int k, n, i;
  452. cptr str;
  453. char ch;
  454. #if 0
  455. char p1 = '(';
  456. #endif
  457. char p2 = ')';
  458. char buf[80];
  459. /*** Instructions ***/
  460. /* Clear screen */
  461. Disp_clear();
  462. /* Display some helpful information */
  463. Disp_putstr(5, 10, -1, COLOR_WHITE,
  464. "Please answer the following questions. Most of the questions");
  465. Disp_putstr(5, 11, -1, COLOR_WHITE,
  466. "display a set of standard answers, and many will also accept");
  467. Disp_putstr(5, 12, -1, COLOR_WHITE,
  468. "some special responses, including 'Q' to quit, 'S' to restart,");
  469. Disp_putstr(5, 13, -1, COLOR_WHITE,
  470. "and '?' for help. Note that 'Q' and 'S' must be capitalized.");
  471. /*** Player sex ***/
  472. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_GENDER);
  473. /* Extra info */
  474. Disp_putstr(5, 15, -1, COLOR_WHITE,
  475. "Your 'sex' does not have any significant gameplay effects.");
  476. /* Prompt for "Sex" */
  477. for(n = 0; n < MAX_SEXES; n++)
  478. {
  479. /* Analyze */
  480. p_ptr->psex = n;
  481. sp_ptr = &sex_info[p_ptr->psex];
  482. str = sp_ptr->title;
  483. /* Display */
  484. strnfmt(buf, sizeof(buf), "%c%c %s", I2A(n), p2, str);
  485. put_str(buf, 21 + (n / 5), 2 + 15 * (n % 5));
  486. }
  487. /* Choose */
  488. sp_ptr = NULL;
  489. while(1)
  490. {
  491. sprintf(buf, "Choose a sex (%c-%c, or * for random): ",
  492. I2A(0), I2A(n - 1));
  493. put_str(buf, 20, 2);
  494. ch = inkey();
  495. if(ch == 'Q')
  496. quit(NULL);
  497. if(ch == 'S')
  498. return (FALSE);
  499. k = (islower((unsigned char) ch) ? A2I(ch) : -1);
  500. if(ch == ESCAPE)
  501. ch = '*';
  502. if(ch == '*')
  503. k = rand_int(MAX_SEXES);
  504. if((k >= 0) && (k < n))
  505. break;
  506. if(ch == '?')
  507. do_cmd_help();
  508. else
  509. bell("Illegal sex!");
  510. }
  511. /* Set sex */
  512. p_ptr->psex = k;
  513. sp_ptr = &sex_info[p_ptr->psex];
  514. /* Sex */
  515. put_str("Sex", 3, 1);
  516. c_put_str(COLOR_L_BLUE, sp_ptr->title, 3, 8);
  517. /* Clean up */
  518. clear_from(15);
  519. /*** Player race ***/
  520. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_RACE);
  521. /* Extra info */
  522. Disp_putstr(5, 15, -1, COLOR_WHITE,
  523. "Your 'race' determines various intrinsic factors and bonuses.");
  524. /* Dump races */
  525. for(n = 0; n < z_info->p_max; n++)
  526. {
  527. /* Analyze */
  528. p_ptr->prace = n;
  529. rp_ptr = &p_info[n];
  530. str = p_name + rp_ptr->name;
  531. /* Display */
  532. strnfmt(buf, sizeof(buf), "%c%c %s", I2A(n), p2, str);
  533. put_str(buf, 21 + (n / 5), 2 + 15 * (n % 5));
  534. }
  535. /* Choose */
  536. rp_ptr = NULL;
  537. while(1)
  538. {
  539. sprintf(buf, "Choose a race (%c-%c, or * for random): ",
  540. I2A(0), I2A(n - 1));
  541. put_str(buf, 20, 2);
  542. ch = inkey();
  543. if(ch == 'Q')
  544. quit(NULL);
  545. if(ch == 'S')
  546. return (FALSE);
  547. k = (islower((unsigned char) ch) ? A2I(ch) : -1);
  548. if(ch == ESCAPE)
  549. ch = '*';
  550. if(ch == '*')
  551. k = rand_int(z_info->p_max);
  552. if((k >= 0) && (k < n))
  553. break;
  554. if(ch == '?')
  555. do_cmd_help();
  556. else
  557. bell("Illegal race!");
  558. }
  559. /* Set race */
  560. p_ptr->prace = k;
  561. rp_ptr = &p_info[p_ptr->prace];
  562. /* Race */
  563. put_str("Race", 4, 1);
  564. c_put_str(COLOR_L_BLUE, p_name + rp_ptr->name, 4, 8);
  565. /* Clean up */
  566. clear_from(15);
  567. /*** Player class ***/
  568. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_CLASS);
  569. /* Extra info */
  570. Disp_putstr(5, 15, -1, COLOR_WHITE,
  571. "Your 'class' determines various intrinsic abilities and bonuses.");
  572. Disp_putstr(5, 16, -1, COLOR_WHITE,
  573. "Any entries with a (*) should only be used by advanced players.");
  574. /* Dump classes */
  575. for(n = 0; n < z_info->c_max; n++)
  576. {
  577. cptr mod = "";
  578. /* Analyze */
  579. p_ptr->pclass = n;
  580. cp_ptr = &c_info[p_ptr->pclass];
  581. mp_ptr = &cp_ptr->spells;
  582. str = c_name + cp_ptr->name;
  583. /* Verify legality */
  584. if(!(rp_ptr->choice & (1L << n)))
  585. mod = " (*)";
  586. /* Display */
  587. strnfmt(buf, sizeof(buf), "%c%c %s%s", I2A(n), p2, str, mod);
  588. put_str(buf, 21 + (n / 3), 2 + 20 * (n % 3));
  589. }
  590. /* Get a class */
  591. cp_ptr = NULL;
  592. while(1)
  593. {
  594. sprintf(buf, "Choose a class (%c-%c, or * for random): ",
  595. I2A(0), I2A(n - 1));
  596. put_str(buf, 20, 2);
  597. ch = inkey();
  598. if(ch == 'Q')
  599. quit(NULL);
  600. if(ch == 'S')
  601. return (FALSE);
  602. k = (islower((unsigned char) ch) ? A2I(ch) : -1);
  603. if(ch == ESCAPE)
  604. ch = '*';
  605. if(ch == '*')
  606. {
  607. while(1)
  608. {
  609. k = rand_int(z_info->c_max);
  610. /* Try again if not a legal choice */
  611. if(!(rp_ptr->choice & (1L << k)))
  612. continue;
  613. break;
  614. }
  615. }
  616. if((k >= 0) && (k < n))
  617. break;
  618. if(ch == '?')
  619. do_cmd_help();
  620. else
  621. bell("Illegal class!");
  622. }
  623. /* Set class */
  624. p_ptr->pclass = k;
  625. cp_ptr = &c_info[p_ptr->pclass];
  626. mp_ptr = &cp_ptr->spells;
  627. /* Class */
  628. put_str("Class", 5, 1);
  629. c_put_str(COLOR_L_BLUE, c_name + cp_ptr->name, 5, 8);
  630. /* Clean up */
  631. clear_from(15);
  632. /*** Birth options ***/
  633. fprintf(stderr, "player_birth_aux_1(): options?\n");
  634. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_OPTIONS_QUERY);
  635. /* Extra info */
  636. Disp_putstr(5, 15, -1, COLOR_WHITE,
  637. "You can change your options at any time, but the 'Birth' options");
  638. Disp_putstr(5, 16, -1, COLOR_WHITE,
  639. "must be changed now to affect the birth of this character.");
  640. /* Verify birth options */
  641. fprintf(stderr, "player_birth_aux_1(): options input loop\n");
  642. while(1)
  643. {
  644. sprintf(buf, "Modify options (y/n)? ");
  645. put_str(buf, 20, 2);
  646. ch = inkey();
  647. fprintf(stderr, "player_birth_aux_1(): ch = %c\n", ch);
  648. if(ch == 'Q')
  649. quit(NULL);
  650. if(ch == 'S')
  651. return (FALSE);
  652. if((ch == '\r') || (ch == '\n'))
  653. break;
  654. if(ch == 'y' || ch == 'n')
  655. break;
  656. if(ch == '?')
  657. do_cmd_help();
  658. else
  659. bell("Illegal answer!");
  660. }
  661. /* Verify */
  662. fprintf(stderr, "player_birth_aux_1(): verify\n");
  663. if(ch == 'y')
  664. {
  665. Disp_xtra(DISP_XTRA_PREP, DISPLAY_OPTIONS);
  666. Disp_xtra(DISP_XTRA_SHOW, DISPLAY_OPTIONS);
  667. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_OPTIONS);
  668. /* Interact with options */
  669. do_cmd_options();
  670. }
  671. /* Set adult options from birth options */
  672. fprintf(stderr, "player_birth_aux_1(): set adult options\n");
  673. for(i = OPT_BIRTH; i < OPT_CHEAT; i++)
  674. {
  675. op_ptr->opt[OPT_ADULT + (i - OPT_BIRTH)] = op_ptr->opt[i];
  676. }
  677. /* Reset score options from cheat options */
  678. for(i = OPT_CHEAT; i < OPT_ADULT; i++)
  679. {
  680. op_ptr->opt[OPT_SCORE + (i - OPT_CHEAT)] = op_ptr->opt[i];
  681. }
  682. /* Clean up */
  683. clear_from(10);
  684. /* Done */
  685. fprintf(stderr, "player_birth_aux_1(): return TRUE\n");
  686. return (TRUE);
  687. }
  688. /*
  689. * Initial stat costs (initial stats always range from 10 to 18 inclusive).
  690. */
  691. static const int birth_stat_costs[(18 - 10) + 1] =
  692. { 0, 1, 2, 4, 7, 11, 16, 22, 30 };
  693. /*
  694. * Helper function for 'player_birth()'.
  695. *
  696. * This function handles "point-based" character creation.
  697. *
  698. * The player selects, for each stat, a value from 10 to 18 (inclusive),
  699. * each costing a certain amount of points (as above), from a pool of 48
  700. * available points, to which race/class modifiers are then applied.
  701. *
  702. * Each unused point is converted into 100 gold pieces.
  703. */
  704. static bool
  705. player_birth_aux_2(void)
  706. {
  707. int i;
  708. int row = 3;
  709. int col = 42;
  710. int stat = 0;
  711. int stats[A_MAX];
  712. int cost;
  713. char ch;
  714. char buf[80];
  715. /* Set the display */
  716. Disp_xtra(DISP_XTRA_STAGE,
  717. SCENE_NEW_CHARACTER_STAGE_STATS_POINTBASED);
  718. /* Initialize stats */
  719. for(i = 0; i < A_MAX; i++)
  720. {
  721. /* Initial stats */
  722. stats[i] = 10;
  723. }
  724. /* Roll for base hitpoints */
  725. get_extra();
  726. /* Roll for age/height/weight */
  727. get_ahw();
  728. /* Roll for social class */
  729. get_history();
  730. /* Interact */
  731. while(1)
  732. {
  733. /* Reset cost */
  734. cost = 0;
  735. /* Process stats */
  736. for(i = 0; i < A_MAX; i++)
  737. {
  738. /* Variable stat maxes */
  739. if(adult_maximize)
  740. {
  741. /* Reset stats */
  742. p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stats[i];
  743. }
  744. /* Fixed stat maxes */
  745. else
  746. {
  747. /* Obtain a "bonus" for "race" and "class" */
  748. int bonus =
  749. rp_ptr->r_adj[i] + cp_ptr->c_adj[i];
  750. /* Apply the racial/class bonuses */
  751. p_ptr->stat_cur[i] = p_ptr->stat_max[i] =
  752. modify_stat_value(stats[i], bonus);
  753. }
  754. /* Total cost */
  755. cost += birth_stat_costs[stats[i] - 10];
  756. }
  757. /* Restrict cost */
  758. if(cost > 48)
  759. {
  760. /* Warning */
  761. bell("Excessive stats!");
  762. /* Reduce stat */
  763. stats[stat]--;
  764. /* Recompute costs */
  765. continue;
  766. }
  767. /* Gold is inversely proportional to cost */
  768. p_ptr->au = (100 * (48 - cost)) + 100;
  769. /* Calculate the bonuses and hitpoints */
  770. p_ptr->update |= (PU_BONUS | PU_HP);
  771. /* Update stuff */
  772. update_stuff();
  773. /* Fully healed */
  774. p_ptr->chp = p_ptr->mhp;
  775. /* Fully rested */
  776. p_ptr->csp = p_ptr->msp;
  777. /* Display the player */
  778. display_player(0);
  779. /* Display the costs header */
  780. put_str("Cost", row - 1, col + 32);
  781. /* Display the costs */
  782. for(i = 0; i < A_MAX; i++)
  783. {
  784. /* Display cost */
  785. sprintf(buf, "%4d", birth_stat_costs[stats[i] - 10]);
  786. put_str(buf, row + i, col + 32);
  787. }
  788. /* Prompt XXX XXX XXX */
  789. sprintf(buf,
  790. "Total Cost %2d/48. Use 2/8 to move, 4/6 to modify, 'Enter' to accept.",
  791. cost);
  792. prt(buf, 0, 0);
  793. /* Place cursor just after cost of current stat */
  794. Disp_gotoxy(col + 36, row + stat);
  795. Disp_param(DISPLAY_CHARACTER, DISP_PARAM_VAR1, (void *)(stat + 1));
  796. /* Get key */
  797. ch = inkey();
  798. /* Quit */
  799. if(ch == 'Q')
  800. quit(NULL);
  801. /* Start over */
  802. if(ch == 'S')
  803. return (FALSE);
  804. /* Done */
  805. if((ch == '\r') || (ch == '\n'))
  806. break;
  807. /* Prev stat */
  808. if(ch == '8')
  809. {
  810. stat = (stat + A_MAX - 1) % A_MAX;
  811. }
  812. /* Next stat */
  813. if(ch == '2')
  814. {
  815. stat = (stat + 1) % A_MAX;
  816. }
  817. /* Decrease stat */
  818. if((ch == '4') && (stats[stat] > 10))
  819. {
  820. stats[stat]--;
  821. }
  822. /* Increase stat */
  823. if((ch == '6') && (stats[stat] < 18))
  824. {
  825. stats[stat]++;
  826. }
  827. }
  828. /* Done */
  829. return (TRUE);
  830. }
  831. /*
  832. * Helper function for 'player_birth()'.
  833. *
  834. * This function handles "auto-rolling" and "random-rolling".
  835. *
  836. * The delay may be reduced, but is recommended to keep players
  837. * from continuously rolling up characters, which can be VERY
  838. * expensive CPU wise. And it cuts down on player stupidity.
  839. */
  840. static bool
  841. player_birth_aux_3(void)
  842. {
  843. int i, j, m, v;
  844. bool flag;
  845. bool prev = FALSE;
  846. char ch;
  847. char b1 = '[';
  848. char b2 = ']';
  849. char buf[80];
  850. #ifdef ALLOW_AUTOROLLER
  851. s16b stat_limit[A_MAX];
  852. s32b stat_match[A_MAX];
  853. s32b auto_round = 0L;
  854. s32b last_round;
  855. /*** Autoroll ***/
  856. /* Initialize */
  857. if(adult_auto_roller)
  858. {
  859. int mval[A_MAX];
  860. char inp[80];
  861. Disp_xtra(DISP_XTRA_STAGE,
  862. SCENE_NEW_CHARACTER_STAGE_STATS_AUTOROLLER);
  863. /* Extra info */
  864. Disp_putstr(5, 10, -1, COLOR_WHITE,
  865. "The auto-roller will automatically ignore characters which do");
  866. Disp_putstr(5, 11, -1, COLOR_WHITE,
  867. "not meet the minimum values for any stats specified below.");
  868. Disp_putstr(5, 12, -1, COLOR_WHITE,
  869. "Note that stats are not independent, so it is not possible to");
  870. Disp_putstr(5, 13, -1, COLOR_WHITE,
  871. "get perfect (or even high) values for all your stats.");
  872. /* Prompt for the minimum stats */
  873. put_str("Enter minimum value for: ", 15, 2);
  874. /* Output the maximum stats */
  875. for(i = 0; i < A_MAX; i++)
  876. {
  877. /* Reset the "success" counter */
  878. stat_match[i] = 0;
  879. /* Race/Class bonus */
  880. j = rp_ptr->r_adj[i] + cp_ptr->c_adj[i];
  881. /* Obtain the "maximal" stat */
  882. m = adjust_stat(17, j, TRUE);
  883. /* Save the maximum */
  884. mval[i] = m;
  885. /* Extract a textual format */
  886. /* cnv_stat(m, inp); */
  887. /* Above 18 */
  888. if(m > 18)
  889. {
  890. sprintf(inp, "(Max of 18/%02d):", (m - 18));
  891. }
  892. /* From 3 to 18 */
  893. else
  894. {
  895. sprintf(inp, "(Max of %2d):", m);
  896. }
  897. /* Prepare a prompt */
  898. strnfmt(buf, sizeof(buf), "%-5s%-20s", stat_names[i], inp);
  899. /* Dump the prompt */
  900. put_str(buf, 16 + i, 5);
  901. Disp_xtra(DISP_XTRA_PREP, DISPLAY_DIALOG);
  902. Disp_param(DISPLAY_DIALOG, DISP_PARAM_BUFFER1, (void *)buf);
  903. Disp_param(DISPLAY_DIALOG, DISP_PARAM_BUFFER2, (void *)inp);
  904. #if 0
  905. }
  906. /* Input the minimum stats */
  907. for(i = 0; i < A_MAX; i++)
  908. {
  909. #endif
  910. /* Get a minimum stat */
  911. while(TRUE)
  912. {
  913. char *s;
  914. /* Move the cursor */
  915. put_str("", 16 + i, 30);
  916. /* Default */
  917. strcpy(inp, "");
  918. /* Get a response (or escape) */
  919. Disp_xtra(DISP_XTRA_SHOW, DISPLAY_DIALOG);
  920. if(!askfor_aux(inp, 9))
  921. inp[0] = '\0';
  922. /* Hack -- add a fake slash */
  923. strcat(inp, "/");
  924. /* Hack -- look for the "slash" */
  925. s = strchr(inp, '/');
  926. /* Hack -- Nuke the slash */
  927. *s++ = '\0';
  928. /* Hack -- Extract an input */
  929. v = atoi(inp) + atoi(s);
  930. /* Break on valid input */
  931. if(v <= mval[i])
  932. break;
  933. }
  934. Disp_xtra(DISP_XTRA_HIDE, DISPLAY_DIALOG);
  935. /* Save the minimum stat */
  936. stat_limit[i] = (v > 0) ? v : 0;
  937. }
  938. }
  939. #endif /* ALLOW_AUTOROLLER */
  940. /* Clean up */
  941. clear_from(10);
  942. /*** Generate ***/
  943. Disp_xtra(DISP_XTRA_PREP, DISPLAY_CHARACTER);
  944. Disp_xtra(DISP_XTRA_SHOW, DISPLAY_CHARACTER);
  945. /* Roll */
  946. while(TRUE)
  947. {
  948. int col = 42;
  949. /* Feedback */
  950. if(adult_auto_roller)
  951. {
  952. Disp_clear();
  953. /* Labels */
  954. put_str(" Limit", 2, col + 5);
  955. put_str(" Freq", 2, col + 13);
  956. put_str(" Roll", 2, col + 24);
  957. /* Put the minimal stats */
  958. for(i = 0; i < A_MAX; i++)
  959. {
  960. /* Label stats */
  961. put_str(stat_names[i], 3 + i, col);
  962. /* Put the stat */
  963. cnv_stat(stat_limit[i], buf);
  964. c_put_str(COLOR_L_BLUE, buf, 3 + i, col + 5);
  965. }
  966. /* Note when we started */
  967. last_round = auto_round;
  968. /* Label count */
  969. put_str("Round:", 10, col + 13);
  970. /* Indicate the state */
  971. put_str("(Hit ESC to stop)", 12, col + 13);
  972. /* Auto-roll */
  973. while(1)
  974. {
  975. bool accept = TRUE;
  976. /* Get a new character */
  977. get_stats();
  978. /* Advance the round */
  979. auto_round++;
  980. /* Hack -- Prevent overflow */
  981. if(auto_round >= 1000000L)
  982. break;
  983. /* Check and count acceptable stats */
  984. for(i = 0; i < A_MAX; i++)
  985. {
  986. /* This stat is okay */
  987. if(stat_use[i] >= stat_limit[i])
  988. {
  989. stat_match[i]++;
  990. }
  991. /* This stat is not okay */
  992. else
  993. {
  994. accept = FALSE;
  995. }
  996. }
  997. /* Break if "happy" */
  998. if(accept)
  999. break;
  1000. /* Take note every 25 rolls */
  1001. flag = (!(auto_round % 25L));
  1002. /* Update display occasionally */
  1003. if(flag || (auto_round < last_round + 100))
  1004. {
  1005. /* Put the stats (and percents) */
  1006. for(i = 0; i < A_MAX; i++)
  1007. {
  1008. /* Put the stat */
  1009. cnv_stat(stat_use[i], buf);
  1010. c_put_str(COLOR_L_GREEN, buf,
  1011. 3 + i, col + 24);
  1012. /* Put the percent */
  1013. if(stat_match[i])
  1014. {
  1015. int p = 1000L *
  1016. stat_match[i] / auto_round;
  1017. byte attr =
  1018. (p <
  1019. 100) ? COLOR_YELLOW : COLOR_L_GREEN;
  1020. sprintf(buf,
  1021. "%3d.%d%%", p / 10, p % 10);
  1022. c_put_str(attr, buf, 3 + i, col + 13);
  1023. }
  1024. /* Never happened */
  1025. else
  1026. {
  1027. c_put_str(COLOR_RED,
  1028. "(NONE)", 3 + i, col + 13);
  1029. }
  1030. }
  1031. /* Dump round */
  1032. put_str(format("%10ld", auto_round),
  1033. 10, col + 20);
  1034. /* Make sure they see everything */
  1035. Disp_fresh();
  1036. /* Delay 1/10 second */
  1037. if(flag)
  1038. Disp_xtra(DISP_XTRA_DELAY, 100);
  1039. /* Do not wait for a key */
  1040. inkey_scan = TRUE;
  1041. /* Check for a keypress */
  1042. if(inkey())
  1043. break;
  1044. }
  1045. }
  1046. }
  1047. /* Otherwise just get a character */
  1048. else
  1049. {
  1050. /* Get a new character */
  1051. get_stats();
  1052. }
  1053. /* Flush input */
  1054. flush();
  1055. /*** Display ***/
  1056. /* Force the overlay to redisplay its stats */
  1057. Disp_param(DISPLAY_CHARACTER, DISP_PARAM_RECALC, NULL);
  1058. /* Set the display */
  1059. Disp_xtra(DISP_XTRA_STAGE,
  1060. SCENE_NEW_CHARACTER_STAGE_STATS_APPROVE);
  1061. /* Roll for base hitpoints */
  1062. get_extra();
  1063. /* Roll for age/height/weight */
  1064. get_ahw();
  1065. /* Roll for social class */
  1066. get_history();
  1067. /* Roll for gold */
  1068. get_money();
  1069. /* Input loop */
  1070. while(TRUE)
  1071. {
  1072. fprintf(stderr, "player_birth_aux_3(): top of input loop\n");
  1073. /* Calculate the bonuses and hitpoints */
  1074. p_ptr->update |= (PU_BONUS | PU_HP);
  1075. /* Update stuff */
  1076. update_stuff();
  1077. /* Fully healed */
  1078. p_ptr->chp = p_ptr->mhp;
  1079. /* Fully rested */
  1080. p_ptr->csp = p_ptr->msp;
  1081. /* Display the player */
  1082. display_player(0);
  1083. /* Prepare a prompt (must squeeze everything in) */
  1084. Disp_gotoxy(2, 23);
  1085. Disp_addch(COLOR_WHITE, b1);
  1086. Disp_addstr(-1, COLOR_WHITE, "'r' to reroll");
  1087. if(prev)
  1088. Disp_addstr(-1, COLOR_WHITE, ", 'p' for prev");
  1089. Disp_addstr(-1, COLOR_WHITE, ", or 'Enter' to accept");
  1090. Disp_addch(COLOR_WHITE, b2);
  1091. /* Prompt and get a command */
  1092. fprintf(stderr, "player_birth_aux_3(): get character\n");
  1093. ch = inkey();
  1094. fprintf(stderr, "player_birth_aux_3(): ch = '%c'\n", ch);
  1095. /* Quit */
  1096. if(ch == 'Q')
  1097. quit(NULL);
  1098. /* Start over */
  1099. if(ch == 'S')
  1100. return (FALSE);
  1101. /* 'Enter' accepts the roll */
  1102. if((ch == '\r') || (ch == '\n'))
  1103. break;
  1104. /* Reroll this character */
  1105. if((ch == ' ') || (ch == 'r'))
  1106. break;
  1107. /* Previous character */
  1108. if(prev && (ch == 'p'))
  1109. {
  1110. load_prev_data();
  1111. continue;
  1112. }
  1113. /* Help */
  1114. if(ch == '?')
  1115. {
  1116. do_cmd_help();
  1117. continue;
  1118. }
  1119. /* Warning */
  1120. bell("Illegal auto-roller command!");
  1121. }
  1122. /* Are we done? */
  1123. fprintf(stderr, "player_birth_aux_3(): are we done?\n");
  1124. if((ch == '\r') || (ch == '\n'))
  1125. break;
  1126. /* Save this for the "previous" character */
  1127. save_prev_data();
  1128. /* Note that a previous roll exists */
  1129. prev = TRUE;
  1130. }
  1131. /* Clear prompt */
  1132. clear_from(23);
  1133. /* Done */
  1134. fprintf(stderr, "player_birth_aux_3(): return(true);\n");
  1135. return (TRUE);
  1136. }
  1137. /*
  1138. * Helper function for 'player_birth()'.
  1139. *
  1140. * See "display_player" for screen layout code.
  1141. */
  1142. static int
  1143. player_birth_aux(void)
  1144. {
  1145. char ch;
  1146. cptr prompt =
  1147. "['Q' to suicide, 'S' to start over, or any other key to continue]";
  1148. /* Ask questions */
  1149. if(!player_birth_aux_1())
  1150. return (FALSE);
  1151. /* Point-based */
  1152. if(adult_point_based)
  1153. {
  1154. /* Point based */
  1155. fprintf(stderr, "player_birth_aux(): point-based\n");
  1156. if(!player_birth_aux_2())
  1157. return (FALSE);
  1158. }
  1159. /* Random */
  1160. else
  1161. {
  1162. /* Auto-roll */
  1163. fprintf(stderr, "player_birth_aux(): auto-roll\n");
  1164. if(!player_birth_aux_3())
  1165. return (FALSE);
  1166. }
  1167. /* Set the display */
  1168. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_NAME);
  1169. /* Get a name, prepare savefile */
  1170. get_name();
  1171. /* Display the player */
  1172. display_player(0);
  1173. /* Set the display */
  1174. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_FINALIZE);
  1175. /* Prompt for it */
  1176. prt(prompt, Disp->hgt - 1, Disp->wid / 2 - strlen(prompt) / 2);
  1177. /* Get a key */
  1178. ch = inkey();
  1179. /* Quit */
  1180. if(ch == 'Q')
  1181. return(-1);
  1182. // quit(NULL);
  1183. /* Start over */
  1184. if(ch == 'S')
  1185. return (FALSE);
  1186. /* Accept */
  1187. return (TRUE);
  1188. }
  1189. /*
  1190. * Create a new character.
  1191. *
  1192. * Note that we may be called with "junk" leftover in the various
  1193. * fields, so we must be sure to clear them first.
  1194. */
  1195. int
  1196. player_birth(void)
  1197. {
  1198. int i, n;
  1199. /* Create a new character */
  1200. while(1)
  1201. {
  1202. int rc;
  1203. Disp_xtra(DISP_XTRA_SCENE, SCENE_NEW_CHARACTER);
  1204. Disp_xtra(DISP_XTRA_STAGE, SCENE_NEW_CHARACTER_STAGE_GENDER);
  1205. /* Wipe the player */
  1206. player_wipe();
  1207. /* Roll up a new character */
  1208. rc = player_birth_aux();
  1209. if(rc == -1)
  1210. return -1;
  1211. if(rc)
  1212. break;
  1213. }
  1214. /* Note player birth in the message recall */
  1215. message_add(" ", MSG_GENERIC);
  1216. message_add(" ", MSG_GENERIC);
  1217. message_add("====================", MSG_GENERIC);
  1218. message_add(" ", MSG_GENERIC);
  1219. message_add(" ", MSG_GENERIC);
  1220. /* Hack -- outfit the player */
  1221. player_outfit();
  1222. /* Event -- player birth done */
  1223. player_birth_done_hook();
  1224. /* Shops */
  1225. for(n = 0; n < MAX_STORES; n++)
  1226. {
  1227. /* Initialize */
  1228. store_init(n);
  1229. /* Ignore home */
  1230. if(n == STORE_HOME)
  1231. continue;
  1232. /* Maintain the shop (ten times) */
  1233. for(i = 0; i < 10; i++)
  1234. {
  1235. store_maint(n);
  1236. }
  1237. }
  1238. return 0;
  1239. }