/*
 * create.c: 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 "constant.h"
#include "types.h"
#include "config.h"
#include "externs.h"

#ifdef USG
#ifndef ATARIST_MWC
#include <string.h>
#endif
#else
#include <strings.h>
#endif

/* Lets do all prototypes correctly.... -CWS */
#ifndef NO_LINT_ARGS
#ifdef __STDC__
static void change_stat(int, int);
static int  monval(int);

#else
static void change_stat();
static int  monval();

#endif

static void get_stats();
static void set_prev_stats();
static int  get_prev_stats();
static void get_all_stats();
static void put_auto_stats();
static void choose_race();
static void print_history();
static void set_prev_history();
static void get_prev_history();
static void get_sex();
static void get_ahw();
static void set_prev_ahw();
static void get_prev_ahw();
static void get_class();
static void get_class_choice();
static void get_money();

#endif

struct previous {
    int16u age;
    int16u wt;
    int16u ht;
    int16  disarm;
    int16u stat[6];
    int16u sc;
    char   history[4][60];
    background_type     bg;
}      prev;

extern int peek;

/* Generates character's stats			-JWT-	 */
static void
get_stats()
{
    register int i, tot;
    int dice[18];

    do {
	tot = 0;
	for (i = 0; i < 18; i++) {
	    dice[i] = randint(3 + i % 3); /* Roll 3,4,5 sided dice once each */
	    tot += dice[i];
	}
    }
    while (tot <= 42 || tot >= 54);
    
    for (i = 0; i < 6; i++)
	py.stats.max_stat[i] = 5 + dice[3 * i] + dice[3 * i + 1] +
	    dice[3 * i + 2];
}


/* Returns adjusted stat                                       -JK-  */
/* Algorithm by ...                                            -JWT- */
/* Used by change_stats and auto_roller
 * auto_roll is boolean and states maximum changes
 * should be used rather than random ones
 * to allow specification of higher values to wait for
 */

static int
adjust_stat(stat_value, amount, auto_roll)
int stat_value;
int16 amount;
int auto_roll;
{
  register int i;
 
  if (amount < 0)
    for (i = 0; i > amount; i--)
      {
/* OK so auto_roll conditions not needed for negative amounts since stat_value
 * is always 15 at least currently!  -JK
 */
                
             if (stat_value > 108)
               stat_value--;
             else if (stat_value > 88)
                 stat_value -= ((auto_roll ? 6 : randint(6)) + 2);
             else if (stat_value > 18)
               {
                 stat_value -= ((auto_roll ? 15 : randint(15)) + 5);
                 if (stat_value < 18)
                   stat_value = 18;
               }
             else if (stat_value > 3)
               stat_value--;
      }
  else
    for (i = 0; i < amount; i++)
      {
        if (stat_value < 18)
          stat_value++;
        else if (stat_value < 88)
          stat_value += ((auto_roll ? 15 : randint(15)) + 5);
        else if (stat_value < 108)
          stat_value += ((auto_roll ? 6 : randint(6)) + 2);
        else if (stat_value < 118)
          stat_value++;
      }
  return stat_value;
}


/* Changes stats by given amount                                -JWT-   */
static void change_stat(stat, amount)
int stat;
int amount;
{
  py.stats.max_stat[stat] =
        adjust_stat(py.stats.max_stat[stat], (int16) amount, FALSE);
}


static void
set_prev_stats()
{
    register int        i;

    for (i = 0; i < 6; i++)
	prev.stat[i] = (int16u) py.stats.max_stat[i];

    return;
}


static int
get_prev_stats()
{
    register int        i;

    if (!prev.stat[0])
	return 0;
    for (i = 0; i < 6; i++) {
	py.stats.cur_stat[i] = (py.stats.max_stat[i] = prev.stat[i]);
	py.stats.use_stat[i] = prev.stat[i];
    }
    py.misc.ptodam = todam_adj();
    py.misc.ptohit = tohit_adj();
    py.misc.pac = toac_adj();
    prev.stat[0] = 0;
    return 1;
}


