summaryrefslogtreecommitdiff
path: root/src/birth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/birth.c')
-rw-r--r--src/birth.c3825
1 files changed, 0 insertions, 3825 deletions
diff --git a/src/birth.c b/src/birth.c
deleted file mode 100644
index f073b2f6..00000000
--- a/src/birth.c
+++ /dev/null
@@ -1,3825 +0,0 @@
-/* File: birth.c */
-
-/* Purpose: create a player character */
-
-/*
- * Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
- *
- * This software may be copied and distributed for educational, research, and
- * not for profit purposes provided that this copyright and statement are
- * included in all such copies.
- */
-
-#include "angband.h"
-
-/*
- * How often the autoroller will update the display and pause
- * to check for user interuptions.
- * Bigger values will make the autoroller faster, but slower
- * system may have problems because the user can't stop the
- * autoroller for this number of rolls.
- */
-#define AUTOROLLER_STEP 25L
-
-/*
- * Maximum number of tries for selection of a proper quest monster
- */
-#define MAX_TRIES 100
-
-/* Max quests */
-static byte max_quests = 0;
-
-/*
- * Current stats
- */
-static s16b stat_use[6];
-
-/*
- * Autoroll limit
- */
-static s16b stat_limit[6];
-
-/*
- * Autoroll matches
- */
-static s32b stat_match[6];
-
-/*
- * Autoroll round
- */
-static s32b auto_round;
-
-/*
- * Last round
- */
-static s32b last_round;
-
-/* Human */
-static char *human_syllable1[] =
-{
- "Ab", "Ac", "Ad", "Af", "Agr", "Ast", "As", "Al", "Adw", "Adr", "Ar",
- "B", "Br", "C", "Cr", "Ch", "Cad", "D", "Dr", "Dw", "Ed", "Eth", "Et",
- "Er", "El", "Eow", "F", "Fr", "G", "Gr", "Gw", "Gal", "Gl", "H", "Ha",
- "Ib", "Jer", "K", "Ka", "Ked", "L", "Loth", "Lar", "Leg", "M", "Mir",
- "N", "Nyd", "Ol", "Oc", "On", "P", "Pr", "R", "Rh", "S", "Sev", "T",
- "Tr", "Th", "V", "Y", "Z", "W", "Wic",
-};
-
-static char *human_syllable2[] =
-{
- "a", "ae", "au", "ao", "are", "ale", "ali", "ay", "ardo", "e", "ei",
- "ea", "eri", "era", "ela", "eli", "enda", "erra", "i", "ia", "ie",
- "ire", "ira", "ila", "ili", "ira", "igo", "o", "oa", "oi", "oe",
- "ore", "u", "y",
-};
-
-static char *human_syllable3[] =
-{
- "a", "and", "b", "bwyn", "baen", "bard", "c", "ctred", "cred", "ch",
- "can", "d", "dan", "don", "der", "dric", "dfrid", "dus", "f", "g",
- "gord", "gan", "l", "li", "lgrin", "lin", "lith", "lath", "loth",
- "ld", "ldric", "ldan", "m", "mas", "mos", "mar", "mond", "n",
- "nydd", "nidd", "nnon", "nwan", "nyth", "nad", "nn", "nnor", "nd",
- "p", "r", "ron", "rd", "s", "sh", "seth", "sean", "t", "th", "tha",
- "tlan", "trem", "tram", "v", "vudd", "w", "wan", "win", "wyn", "wyr",
- "wyr", "wyth",
-};
-
-/*
- * Random Name Generator
- * based on a Javascript by Michael Hensley
- * "http://geocities.com/timessquare/castle/6274/"
- */
-static void create_random_name(int race, char *name)
-{
- char *syl1, *syl2, *syl3;
-
- int idx;
-
-
- /* Paranoia */
- if (!name) return;
-
- /* Select the monster type */
- switch (race)
- {
- /* Create the monster name */
-
- /* Use human ones */
- default:
- {
- idx = rand_int(sizeof(human_syllable1) / sizeof(char *));
- syl1 = human_syllable1[idx];
- idx = rand_int(sizeof(human_syllable2) / sizeof(char *));
- syl2 = human_syllable2[idx];
- idx = rand_int(sizeof(human_syllable3) / sizeof(char *));
- syl3 = human_syllable3[idx];
-
- break;
- }
- }
-
- /* Concatenate selected syllables */
- strnfmt(name, 32, "%s%s%s", syl1, syl2, syl3);
-}
-
-
-void print_desc_aux(cptr txt, int y, int xx)
-{
- int i = -1, x = xx;
-
-
- while (txt[++i] != 0)
- {
- if (txt[i] == '\n')
- {
- x = xx;
- y++;
- }
- else
- {
- Term_putch(x++, y, TERM_YELLOW, txt[i]);
- }
- }
-}
-
-void print_desc(cptr txt)
-{
- print_desc_aux(txt, 12, 1);
-}
-
-/*
- * Save the current data for later
- */
-static void save_prev_data(void)
-{
- int i;
-
-
- /*** Save the current data ***/
-
- /* Save the data */
- previous_char.sex = p_ptr->psex;
- previous_char.race = p_ptr->prace;
- previous_char.rmod = p_ptr->pracem;
- previous_char.pclass = p_ptr->pclass;
- previous_char.spec = p_ptr->pspec;
-
- previous_char.quests = max_quests;
-
- previous_char.god = p_ptr->pgod;
- previous_char.grace = p_ptr->grace;
-
- previous_char.age = p_ptr->age;
- previous_char.wt = p_ptr->wt;
- previous_char.ht = p_ptr->ht;
- previous_char.sc = p_ptr->sc;
- previous_char.au = p_ptr->au;
-
- /* Save the stats */
- for (i = 0; i < 6; i++)
- {
- previous_char.stat[i] = p_ptr->stat_max[i];
- }
- previous_char.luck = p_ptr->luck_base;
-
- /* Save the chaos patron */
- previous_char.chaos_patron = p_ptr->chaos_patron;
-
- /* Save the weapon specialty */
- previous_char.weapon = 0;
-
- /* Save the history */
- for (i = 0; i < 4; i++)
- {
- strcpy(previous_char.history[i], history[i]);
- }
-}
-
-
-/*
- * Load the previous data
- */
-static void load_prev_data(bool_ save)
-{
- int i;
-
- birther temp;
-
-
- /*** Save the current data ***/
-
- /* Save the data */
- temp.age = p_ptr->age;
- temp.wt = p_ptr->wt;
- temp.ht = p_ptr->ht;
- temp.sc = p_ptr->sc;
- temp.au = p_ptr->au;
-
- /* Save the stats */
- for (i = 0; i < 6; i++)
- {
- temp.stat[i] = p_ptr->stat_max[i];
- }
- temp.luck = p_ptr->luck_base;
-
- /* Save the chaos patron */
- temp.chaos_patron = p_ptr->chaos_patron;
-
- /* Save the weapon specialty */
- temp.weapon = 0;
-
- /* Save the history */
- for (i = 0; i < 4; i++)
- {
- strcpy(temp.history[i], history[i]);
- }
-
-
- /*** Load the previous data ***/
-
- /* Load the data */
- p_ptr->age = previous_char.age;
- p_ptr->wt = previous_char.wt;
- p_ptr->ht = previous_char.ht;
- p_ptr->sc = previous_char.sc;
- p_ptr->au = previous_char.au;
-
- /* Load the stats */
- for (i = 0; i < 6; i++)
- {
- p_ptr->stat_max[i] = previous_char.stat[i];
- p_ptr->stat_cur[i] = previous_char.stat[i];
- }
- p_ptr->luck_base = previous_char.luck;
- p_ptr->luck_max = previous_char.luck;
-
- /* Load the chaos patron */
- p_ptr->chaos_patron = previous_char.chaos_patron;
-
- /* Load the history */
- for (i = 0; i < 4; i++)
- {
- strcpy(history[i], previous_char.history[i]);
- }
-
-
- /*** Save the current data ***/
- if (!save) return;
-
- /* Save the data */
- previous_char.age = temp.age;
- previous_char.wt = temp.wt;
- previous_char.ht = temp.ht;
- previous_char.sc = temp.sc;
- previous_char.au = temp.au;
-
- /* Save the stats */
- for (i = 0; i < 6; i++)
- {
- previous_char.stat[i] = temp.stat[i];
- }
- previous_char.luck = temp.luck;
-
- /* Save the chaos patron */
- previous_char.chaos_patron = temp.chaos_patron;
-
- /* Save the weapon specialty */
- previous_char.weapon = temp.weapon;
-
- /* Save the history */
- for (i = 0; i < 4; i++)
- {
- strcpy(previous_char.history[i], temp.history[i]);
- }
-}
-
-
-
-
-/*
- * Returns adjusted stat -JK- Algorithm by -JWT-
- *
- * auto_roll is boolean and states maximum changes should be used rather
- * than random ones to allow specification of higher values to wait for
- *
- * The "p_ptr->maximize" code is important -BEN-
- */
-static int adjust_stat(int value, int amount, int auto_roll)
-{
- int i;
-
-
- /* Negative amounts */
- if (amount < 0)
- {
- /* Apply penalty */
- for (i = 0; i < (0 - amount); i++)
- {
- if (value >= 18 + 10)
- {
- value -= 10;
- }
- else if (value > 18)
- {
- value = 18;
- }
- else if (value > 3)
- {
- value--;
- }
- }
- }
-
- /* Positive amounts */
- else if (amount > 0)
- {
- /* Apply reward */
- for (i = 0; i < amount; i++)
- {
- if (value < 18)
- {
- value++;
- }
- else if (p_ptr->maximize)
- {
- value += 10;
- }
- else if (value < 18 + 70)
- {
- value += ((auto_roll ? 15 : randint(15)) + 5);
- }
- else if (value < 18 + 90)
- {
- value += ((auto_roll ? 6 : randint(6)) + 2);
- }
- else if (value < 18 + 100)
- {
- value++;
- }
- }
- }
-
- /* Return the result */
- return (value);
-}
-
-
-
-
-/*
- * Roll for a characters stats
- *
- * For efficiency, we include a chunk of "calc_bonuses()".
- */
-static void get_stats(void)
-{
- int i, j;
-
- int bonus;
-
- int dice[18];
-
-
- /* Roll and verify some stats */
- while (TRUE)
- {
- /* Roll some dice */
- for (j = i = 0; i < 18; i++)
- {
- /* Roll the dice */
- dice[i] = randint(3 + i % 3);
-
- /* Collect the maximum */
- j += dice[i];
- }
-
- /*
- * Verify totals
- *
- * 57 was 54... I hate 'magic numbers' :< TY
- *
- * (d3 + d4 + d5) ~= 7.5 (+- 4.5)
- * with 5 makes avg. stat value of 12.5 (min 8, max 17)
- *
- * (d3 + d4 + d5) x 6 ~= 45 (+- 18)
- *
- * So the original value (still used by Vanilla as of 2.9.3)
- * allows (avg - 2)..(avg + 8), while this Z version
- * (avg - 2)..(avg + 11). I don't understand what TY meant
- * by "magic numbers", but I like big stats :) -- pelpel
- *
- */
- if ((j > 42) && (j < 57)) break;
- }
-
- /* Acquire the stats */
- for (i = 0; i < 6; i++)
- {
- /* Extract 5 + 1d3 + 1d4 + 1d5 */
- j = 5 + dice[3 * i] + dice[3 * i + 1] + dice[3 * i + 2];
-
- /* Save that value */
- p_ptr->stat_max[i] = j;
-
- /* Obtain a "bonus" for "race" and "class" */
- bonus = rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i];
-
- /* Variable stat maxes */
- if (p_ptr->maximize)
- {
- /* Start fully healed */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i];
-
- /* Efficiency -- Apply the racial/class bonuses */
- stat_use[i] = modify_stat_value(p_ptr->stat_max[i], bonus);
- }
-
- /* Fixed stat maxes */
- else
- {
- /* Apply the bonus to the stat (somewhat randomly) */
- stat_use[i] = adjust_stat(p_ptr->stat_max[i], bonus, FALSE);
-
- /* Save the resulting stat maximum */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stat_use[i];
- }
-
- /* No temporary drain (yet...) */
- p_ptr->stat_cnt[i] = 0;
- p_ptr->stat_los[i] = 0;
- }
-
- /* Get luck */
- p_ptr->luck_base = rp_ptr->luck + rmp_ptr->luck + rand_range( -5, 5);
- p_ptr->luck_max = p_ptr->luck_base;
-}
-
-
-/*
- * Roll for some info that the auto-roller ignores
- */
-static void get_extra(void)
-{
- int i, j, min_value, max_value;
-
-#ifdef SHOW_LIFE_RATE
-
- int percent;
-
-#endif
-
-
- /* Level one */
- p_ptr->max_plv = p_ptr->lev = 1;
-
- /* Experience factor */
- p_ptr->expfact = rp_ptr->r_exp + rmp_ptr->r_exp + cp_ptr->c_exp;
-
- /* Initialize arena and rewards information -KMW- */
- p_ptr->arena_number = 0;
- p_ptr->inside_arena = 0;
- p_ptr->inside_quest = 0;
- p_ptr->exit_bldg = TRUE; /* only used for arena now -KMW- */
-
- /* Hitdice */
- p_ptr->hitdie = rp_ptr->r_mhp + rmp_ptr->r_mhp + cp_ptr->c_mhp;
-
- /* Initial hitpoints */
- p_ptr->mhp = p_ptr->hitdie;
-
- /* Minimum hitpoints at highest level */
- min_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 3) / 8;
- min_value += PY_MAX_LEVEL;
-
- /* Maximum hitpoints at highest level */
- max_value = (PY_MAX_LEVEL * (p_ptr->hitdie - 1) * 5) / 8;
- max_value += PY_MAX_LEVEL;
-
- /* Pre-calculate level 1 hitdice */
- player_hp[0] = p_ptr->hitdie;
-
- /* Roll out the hitpoints */
- while (TRUE)
- {
- /* Roll the hitpoint values */
- for (i = 1; i < PY_MAX_LEVEL; i++)
- {
- j = randint(p_ptr->hitdie);
- player_hp[i] = player_hp[i - 1] + j;
- }
-
- /* XXX Could also require acceptable "mid-level" hitpoints */
-
- /* Require "valid" hitpoints at highest level */
- if (player_hp[PY_MAX_LEVEL - 1] < min_value) continue;
- if (player_hp[PY_MAX_LEVEL - 1] > max_value) continue;
-
- /* Acceptable */
- break;
- }
-
- p_ptr->tactic = 4;
- p_ptr->movement = 4;
-
-#ifdef SHOW_LIFE_RATE
-
- percent = (int)(((long)player_hp[PY_MAX_LEVEL - 1] * 200L) /
- (p_ptr->hitdie + ((PY_MAX_LEVEL - 1) * p_ptr->hitdie)));
-
- msg_format("Current Life Rating is %d/100.", percent);
- msg_print(NULL);
-
-#endif /* SHOW_LIFE_RATE */
-}
-
-
-/*
- * Get the racial history, and social class, using the "history charts".
- */
-static void get_history(void)
-{
- int i, n, chart, roll, social_class;
-
- char *s, *t;
-
- char buf[240];
-
-
- /* Clear the previous history strings */
- for (i = 0; i < 4; i++) history[i][0] = '\0';
-
- /* Clear the history text */
- buf[0] = '\0';
-
- /* Initial social class */
- social_class = randint(4);
-
- /* Starting place */
- chart = rp_ptr->chart;
-
- /* Process the history */
- while (chart)
- {
- /* Start over */
- i = 0;
-
- /* Roll for nobility */
- roll = randint(100);
-
-
- /* Access the proper entry in the table */
- while ((chart != bg[i].chart) || (roll > bg[i].roll)) i++;
-
- /* Acquire the textual history */
- (void)strcat(buf, bg[i].info + rp_text);
-
- /* Add in the social class */
- social_class += (int)(bg[i].bonus) - 50;
-
- /* Enter the next chart */
- chart = bg[i].next;
- }
-
-
-
- /* Verify social class */
- if (social_class > 100) social_class = 100;
- else if (social_class < 1) social_class = 1;
-
- /* Save the social class */
- p_ptr->sc = social_class;
-
-
- /* Skip leading spaces */
- for (s = buf; *s == ' '; s++) /* loop */;
-
- /* Get apparent length */
- n = strlen(s);
-
- /* Kill trailing spaces */
- while ((n > 0) && (s[n - 1] == ' ')) s[--n] = '\0';
-
-
- /* Start at first line */
- i = 0;
-
- /* Collect the history */
- while (TRUE)
- {
- /* Extract remaining length */
- n = strlen(s);
-
- /* All done */
- if (n < 60)
- {
- /* Save one line of history */
- strcpy(history[i++], s);
-
- /* All done */
- break;
- }
-
- /* Find a reasonable break-point */
- for (n = 60; ((n > 0) && (s[n - 1] != ' ')); n--) /* loop */;
-
- /* Save next location */
- t = s + n;
-
- /* Wipe trailing spaces */
- while ((n > 0) && (s[n - 1] == ' ')) s[--n] = '\0';
-
- /* Save one line of history */
- strcpy(history[i++], s);
-
- /* Start next line */
- for (s = t; *s == ' '; s++) /* loop */;
- }
-}
-
-
-/*
- * Fill the random_artifacts array with relevant info.
- */
-errr init_randart(void)
-{
- int i;
-
- long cost;
-
- random_artifact* ra_ptr;
-
- char buf[80];
-
-
- for (i = 0; i < MAX_RANDARTS; i++)
- {
- ra_ptr = &random_artifacts[i];
-
- strcpy(ra_ptr->name_short,
- get_line("rart_s.txt", ANGBAND_DIR_FILE, buf, i));
- strcpy(ra_ptr->name_full,
- get_line("rart_f.txt", ANGBAND_DIR_FILE, buf, i));
-
- ra_ptr->attr = randint(15);
- ra_ptr->activation = rand_int(MAX_T_ACT);
- ra_ptr->generated = FALSE;
-
- cost = randnor(0, 250);
-
- if (cost < 0) cost = 0;
-
- ra_ptr->cost = cost;
- }
-
- return 0;
-}
-
-
-/*
- * A helper function for get_ahw(), also called by polymorph code
- */
-void get_height_weight(void)
-{
- int h_mean, h_stddev;
-
- int w_mean, w_stddev;
-
-
- /* Extract mean and standard deviation -- Male */
- if (p_ptr->psex == SEX_MALE)
- {
- h_mean = rp_ptr->m_b_ht + rmp_ptr->m_b_ht;
- h_stddev = rp_ptr->m_m_ht + rmp_ptr->m_m_ht;
-
- w_mean = rp_ptr->m_b_wt + rmp_ptr->m_b_wt;
- w_stddev = rp_ptr->m_m_wt + rmp_ptr->m_m_wt;
- }
-
- /* Female */
- else if (p_ptr->psex == SEX_FEMALE)
- {
- h_mean = rp_ptr->f_b_ht + rmp_ptr->f_b_ht;
- h_stddev = rp_ptr->f_m_ht + rmp_ptr->f_m_ht;
-
- w_mean = rp_ptr->f_b_wt + rmp_ptr->f_b_wt;
- w_stddev = rp_ptr->f_m_wt + rmp_ptr->f_m_wt;
- }
-
- /* Neuter XXX */
- else
- {
- h_mean = (rp_ptr->m_b_ht + rmp_ptr->m_b_ht +
- rp_ptr->f_b_ht + rmp_ptr->f_b_ht) / 2,
- h_stddev = (rp_ptr->m_m_ht + rmp_ptr->m_m_ht +
- rp_ptr->f_m_ht + rmp_ptr->f_m_ht) / 2;
-
- w_mean = (rp_ptr->m_b_wt + rmp_ptr->m_b_wt +
- rp_ptr->f_b_wt + rmp_ptr->f_b_wt) / 2,
- w_stddev = (rp_ptr->m_m_wt + rmp_ptr->m_m_wt +
- rp_ptr->f_m_wt + rmp_ptr->f_m_wt) / 2;
- }
-
- /* Calculate height/weight */
- p_ptr->ht = randnor(h_mean, h_stddev);
- p_ptr->wt = randnor(w_mean, w_stddev);
-
- /* Weight/height shouldn't be negative */
- if (p_ptr->ht < 1) p_ptr->ht = 1;
- if (p_ptr->wt < 1) p_ptr->wt = 1;
-}
-
-
-/*
- * Computes character's age, height, and weight
- */
-static void get_ahw(void)
-{
- /* Calculate the age */
- p_ptr->age = rp_ptr->b_age + rmp_ptr->b_age +
- randint(rp_ptr->m_age + rmp_ptr->m_age);
-
- /* Calculate the height/weight */
- get_height_weight();
-}
-
-
-
-
-/*
- * Get the player's starting money
- */
-static void get_money(void)
-{
- int i, gold;
-
-
- /* Social Class determines starting gold */
- gold = (p_ptr->sc * 6) + randint(100) + 300;
-
- /* Process the stats */
- for (i = 0; i < 6; i++)
- {
- /* Mega-Hack -- reduce gold for high stats */
- if (stat_use[i] >= 18 + 50) gold -= 300;
- else if (stat_use[i] >= 18 + 20) gold -= 200;
- else if (stat_use[i] > 18) gold -= 150;
- else gold -= (stat_use[i] - 8) * 10;
- }
-
- /* Minimum 100 gold */
- if (gold < 100) gold = 100;
-
- /* Save the gold */
- p_ptr->au = gold;
-}
-
-
-
-/*
- * Display stat values, subset of "put_stats()"
- *
- * See 'display_player()' for basic method.
- */
-static void birth_put_stats(void)
-{
- int i, p;
-
- byte attr;
-
- char buf[80];
-
-
- /* Put the stats (and percents) */
- for (i = 0; i < 6; i++)
- {
- /* Put the stat */
- cnv_stat(p_ptr->stat_use[i], buf);
- c_put_str(TERM_L_GREEN, buf, 2 + i, 66);
-
- /* Put the percent */
- if (stat_match[i])
- {
- p = 1000L * stat_match[i] / auto_round;
- attr = (p < 100) ? TERM_YELLOW : TERM_L_GREEN;
- strnfmt(buf, 80, "%3d.%d%%", p / 10, p % 10);
- c_put_str(attr, buf, 2 + i, 73);
- }
-
- /* Never happened */
- else
- {
- c_put_str(TERM_RED, "(NONE)", 2 + i, 73);
- }
- }
-}
-
-
-/*
- * Clear all the global "character" data
- */
-static void player_wipe(void)
-{
- int i, j;
-
- bool_ *powers;
- bool_ *corruptions;
-
-
- /* Wipe special levels */
- wipe_saved();
-
- /* Save the powers & corruptions */
- powers = p_ptr->powers;
- corruptions = p_ptr->corruptions;
-
- /* Hack -- zero the struct */
- p_ptr = WIPE(p_ptr, player_type);
-
- /* Restore the powers & corruptions */
- p_ptr->powers = powers;
- p_ptr->corruptions = corruptions;
-
- /* Not dead yet */
- p_ptr->lives = 0;
-
- /* Wipe the corruptions */
- (void)C_WIPE(p_ptr->corruptions, max_corruptions, bool_);
-
- /* Wipe the history */
- for (i = 0; i < 4; i++)
- {
- for (j = 0; j < 60; j++)
- {
- if (j < 59) history[i][j] = ' ';
- else history[i][j] = '\0';
- }
- }
-
- /* Wipe the towns */
- for (i = 0; i < max_d_idx; i++)
- {
- for (j = 0; j < MAX_DUNGEON_DEPTH; j++)
- {
- special_lvl[j][i] = 0;
- }
- }
-
- /* Wipe the towns */
- for (i = max_real_towns + 1; i < max_towns; i++)
- {
- town_info[i].flags = 0;
- }
-
- /* Wipe the quests */
- for (i = 0; i < MAX_Q_IDX_INIT; i++)
- {
- quest[i].status = QUEST_STATUS_UNTAKEN;
- for (j = 0; j < 4; j++)
- {
- quest[i].data[j] = 0;
- }
- }
-
- /* Wipe the rune spells */
- rune_num = 0;
- for (i = 0; i < MAX_RUNES; i++)
- {
- strcpy(rune_spells[i].name, "");
- rune_spells[i].type = 0;
- rune_spells[i].rune2 = 0;
- rune_spells[i].mana = 0;
- }
-
- /* No items */
- inven_cnt = 0;
- equip_cnt = 0;
-
- /* Clear the inventory */
- for (i = 0; i < INVEN_TOTAL; i++)
- {
- object_wipe(&p_ptr->inventory[i]);
- }
-
- /* Generate random artifacts */
- init_randart();
-
- /* Start with no artifacts made yet */
- for (i = 0; i < max_a_idx; i++)
- {
- artifact_type *a_ptr = &a_info[i];
- a_ptr->cur_num = 0;
- }
-
- /* Reset the "objects" */
- for (i = 1; i < max_k_idx; i++)
- {
- object_kind *k_ptr = &k_info[i];
-
- /* Reset "tried" */
- k_ptr->tried = FALSE;
-
- /* Reset "aware" */
- k_ptr->aware = FALSE;
-
- /* Reset "know" */
- k_ptr->know = FALSE;
-
- /* Reset "artifact" */
- k_ptr->artifact = 0;
- }
-
-
- /* Reset the "monsters" */
- for (i = 1; i < max_r_idx; i++)
- {
- monster_race *r_ptr = &r_info[i];
-
- /* Hack -- Reset the counter */
- r_ptr->cur_num = 0;
-
- /* Hack -- Reset the max counter */
- r_ptr->max_num = 100;
-
- /* Hack -- Reset the max counter */
- if (r_ptr->flags1 & RF1_UNIQUE) r_ptr->max_num = 1;
- if (r_ptr->flags3 & RF3_UNIQUE_4) r_ptr->max_num = 4;
-
- /* Clear player kills */
- r_ptr->r_pkills = 0;
-
- /* Clear saved flag */
- r_ptr->on_saved = FALSE;
- }
-
-
- /* Hack -- Well fed player */
- p_ptr->food = PY_FOOD_FULL - 1;
-
- /* Wipe the alchemists' recipes */
- for ( i = 0 ; i < 32 ; i++)
- alchemist_known_egos[i] = 0;
- for ( i = 0 ; i < 6 ; i++)
- alchemist_known_artifacts[i] = 0;
- alchemist_gained = 0;
-
- /* Clear "cheat" options */
- cheat_peek = FALSE;
- cheat_hear = FALSE;
- cheat_room = FALSE;
- cheat_xtra = FALSE;
- cheat_know = FALSE;
- cheat_live = FALSE;
-
- /* Assume no winning game */
- total_winner = 0;
- has_won = FALSE;
-
- /* Assume no cheating */
- noscore = 0;
- wizard = 0;
-
- /* Assume no innate spells */
- spell_num = 0;
-
- /* Clear the fate */
- for (i = 0; i < MAX_FATES; i++)
- {
- fates[i].fate = 0;
- }
- p_ptr->no_mortal = FALSE;
-
- /* Player don't have the black breath from the beginning !*/
- p_ptr->black_breath = FALSE;
-
- /* Default pet command settings */
- p_ptr->pet_follow_distance = 6;
- p_ptr->pet_open_doors = FALSE;
- p_ptr->pet_pickup_items = FALSE;
-
- /* Body changing initialisation */
- p_ptr->body_monster = 0;
- p_ptr->disembodied = FALSE;
-
- /* Wipe the bounties */
- total_bounties = 0;
-
- /* Wipe spells */
- p_ptr->xtra_spells = 0;
-
- /* Wipe xtra hp */
- p_ptr->hp_mod = 0;
-
- /* Wipe the monsters */
- wipe_m_list();
-
- /* Wipe the doppleganger */
- doppleganger = 0;
-
- /* Wipe the recall depths */
- for (i = 0; i < max_d_idx; i++)
- {
- max_dlv[i] = 0;
- }
-
- /* Wipe the known inscription list */
- for (i = 0; i < MAX_INSCRIPTIONS; i++)
- {
- inscription_info[i].know = FALSE;
- }
-
- /* Wipe the known traps list */
- for (i = 0; i < max_t_idx; i++)
- {
- t_info[i].known = 0;
- t_info[i].ident = FALSE;
- }
-
- /* Reset wild_mode to FALSE */
- p_ptr->wild_mode = FALSE;
- p_ptr->old_wild_mode = FALSE;
-
- /* Initialize allow_one_death */
- p_ptr->allow_one_death = 0;
-
- p_ptr->loan = p_ptr->loan_time = 0;
-
- /* Wipe the power list */
- for (i = 0; i < POWER_MAX_INIT; i++)
- {
- p_ptr->powers_mod[i] = 0;
- }
-
- /* No companions killed */
- p_ptr->companion_killed = 0;
-}
-
-
-/* Create an object */
-void outfit_obj(int tv, int sv, int pval, int dd, int ds)
-{
- object_type forge;
- object_type *q_ptr;
-
- /* Get local object */
- q_ptr = &forge;
- q_ptr->pval = 0;
- q_ptr->pval2 = 0;
-
- /* Hack -- Give the player an object */
- object_prep(q_ptr, lookup_kind(tv, sv));
-
- if (pval)
- q_ptr->pval = pval;
-
- /* These objects are "storebought" */
- q_ptr->ident |= IDENT_MENTAL;
- q_ptr->number = damroll(dd, ds);
-
- object_aware(q_ptr);
- object_known(q_ptr);
- (void)inven_carry(q_ptr, FALSE);
-}
-
-
-/*
- * Init players with some belongings
- *
- * Having an item makes the player "aware" of its purpose.
- */
-static void player_outfit(void)
-{
- int i;
-
- /*
- * Get an adventurer guide describing a bit of the
- * wilderness.
- */
- {
- object_type forge;
- object_type *q_ptr = &forge;
- /* Hack -- Give the player an adventurer guide */
- object_prep(q_ptr, lookup_kind(TV_PARCHMENT, 20));
- q_ptr->number = 1;
- object_aware(q_ptr);
- object_known(q_ptr);
- (void)inven_carry(q_ptr, FALSE);
- }
-
- process_hooks(HOOK_BIRTH_OBJECTS, "()");
-
- {
- object_type forge;
- object_type *q_ptr = &forge;
- /* Hack -- Give the player some food */
- object_prep(q_ptr, lookup_kind(TV_FOOD, SV_FOOD_RATION));
- q_ptr->number = (byte)rand_range(3, 7);
- object_aware(q_ptr);
- object_known(q_ptr);
- (void)inven_carry(q_ptr, FALSE);
- }
-
- {
- object_type forge;
- object_type *q_ptr = &forge;
- /* Hack -- Give the player some torches */
- object_prep(q_ptr, lookup_kind(TV_LITE, SV_LITE_TORCH));
- q_ptr->number = (byte)rand_range(3, 7);
- q_ptr->timeout = rand_range(3, 7) * 500;
- object_aware(q_ptr);
- object_known(q_ptr);
- (void)inven_carry(q_ptr, FALSE);
- }
-
- /* Rogues have a better knowledge of traps */
- if (has_ability(AB_TRAPPING))
- {
- t_info[TRAP_OF_DAGGER_I].known = randint(50) + 50;
- t_info[TRAP_OF_POISON_NEEDLE].known = randint(50) + 50;
- t_info[TRAP_OF_FIRE_BOLT].known = randint(50) + 50;
- t_info[TRAP_OF_DAGGER_I].ident = TRUE;
- t_info[TRAP_OF_POISON_NEEDLE].ident = TRUE;
- t_info[TRAP_OF_FIRE_BOLT].ident = TRUE;
-
- /* Hack -- Give the player a some ammo for the traps */
- object_type forge;
- object_type *q_ptr = &forge;
- object_prep(q_ptr, lookup_kind(TV_SHOT, SV_AMMO_NORMAL));
- q_ptr->number = (byte)rand_range(5, 15);
- object_aware(q_ptr);
- object_known(q_ptr);
-
- /* These objects are "storebought" */
- q_ptr->ident |= IDENT_MENTAL;
-
- (void)inven_carry(q_ptr, FALSE);
- }
-
- /* Hack -- Give the player some useful objects */
- for (i = 0; i < rp_ptr->obj_num; i++)
- outfit_obj(rp_ptr->obj_tval[i], rp_ptr->obj_sval[i], rp_ptr->obj_pval[i], rp_ptr->obj_dd[i], rp_ptr->obj_ds[i]);
- for (i = 0; i < rmp_ptr->obj_num; i++)
- outfit_obj(rmp_ptr->obj_tval[i], rmp_ptr->obj_sval[i], rmp_ptr->obj_pval[i], rmp_ptr->obj_dd[i], rmp_ptr->obj_ds[i]);
- for (i = 0; i < cp_ptr->obj_num; i++)
- outfit_obj(cp_ptr->obj_tval[i], cp_ptr->obj_sval[i], cp_ptr->obj_pval[i], cp_ptr->obj_dd[i], cp_ptr->obj_ds[i]);
- for (i = 0; i < cp_ptr->spec[p_ptr->pspec].obj_num; i++)
- outfit_obj(cp_ptr->spec[p_ptr->pspec].obj_tval[i], cp_ptr->spec[p_ptr->pspec].obj_sval[i], cp_ptr->spec[p_ptr->pspec].obj_pval[i], cp_ptr->spec[p_ptr->pspec].obj_dd[i], cp_ptr->spec[p_ptr->pspec].obj_ds[i]);
-}
-
-
-/* Possible number(and layout) or random quests */
-#define MAX_RANDOM_QUESTS_TYPES ((8 * 3) + (8 * 1))
-int random_quests_types[MAX_RANDOM_QUESTS_TYPES] =
-{
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 1, 5, 6, 7, 10, 11, 12, 14, /* Princess type */
- 20, 13, 15, 16, 9, 17, 18, 8, /* Hero Sword Quest */
-};
-
-/* Enforce OoD monsters until this level */
-#define RQ_LEVEL_CAP 49
-
-static void gen_random_quests(int n)
-{
- int step, lvl, i, k;
- int old_type = dungeon_type;
-
- /* Factor dlev value by 1000 to keep precision */
- step = (98 * 1000) / n;
-
- lvl = step / 2;
-
- quest[QUEST_RANDOM].status = QUEST_STATUS_TAKEN;
-
- for (i = 0; i < n; i++)
- {
- monster_race *r_ptr = &r_info[2];
-
- int rl = (lvl / 1000) + 1;
-
- int min_level;
-
- int tries = 5000;
-
- random_quest *q_ptr = &random_quests[rl];
-
- int j;
-
- /* Find the appropriate dungeon */
- for (j = 0; j < max_d_idx; j++)
- {
- dungeon_info_type *d_ptr = &d_info[j];
-
- if (!(d_ptr->flags1 & DF1_PRINCIPAL)) continue;
-
- if ((d_ptr->mindepth <= rl) && (rl <= d_ptr->maxdepth))
- {
- dungeon_type = j;
- break;
- }
- }
-
- q_ptr->type = random_quests_types[rand_int(MAX_RANDOM_QUESTS_TYPES)];
-
- /* XXX XXX XXX Try until valid choice is found */
- while (tries)
- {
- bool_ ok;
-
- tries--;
-
- /* Random monster 5 - 10 levels out of depth */
- q_ptr->r_idx = get_mon_num(rl + 4 + randint(6));
-
- if (!q_ptr->r_idx) continue;
-
- r_ptr = &r_info[q_ptr->r_idx];
-
- /* Accept only monsters that can be generated */
- if (r_ptr->flags9 & RF9_SPECIAL_GENE) continue;
- if (r_ptr->flags9 & RF9_NEVER_GENE) continue;
-
- /* Accept only monsters that are not breeders */
- if (r_ptr->flags4 & RF4_MULTIPLY) continue;
-
- /* Forbid joke monsters */
- if (r_ptr->flags8 & RF8_JOKEANGBAND) continue;
-
- /* Accept only monsters that are not friends */
- if (r_ptr->flags7 & RF7_PET) continue;
-
- /* Refuse nazguls */
- if (r_ptr->flags7 & RF7_NAZGUL) continue;
-
- /* Accept only monsters that are not good */
- if (r_ptr->flags3 & RF3_GOOD) continue;
-
- /* Assume no explosion attacks */
- ok = TRUE;
-
- /* Reject monsters with exploding attacks */
- for (k = 0; k < 4; k++)
- {
- if (r_ptr->blow[k].method == RBM_EXPLODE) ok = FALSE;
- }
- if (!ok) continue;
-
- /* No mutliple uniques */
- if ((r_ptr->flags1 & RF1_UNIQUE) &&
- ((q_ptr->type != 1) || (r_ptr->max_num == -1))) continue;
-
- /* No single non uniques */
- if ((!(r_ptr->flags1 & RF1_UNIQUE)) && (q_ptr->type == 1)) continue;
-
- /* Level restriction */
- min_level = (rl > RQ_LEVEL_CAP) ? RQ_LEVEL_CAP : rl;
-
- /* Accept monsters matching the level restriction */
- if (r_ptr->level > min_level) break;
- }
-
- /* Arg could not find anything ??? */
- if (!tries)
- {
- if (wizard) message_add(MESSAGE_MSG, format("Could not find quest monster on lvl %d", rl), TERM_RED);
- q_ptr->type = 0;
- }
- else
- {
- if (r_ptr->flags1 & RF1_UNIQUE)
- {
- r_ptr->max_num = -1;
- }
-
- q_ptr->done = FALSE;
-
- if (wizard) message_add(MESSAGE_MSG,
- format("Quest for %d on lvl %d",
- q_ptr->r_idx, rl), TERM_RED);
- }
-
- lvl += step;
- }
-
- dungeon_type = old_type;
-}
-
-int dump_classes(s16b *classes, int sel, u32b *restrictions)
-{
- int n = 0;
-
- char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, c_head->text_size, char);
-
- /* Clean up */
- clear_from(12);
-
- while (classes[n] != -1)
- {
- cptr mod = "";
- char p2 = ')', p1 = ' ';
-
- /* Analyze */
- p_ptr->pclass = classes[n];
- cp_ptr = &class_info[p_ptr->pclass];
- str = cp_ptr->title + c_name;
-
- if (sel == n)
- {
- p1 = '[';
- p2 = ']';
- }
-
- /* Display */
- strnfmt(buf, 80, "%c%c%c %s%s", p1,
- (n <= 25) ? I2A(n) : I2D(n - 26), p2, str, mod);
-
- /* Print some more info */
- if (sel == n)
- {
- strnfmt(desc, c_head->text_size, "%s%s", cp_ptr->desc + c_text,
- cp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
-
- if (!(restrictions[classes[n] / 32] & BIT(classes[n])) ||
- cp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- else
- c_put_str(TERM_L_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- }
- else
- {
- if (!(restrictions[classes[n] / 32] & BIT(classes[n])) ||
- cp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_SLATE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- else
- put_str(buf, 18 + (n / 4), 1 + 20 * (n % 4));
- }
- n++;
- }
-
- C_FREE(desc, c_head->text_size, char);
-
- return (n);
-}
-
-int dump_specs(int sel)
-{
- int n = 0;
-
- char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, c_head->text_size, char);
-
- /* Clean up */
- clear_from(12);
-
- for (n = 0; n < MAX_SPEC; n++)
- {
- char p2 = ')', p1 = ' ';
-
- /* Found the last one ? */
- if (!class_info[p_ptr->pclass].spec[n].title) break;
-
- /* Analyze */
- p_ptr->pspec = n;
- spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
- str = spp_ptr->title + c_name;
-
- if (sel == n)
- {
- p1 = '[';
- p2 = ']';
- }
-
- /* Display */
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
-
- /* Print some more info */
- if (sel == n)
- {
- strnfmt(desc, c_head->text_size, "%s%s", spp_ptr->desc + c_text,
- spp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
-
- if (spp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- else
- c_put_str(TERM_L_BLUE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- }
- else
- {
- if (spp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_SLATE, buf, 18 + (n / 4), 1 + 20 * (n % 4));
- else
- put_str(buf, 18 + (n / 4), 1 + 20 * (n % 4));
- }
- }
-
- C_FREE(desc, c_head->text_size, char);
-
- return (n);
-}
-
-int dump_races(int sel)
-{
- int n = 0;
-
- char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, rp_head->text_size, char);
-
- /* Clean up */
- clear_from(12);
-
- for (n = 0; n < max_rp_idx; n++)
- {
- char p2 = ')', p1 = ' ';
-
- /* Analyze */
- p_ptr->prace = n;
- rp_ptr = &race_info[p_ptr->prace];
- str = rp_ptr->title + rp_name;
-
- if (sel == n)
- {
- p1 = '[';
- p2 = ']';
- }
-
- /* Display */
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
-
- /* Print some more info */
- if (sel == n)
- {
- strnfmt(desc, rp_head->text_size, "%s%s", rp_ptr->desc + rp_text,
- rp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
-
- if (rp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- else
- c_put_str(TERM_L_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- }
- else
- {
- if (rp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_SLATE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- else
- put_str(buf, 18 + (n / 5), 1 + 15 * (n % 5));
- }
- }
-
- C_FREE(desc, rp_head->text_size, char);
-
- return (n);
-}
-
-
-int dump_rmods(int sel, int *racem, int max)
-{
- int n = 0;
-
- char buf[80];
- char *desc;
-
- cptr str;
-
- C_MAKE(desc, rmp_head->text_size, char);
-
- /* Clean up */
- clear_from(12);
-
- /* Dump races */
- for (n = 0; n < max; n++)
- {
- char p2 = ')', p1 = ' ';
-
- /* Analyze */
- p_ptr->pracem = racem[n];
- rmp_ptr = &race_mod_info[p_ptr->pracem];
- str = rmp_ptr->title + rmp_name;
-
- if (sel == n)
- {
- p1 = '[';
- p2 = ']';
- }
-
- /* Display */
- if (racem[n])
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(n), p2, str);
- else
- strnfmt(buf, 80, "%c%c%c Classical", p1, I2A(n), p2);
-
- /* Print some more info */
- if (sel == n)
- {
- strnfmt(desc, rmp_head->text_size, "%s%s", rmp_ptr->desc + rmp_text,
- rmp_ptr->flags1 & PR1_EXPERIMENTAL ? "\nEXPERIMENTAL" : "");
- print_desc(desc);
-
- if (rmp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- else
- c_put_str(TERM_L_BLUE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- }
- else
- {
- if (rmp_ptr->flags1 & PR1_EXPERIMENTAL)
- c_put_str(TERM_SLATE, buf, 18 + (n / 5), 1 + 15 * (n % 5));
- else
- put_str(buf, 18 + (n / 5), 1 + 15 * (n % 5));
- }
- }
-
- C_FREE(desc, rmp_head->text_size, char);
-
- return (n);
-}
-
-int dump_gods(int sel, int *choice, int max)
-{
- int i, j;
- char buf[80];
- cptr str;
-
- /* Clean up */
- clear_from(12);
-
- Term_putstr(5, 17, -1, TERM_WHITE,
- "You can choose to worship a god, some class must start with a god.");
-
- for (i = 0; i < max; i++)
- {
- char p2 = ')', p1 = ' ';
- int n = choice[i];
- deity_type *g_ptr = &deity_info[0];
-
- if (!n) str = "No God";
- else
- {
- g_ptr = &deity_info[n];
- str = g_ptr->name;
- }
-
- if (sel == i)
- {
- p1 = '[';
- p2 = ']';
- }
-
- /* Display */
- strnfmt(buf, 80, "%c%c%c %s", p1, I2A(i), p2, str);
-
- /* Print some more info */
- if (sel == i)
- {
- if (n)
- {
- /* Display the first four lines of the god description */
- for (j = 0; j < 4; j++)
- if (strcmp(g_ptr->desc[j], ""))
- print_desc_aux(g_ptr->desc[j], 12 + j, 1);
- }
- else print_desc("You can begin as an atheist and still convert to a god later.");
-
- c_put_str(TERM_L_BLUE, buf, 20 + (i / 4), 1 + 20 * (i % 4));
- }
- else
- {
- put_str(buf, 20 + (i / 4), 1 + 20 * (i % 4));
- }
- }
-
- return (max);
-}
-
-
-/* Ask questions */
-static bool_ do_quick_start = FALSE;
-
-static bool_ player_birth_aux_ask()
-{
- int i, k, n, v, sel;
-
- s32b tmp;
-
- int racem[100], max_racem = 0;
-
- u32b restrictions[2];
-
- cptr str;
-
- char c;
-
- char p2 = ')';
-
- char buf[200];
- char inp[200];
-
- s16b *class_types;
-
- s32b allow_quest;
-
- /*** Intro ***/
-
- /* Clear screen */
- Term_clear();
-
- /* Title everything */
- put_str("Name :", 2, 1);
- put_str("Sex :", 3, 1);
- put_str("Race :", 4, 1);
- put_str("Class :", 5, 1);
-
- /* Dump the default name */
- c_put_str(TERM_L_BLUE, player_name, 2, 9);
-
-
- /*** Instructions ***/
-
- /* Display some helpful information */
- Term_putstr(5, 8, -1, TERM_WHITE,
- "Please answer the following questions. Most of the questions");
- Term_putstr(5, 9, -1, TERM_WHITE,
- "display a set of standard answers, and many will also accept");
- Term_putstr(5, 10, -1, TERM_WHITE,
- "some special responses, including 'Q' to quit, 'S' to restart,");
- Term_putstr(5, 11, -1, TERM_WHITE,
- "and '?' for help. Note that 'Q' and 'S' must be capitalized.");
-
-
- /*** Quick Start ***/
-
- if (previous_char.quick_ok)
- {
- /* Extra info */
- Term_putstr(1, 15, -1, TERM_WHITE,
- "Do you want to use the quick start function(same character as your last one).");
-
- /* Choose */
- while (1)
- {
- put_str("Use quick start (y/n)?", 20, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- else if (c == 'S') return (FALSE);
- else if ((c == 'y') || (c == 'Y'))
- {
- do_quick_start = TRUE;
- break;
- }
- else
- {
- do_quick_start = FALSE;
- break;
- }
- }
- }
-
- /* Clean up */
- clear_from(15);
-
- /*** Player sex ***/
-
- if (do_quick_start)
- {
- k = previous_char.sex;
- }
- else
- {
- /* Extra info */
- Term_putstr(5, 15, -1, TERM_WHITE,
- "Your 'sex' does not have any significant gameplay effects.");
-
- /* Prompt for "Sex" */
- for (n = 0; n < MAX_SEXES; n++)
- {
- /* Analyze */
- p_ptr->psex = n;
- sp_ptr = &sex_info[p_ptr->psex];
- str = sp_ptr->title;
-
- /* Display */
- strnfmt(buf, 200, "%c%c %s", I2A(n), p2, str);
- put_str(buf, 21 + (n / 5), 2 + 15 * (n % 5));
- }
-
- /* Choose */
- while (1)
- {
- strnfmt(buf, 200, "Choose a sex (%c-%c), * for random, = for options: ", I2A(0), I2A(n - 1));
- put_str(buf, 20, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- k = rand_int(MAX_SEXES);
- break;
- }
- k = (islower(c) ? A2I(c) : -1);
- if ((k >= 0) && (k < n)) break;
- if (c == '?') do_cmd_help();
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else bell();
- }
- }
-
- /* Set sex */
- p_ptr->psex = k;
- sp_ptr = &sex_info[p_ptr->psex];
- str = sp_ptr->title;
-
- /* Display */
- c_put_str(TERM_L_BLUE, str, 3, 9);
-
- /* Clean up */
- clear_from(15);
-
-
- /*** Player race ***/
-
- if (do_quick_start)
- {
- k = previous_char.race;
- }
- else
- {
- /* Only one choice = instant choice */
- if (max_rp_idx == 1)
- k = 0;
- else
- {
- /* Extra info */
- Term_putstr(5, 16, -1, TERM_WHITE,
- "Your 'race' determines various intrinsic factors and bonuses.");
- hack_corruption = FALSE;
-
- /* Dump races */
- sel = 0;
- n = dump_races(sel);
-
- /* Choose */
- while (1)
- {
- strnfmt(buf, 200, "Choose a race (%c-%c), * for a random choice, = for options, 8/2/4/6 for movement: ",
- I2A(0), I2A(max_rp_idx - 1));
- put_str(buf, 17, 2);
-
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- k = rand_int(max_rp_idx);
- break;
- }
- k = (islower(c) ? A2I(c) : -1);
- if ((k >= 0) && (k < n)) break;
- if (c == '?') exec_lua(format("ingame_help('select_context', 'race', '%s')", race_info[sel].title + rp_name));
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else if (c == '2')
- {
- sel += 5;
- if (sel >= n) sel %= 5;
- dump_races(sel);
- }
- else if (c == '8')
- {
- sel -= 5;
- if (sel < 0) sel = n - 1 -( ( -sel) % 5);
- /* C's modulus operator does not have defined
- results for negative first values. Damn. */
- dump_races(sel);
- }
- else if (c == '6')
- {
- sel++;
- if (sel >= n) sel = 0;
- dump_races(sel);
- }
- else if (c == '4')
- {
- sel--;
- if (sel < 0) sel = n - 1;
- dump_races(sel);
- }
- else if (c == '\r')
- {
- k = sel;
- break;
- }
- else bell();
- }
- }
- }
- /* Set race */
- p_ptr->prace = k;
- rp_ptr = &race_info[p_ptr->prace];
- str = rp_ptr->title + rp_name;
-
- /* Display */
- c_put_str(TERM_L_BLUE, str, 4, 9);
-
- /* Get a random name */
- if (!do_quick_start) create_random_name(p_ptr->prace, player_name);
-
- /* Display */
- c_put_str(TERM_L_BLUE, player_name, 2, 9);
-
- /* Clean up */
- clear_from(12);
-
-
- /*** Player race mod ***/
- if (do_quick_start)
- {
- k = previous_char.rmod;
- p_ptr->pracem = k;
- rmp_ptr = &race_mod_info[p_ptr->pracem];
- }
- else
- {
- /* Only one choice = instant choice */
- if (max_rmp_idx == 1)
- k = 0;
- else
- {
- for (n = 0; n < 100; n++) racem[n] = 0;
-
- max_racem = 0;
- for (n = 0; n < max_rmp_idx; n++)
- {
- /* Analyze */
- p_ptr->pracem = n;
- rmp_ptr = &race_mod_info[p_ptr->pracem];
-
- /* Must be an ok choice */
- if (!(BIT(p_ptr->prace) & rmp_ptr->choice[p_ptr->prace / 32])) continue;
-
- /* Ok thats a possibility */
- racem[max_racem++] = n;
- }
-
- /* Ah ! nothing found, lets use the default */
- if (!max_racem) p_ptr->pracem = 0;
- /* Only one ? use it */
- else if (max_racem == 1) p_ptr->pracem = racem[0];
- /* We got to ask the player */
- else
- {
- /* Extra info */
- Term_putstr(5, 15, -1, TERM_WHITE,
- "Your 'race modifier' determines various intrinsic factors and bonuses.");
-
- /* Dump races */
- sel = 0;
- n = dump_rmods(sel, racem, max_racem);
-
- /* Choose */
- while (1)
- {
- strnfmt(buf, 200, "Choose a race modifier (%c-%c), * for a random choice, = for options: ",
- I2A(0), I2A(max_racem - 1));
- put_str(buf, 17, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- do
- {
- k = rand_int(max_racem);
- }
- while (!(BIT(racem[k]) & rmp_ptr->choice[racem[k] / 32]));
- break;
- }
- else if (c == '?') exec_lua(format("ingame_help('select_context', 'subrace', '%s')", race_mod_info[racem[sel]].title + rmp_name));
-
- k = (islower(c) ? A2I(c) : -1);
- if ((k >= 0) && (k < max_racem) &&
- (BIT(p_ptr->prace) & race_mod_info[racem[k]].choice[p_ptr->prace / 32])) break;
-
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else if (c == '2')
- {
- sel += 5;
- if (sel >= n) sel = sel - n + 1;
- dump_rmods(sel, racem, max_racem);
- }
- else if (c == '8')
- {
- sel -= 5;
- if (sel < 0) sel = n - 1 + sel;
- dump_rmods(sel, racem, max_racem);
- }
- else if (c == '6')
- {
- sel++;
- if (sel >= n) sel = 0;
- dump_rmods(sel, racem, max_racem);
- }
- else if (c == '4')
- {
- sel--;
- if (sel < 0) sel = n - 1;
- dump_rmods(sel, racem, max_racem);
- }
- else if (c == '\r')
- {
- k = sel;
- break;
- }
- else bell();
- }
-
- /* Set race */
- p_ptr->pracem = racem[k];
- }
- rmp_ptr = &race_mod_info[p_ptr->pracem];
-
- /* Display */
- c_put_str(TERM_L_BLUE, get_player_race_name(p_ptr->prace, p_ptr->pracem), 4, 9);
- }
- }
-
- /* Clean up */
- clear_from(12);
-
-
- /*** Player class ***/
- if (do_quick_start)
- {
- k = previous_char.pclass;
- p_ptr->pclass = k;
- cp_ptr = &class_info[p_ptr->pclass];
- k = previous_char.spec;
- p_ptr->pspec = k;
- spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
- }
- else
- {
- int z;
-
- for (z = 0; z < 2; z++)
- restrictions[z] = (rp_ptr->choice[z] | rmp_ptr->pclass[z]) & (~rmp_ptr->mclass[z]);
-
- if (max_mc_idx > 1)
- {
- /* Extra info */
- Term_putstr(5, 13, -1, TERM_WHITE,
- "Your 'class' determines various intrinsic abilities and bonuses.");
-
- /* Get a class type */
- for (i = 0; i < max_mc_idx; i++)
- c_put_str(meta_class_info[i].color, format("%c) %s", I2A(i), meta_class_info[i].name), 16 + i, 2);
- while (1)
- {
- strnfmt(buf, 200, "Choose a class type (a-%c), * for random, = for options: ", I2A(max_mc_idx - 1));
- put_str(buf, 15, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- k = rand_int(max_mc_idx);
- break;
- }
- k = (islower(c) ? A2I(c) : (D2I(c) + 26));
- if ((k >= 0) && (k < max_mc_idx)) break;
- if (c == '?') do_cmd_help();
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else bell();
- }
- }
- else
- {
- k = 0;
- }
- class_types = meta_class_info[k].classes;
- clear_from(15);
-
- /* Count classes */
- n = 0;
- while (class_types[n] != -1) n++;
-
- /* Only one choice = instant choice */
- if (n == 1)
- k = 0;
- else
- {
- /* Dump classes */
- sel = 0;
- n = dump_classes(class_types, sel, restrictions);
-
- /* Get a class */
- while (1)
- {
- strnfmt(buf, 200, "Choose a class (%c-%c), * for random, = for options, 8/2/4 for up/down/back: ", I2A(0), (n <= 25) ? I2A(n - 1) : I2D(n - 26-1));
- put_str(buf, 15, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- k = randint(n) - 1;
- break;
- }
- k = (islower(c) ? A2I(c) : (D2I(c) + 26));
- if ((k >= 0) && (k < n)) break;
- if (c == '?') exec_lua(format("ingame_help('select_context', 'class', '%s')", class_info[class_types[sel]].title + c_name));
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else if (c == '2')
- {
- sel += 4;
- if (sel >= n) sel %= 4;
- dump_classes(class_types, sel, restrictions);
- }
- else if (c == '8')
- {
- sel -= 4;
- if (sel < 0) sel = n - 1 -( ( -sel) % 4);
- /* C's modulus operator does not have defined
- results for negative first values. Damn. */
- dump_classes(class_types, sel, restrictions);
- }
- else if (c == '6')
- {
- sel++;
- if (sel >= n) sel = 0;
- dump_classes(class_types, sel, restrictions);
- }
- else if (c == '4')
- {
- sel--;
- if (sel < 0) sel = n - 1;
- dump_classes(class_types, sel, restrictions);
- }
- else if (c == '\r')
- {
- k = sel;
- break;
- }
- else bell();
- }
- }
-
- /* Set class */
- p_ptr->pclass = class_types[k];
-
- /* Choose class spec */
- clear_from(15);
-
- /* Count choices */
- for (n = 0; n < MAX_SPEC; n++)
- {
- /* Found the last one ? */
- if (!class_info[p_ptr->pclass].spec[n].title) break;
- }
-
- /* Only one choice = auto choice */
- if (n == 1)
- k = 0;
- else
- {
- /* Dump classes spec */
- sel = 0;
- n = dump_specs(sel);
-
- /* Get a class */
- while (1)
- {
- strnfmt(buf, 200, "Choose a class specialisation (%c-%c), * for random, = for options, 8/2/4/6 for up/down/left/right: ", I2A(0), (n <= 25) ? I2A(n - 1) : I2D(n - 26-1));
- put_str(buf, 15, 2);
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S') return (FALSE);
- if (c == '*')
- {
- k = randint(n) - 1;
- break;
- }
- k = (islower(c) ? A2I(c) : (D2I(c) + 26));
- if ((k >= 0) && (k < n)) break;
- if (c == '?') exec_lua(format("ingame_help('select_context', 'class', '%s')", class_info[p_ptr->pclass].spec[sel].title + c_name));
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else if (c == '2')
- {
- sel += 4;
- if (sel >= n) sel = sel - n + 1;
- dump_specs(sel);
- }
- else if (c == '8')
- {
- sel -= 4;
- if (sel < 0) sel = n - 1 + sel;
- dump_specs(sel);
- }
- else if (c == '6')
- {
- sel++;
- if (sel >= n) sel = 0;
- dump_specs(sel);
- }
- else if (c == '4')
- {
- sel--;
- if (sel < 0) sel = n - 1;
- dump_specs(sel);
- }
- else if (c == '\r')
- {
- k = sel;
- break;
- }
- else bell();
- }
- }
-
- /* Set class spec */
- p_ptr->pspec = k;
- }
- cp_ptr = &class_info[p_ptr->pclass];
- spp_ptr = &class_info[p_ptr->pclass].spec[p_ptr->pspec];
- str = spp_ptr->title + c_name;
-
- /* Display */
- c_put_str(TERM_L_BLUE, str, 5, 9);
-
- /* Clean up */
- clear_from(15);
-
- /*** Player god ***/
- if (do_quick_start)
- {
- k = previous_char.god;
- p_ptr->pgod = k;
- set_grace(previous_char.grace);
- }
- else if (PRACE_FLAG(PR1_NO_GOD))
- {
- p_ptr->pgod = GOD_NONE;
- }
- else
- {
- int *choice;
- int max = 0;
-
- C_MAKE(choice, max_gods, int);
-
- /* Get the list of possible gods */
- for (n = 0; n < max_gods; n++)
- {
- if ((cp_ptr->gods | spp_ptr->gods) & BIT(n))
- choice[max++] = n;
- }
-
- if (!max)
- {
- p_ptr->pgod = GOD_NONE;
- }
- else if (max == 1)
- {
- p_ptr->pgod = choice[0];
- }
- else if (max > 1)
- {
- sel = 0;
- n = dump_gods(sel, choice, max);
-
- /* Choose */
- while (1)
- {
- strnfmt(buf, 200, "Choose a god (%c-%c), * for a random choice, "
- "= for options, 8/2/4/6 for movement: ",
- I2A(0), I2A(max - 1));
- put_str(buf, 19, 2);
-
- c = inkey();
- if (c == 'Q') quit(NULL);
- if (c == 'S')
- {
- C_FREE(choice, max_gods, int);
-
- return (FALSE);
- }
- if (c == '*')
- {
- k = choice[randint(max) - 1];
- break;
- }
- k = (islower(c) ? A2I(c) : -1);
- if ((k >= 0) && (k < max))
- {
- k = choice[k];
- break;
- }
- if (c == '?') exec_lua(format("ingame_help('select_context', 'god', '%s')", deity_info[choice[sel]].name));
- else if (c == '=')
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- else if (c == '2')
- {
- sel += 4;
- if (sel >= n) sel %= 4;
- dump_gods(sel, choice, max);
- }
- else if (c == '8')
- {
- sel -= 4;
- /* C's modulus operator does not have defined
- results for negative first values. Damn. */
- if (sel < 0) sel = n - 1 -( ( -sel) % 4);
- dump_gods(sel, choice, max);
- }
- else if (c == '6')
- {
- sel++;
- if (sel >= n) sel = 0;
- dump_gods(sel, choice, max);
- }
- else if (c == '4')
- {
- sel--;
- if (sel < 0) sel = n - 1;
- dump_gods(sel, choice, max);
- }
- else if (c == '\r')
- {
- k = choice[sel];
- break;
- }
- else bell();
- }
-
- C_FREE(choice, max_gods, int);
-
- /* Set god */
- p_ptr->pgod = k;
- p_ptr->grace = 0;
- }
-
- /* A god that like us ? more grace ! */
- if (PRACE_FLAGS(PR1_GOD_FRIEND))
- {
- set_grace(200);
- }
- else
- {
- set_grace(100);
- }
- }
-
- /* Clean up */
- clear_from(12);
-
- if (!do_quick_start)
- {
- /* Clear */
- clear_from(15);
-
- /* */
- if (get_check("Do you want to modify the options"))
- {
- screen_save();
- do_cmd_options_aux(6, "Startup Options", FALSE);
- screen_load();
- }
- }
-
- /* Set birth options: maximize, preserve, sepcial levels and astral */
- p_ptr->maximize = maximize;
- p_ptr->preserve = preserve;
- p_ptr->special = special_lvls;
- p_ptr->astral = (PRACE_FLAG2(PR2_ASTRAL)) ? TRUE : FALSE;
-
- /*
- * A note by pelpel. (remove this please)
- * Be it the new Vanilla way (adult vs. birth options) or
- * the old one (player_type members), it would be less confusing
- * to handle birth-only options in a uniform fashion,the above and
- * the following:
- * ironman_rooms,
- * joke_monsters,
- * always_small_level, and
- * fate_option
- */
-
-
- /* Set the recall dungeon accordingly */
- call_lua("get_module_info", "(s)", "d", "base_dungeon", &tmp);
- dungeon_type = tmp;
- p_ptr->recall_dungeon = dungeon_type;
- max_dlv[dungeon_type] = d_info[dungeon_type].mindepth;
-
- if (p_ptr->astral)
- {
- s32b x, y, astral_dun;
-
- call_lua("get_module_info", "(s)", "d", "astral_dungeon", &astral_dun);
- dungeon_type = astral_dun;
-
- /* Somewhere in the misty mountains */
- call_lua("get_module_info", "(s)", "d", "astral_wild_x", &x);
- call_lua("get_module_info", "(s)", "d", "astral_wild_y", &y);
- p_ptr->wilderness_x = x;
- p_ptr->wilderness_y = y;
- }
-
- /* Clean up */
- clear_from(10);
-
- /*** User enters number of quests ***/
- /* Heino Vander Sanden and Jimmy De Laet */
-
- call_lua("get_module_info", "(s)", "d", "rand_quest", &allow_quest);
- if (!ironman_rooms && allow_quest)
- {
- if (do_quick_start)
- {
- v = previous_char.quests;
- }
- else
- {
- /* Extra info */
- Term_putstr(5, 15, -1, TERM_WHITE,
- "Select the number of optional random quests you'd like to receive.");
- Term_putstr(5, 16, -1, TERM_WHITE,
- "If you do not want any optional quests, enter 0.");
-
- /* Ask the number of additional quests */
- while (TRUE)
- {
- put_str(format("Number of quests? (0-%u) ",
- MAX_RANDOM_QUEST - 1), 20, 2);
-
- /* Get a the number of additional quest */
- while (TRUE)
- {
- /* Move the cursor */
- put_str("", 20, 27);
-
- /* Default */
- strcpy(inp, "20");
-
- /* Get a response (or escape) */
- if (!askfor_aux(inp, 2)) inp[0] = '\0';
- if (inp[0] == '*') v = rand_int(MAX_RANDOM_QUEST);
- else v = atoi(inp);
-
- /* Break on valid input */
- if ((v < MAX_RANDOM_QUEST) && ( v >= 0 )) break;
- }
- break;
- }
-
- /* Clear */
- clear_from(15);
- }
- }
- else
- {
- /* NO quests for ironman rooms or persistent levels, since they
- don't work */
- v = 0;
- }
-
- /* Set the quest monster hook */
- get_mon_num_hook = monster_quest;
-
- /* Prepare allocation table */
- get_mon_num_prep();
-
- /* Generate quests */
- for (i = 0; i < MAX_RANDOM_QUEST; i++) random_quests[i].type = 0;
- if (v) gen_random_quests(v);
- max_quests = v;
-
- p_ptr->inside_quest = 0;
-
- /* Init the plots */
- call_lua("get_module_info", "(s)", "d", "C_quest", &allow_quest);
- if (allow_quest)
- {
- plots[PLOT_MAIN] = QUEST_NECRO;
- quest[plots[PLOT_MAIN]].status = QUEST_STATUS_TAKEN;
-
- plots[PLOT_BREE] = QUEST_THIEVES;
- quest[plots[PLOT_BREE]].status = QUEST_STATUS_UNTAKEN;
-
- plots[PLOT_LORIEN] = QUEST_WOLVES;
- quest[plots[PLOT_LORIEN]].status = QUEST_STATUS_UNTAKEN;
-
- plots[PLOT_GONDOLIN] = QUEST_DRAGONS;
- quest[plots[PLOT_GONDOLIN]].status = QUEST_STATUS_UNTAKEN;
-
- plots[PLOT_MINAS] = QUEST_HAUNTED;
- quest[plots[PLOT_MINAS]].status = QUEST_STATUS_UNTAKEN;
-
- plots[PLOT_KHAZAD] = QUEST_EVIL;
- quest[plots[PLOT_KHAZAD]].status = QUEST_STATUS_UNTAKEN;
-
- plots[PLOT_OTHER] = QUEST_NULL;
- }
-
- quest_random_init_hook(QUEST_RANDOM);
-
- /* Ok */
- return (TRUE);
-}
-
-
-
-
-/*
- * Initial stat costs (initial stats always range from 10 to 18 inclusive).
- */
-static const int birth_stat_costs[(18-10) + 1] =
-{
- 0, 1, 2, 4, 7, 11, 16, 22, 30
-};
-
-
-/*
- * Helper function for 'player_birth()'.
- *
- * This function handles "point-based" character creation.
- *
- * The player selects, for each stat, a value from 10 to 18 (inclusive),
- * each costing a certain amount of points (as above), from a pool of 48
- * available points, to which race/class modifiers are then applied.
- *
- * Each unused point is converted into 100 gold pieces, with a maximum of
- * 600 gp at birth.
- *
- * Taken from V 2.9.0
- */
-static bool_ player_birth_aux_point(void)
-{
- int i;
-
- int row = 3;
-
- int col = 42;
-
- int stat = 0;
-
- int stats[6];
-
- int cost;
-
- char ch;
-
- char buf[80];
-
- int mode = 0;
-
-
- /* Initialize stats */
- for (i = 0; i < 6; i++)
- {
- /* Initial stats */
- stats[i] = 10;
- }
-
-
- /* Roll for base hitpoints */
- get_extra();
-
- /* Roll for age/height/weight */
- get_ahw();
-
- /* Roll for social class */
- get_history();
-
- /*** Generate ***/
- process_hooks(HOOK_BIRTH, "()");
-
- /* Hack -- get a chaos patron even if you are not a chaos warrior */
- p_ptr->chaos_patron = (randint(MAX_PATRON)) - 1;
-
- /* Get luck */
- p_ptr->luck_base = rp_ptr->luck + rmp_ptr->luck + rand_range( -5, 5);
- p_ptr->luck_max = p_ptr->luck_base;
-
- /* Interact */
- while (1)
- {
- /* Reset cost */
- cost = 0;
-
- /* Process stats */
- for (i = 0; i < 6; i++)
- {
- /* Variable stat maxes */
- if (p_ptr->maximize)
- {
- /* Reset stats */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stats[i];
-
- }
-
- /* Fixed stat maxes */
- else
- {
- /* Obtain a "bonus" for "race" and "class" */
- int bonus = rp_ptr->r_adj[i] + cp_ptr->c_adj[i];
-
- /* Apply the racial/class bonuses */
- p_ptr->stat_cur[i] = p_ptr->stat_max[i] =
- modify_stat_value(stats[i], bonus);
- }
-
- /* Total cost */
- cost += birth_stat_costs[stats[i] - 10];
- }
-
- /* Restrict cost */
- if (cost > 48)
- {
- /* Warning */
- bell();
-
- /* Reduce stat */
- stats[stat]--;
-
- /* Recompute costs */
- continue;
- }
-
- /* Gold is inversely proportional to cost */
- p_ptr->au = (100 * (48 - cost)) + 100;
-
- /* Maximum of 600 gold */
- if (p_ptr->au > 600) p_ptr->au = 600;
-
- /* Calculate the bonuses and hitpoints */
- p_ptr->update |= (PU_BONUS | PU_HP);
-
- /* Update stuff */
- update_stuff();
-
- /* Fully healed */
- p_ptr->chp = p_ptr->mhp;
-
- /* Fully rested */
- p_ptr->csp = p_ptr->msp;
-
- /* Display the player */
- display_player(mode);
-
- /* Display the costs header */
- put_str("Cost", row - 2, col + 32);
-
- /* Display the costs */
- for (i = 0; i < 6; i++)
- {
- /* Display cost */
- strnfmt(buf, 80, "%4d", birth_stat_costs[stats[i] - 10]);
- put_str(buf, row + (i - 1), col + 32);
- }
-
-
- /* Prompt XXX XXX XXX */
- strnfmt(buf, 80, "Total Cost %2d/48. Use 2/8 to move, 4/6 to modify, ESC to accept.", cost);
- prt(buf, 0, 0);
-
- /* Place cursor just after cost of current stat */
- Term_gotoxy(col + 36, row + stat - 1);
-
- /* Get key */
- ch = inkey();
-
- /* Quit */
- if (ch == 'Q') quit(NULL);
-
- /* Start over */
- if (ch == 'S') return (FALSE);
-
- /* Done */
- if (ch == ESCAPE) break;
-
- /* Prev stat */
- if (ch == '8')
- {
- stat = (stat + 6 - 1) % 6;
- }
-
- /* Next stat */
- if (ch == '2')
- {
- stat = (stat + 1) % 6;
- }
-
- /* Decrease stat */
- if ((ch == '4') && (stats[stat] > 10))
- {
- stats[stat]--;
- }
-
- /* Increase stat */
- if ((ch == '6') && (stats[stat] < 18))
- {
- stats[stat]++;
- }
- }
-
-
- /* Done */
- return (TRUE);
-}
-
-/*
- * Use the autoroller or not to generate a char
- */
-static bool_ player_birth_aux_auto()
-{
- int i, j, m, v;
-
- int mode = 0;
-
- bool_ flag = FALSE;
-
- bool_ prev = FALSE;
-
- char c;
-
- char b1 = '[';
-
- char b2 = ']';
-
- char buf[80];
-
- char inp[80];
-
-
-#ifdef ALLOW_AUTOROLLER
-
- /* Initialize */
- if (autoroll)
- {
- int mval[6];
-
-
- /* Clear fields */
- auto_round = 0L;
- last_round = 0L;
-
- /* Clean up */
- clear_from(10);
-
- /* Prompt for the minimum stats */
- put_str("Enter minimum attribute for: ", 15, 2);
-
- /* Output the maximum stats */
- for (i = 0; i < 6; i++)
- {
- char stat_buf[15];
-
- /* Reset the "success" counter */
- stat_match[i] = 0;
-
- /* Race/Class bonus */
- j = rp_ptr->r_adj[i] + rmp_ptr->r_adj[i] + cp_ptr->c_adj[i];
-
- /* Obtain the "maximal" stat */
- m = adjust_stat(17, j, TRUE);
-
-
- /* Save the maximum */
- mval[i] = m;
-
- /* Extract a textual format */
- cnv_stat(m, stat_buf);
-
- strnfmt(inp, 80, "(Max of %s):", stat_buf);
-
- /* Prepare a prompt */
- strnfmt(buf, 80, "%-5s: %-20s", stat_names[i], inp);
-
- /* Dump the prompt */
- put_str(buf, 16 + i, 5);
- }
-
- /* Input the minimum stats */
- for (i = 0; i < 6; i++)
- {
- /* Get a minimum stat */
- while (TRUE)
- {
- char *s;
-
- /* Move the cursor */
- put_str("", 16 + i, 30);
-
- /* Default */
- strcpy(inp, "");
-
- /* Get a response (or escape) */
- if (!askfor_aux(inp, 8)) inp[0] = '\0';
-
- /* Weirdos stat display .. erm .. I mean, original stat display */
- if (!linear_stats)
- {
- /* Hack -- add a fake slash */
- strcat(inp, "/");
-
- /* Hack -- look for the "slash" */
- s = strchr(inp, '/');
-
- /* Hack -- Nuke the slash */
- *s++ = '\0';
-
- /* Hack -- Extract an input */
- v = atoi(inp) + atoi(s);
- }
- else
- {
- int z = atoi(inp);
-
- if (z <= 18)
- v = z;
- else
- {
- int extra = z - 18;
- v = 18 + (extra * 10);
- }
- }
-
- /* Break on valid input */
- if (v <= mval[i]) break;
- }
-
- /* Save the minimum stat */
- stat_limit[i] = (v > 0) ? v : 0;
- }
- }
-
-#endif /* ALLOW_AUTOROLLER */
-
- /* Roll */
- while (TRUE)
- {
- /* Feedback */
- if (autoroll)
- {
- Term_clear();
-
- put_str("Name :", 2, 1);
- put_str("Sex :", 3, 1);
- put_str("Race :", 4, 1);
- put_str("Class:", 5, 1);
-
- c_put_str(TERM_L_BLUE, player_name, 2, 9);
- c_put_str(TERM_L_BLUE, sp_ptr->title, 3, 9);
- strnfmt(buf, 80, "%s", get_player_race_name(p_ptr->prace, p_ptr->pracem));
- c_put_str(TERM_L_BLUE, buf, 4, 9);
- c_put_str(TERM_L_BLUE, spp_ptr->title + c_name, 5, 9);
-
- /* Label stats */
- put_str("STR:", 2 + A_STR, 61);
- put_str("INT:", 2 + A_INT, 61);
- put_str("WIS:", 2 + A_WIS, 61);
- put_str("DEX:", 2 + A_DEX, 61);
- put_str("CON:", 2 + A_CON, 61);
- put_str("CHR:", 2 + A_CHR, 61);
-
- /* Note when we started */
- last_round = auto_round;
-
- /* Indicate the state */
- put_str("(Hit ESC to abort)", 11, 61);
-
- /* Label count */
- put_str("Round:", 9, 61);
- }
-
- /* Otherwise just get a character */
- else
- {
- /* Get a new character */
- get_stats();
- }
-
- /* Auto-roll */
- while (autoroll)
- {
- bool_ accept = TRUE;
-
- /* Get a new character */
- get_stats();
-
- /* Advance the round */
- auto_round++;
-
- /* Hack -- Prevent overflow */
- if (auto_round >= 1000000L) break;
-
- /* Check and count acceptable stats */
- for (i = 0; i < 6; i++)
- {
- /* This stat is okay */
- if (stat_use[i] >= stat_limit[i])
- {
- stat_match[i]++;
- }
-
- /* This stat is not okay */
- else
- {
- accept = FALSE;
- }
- }
-
- /* Break if "happy" */
- if (accept) break;
-
- /* Take note every 25 rolls */
- flag = (!(auto_round % AUTOROLLER_STEP));
-
- /* Update display occasionally */
- if (flag || (auto_round < last_round + 100))
- {
- /* Dump data */
- birth_put_stats();
-
- /* Dump round */
- put_str(format("%6ld", auto_round), 9, 73);
-
- /* Make sure they see everything */
- Term_fresh();
-
-#ifndef USE_FAST_AUTOROLLER
-
- /* Delay 1/10 second */
- if (fast_autoroller && flag) Term_xtra(TERM_XTRA_DELAY, 100);
-
-#endif
- /* Do not wait for a key */
- inkey_scan = TRUE;
-
- /* Check for a keypress */
- if (inkey()) break;
- }
- }
-
- /* Flush input */
- flush();
-
-
- /*** Display ***/
-
- /* Mode */
- mode = 0;
-
- /* Roll for base hitpoints */
- get_extra();
-
- /* Roll for age/height/weight */
- get_ahw();
-
- /* Roll for social class */
- get_history();
-
- /* Roll for gold */
- get_money();
-
- /*** Generate ***/
- process_hooks(HOOK_BIRTH, "()");
-
- /* Hack -- get a chaos patron even if you are not a chaos warrior */
- p_ptr->chaos_patron = (randint(MAX_PATRON)) - 1;
-
- /* Input loop */
- while (TRUE)
- {
- /* Calculate the bonuses and hitpoints */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_BODY);
-
- /* Update stuff */
- update_stuff();
-
- /* Fully healed */
- p_ptr->chp = p_ptr->mhp;
-
- /* Fully rested */
- p_ptr->csp = p_ptr->msp;
-
- /* Display the player */
- display_player(mode);
-
- /* Prepare a prompt (must squeeze everything in) */
- Term_gotoxy(2, 23);
- Term_addch(TERM_WHITE, b1);
- Term_addstr( -1, TERM_WHITE, "'r' to reroll");
- if (prev) Term_addstr( -1, TERM_WHITE, ", 'p' for prev");
- if (mode) Term_addstr( -1, TERM_WHITE, ", 'h' for Misc.");
- else Term_addstr( -1, TERM_WHITE, ", 'h' for History");
- Term_addstr( -1, TERM_WHITE, ", or ESC to accept");
- Term_addch(TERM_WHITE, b2);
-
- /* Prompt and get a command */
- c = inkey();
-
- /* Quit */
- if (c == 'Q') quit(NULL);
-
- /* Start over */
- if (c == 'S') return (FALSE);
-
- /* Escape accepts the roll */
- if (c == ESCAPE) break;
-
- /* Reroll this character */
- if ((c == ' ') || (c == 'r')) break;
-
- /* Previous character */
- if (prev && (c == 'p'))
- {
- load_prev_data(TRUE);
- continue;
- }
-
- /* Toggle the display */
- if ((c == 'H') || (c == 'h'))
- {
- mode = ((mode != 0) ? 0 : 1);
- continue;
- }
-
- /* Help */
- if (c == '?')
- {
- do_cmd_help();
- continue;
- }
-
- /* Warning */
- bell();
- }
-
- /* Are we done? */
- if (c == ESCAPE) break;
-
- /* Save this for the "previous" character */
- save_prev_data();
-
- /* Note that a previous roll exists */
- prev = TRUE;
- }
-
- /* Clear prompt */
- clear_from(23);
-
- return (TRUE);
-}
-
-
-/*
- * Helper function for 'player_birth()'
- *
- * The delay may be reduced, but is recommended to keep players
- * from continuously rolling up characters, which can be VERY
- * expensive CPU wise. And it cuts down on player stupidity.
- */
-static bool_ player_birth_aux()
-{
- char c;
-
- int i, j;
-
- int y = 0, x = 0;
-
- char old_history[4][60];
-
- /* Ask */
- if (!player_birth_aux_ask()) return (FALSE);
-
- for (i = 1; i < max_s_idx; i++)
- s_info[i].dev = FALSE;
- for (i = 1; i < max_s_idx; i++)
- {
- s32b value = 0, mod = 0;
-
- compute_skills(&value, &mod, i);
-
- init_skill(value, mod, i);
-
- /* Develop only revelant branches */
- if (s_info[i].value || s_info[i].mod)
- {
- int z = s_info[i].father;
-
- while (z != -1)
- {
- s_info[z].dev = TRUE;
- z = s_info[z].father;
- if (z == 0)
- break;
- }
- }
- }
-
- if (do_quick_start)
- {
- load_prev_data(FALSE);
-
- /* Roll for base hitpoints */
- get_extra();
-
- /* Calculate the bonuses and hitpoints */
- p_ptr->update |= (PU_BONUS | PU_HP | PU_MANA | PU_BODY);
-
- /* Update stuff */
- update_stuff();
-
- /* Fully healed */
- p_ptr->chp = p_ptr->mhp;
-
- /* Fully rested */
- p_ptr->csp = p_ptr->msp;
- }
- else
- {
- /* Point based */
- if (point_based)
- {
- if (!player_birth_aux_point()) return FALSE;
- }
- /* Auto-roll */
- else
- {
- if (!player_birth_aux_auto()) return FALSE;
- }
-
- /* Edit character background */
- for (i = 0; i < 4; i++)
- {
- strnfmt(old_history[i], 60, "%s", history[i]);
- }
- /* Turn 0 to space */
- for (i = 0; i < 4; i++)
- {
- for (j = 0; history[i][j]; j++) /* loop */;
-
- for (; j < 59; j++) history[i][j] = ' ';
- }
- display_player(1);
- c_put_str(TERM_L_GREEN, "(Character Background - Edit Mode)", 15, 20);
- while (TRUE)
- {
- for (i = 0; i < 4; i++)
- {
- put_str(history[i], i + 16, 10);
- }
- c_put_str(TERM_L_BLUE, format("%c", history[y][x]), y + 16, x + 10);
-
- /* Place cursor just after cost of current stat */
- Term_gotoxy(x + 10, y + 16);
-
- c = inkey();
-
- if (c == '8')
- {
- y--;
- if (y < 0) y = 3;
- }
- else if (c == '2')
- {
- y++;
- if (y > 3) y = 0;
- }
- else if (c == '6')
- {
- x++;
- if (x > 59) x = 0;
- }
- else if (c == '4')
- {
- x--;
- if (x < 0) x = 59;
- }
- else if (c == '\r')
- {
- break;
- }
- else if (c == ESCAPE)
- {
- for (i = 0; i < 4; i++)
- {
- strnfmt(history[i], 60, "%s", old_history[i]);
- put_str(history[i], i + 16, 10);
- }
- break;
- }
- else
- {
- history[y][x++] = c;
- if (x > 58)
- {
- x = 0;
- y++;
- if (y > 3) y = 0;
- }
- }
- }
-
-
- /*** Finish up ***/
-
- /* Get a name, recolor it, prepare savefile */
-
- get_name();
-
-
- /* Prompt for it */
- prt("['Q' to suicide, 'S' to start over, or ESC to continue]", 23, 10);
-
- /* Get a key */
- c = inkey();
-
- /* Quit */
- if (c == 'Q') quit(NULL);
-
- /* Start over */
- if (c == 'S') return (FALSE);
- }
-
- /* Save this for the next character */
- previous_char.quick_ok = TRUE;
- save_prev_data();
-
- /* Accept */
- return (TRUE);
-}
-
-
-/*
- * Helper function for validate_bg().
- */
-static void validate_bg_aux(int chart, bool_ chart_checked[], char *buf)
-{
- char *s;
-
- int i;
-
-
- /* Assume the chart does not exist */
- bool_ chart_exists = FALSE;
-
- /* Assume the chart is not complete */
- bool_ chart_complete = FALSE;
-
- int bg_max = max_bg_idx;
-
- /* No chart */
- if (!chart) return;
-
- /* Already saw this chart */
- if (chart_checked[chart]) return;
-
- /* Build a debug message */
- s = buf + strlen(buf);
-
- /* XXX XXX XXX */
- (void) strnfmt(s, -1, "%d --> ", chart);
-
- /* Check each chart */
- for (i = 0; i < bg_max; i++)
- {
- /* Require same chart */
- if (bg[i].chart != chart) continue;
-
- /* The chart exists */
- chart_exists = TRUE;
-
- /* Validate the "next" chart recursively */
- validate_bg_aux(bg[i].next, chart_checked, buf);
-
- /* Require a terminator */
- if (bg[i].roll != 100) continue;
-
- /* The chart is complete */
- chart_complete = TRUE;
- }
-
- /* Failed: The chart does not exist */
- if (!chart_exists)
- {
- quit_fmt("birth.c: bg[] chart %d does not exist\n%s", chart, buf);
- }
-
- /* Failed: The chart is not complete */
- if (!chart_complete)
- {
- quit_fmt("birth.c: bg[] chart %d is not complete", chart);
- }
-
- /* Remember we saw this chart */
- chart_checked[chart] = TRUE;
-
- /* Build a debug message */
- *s = 0;
-}
-
-
-/*
- * Verify that the bg[] table is valid.
- */
-static void validate_bg(void)
-{
- int i, race;
-
- bool_ chart_checked[512];
-
- char buf[1024];
-
-
- for (i = 0; i < 512; i++) chart_checked[i] = FALSE;
-
- /* Check each race */
- for (race = 0; race < max_rp_idx; race++)
- {
- /* Get the first chart for this race */
- int chart = race_info[race].chart;
-
- (void) strcpy(buf, "");
-
- /* Validate the chart recursively */
- validate_bg_aux(chart, chart_checked, buf);
- }
-}
-
-/*
- * Initialize a random town
- */
-void init_town(int t_idx, int level)
-{
- town_type *t_ptr = &town_info[t_idx];
-
- /* Mark it as existent */
- t_ptr->flags |= (TOWN_REAL);
-
- /* Mark it as not found */
- t_ptr->flags &= ~(TOWN_KNOWN);
-
- /* Generation seed for the town */
- t_ptr->seed = randint(0x10000000);
-
- /* Total hack and not even used */
- t_ptr->numstores = 8;
-}
-
-/*
- * Create a new character.
- *
- * Note that we may be called with "junk" leftover in the various
- * fields, so we must be sure to clear them first.
- */
-void player_birth(void)
-{
- int i, j, rtown = TOWN_RANDOM;
-
- /* Validate the bg[] table */
- validate_bg();
-
- /* Create a new character */
- while (1)
- {
- /* Wipe the player */
- player_wipe();
-
- /* Roll up a new character */
- if (player_birth_aux()) break;
- }
-
- /* Finish skills */
- p_ptr->skill_points = 0;
- p_ptr->skill_last_level = 1;
-
- recalc_skills(FALSE);
-
- /* grab level 1 abilities */
- for (i = 0; i < max_ab_idx; i++)
- ab_info[i].acquired = FALSE;
- apply_level_abilities(1);
-
- /* Complete the god */
- i = p_ptr->pgod;
- p_ptr->pgod = 0;
- follow_god(i, TRUE);
-
- /* Select the default melee type */
- select_default_melee();
-
- /* Make a note file if that option is set */
- if (take_notes)
- {
- add_note_type(NOTE_BIRTH);
- }
-
- /* Note player birth in the message recall */
- message_add(MESSAGE_MSG, " ", TERM_L_BLUE);
- message_add(MESSAGE_MSG, " ", TERM_L_BLUE);
- message_add(MESSAGE_MSG, "====================", TERM_L_BLUE);
- message_add(MESSAGE_MSG, " ", TERM_L_BLUE);
- message_add(MESSAGE_MSG, " ", TERM_L_BLUE);
-
- /* Hack -- outfit the player */
- player_outfit();
-
- /* Initialize random towns in the dungeons */
- for (i = 0; i < max_d_idx; i++)
- {
- dungeon_info_type *d_ptr = &d_info[i];
- int num = 0, z;
-
- d_ptr->t_num = 0;
- for (z = 0; z < TOWN_DUNGEON; z++)
- {
- d_ptr->t_idx[z] = 0;
- d_ptr->t_level[z] = 0;
- }
- if (!(d_ptr->flags1 & DF1_RANDOM_TOWNS)) continue;
-
- /* Can we add a town ? */
- while (magik(TOWN_CHANCE - (num * 10)))
- {
- int lev;
-
- d_ptr->t_idx[num] = rtown;
- rtown++;
-
- while (TRUE)
- {
- int j;
- bool_ ok = TRUE;
-
- lev = rand_range(d_ptr->mindepth, d_ptr->maxdepth - 1);
-
- /* Be sure it wasnt already used */
- for (j = 0; j < num; j++)
- {
- if (d_ptr->t_level[j] == lev) ok = FALSE;
- }
-
- /* Ok found one */
- if (ok) break;
- }
- d_ptr->t_level[num] = lev;
-
- if (wizard) message_add(MESSAGE_MSG, format("Random dungeon town: d_idx:%d, lev:%d", i, lev), TERM_WHITE);
-
- /* Create the town */
- init_town(d_ptr->t_idx[num], d_ptr->t_level[num]);
-
- num++;
-
- /* No free slots left */
- if (num >= TOWN_DUNGEON) break;
- }
-
- d_ptr->t_num = num;
- }
-
- /* Init the towns */
- for (i = 1; i < max_towns; i++)
- {
- /* Not destroyed ! yet .. ;) */
- town_info[i].destroyed = FALSE;
-
- /* Ignore non-existent towns */
- if (!(town_info[i].flags & (TOWN_REAL))) continue;
-
- create_stores_stock(i);
-
- /* Init the stores */
- for (j = 0; j < max_st_idx; j++)
- {
- /* Initialize */
- store_init(i, j);
- }
- }
-
- /* Init wilderness seeds */
- for (i = 0; i < max_wild_x; i++)
- {
- for (j = 0; j < max_wild_y; j++)
- {
- wild_map[j][i].seed = rand_int(0x10000000);
- wild_map[j][i].entrance = 0;
- wild_map[j][i].known = FALSE;
- }
- }
-
- /* Select bounty monsters. */
- select_bounties();
-}
-
-
-
-
-char savefile_module[46][80];
-char savefile_names[46][30];
-char savefile_desc[46][80];
-bool_ savefile_alive[46];
-int savefile_idx[46];
-
-/*
- * Grab all the names from an index
- */
-int load_savefile_names()
-{
- FILE *fff;
- char buf[1024];
- char tmp[50];
- char player_base_save[32];
- int max = 0, fd;
-
-
- /* Build the filename */
- strcpy(tmp, "global.svg");
- path_build(buf, 1024, ANGBAND_DIR_SAVE, tmp);
-
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
-
- /* Read the file */
- fff = my_fopen(buf, "r");
-
- /* Failure */
- if (!fff) return (0);
-
-
- /* Save the current 'player_base' */
- strncpy(player_base_save, player_base, 32);
-
-
- /*
- * Parse, use '@' intead of ':' as a separator because it cannot exists
- * in savefiles
- */
- while (0 == my_fgets(fff, buf, 1024))
- {
- int i = 0, start, count;
-
- /* Check for pre-ToME 2.1.2 file */
- count = 0;
- i = 0;
- while (buf[i] && buf[i] != '\n')
- {
- if (buf[i] == '@')
- ++count;
- ++i;
- }
-
- /* Check module if a current svg file */
- start = 0;
- i = 0;
- if (count > 1)
- {
- while (buf[i] != '@')
- {
- savefile_module[max][i - start] = buf[i];
- i++;
- }
- savefile_module[max][i] = '\0';
- i++;
- }
- /* Default to ToME for old files */
- else
- {
- savefile_module[max][0] = 'T';
- savefile_module[max][1] = 'o';
- savefile_module[max][2] = 'M';
- savefile_module[max][3] = 'E';
- savefile_module[max][4] = '\0';
- }
-
- if (buf[i] == '0') savefile_alive[max] = FALSE;
- else if (buf[i] == '1') savefile_alive[max] = TRUE;
-
- i++;
- start = i;
- while (buf[i] != '@')
- {
- savefile_names[max][i - start] = buf[i];
- i++;
- }
- savefile_names[max][i - start] = '\0';
- i++;
- strcpy(savefile_desc[max], buf + i);
-
- /* Build platform-dependent savefile name */
- strncpy(player_base, savefile_names[max], 32);
- process_player_name(TRUE);
-
- /* File type is 'SAVE' */
- FILE_TYPE(FILE_TYPE_SAVE);
-
- /* Try to open the savefile */
- fd = fd_open(savefile, O_RDONLY);
-
- /* Still existing ? */
- if (fd >= 0)
- {
- fd_close(fd);
- max++;
- }
- }
-
- my_fclose(fff);
-
- /* Restore the values of 'player_base' and 'savefile' */
- strncpy(player_base, player_base_save, 32);
- process_player_name(TRUE);
-
- return (max);
-}
-
-
-/*
- * Save all the names from an index
- */
-void save_savefile_names()
-{
- FILE *fff;
- char buf[1024];
- char tmp[50];
- int max = load_savefile_names(), i;
-
-
- /* Build the filename */
- strcpy(tmp, "global.svg");
- path_build(buf, 1024, ANGBAND_DIR_SAVE, tmp);
-
- /* File type is "TEXT" */
- FILE_TYPE(FILE_TYPE_TEXT);
-
- /* Read the file */
- fff = my_fopen(buf, "w");
-
- /* Failure */
- if (!fff) return;
-
- /*
- * Save, use '@' intead of ':' as a separator because it cannot exists
- * in savefiles
- */
- fprintf(fff, "%s@%c%s@%s, the %s %s is %s\n", game_module,
- (death) ? '0' : '1', player_base, player_name,
- get_player_race_name(p_ptr->prace, p_ptr->pracem),
- spp_ptr->title + c_name,
- (!death) ? "alive" : "dead");
-
- for (i = 0; i < max; i++)
- {
- if (!strcmp(savefile_names[i], player_base)) continue;
- fprintf(fff, "%s@%c%s@%s\n", savefile_module[i],
- (savefile_alive[i]) ? '1' : '0', savefile_names[i], savefile_desc[i]);
- }
-
- my_fclose(fff);
-}
-
-
-static void dump_savefiles(int sel, int max)
-{
- int i;
-
- char buf[40], pre = ' ', post = ')';
-
- char ind;
-
-
- for (i = 0; i < max; i++)
- {
- ind = I2A(i % 26);
- if (i >= 26) ind = toupper(ind);
-
- if (sel == i)
- {
- pre = '[';
- post = ']';
- }
- else
- {
- pre = ' ';
- post = ')';
- }
-
- if (i == 0) strnfmt(buf, 40, "%c%c%c New Character", pre, ind, post);
- else if (i == 1) strnfmt(buf, 40, "%c%c%c Load Savefile", pre, ind, post);
- else strnfmt(buf, 40, "%c%c%c %s", pre, ind, post, savefile_names[savefile_idx[i - 2]]);
-
- if (sel == i)
- {
- if (i >= 2)
- {
- if (savefile_alive[i - 2]) c_put_str(TERM_L_GREEN, savefile_desc[savefile_idx[i - 2]], 5, 0);
- else c_put_str(TERM_L_RED, savefile_desc[savefile_idx[i - 2]], 5, 0);
- }
- else if (i == 1) c_put_str(TERM_YELLOW, "Load an existing savefile that is not in the list", 5, 0);
- else c_put_str(TERM_YELLOW, "Create a new character", 5, 0);
- c_put_str(TERM_L_BLUE, buf, 6 + (i / 4), 20 * (i % 4));
- }
- else
- put_str(buf, 6 + (i / 4), 20 * (i % 4));
- }
-}
-
-
-/* Asks for new game or load game */
-bool_ no_begin_screen = FALSE;
-
-bool_ begin_screen()
-{
- int m, k, sel, max;
-
-savefile_try_again:
- sel = 0;
-
- /* Grab the savefiles */
- max = load_savefile_names();
-
- /* Get only the usable savefiles */
- for (k = 0, m = 0; k < max; k++)
- {
- s32b can_use;
-
- call_lua("module_savefile_loadable", "(s)", "d", savefile_module[k], &can_use);
- if (can_use)
- {
- savefile_idx[m++] = k;
- }
- }
- max = m + 2;
- if (max > 2) sel = 2;
-
- while (TRUE)
- {
- /* Clear screen */
- Term_clear();
-
- /* Let the user choose */
- c_put_str(TERM_YELLOW, format("Welcome to %s! To play you will need a character.", game_module), 1, 10);
- put_str("Press 8/2/4/6 to move, Return to select, Backspace to delete a savefile.", 3, 3);
- put_str("and Esc to quit.", 4, 32);
-
- dump_savefiles(sel, max);
-
- k = inkey();
-
- if (k == ESCAPE)
- {
- quit(NULL);
- }
- if (k == '6')
- {
- sel++;
- if (sel >= max) sel = 0;
- continue;
- }
- else if (k == '4')
- {
- sel--;
- if (sel < 0) sel = max - 1;
- continue;
- }
- else if (k == '2')
- {
- sel += 4;
- if (sel >= max) sel = sel % max;
- continue;
- }
- else if (k == '8')
- {
- sel -= 4;
- if (sel < 0) sel = (sel + max - 1) % max;
- continue;
- }
- else if (k == '\r')
- {
- if (sel < 26) k = I2A(sel);
- else k = toupper(I2A(sel));
- }
- else if (((k == 0x7F) || (k == '\010')) && (sel >= 2))
- {
- char player_base_save[32];
-
- if (!get_check(format("Really delete '%s'?", savefile_names[savefile_idx[sel - 2]]))) continue;
-
- /* Save current 'player_base' */
- strncpy(player_base_save, player_base, 32);
-
- /* Build platform-dependent save file name */
- strncpy(player_base, savefile_names[savefile_idx[sel - 2]], 32);
- process_player_name(TRUE);
-
- /* Remove the savefile */
- fd_kill(savefile);
-
- /* Restore 'player_base' and 'savefile' */
- strncpy(player_base, player_base_save, 32);
- process_player_name(TRUE);
-
- /* Reload, gods I hate using goto .. */
- goto savefile_try_again;
-
- continue;
- }
-
- if (k == 'a')
- {
- /* Display prompt */
- prt("Enter the name of the savefile that will hold this character: ", 23, 0);
-
- /* Ask the user for a string */
- if (!askfor_aux(player_base, 15)) continue;
-
- /* Process the player name */
- process_player_name(TRUE);
-
- return (TRUE);
- }
- if (k == 'b')
- {
- /* Display prompt */
- prt("Enter the name of a savefile: ", 23, 0);
-
- /* Ask the user for a string */
- if (!askfor_aux(player_base, 15)) continue;
-
- /* Process the player name */
- process_player_name(TRUE);
-
- return (FALSE);
- }
- else
- {
- int x;
-
- if (islower(k)) x = A2I(k);
- else x = A2I(tolower(k)) + 26;
-
- if ((x < 2) || (x >= max)) continue;
-
- strnfmt(player_base, 32, "%s", savefile_names[savefile_idx[x - 2]]);
-
- /* Process the player name */
- process_player_name(TRUE);
-
- return (FALSE);
- }
- }
-
- /* Shouldnt happen */
- return (FALSE);
-}