=== modified file 'src/birth.c' --- src/birth.c +++ src/birth.c @@ -111,16 +111,15 @@ /* Load the data */ p_ptr->age = prev.age; - p_ptr->wt = prev.wt; - p_ptr->ht = prev.ht; + p_ptr->wt = p_ptr->wt_birth = prev.wt; + p_ptr->ht = p_ptr->ht_birth = prev.ht; p_ptr->sc = prev.sc; - p_ptr->au = prev.au; + p_ptr->au = p_ptr->au_birth = prev.au; /* Load the stats */ for (i = 0; i < A_MAX; i++) { - p_ptr->stat_max[i] = prev.stat[i]; - p_ptr->stat_cur[i] = prev.stat[i]; + p_ptr->stat_max[i] = p_ptr->stat_cur[i] = p_ptr->stat_birth[i] = prev.stat[i]; } /* Load the history */ @@ -265,6 +264,8 @@ /* Save the resulting stat maximum */ p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stat_use[i]; } + + p_ptr->stat_birth[i] = p_ptr->stat_max[i]; } } @@ -385,15 +386,15 @@ /* Calculate the height/weight for males */ if (p_ptr->psex == SEX_MALE) { - p_ptr->ht = Rand_normal(rp_ptr->m_b_ht, rp_ptr->m_m_ht); - p_ptr->wt = Rand_normal(rp_ptr->m_b_wt, rp_ptr->m_m_wt); + p_ptr->ht = p_ptr->ht_birth = Rand_normal(rp_ptr->m_b_ht, rp_ptr->m_m_ht); + p_ptr->wt = p_ptr->wt_birth = Rand_normal(rp_ptr->m_b_wt, rp_ptr->m_m_wt); } /* Calculate the height/weight for females */ else if (p_ptr->psex == SEX_FEMALE) { - p_ptr->ht = Rand_normal(rp_ptr->f_b_ht, rp_ptr->f_m_ht); - p_ptr->wt = Rand_normal(rp_ptr->f_b_wt, rp_ptr->f_m_wt); + p_ptr->ht = p_ptr->ht_birth = Rand_normal(rp_ptr->f_b_ht, rp_ptr->f_m_ht); + p_ptr->wt = p_ptr->wt_birth = Rand_normal(rp_ptr->f_b_wt, rp_ptr->f_m_wt); } } @@ -426,7 +427,7 @@ if (gold < 100) gold = 100; /* Save the gold */ - p_ptr->au = gold; + p_ptr->au = p_ptr->au_birth = gold; } @@ -1030,6 +1031,10 @@ static bool player_birth_aux_1(void) { int i, res, cur; + + /* Wipe the player */ + player_wipe(); + /*** Instructions ***/ @@ -1177,8 +1182,7 @@ if (adult_maximize) { /* Reset stats */ - p_ptr->stat_cur[i] = p_ptr->stat_max[i] = stats[i]; - + p_ptr->stat_cur[i] = p_ptr->stat_max[i] = p_ptr->stat_birth[i] = stats[i]; } /* Fixed stat maxes */ @@ -1210,7 +1214,7 @@ } /* Gold is inversely proportional to cost */ - p_ptr->au = (100 * (48 - cost)) + 100; + p_ptr->au = p_ptr->au_birth = (100 * (48 - cost)) + 100; /* Calculate the bonuses and hitpoints */ p_ptr->update |= (PU_BONUS | PU_HP); @@ -1700,6 +1704,133 @@ /* + * Helper function for 'player_birth_quick()'. + * + * See "display_player" for screen layout code. + */ +static bool player_birth_quick(void) +{ + char ch; + int i; + birther old_char; + byte old_class; + byte old_race; + byte old_sex; + byte old_hitdie; + u16b old_expfact; + s16b old_hp[PY_MAX_LEVEL]; + + old_sex = p_ptr->psex; + old_class = p_ptr->pclass; + old_race = p_ptr->prace; + + old_hitdie = p_ptr->hitdie; + old_expfact = p_ptr->expfact; + + old_char.age = p_ptr->age; + old_char.au = p_ptr->au_birth; + old_char.ht = p_ptr->ht_birth; + old_char.wt = p_ptr->wt_birth; + old_char.sc = p_ptr->sc; + + /* Save the stats */ + for (i = 0; i < A_MAX; i++) + { + old_char.stat[i] = p_ptr->stat_birth[i]; + } + + /* Save the history */ + my_strcpy(old_char.history, p_ptr->history, sizeof(old_char.history)); + + /* Save the hp */ + for (i = 0; i < PY_MAX_LEVEL; i++) + { + old_hp[i] = p_ptr->player_hp[i]; + } + + /* Wipe the player */ + player_wipe(); + + /* Level one */ + p_ptr->max_lev = p_ptr->lev = 1; + + p_ptr->psex = old_sex; + p_ptr->pclass = old_class; + p_ptr->prace = old_race; + + p_ptr->hitdie = old_hitdie; + p_ptr->expfact = old_expfact; + + p_ptr->age = old_char.age; + p_ptr->au_birth = p_ptr->au = old_char.au; + p_ptr->ht = old_char.ht; + p_ptr->wt = old_char.wt; + p_ptr->sc = old_char.sc; + + /* Load the stats */ + for (i = 0; i < A_MAX; i++) + { + p_ptr->stat_birth[i] = p_ptr->stat_cur[i] = p_ptr->stat_max[i] = old_char.stat[i]; + } + + /* Load the history */ + my_strcpy(p_ptr->history, old_char.history, sizeof(p_ptr->history)); + + /* Load the hp */ + for (i = 0; i < PY_MAX_LEVEL; i++) + { + p_ptr->player_hp[i] = old_hp[i]; + } + + /* Set adult options from birth options */ + for (i = OPT_BIRTH; i < OPT_CHEAT; i++) + { + op_ptr->opt[OPT_ADULT + (i - OPT_BIRTH)] = op_ptr->opt[i]; + } + + /* Reset score options from cheat options */ + for (i = OPT_CHEAT; i < OPT_ADULT; i++) + { + op_ptr->opt[OPT_SCORE + (i - OPT_CHEAT)] = op_ptr->opt[i]; + } + + /* 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(0); + + /* Get a name, prepare savefile */ + get_name(); + + /* Prompt for it */ + prt("['CTRL-X' to quit, 'ESC' to start over, or any other key to continue]", 23, 5); + + /* Get a key */ + ch = inkey(); + + /* Quit */ + if (ch == KTRL('X')) quit(NULL); + + /* Start over */ + if (ch == ESCAPE) return (FALSE); + + /* Accept */ + return (TRUE); +} + + + +/* * Create a new character. * * Note that we may be called with "junk" leftover in the various @@ -1708,16 +1839,43 @@ void player_birth(void) { int i, n; + bool done = FALSE; + char ch; + + + /* + * If this a pre-existing savefile, offer to do a quick creation, based + * on the previous character. + */ + if (character_existed) + { + /* Prompt */ + while (TRUE) + { + Term_clear(); + + put_str("Quick-start character based on previous one (y/n)? ", 2, 2); + ch = inkey(); + if (ch == KTRL('X')) quit(NULL); + if ((ch == ESCAPE) || (ch == '\r') || (ch == '\n')) break; + if (strchr("YyNn", ch)) break; + if (ch == '?') (void)show_file("birth.hlp", NULL, 0, 0); + else bell("Illegal answer!"); + } + + /* Quick generation */ + if ((ch == 'y') || (ch == 'Y')) + { + if (player_birth_quick()) done = TRUE; + } + } /* Create a new character */ - while (1) - { - /* Wipe the player */ - player_wipe(); - + while (!done) + { /* Roll up a new character */ - if (player_birth_aux()) break; + done = player_birth_aux(); } === modified file 'src/externs.h' --- src/externs.h +++ src/externs.h @@ -91,6 +91,7 @@ extern bool arg_force_original; extern bool arg_force_roguelike; extern bool character_generated; +extern bool character_existed; extern bool character_dungeon; extern bool character_loaded; extern bool character_saved; === modified file 'src/load.c' --- src/load.c +++ src/load.c @@ -989,15 +989,19 @@ /* Age/Height/Weight */ rd_s16b(&p_ptr->age); rd_s16b(&p_ptr->ht); + rd_s16b(&p_ptr->ht_birth); rd_s16b(&p_ptr->wt); + rd_s16b(&p_ptr->wt_birth); /* Read the stat info */ for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_max[i]); for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_cur[i]); + for (i = 0; i < A_MAX; i++) rd_s16b(&p_ptr->stat_birth[i]); strip_bytes(24); /* oops */ rd_s32b(&p_ptr->au); + rd_s32b(&p_ptr->au_birth); rd_s32b(&p_ptr->max_exp); rd_s32b(&p_ptr->exp); @@ -2231,6 +2235,9 @@ /* Forget death */ p_ptr->is_dead = FALSE; + /* A character existed in this savefile. */ + character_existed = TRUE; + /* Count lives */ sf_lives++; === modified file 'src/save.c' --- src/save.c +++ src/save.c @@ -1026,15 +1026,20 @@ wr_s16b(p_ptr->age); wr_s16b(p_ptr->ht); wr_s16b(p_ptr->wt); - - /* Dump the stats (maximum and current) */ + wr_s16b(p_ptr->ht_birth); + wr_s16b(p_ptr->wt_birth); + + /* Dump the stats (maximum and current and birth) */ for (i = 0; i < A_MAX; ++i) wr_s16b(p_ptr->stat_max[i]); for (i = 0; i < A_MAX; ++i) wr_s16b(p_ptr->stat_cur[i]); + for (i = 0; i < A_MAX; ++i) wr_s16b(p_ptr->stat_birth[i]); /* Ignore the transient stats */ for (i = 0; i < 12; ++i) wr_s16b(0); wr_u32b(p_ptr->au); + wr_u32b(p_ptr->au_birth); + wr_u32b(p_ptr->max_exp); wr_u32b(p_ptr->exp); === modified file 'src/types.h' --- src/types.h +++ src/types.h @@ -1047,6 +1047,12 @@ byte ammo_tval; /* Ammo variety */ s16b pspeed; /* Current speed */ + + /* Generation fields (for quick start) */ + s32b au_birth; /* Birth gold */ + byte stat_birth[A_MAX]; /* Birth "natural" stat values */ + s16b ht_birth; /* Birth Height */ + s16b wt_birth; /* Birth Weight */ }; === modified file 'src/variable.c' --- src/variable.c +++ src/variable.c @@ -61,6 +61,7 @@ */ bool character_generated; /* The character exists */ +bool character_existed; /* A character existed on the same savefile */ bool character_dungeon; /* The character has a dungeon */ bool character_loaded; /* The character was loaded from a savefile */ bool character_saved; /* The character was just saved to a savefile */