/*
 * generate all stats and modify for race. needed in a separate module so
 * looping of character selection would be allowed     -RGM- 
 */
static void
get_all_stats()
{
    register player_type *p_ptr;
    register race_type *r_ptr;
    register int        j;

    p_ptr = &py;
    r_ptr = &race[p_ptr->misc.prace];
    get_stats();
    change_stat(A_STR, r_ptr->str_adj);
    change_stat(A_INT, r_ptr->int_adj);
    change_stat(A_WIS, r_ptr->wis_adj);
    change_stat(A_DEX, r_ptr->dex_adj);
    change_stat(A_CON, r_ptr->con_adj);
    change_stat(A_CHR, r_ptr->chr_adj);
    for (j = 0; j < 6; j++) {
	py.stats.cur_stat[j] = py.stats.max_stat[j];
	py.stats.use_stat[j] = modify_stat(j, py.stats.mod_stat[j]);
    }

    p_ptr->misc.srh = r_ptr->srh;
    p_ptr->misc.bth = r_ptr->bth;
    p_ptr->misc.bthb = r_ptr->bthb;
    p_ptr->misc.fos = r_ptr->fos;
    p_ptr->misc.stl = r_ptr->stl;
    p_ptr->misc.save = r_ptr->bsav;
    p_ptr->misc.hitdie = r_ptr->bhitdie;
    p_ptr->misc.lev = 1;
    p_ptr->misc.ptodam = todam_adj();
    p_ptr->misc.ptohit = tohit_adj();
    p_ptr->misc.ptoac = 0;
    p_ptr->misc.pac = toac_adj();
    p_ptr->misc.expfact = r_ptr->b_exp;
    p_ptr->flags.see_infra = r_ptr->infra;
}

/* copied from misc2.c, so the display loop would work nicely -cft */
static const char *stat_names[] = {"STR: ", "INT: ", "WIS: ", "DEX: ", "CON: ", "CHR: "};


#ifdef AUTOROLLER
/* used for auto-roller.  Just put_stats(), w/o the extra info -CFT */
static void
put_auto_stats()
{
    register int i;
    vtype        buf;

    for (i = 0; i < 6; i++) {
	cnv_stat(py.stats.use_stat[i], buf);
	put_buffer(stat_names[i], 2 + i, 61);
	put_buffer(buf, 2 + i, 66);
	if (py.stats.max_stat[i] > py.stats.cur_stat[i]) {
	    cnv_stat(py.stats.max_stat[i], buf);
	    put_buffer(buf, 2 + i, 73);
	}
    }
}
#endif

/* Allows player to select a race			-JWT-	 */
static void
choose_race()
{
    register int         j, k;
    int                  l, m, exit_flag;
    char                 s;
    char                 tmp_str[80];
    register player_type *p_ptr;
    register race_type   *r_ptr;

    j = 0;
    k = 0;
    l = 2;
    m = 21;
    clear_from(20);
    put_buffer("Choose a race (? for Help):", 20, 2);
    do {
	(void)sprintf(tmp_str, "%c) %s", k + 'a', race[j].trace);
	put_buffer(tmp_str, m, l);
	k++;
	l += 15;
	if (l > 70) {
	    l = 2;
	    m++;
	}
	j++;
    }
    while (j < MAX_RACES);
    exit_flag = FALSE;
    do {
	move_cursor(20, 30);
	s = inkey();
	j = s - 'a';
	if ((j < MAX_RACES) && (j >= 0))
	    exit_flag = TRUE;
	else if (s == '?')
	    helpfile(ANGBAND_WELCOME);
	else
	    bell();
    }
    while (!exit_flag);

    p_ptr = &py;
    r_ptr = &race[j];
    p_ptr->misc.prace = j;
    put_buffer(r_ptr->trace, 3, 15);
}


/* Will print the history of a character			-JWT-	 */
static void
print_history()
{
    register int        i;

    put_buffer("Character Background", 14, 27);
    for (i = 0; i < 4; i++)
	prt(py.misc.history[i], i + 15, 10);
}


static void
set_prev_history()
{
    prev.bg.info = background->info;
    prev.bg.roll = background->roll;
    prev.bg.chart = background->chart;
    prev.bg.next = background->next;
    prev.bg.bonus = background->bonus;
    prev.sc = py.misc.sc;

    (void)strncpy(prev.history[0], py.misc.history[0], 60);
    (void)strncpy(prev.history[1], py.misc.history[1], 60);
    (void)strncpy(prev.history[2], py.misc.history[2], 60);
    (void)strncpy(prev.history[3], py.misc.history[3], 60);

    return;
}


static void
get_prev_history()
{
    register int        i;

    background->info = prev.bg.info;
    background->roll = prev.bg.roll;
    background->chart = prev.bg.chart;
    background->next = prev.bg.next;
    background->bonus = prev.bg.bonus;
    py.misc.sc = prev.sc;

    for (i = 0; i < 4; i++)
	strncpy(py.misc.history[i], prev.history[i], 60);
}


/* Get the racial history, determines social class	-RAK-	 */
/* Assumptions:	Each race has init history beginning at
 * (race-1)*3+1
 * All history parts are in ascending order
 */

static void
get_history()
{
    int                      hist_ptr, cur_ptr, test_roll, flag;
    register int             start_pos, end_pos, cur_len;
    int                      line_ctr, new_start = 0, social_class;
    char                     history_block[240];
    register background_type *b_ptr;

/* Get a block of history text				 */
    if (py.misc.prace == 8)
	hist_ptr = 1;
    else if (py.misc.prace > 8)
	hist_ptr = 2 * 3 + 1;
    else
	hist_ptr = py.misc.prace * 3 + 1;
    history_block[0] = '\0';
    social_class = randint(4);
    cur_ptr = 0;
    do {
	flag = FALSE;
	do {
	    if (background[cur_ptr].chart == hist_ptr) {
		test_roll = randint(100);
		while (test_roll > background[cur_ptr].roll)
		    cur_ptr++;
		b_ptr = &background[cur_ptr];
		(void)strcat(history_block, b_ptr->info);
		social_class += b_ptr->bonus - 50;
		if (hist_ptr > b_ptr->next)
		    cur_ptr = 0;
		hist_ptr = b_ptr->next;
		flag = TRUE;
	    } else
		cur_ptr++;
	}
	while (!flag);
    }
    while (hist_ptr >= 1);

/* clear the previous history strings */
    for (hist_ptr = 0; hist_ptr < 4; hist_ptr++)
	py.misc.history[hist_ptr][0] = '\0';

/* Process block of history text for pretty output	 */
    start_pos = 0;
    end_pos = strlen(history_block) - 1;
    line_ctr = 0;
    flag = FALSE;
    while (history_block[end_pos] == ' ')
	end_pos--;
    do {
	while (history_block[start_pos] == ' ')
	    start_pos++;
	cur_len = end_pos - start_pos + 1;
	if (cur_len > 60) {
	    cur_len = 60;
	    while (history_block[start_pos + cur_len - 1] != ' ')
		cur_len--;
	    new_start = start_pos + cur_len;
	    while (history_block[start_pos + cur_len - 1] == ' ')
		cur_len--;
	} else
	    flag = TRUE;
	(void)strncpy(py.misc.history[line_ctr], &history_block[start_pos],
		      cur_len);
	py.misc.history[line_ctr][cur_len] = '\0';
	line_ctr++;
	start_pos = new_start;
    }
    while (!flag);

/* Compute social class for player			 */
    if (social_class > 100)
	social_class = 100;
    else if (social_class < 1)
	social_class = 1;
    py.misc.sc = social_class;
}


/* Gets the character's sex				-JWT-	 */
static void
get_sex()
{
    register int        exit_flag;
    char                c;

    exit_flag = FALSE;
    clear_from(20);
    put_buffer("Choose a sex (? for Help):", 20, 2);
    put_buffer("m) Male       f) Female", 21, 2);
    do {
	move_cursor(20, 29);
    /* speed not important here */
	c = inkey();
	if (c == 'f' || c == 'F') {
	    py.misc.male = FALSE;
	    put_buffer("Female", 4, 15);
	    exit_flag = TRUE;
	} else if (c == 'm' || c == 'M') {
	    py.misc.male = TRUE;
	    put_buffer("Male", 4, 15);
	    exit_flag = TRUE;
	} else if (c == '?')
	    helpfile(ANGBAND_WELCOME);
	else
	    bell();
    }
    while (!exit_flag);
}


/* Computes character's age, height, and weight		-JWT-	 */
static void
get_ahw()
{
    register int        i;

    i = py.misc.prace;
    py.misc.age = race[i].b_age + randint((int)race[i].m_age);
    if (py.misc.male) {
	py.misc.ht = randnor((int)race[i].m_b_ht, (int)race[i].m_m_ht);
	py.misc.wt = randnor((int)race[i].m_b_wt, (int)race[i].m_m_wt);
    } else {
	py.misc.ht = randnor((int)race[i].f_b_ht, (int)race[i].f_m_ht);
	py.misc.wt = randnor((int)race[i].f_b_wt, (int)race[i].f_m_wt);
    }
    py.misc.disarm += race[i].b_dis;
}


static void
set_prev_ahw()
{
    prev.age = py.misc.age;
    prev.wt = py.misc.wt;
    prev.ht = py.misc.ht;
    prev.disarm = py.misc.disarm;

    return;
}


static void
get_prev_ahw()
{
    py.misc.age = prev.age;
    py.misc.wt = prev.wt;
    py.misc.ht = prev.ht;
    py.misc.disarm = prev.disarm;
    prev.age = prev.wt = prev.ht = prev.disarm = 0;
}


/* Gets a character class				-JWT-	 */
static void
get_class()
{
    register int        i;
    int                 min_value, max_value;
    int                 percent;
    char                buf[50];
    register struct misc *m_ptr;
    register player_type *p_ptr;
    class_type         *c_ptr;

    c_ptr = &class[py.misc.pclass];
    p_ptr = &py;
    change_stat(A_STR, c_ptr->madj_str);
    change_stat(A_INT, c_ptr->madj_int);
    change_stat(A_WIS, c_ptr->madj_wis);
    change_stat(A_DEX, c_ptr->madj_dex);
    change_stat(A_CON, c_ptr->madj_con);
    change_stat(A_CHR, c_ptr->madj_chr);

    for (i = 0; i < 6; i++) {
	p_ptr->stats.cur_stat[i] = p_ptr->stats.max_stat[i];
	p_ptr->stats.use_stat[i] = p_ptr->stats.max_stat[i];
    }
    p_ptr->misc.ptodam = todam_adj();           /* Real values		 */
    p_ptr->misc.ptohit = tohit_adj();
    p_ptr->misc.ptoac = toac_adj();
    p_ptr->misc.pac = 0;
    p_ptr->misc.dis_td = p_ptr->misc.ptodam;	/* Displayed values	 */
    p_ptr->misc.dis_th = p_ptr->misc.ptohit;
    p_ptr->misc.dis_tac = p_ptr->misc.ptoac;
    p_ptr->misc.dis_ac = p_ptr->misc.pac + p_ptr->misc.dis_tac;

/* now set misc stats, do this after setting stats because of con_adj() for
 * hitpoints 
 */
    m_ptr = &py.misc;
    m_ptr->hitdie += c_ptr->adj_hd;
    m_ptr->mhp = con_adj() + m_ptr->hitdie;
    m_ptr->chp = m_ptr->mhp;
    m_ptr->chp_frac = 0;

/* initialize hit_points array: put bounds on total possible hp,
 * only succeed if it is within 1/8 of average value
 */
    min_value = (MAX_PLAYER_LEVEL * 3 * (m_ptr->hitdie - 1)) / 8 +
	MAX_PLAYER_LEVEL;
    max_value = (MAX_PLAYER_LEVEL * 5 * (m_ptr->hitdie - 1)) / 8 +
	MAX_PLAYER_LEVEL;

    player_hp[0] = m_ptr->hitdie;
    do {
	for (i = 1; i < MAX_PLAYER_LEVEL; i++) {
	    player_hp[i] = randint((int)m_ptr->hitdie);
	    player_hp[i] += player_hp[i - 1];
	}
    }
    while ((player_hp[MAX_PLAYER_LEVEL - 1] < min_value) ||
	   (player_hp[MAX_PLAYER_LEVEL - 1] > max_value));

    if (peek) {
	percent = (int)(((long)player_hp[MAX_PLAYER_LEVEL - 1] * 200L) /
		(m_ptr->hitdie + ((MAX_PLAYER_LEVEL - 1) * m_ptr->hitdie)));
	sprintf(buf, "%d%% Life Rating", percent);
	msg_print(buf);
    }
    m_ptr->bth += c_ptr->mbth;
    m_ptr->bthb += c_ptr->mbthb;   /* RAK */
    m_ptr->srh += c_ptr->msrh;
    m_ptr->disarm = c_ptr->mdis + todis_adj();
    m_ptr->fos += c_ptr->mfos;
    m_ptr->stl += c_ptr->mstl;
    m_ptr->save += c_ptr->msav;
    m_ptr->expfact += c_ptr->m_exp;
}

void
rerate()
{
    int         min_value, max_value, i, percent;
    char        buf[50];
    struct misc *m_ptr = &py.misc;

    min_value = (MAX_PLAYER_LEVEL * 3 * (m_ptr->hitdie - 1)) / 8 +
	MAX_PLAYER_LEVEL;
    max_value = (MAX_PLAYER_LEVEL * 5 * (m_ptr->hitdie - 1)) / 8 +
	MAX_PLAYER_LEVEL;
    player_hp[0] = m_ptr->hitdie;
    do {
	for (i = 1; i < MAX_PLAYER_LEVEL; i++) {
	    player_hp[i] = randint((int)m_ptr->hitdie);
	    player_hp[i] += player_hp[i - 1];
	}
    }
    while ((player_hp[MAX_PLAYER_LEVEL - 1] < min_value) ||
	   (player_hp[MAX_PLAYER_LEVEL - 1] > max_value));

    percent = (int)(((long)player_hp[MAX_PLAYER_LEVEL - 1] * 200L) /
		(m_ptr->hitdie + ((MAX_PLAYER_LEVEL - 1) * m_ptr->hitdie)));

    sprintf(buf, "%d%% Life Rating", percent);
    calc_hitpoints();
    prt_stat_block();
    msg_print(buf);
}

/* Gets a character class				-JWT-	 */
static void
get_class_choice()
{
    register int i, j;
    int          k, l, m;
    int          cl[MAX_CLASS], exit_flag;
    class_type   *c_ptr;
    char         tmp_str[80], s;
    int32u       mask;

    for (j = 0; j < MAX_CLASS; j++)
	cl[j] = 0;
    i = py.misc.prace;
    j = 0;
    k = 0;
    l = 2;
    m = 21;
    mask = 0x1;
    clear_from(20);
    put_buffer("Choose a class (? for Help):", 20, 2);
    do {
	if (race[i].rtclass & mask) {
	    (void)sprintf(tmp_str, "%c) %s", k + 'a', class[j].title);
	    put_buffer(tmp_str, m, l);
	    cl[k] = j;
	    l += 15;
	    if (l > 70) {
		l = 2;
		m++;
	    }
	    k++;
	}
	j++;
	mask <<= 1;
    }
    while (j < MAX_CLASS);
    py.misc.pclass = 0;
    exit_flag = FALSE;
    do {
	move_cursor(20, 31);
	s = inkey();
	j = s - 'a';
	if ((j < k) && (j >= 0)) {
	    py.misc.pclass = cl[j];
	    c_ptr = &class[py.misc.pclass];
	    exit_flag = TRUE;
	    clear_from(20);
	    put_buffer(c_ptr->title, 5, 15);
	} else if (s == '?')
	    helpfile(ANGBAND_WELCOME);
	else
	    bell();
    } while (!exit_flag);
}


/* Given a stat value, return a monetary value, which affects the amount of
 * gold a player has. 
 */
static int
monval(i)
    int                 i;
{
    return 5 * ((int)i - 10);
}


static void
get_money()
{
    register int        tmp, gold;
    register int16u    *a_ptr;

    a_ptr = py.stats.max_stat;
    tmp = monval(a_ptr[A_STR]) + monval(a_ptr[A_INT])
	+ monval(a_ptr[A_WIS]) + monval(a_ptr[A_CON])
	+ monval(a_ptr[A_DEX]);

    gold = py.misc.sc * 6 + randint(25) + 325;          /* Social Class adj */
    gold -= tmp;		   /* Stat adj */
    gold += monval(a_ptr[A_CHR]);  /* Charisma adj	 */
    if (!py.misc.male)
	gold += 50;		   /* She charmed the banker into it! -CJS- */
				   /* She slept with the banker.. :) -GDH-  */
    if (gold < 80)
	gold = 80;		   /* Minimum */
    py.misc.au = gold;
}


/* ---------- M A I N  for Character Creation Routine ---------- */
/* -JWT-	 */
void
create_character()
{
    register char       c;

#ifdef AUTOROLLER
    int32u       auto_round = 0;
    register int i;
    int          stat[6];
    int          autoroll = 0;
    int          msstat = 0;/* Max autoroll w/ look for -SAC */
    class_type   *cptr;
    race_type    *rptr;
    char         inp[60];

#endif
    int previous_exists = 0;	/* flag to prevent prev from garbage values */

    town_seed = random();	/* Change random seeds for new characters -CWS */
    randes_seed = random();

    put_character();
    choose_race();
    get_sex();
    get_class_choice();

#ifdef AUTOROLLER
/*
 * This auto-roller stolen from a post on rec.games.moria, which I belive was
 * taken from druid moria 5.something.  If this intrudes on someone's
 * copyright, take it out, and someone let me know -CFT 
 */

    put_buffer("Do you want to use automatic rolling? (? for Help) ", 20, 2);
    do {   /* allow multiple key entry, so they can ask for help and
            * still get back to this menu... -CFT */

	move_cursor(20, 52);
	c = inkey();
	if (c == '?')
	    helpfile(ANGBAND_WELCOME);
    } while ((c != 'y') && (c != 'Y') && (c != 'n') && (c != 'N'));

    if ((c == 'Y') || (c == 'y')) {
	autoroll = 1;
	clear_from(15);
	cptr = &class[py.misc.pclass];
	rptr = &race[py.misc.prace];
	put_buffer("Enter minimum attribute for: ", 15, 2);
	for (i = 0; i < 6; i++) {
	    int                 stat_idx = 0;

	    switch (i) {
	      case 0:
		stat_idx = A_STR;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_str+rptr->str_adj, TRUE);
		sprintf(inp, "    Strength (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	      case 1:
		stat_idx = A_INT;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_int+rptr->int_adj, TRUE);
		sprintf(inp, "Intelligence (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	      case 2:
		stat_idx = A_WIS;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_wis+rptr->wis_adj, TRUE);
		sprintf(inp, "      Wisdom (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	      case 3:
		stat_idx = A_DEX;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_dex+rptr->dex_adj, TRUE);
		sprintf(inp, "   Dexterity (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	      case 4:
		stat_idx = A_CON;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_con+rptr->con_adj, TRUE);
		sprintf(inp, "Constitution (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	      case 5:
		stat_idx = A_CHR;
		clear_from(16 + i);
		msstat = adjust_stat(17, cptr->madj_chr+rptr->chr_adj, TRUE);
		sprintf(inp, "    Charisma (Max of %2d): ", msstat);
		put_buffer(inp, 16 + i, 5);
		break;
	    } /* switch */
	    do {
		inp[0] = '\000';
		get_string(inp, 16 + i, 32, 3);
		stat[stat_idx] = atoi(inp); /* have return give a stat of 3 */
		if (inp[0] == '\015' || inp[0] == '\012' || inp[0] == '\000')
		    stat[stat_idx] = 3;
		if (stat[stat_idx] < 0) {
		    stat[stat_idx] = (-stat[stat_idx]);
		    if (stat[stat_idx] > msstat)
			msstat = stat[stat_idx];
		}
	    } while (stat[stat_idx] > msstat || stat[stat_idx] < 3);
	} /* for i 0 - 5 */
	put_qio();
    }
#endif				   /* AUTOROLLER - main setup code */

    do {			   /* Main generation loop */
	clear_from(9);
#ifdef AUTOROLLER
	if (autoroll)
	    for (i = 2; i < 6; i++)
		erase_line(i, 30);
	do {			   /* Start of AUTOROLLing loop */
#endif
	    get_all_stats();
	    get_class();

#ifdef AUTOROLLER
	    if (autoroll) {
		put_auto_stats();
		auto_round++;
		sprintf(inp, "auto-rolling round #%lu.", (long)auto_round);
		put_buffer(inp, 20, 2);
#if defined(unix) && defined(NICE)
		usleep((long)100000L);
#endif
		put_qio();
	    } else
		put_stats();
	} while ((autoroll) &&
		 ((stat[A_STR] > py.stats.cur_stat[A_STR]) ||
		  (stat[A_INT] > py.stats.cur_stat[A_INT]) ||
		  (stat[A_WIS] > py.stats.cur_stat[A_WIS]) ||
		  (stat[A_DEX] > py.stats.cur_stat[A_DEX]) ||
		  (stat[A_CON] > py.stats.cur_stat[A_CON]) ||
		  (stat[A_CHR] > py.stats.cur_stat[A_CHR]))

#if (defined (unix) || defined(ATARI_ST)) /* CFT's if/elif/else    */
		 && (!check_input(1)));	  /* unix needs flush here */
#elif (defined(MSDOS) || defined(VMS))
	&&(!kbhit()));
    if (kbhit())
	    flush();
#else
    );
#endif				   /* character checks */
#endif				   /* AUTOROLLER main looping section */
       get_history();	           /* Common stuff */
       get_ahw();

	calc_bonuses();
	print_history();
	put_misc1();
	clear_from(20);

	do {			   /* Input loop */
	    if (previous_exists) {
		put_buffer("Hit space: Reroll, ^P: Previous or ESC: Accept: ",
			   20, 2);
		move_cursor(20, 50);
	    } else {
		put_buffer("Hit space: Reroll, or ESC: Accept: ", 20, 2);
		move_cursor(20, 37);
	    }
	    c = inkey();
	    if ((previous_exists) && (c == CTRL('P'))) {
		previous_exists = FALSE;
		if (get_prev_stats()) {
		    get_prev_history();
		    get_prev_ahw();
		    print_history();
		    put_misc1();
		    calc_bonuses();
		    put_stats();
		    clear_from(20);
		}
	    } else if ((c != ' ') && (c != ESCAPE))	/* Prolly better way to do this */
		bell();
	} while ((c != ' ') && (c != ESCAPE));

/* Not going to waste space w/ a check here. So ESC takes a little longer. -SAC */
	set_prev_stats();
	set_prev_history();
	set_prev_ahw();
	previous_exists = TRUE;
    } while (c == ' ');
    get_money();
    put_stats();
    put_misc2();
    put_misc3();
    get_name();
    msg_print(NULL);

/* This delay may be reduced, but is recommended to keep players
 * from continuously rolling up characters, which can be VERY
 * expensive CPU wise.
 */
    pause_exit(23, PLAYER_EXIT_PAUSE);
}
