view xrogue/init.c @ 301:acc3718f50ab

rogue4: delete a duplicate variable definition.
author John "Elwin" Edwards
date Sat, 15 Aug 2020 20:27:06 -0400
parents 0250220d8cdd
children 32bc72dcbf4f
line wrap: on
line source

/*
    init.c - global variable initializaton
 
    XRogue: Expeditions into the Dungeons of Doom
    Copyright (C) 1991 Robert Pietkivitch
    All rights reserved.
    
    Based on "Advanced Rogue"
    Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
    All rights reserved.

    Based on "Rogue: Exploring the Dungeons of Doom"
    Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
    All rights reserved.
    
    See the file LICENSE.TXT for full copyright and licensing information.
*/ 

#include <curses.h>
#include <ctype.h>
#include <string.h>
#include "rogue.h"
#include "mach_dep.h"

/*
 * If there is any news, put it in a character string and assign it to
 * rogue_news.  Otherwise, assign NULL to rogue_news.
 */

static char *rogue_news = "Enter a number within the minimum and maximum \
range.  When satisfied with your  choices, enter a 'y'.  For help at any \
other time enter a '?' or a '='.";

/* replace the above line with this when descriptions are done  */
/* other time enter a '?' or a '='.         For character and item descriptions \
enter a '\\' on any other screen.";
*/

struct words rainbow[NCOLORS] = {
{ "Amber" },          { "Aquamarine" },       { "Beige" },
{ "Black" },          { "Blue" },             { "Brown" },
{ "Clear" },          { "Crimson" },          { "Ecru" },
{ "Gold" },           { "Green" },            { "Grey" },
{ "Indigo" },         { "Khaki" },            { "Lavender" },
{ "Magenta" },        { "Orange" },           { "Pink" },
{ "Plaid" },          { "Purple" },           { "Red" },
{ "Silver" },         { "Saffron" },          { "Scarlet" },
{ "Tan" },            { "Tangerine" },        { "Topaz" },
{ "Turquoise" },      { "Vermilion" },        { "Violet" },
{ "White" },          { "Yellow" }
};

struct words sylls[NSYLLS] = {
    {"a"},   {"ae"},  {"ak"},  {"an"},  {"ax"},  {"ach"}, {"ano"}, {"ars"},
    {"bha"}, {"bar"}, {"bre"}, {"cha"}, {"cre"}, {"cum"}, {"cow"}, {"duh"},
    {"dha"}, {"e"},   {"ea"},  {"em"},  {"et"},  {"ey"},  {"eck"}, {"etk"},
    {"egg"}, {"exl"}, {"fu"},  {"fen"}, {"fid"}, {"gan"}, {"gle"}, {"h"},
    {"ha"},  {"hr"},  {"ht"},  {"how"}, {"hex"}, {"hip"}, {"hoc"}, {"i"},
    {"ia"},  {"ig"},  {"it"},  {"iz"},  {"ion"}, {"ink"}, {"ivi"}, {"iss"},
    {"je"},  {"jin"}, {"jha"}, {"jyr"}, {"ka"},  {"kho"}, {"kal"}, {"kli"},
    {"lu"},  {"lre"}, {"lta"}, {"lri"}, {"m"},   {"ma"},  {"mh"},  {"mi"},
    {"mr"},  {"mar"}, {"myr"}, {"moh"}, {"mul"}, {"nep"}, {"nes"}, {"o"},
    {"oc"},  {"om"},  {"oq"},  {"ox"},  {"orn"}, {"oxy"}, {"olm"}, {"ode"},
    {"po"},  {"pie"}, {"pod"}, {"pot"}, {"qar"}, {"que"}, {"ran"}, {"rah"},
    {"rok"}, {"sa"},  {"sat"}, {"sha"}, {"sol"}, {"sri"}, {"ti"},  {"tem"},
    {"tar"}, {"tki"}, {"tch"}, {"tox"}, {"u"},   {"ub"},  {"uh"},  {"ur"},
    {"uv"},  {"unk"}, {"uwh"}, {"ugh"}, {"uyr"}, {"va"},  {"vil"}, {"vit"},
    {"vom"}, {"vux"}, {"wah"}, {"wex"}, {"xu"},  {"xed"}, {"xen"}, {"ya"},
    {"yep"}, {"yih"}, {"zef"}, {"zen"}, {"zil"}, {"zym"}, {"-"}
};

struct words stones[NSTONES] = {
      { "Agate" },            { "Alexandrite" },      { "Amethyst" },
      { "Azurite" },          { "Bloodstone" },       { "Cairngorm" },
      { "Carnelian" },        { "Chalcedony" },       { "Chrysoberyl" },
      { "Chrysolite" },       { "Chrysoprase" },      { "Citrine" },
      { "Coral" },            { "Diamond" },          { "Emerald" },
      { "Garnet" },           { "Heliotrope" },       { "Hematite" },
      { "Hyacinth" },         { "Jacinth" },          { "Jade" },
      { "Jargoon" },          { "Jasper" },           { "Kryptonite" },
      { "Lapis lazuli" },     { "Malachite" },        { "Mocca stone" },
      { "Moonstone" },        { "Obsidian" },         { "Olivine" },
      { "Onyx" },             { "Opal" },             { "Pearl" },
      { "Peridot" },          { "Quartz" },           { "Rhodochrosite" },
      { "Rhodolite" },        { "Ruby" },             { "Sapphire" },
      { "Sardonyx" },         { "Serpentine" },       { "Spinel" },
      { "Tiger eye" },        { "Topaz" },            { "Tourmaline" },
      { "Turquoise" },        { "Zircon" }
};

struct words wood[NWOOD] = {
        {"Avocado wood"}, {"Balsa"},        {"Banyan"},       {"Birch"},
        {"Cedar"},        {"Cherry"},       {"Cinnabar"},     {"Dogwood"},
        {"Driftwood"},    {"Ebony"},        {"Eucalyptus"},   {"Hemlock"},
        {"Ironwood"},     {"Mahogany"},     {"Manzanita"},    {"Maple"},
        {"Oak"},          {"Pine"},         {"Redwood"},      {"Rosewood"},
        {"Teak"},         {"Walnut"},       {"Aloe"},         {"Sandalwood"}
};

struct words metal[NMETAL] = {
        {"Aluminium"},    {"Bone"},         {"Brass"},        {"Bronze"},
        {"Copper"},       {"Chromium"},     {"Iron"},         {"Lead"},
        {"Magnesium"},    {"Pewter"},       {"Platinum"},     {"Silver"},
        {"Steel"},        {"Tin"},          {"Titanium"},     {"Zinc"}
};

/*
 * make sure all the percentages specified in the tables add up to the
 * right amounts
 */

void
badcheck(char *name, struct magic_item *magic, int bound)
{
    register struct magic_item *end;

    if (magic[bound - 1].mi_prob == 1000)
        return;
    printf("\nBad percentages for %s:\n", name);
    for (end = &magic[bound] ; magic < end ; magic++)
        printf("%4d%% %s\n", magic->mi_prob, magic->mi_name);
    printf(retstr);
    fflush(stdout);
    while (getchar() != '\n')
        continue;
}

/*
 * init_colors:
 *      Initialize the potion color scheme for this time
 */

void
init_colors(void)
{
    register int i;
    register char *str;

    for (i = 0 ; i < MAXPOTIONS ; i++)
    {
        do
            str = rainbow[rnd(NCOLORS)].w_string;
        until (isupper(*str));
        *str = tolower(*str);
        p_colors[i] = str;
        p_know[i] = FALSE;
        p_guess[i] = NULL;
        if (i > 0)
                p_magic[i].mi_prob += p_magic[i-1].mi_prob;
    }
    badcheck("potions", p_magic, MAXPOTIONS);
}

/*
 * do any initialization for food
 */

void
init_foods(void)
{
    register int i;

    for (i=0; i < MAXFOODS; i++) {
        if (i > 0)
            foods[i].mi_prob += foods[i-1].mi_prob;
    }
    badcheck("foods", foods, MAXFOODS);
}

/*
 * init_materials:
 *      Initialize the construction materials for wands and staffs
 */

void
init_materials(void)
{
    register int i;
    register char *str;

    for (i = 0 ; i < MAXSTICKS ; i++)
    {
        do
            if (rnd(100) > 50)
            {
                str = metal[rnd(NMETAL)].w_string;
                if (isupper(*str))
                        ws_type[i] = "wand";
            }
            else
            {
                str = wood[rnd(NWOOD)].w_string;
                if (isupper(*str))
                        ws_type[i] = "staff";
            }
        until (isupper(*str));
        *str = tolower(*str);
        ws_made[i] = str;
        ws_know[i] = FALSE;
        ws_guess[i] = NULL;
        if (i > 0)
                ws_magic[i].mi_prob += ws_magic[i-1].mi_prob;
    }
    badcheck("sticks", ws_magic, MAXSTICKS);
}

/*
 * do any initialization for miscellaneous magic
 */

void
init_misc(void)
{
    register int i;

    for (i=0; i < MAXMM; i++) {
        m_know[i] = FALSE;
        m_guess[i] = NULL;
        if (i > 0)
            m_magic[i].mi_prob += m_magic[i-1].mi_prob;
    }
    badcheck("miscellaneous magic", m_magic, MAXMM);
}

/*
 * init_names:
 *      Generate the names of the various scrolls
 */

void
init_names(void)
{
    register int nsyl;
    register char *cp, *sp;
    register int i, nwords;

    for (i = 0 ; i < MAXSCROLLS ; i++)
    {
        cp = prbuf;
        nwords = rnd(cols/20) + 1 + (cols > 40 ? 1 : 0);
        while(nwords--)
        {
            nsyl = rnd(5)+1;
            while(nsyl--)
            {
                sp = sylls[rnd(NSYLLS)].w_string;
                while(*sp)
                    *cp++ = *sp++;
            }
            *cp++ = ' ';
        }
        *--cp = '\0';
        s_names[i] = (char *) new(strlen(prbuf)+1);
        s_know[i] = FALSE;
        s_guess[i] = NULL;
        strcpy(s_names[i], prbuf);
        if (i > 0)
                s_magic[i].mi_prob += s_magic[i-1].mi_prob;
    }
    badcheck("scrolls", s_magic, MAXSCROLLS);
}

/*
 * init_player:
 *      roll up the rogue
 */

void
init_player(void)
{
    int stat_total, round = 0, minimum, maximum, ch, i, j = 0;
    short do_escape, *our_stats[NUMABILITIES-1];
    struct linked_list  *weap_item, *armor_item, *food_item;
    struct object *obj;

    weap_item = armor_item = food_item = NULL;

    if (char_type == -1) {  /* not set via options */
        /* See what type character will be */
        wclear(hw);
        touchwin(hw);
        wmove(hw,2,0);
        for(i=1; i<=NUM_CHARTYPES-1; i++) {
            wprintw(hw,"[%d] %s\n",i,char_class[i-1].name);
        }
        mvwaddstr(hw, 0, 0, "What character class do you desire? ");
        draw(hw);
        char_type = (wgetch(hw) - '0');
        while (char_type < 1 || char_type > NUM_CHARTYPES-1) {
            wmove(hw,0,0);
            wprintw(hw,"Please enter a character type between 1 and %d: ",
                    NUM_CHARTYPES-1);
            draw(hw);
            char_type = (wgetch(hw) - '0');
        }
        char_type--;
    }
    player.t_ctype = char_type;
    player.t_quiet = 0;
    pack = NULL;

    /* Select the gold */
    purse = 3000;
    switch (player.t_ctype) {
        case C_FIGHTER:
            purse += 200;
        when C_MAGICIAN:
        case C_CLERIC:
        case C_DRUID:
            purse += 100;
        when C_THIEF:
        case C_ASSASSIN:
        purse += 0;
        when C_RANGER:
        case C_PALADIN:
            purse -= 100;
        when C_MONK:
            purse -= 200;
    }
    /* 
     * allow me to describe a super character 
     */
        /* let's lessen the restrictions on this okay? */
    if (wizard && strcmp(getenv("SUPER"),"YES") == 0) {
        pstats.s_str = MAXATT;
        pstats.s_intel = MAXATT;
        pstats.s_wisdom = MAXATT;
        pstats.s_dext = MAXATT;
        pstats.s_const = MAXATT;
        pstats.s_charisma = MAXATT;
        pstats.s_exp = 10000000L;
        pstats.s_lvl = 1;
        pstats.s_lvladj = 0;
        pstats.s_hpt = 500;
        pstats.s_carry = totalenc(&player);
        strcpy(pstats.s_dmg,"4d8");
        check_level();
        wmove(hw,0,0);
        wclrtoeol(hw);
        draw(hw);
        mpos = 0;

    /* set quest item */
    if(player.t_ctype == C_FIGHTER)  quest_item = AXE_AKLAD;
    if(player.t_ctype == C_RANGER)   quest_item = BRIAN_MANDOLIN;
    if(player.t_ctype == C_PALADIN)  quest_item = HEIL_ANKH;
    if(player.t_ctype == C_MAGICIAN) quest_item = STONEBONES_AMULET;
    if(player.t_ctype == C_CLERIC)   quest_item = GERYON_HORN;
    if(player.t_ctype == C_THIEF)    quest_item = MUSTY_DAGGER;
    if(player.t_ctype == C_ASSASSIN) quest_item = EYE_VECNA;
    if(player.t_ctype == C_DRUID)    quest_item = QUILL_NAGROM;
    if(player.t_ctype == C_MONK)     quest_item = EMORI_CLOAK;

    /* armor */
        if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN)
            j = STUDDED_LEATHER;
        else if (player.t_ctype == C_MONK) {
        armor_item = spec_item(MM, MM_BRACERS, 20, 0);
        obj = OBJPTR(armor_item);
            obj->o_weight = things[TYP_MM].mi_wght;
        whatis (armor_item);  /* identify it */
            obj->o_flags |= (ISKNOW | ISPROT);
            add_pack(armor_item, TRUE);
            cur_misc[WEAR_BRACERS] = obj;
        goto w_armorjmp; 
    }
        else j =  PLATE_ARMOR;

        armor_item = spec_item(ARMOR, j, 20, 0);
        obj = OBJPTR(armor_item);
        obj->o_weight = armors[j].a_wght;
        obj->o_flags |= (ISKNOW | ISPROT);
        add_pack(armor_item, TRUE);
        cur_armor = obj;

    w_armorjmp:  /* monk doesn't wear armor */

        /* weapons */
        if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN ||
            player.t_ctype == C_MONK) 
        j = BASWORD;
        else if (player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER ||
        player.t_ctype == C_PALADIN)
        j = TWOSWORD;
    else j = TRIDENT;

        weap_item = spec_item(WEAPON, j, 20, 20);
        obj = OBJPTR(weap_item);
        obj->o_flags |= (ISKNOW | ISPROT);
        obj->o_weight = weaps[j].w_wght;
        add_pack(weap_item, TRUE);
        cur_weapon = obj;

    /* food */
        food_item = spec_item(FOOD, E_RATION, 0, 0);
        obj = OBJPTR(food_item);
        obj->o_flags |= ISKNOW;
        obj->o_weight = foods[TYP_FOOD].mi_wght;
        add_pack(food_item, TRUE); /* just one */

    /* give wizard plenty gold */
        purse = 50000;
    }
    else 
    /* default attributes checked */
    {
    if (def_attr == TRUE) {  /* "default" option used in ROGUEOPTS */
    switch(player.t_ctype) {
        /* set "default attributes" option and quest items here */
        case C_FIGHTER:
        case C_MONK:
                pstats.s_intel = 7;
                pstats.s_dext = 16;
                pstats.s_charisma = 11;
            if (player.t_ctype == C_FIGHTER) {
                    pstats.s_str = 16;
                    pstats.s_wisdom = 7;
                    pstats.s_const = 17;
                quest_item = AXE_AKLAD;
        }
        else {
                    pstats.s_str = 11;
                    pstats.s_wisdom = 11;
                    pstats.s_const = 18;
                quest_item = EMORI_CLOAK;
        }
        when C_RANGER:
        case C_PALADIN:
                pstats.s_str = 11;
                pstats.s_dext = 16;
                pstats.s_const = 16;
                pstats.s_charisma = 13;
            /* intelligence or wisdom */
            if (player.t_ctype == C_RANGER) {
                    pstats.s_intel = 11;
                    pstats.s_wisdom = 7;
                quest_item = BRIAN_MANDOLIN;
            }
            else {
                    pstats.s_intel = 7;
                    pstats.s_wisdom = 11;
                quest_item = HEIL_ANKH;
            }
        when C_THIEF:
        case C_ASSASSIN:
                pstats.s_intel = 7;
                pstats.s_str = 14;
                pstats.s_wisdom = 7;
                pstats.s_dext = 18;
                pstats.s_const = 17;
                pstats.s_charisma = 11;
            if (player.t_ctype == C_THIEF) 
                quest_item = MUSTY_DAGGER;
            else
                quest_item = EYE_VECNA;
        when C_MAGICIAN:
        case C_CLERIC:
        case C_DRUID:
                pstats.s_str = 10;
                pstats.s_dext = 16;
                pstats.s_const = 15;
                pstats.s_charisma = 12;
            /* intelligence & wisdom */
            if (player.t_ctype == C_MAGICIAN) {
                    pstats.s_intel = 14;
                    pstats.s_wisdom = 7;
            }
            else {
                    pstats.s_intel = 7;
                    pstats.s_wisdom = 14;
            }
            if (player.t_ctype == C_MAGICIAN) 
                quest_item = STONEBONES_AMULET;
            else if (player.t_ctype == C_CLERIC) 
                quest_item = GERYON_HORN;
            else
                quest_item = QUILL_NAGROM;
    }
        /* Intialize */
        pstats.s_exp = 0L;
        pstats.s_lvl = 1;
        pstats.s_lvladj = 0;
        pstats.s_exp = 0L;
        strcpy(pstats.s_dmg,"2d4");
        pstats.s_carry = totalenc(&player);
        check_level();
        wmove(hw,0,0);
        wclrtoeol(hw);
        draw(hw);
        mpos = 0;

        /* Get the hit points. */
        pstats.s_hpt = 12 + const_bonus();  /* Base plus bonus */

        /* Add in the component that varies according to class */
        pstats.s_hpt += char_class[player.t_ctype].hit_pts;

        /* dole out some armor */
        if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN)
        j = STUDDED_LEATHER;
        else if (player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER ||
             player.t_ctype == C_PALADIN) {
         switch (rnd(4)) {
             case 0:         j = PLATE_ARMOR;
             when 1:         j = PLATE_MAIL;
             when 2: case 3: j = BANDED_MAIL;
        }
    }
        else if (player.t_ctype == C_MONK) {
        if (rnd(3) == 0) j = MM_PROTECT;
        else j = MM_BRACERS;
        armor_item = spec_item(MM, j, rnd(125)/60+3, 0);
        obj = OBJPTR(armor_item);
            obj->o_weight = things[TYP_MM].mi_wght;
        whatis (armor_item);  /* identify it */
            obj->o_flags |= ISKNOW;
            add_pack(armor_item, TRUE);
        goto p_armorjmp;
    }
    else {  /* other characters */
        switch (rnd(7)) {
        case 0:         j = PLATE_MAIL;
        when 1: case 2: j = BANDED_MAIL;
        when 3: case 4: j = SPLINT_MAIL;
        when 5: case 6: j = PADDED_ARMOR;
        }
    }
        armor_item = spec_item(ARMOR, j, rnd(100)/85, 0);
        obj = OBJPTR(armor_item);
        obj->o_weight = armors[j].a_wght;
        obj->o_flags |= ISKNOW;
        add_pack(armor_item, TRUE);

    p_armorjmp:  /* monk doesn't wear armor */

        /* give him a weapon */
        if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASSIN ||
            player.t_ctype == C_MONK) {
        switch (rnd(5)) {
        case 0:         j = BASWORD;
        when 1: case 2: j = TRIDENT;
        when 3: case 4: j = BARDICHE;
        }
    }
        else if (player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER ||
        player.t_ctype == C_PALADIN) {
        switch (rnd(5)) {
        case 0:         j= TWOSWORD;
        when 1: case 2: j= TRIDENT;
        when 3: case 4: j= SWORD;
        }
    }
        else {
        switch (rnd(7)) {
        case 0:         j = TRIDENT;
        when 1: case 2: j = SWORD;
        when 3: case 4: j = BARDICHE;
        when 5:         j = MACE;
        when 6:         j = SPETUM;
        }
    }
        weap_item = spec_item(WEAPON, j, rnd(155)/75, rnd(165)/80);
        obj = OBJPTR(weap_item);
        obj->o_weight = weaps[j].w_wght;
        obj->o_flags |= ISKNOW;
        add_pack(weap_item, TRUE);

        /* food rations */
        food_item = spec_item(FOOD, E_RATION, 0, 0);
        obj = OBJPTR(food_item);
        obj->o_weight = foods[TYP_FOOD].mi_wght;
        obj->o_flags |= ISKNOW;
        add_pack(food_item, TRUE);

    /* give him some fruit - coose from those w/o special effects */
    switch (rnd(6)) {
        case 0: j = E_BANANA;
        when 1: j = E_BLUEBERRY;
        when 2: j = E_ELDERBERRY;
        when 3: j = E_GUANABANA;
        when 4: j = E_CAPRIFIG;
        when 5: j = E_GOOSEBERRY;
    }
        food_item = spec_item(FOOD, j, 0, 0);
        obj = OBJPTR(food_item);
        obj->o_weight = foods[TYP_FOOD].mi_wght;
        obj->o_flags |= ISKNOW;
        add_pack(food_item, TRUE);

    /* adjust purse */
    purse = 2000;
    }
    else {  /* select attibutes */
        switch(player.t_ctype) {
            case C_FIGHTER:     round = A_STRENGTH;
            when C_RANGER:      round = A_CHARISMA;
            when C_PALADIN:     round = A_CHARISMA;
            when C_MAGICIAN:    round = A_INTELLIGENCE;
            when C_CLERIC:      round = A_WISDOM;
            when C_THIEF:       round = A_DEXTERITY;
            when C_ASSASSIN:    round = A_DEXTERITY;
            when C_DRUID:       round = A_WISDOM;
            when C_MONK:        round = A_CONSTITUTION;
        }

        do {
            wclear(hw);

            /* If there is any news, display it */
            if (rogue_news) {
                register int i;

                /* Print a separator line */
                wmove(hw, 12, 0);
                for (i=0; i<cols; i++) waddch(hw, '-');

                /* Print the news */
                mvwaddstr(hw, 14, 0, rogue_news);
            }

            stat_total = MAXSTATS;
            do_escape = FALSE;  /* No escape seen yet */

            /* Initialize abilities */
            pstats.s_intel = 0;
            pstats.s_str = 0;
            pstats.s_wisdom = 0;
            pstats.s_dext = 0;
            pstats.s_const = 0;
            pstats.s_charisma = 0;

            /* Initialize pointer into abilities */
            our_stats[A_INTELLIGENCE] = &pstats.s_intel;
            our_stats[A_STRENGTH] = &pstats.s_str;
            our_stats[A_WISDOM] = &pstats.s_wisdom;
            our_stats[A_DEXTERITY] = &pstats.s_dext;
            our_stats[A_CONSTITUTION] = &pstats.s_const;

            /* Let player distribute attributes */
            for (i=0; i<NUMABILITIES-1; i++) {
                wmove(hw, 2, 0);
                wprintw(hw, "You are creating a %s with %2d attribute points.",
                                char_class[player.t_ctype].name, stat_total);

                /*
                 * Player must have a minimum of 7 in any attribute and 11 in
                 * the player's primary attribute.
                 */
                minimum = (round == i ? 11 : 7);

                /* Subtract out remaining minimums */
                maximum = stat_total - (7 * (NUMABILITIES-1 - i));

                /* Subtract out remainder of profession minimum (11 - 7) */
                if (round > i) maximum -= 4;

                /* Maximum can't be greater than 18 */
                if (maximum > 18) maximum = 18;

                wmove(hw, 4, 0);
                wprintw(hw,
                   "Minimum: %2d;  Maximum: %2d  (%s corrects previous entry)",
                   minimum, maximum, unctrl('\b'));

                wmove(hw, 6, 0);
                wprintw(hw, "    Int: %-2d", pstats.s_intel);
                wprintw(hw, "    Str: %-2d", pstats.s_str);
                wprintw(hw, "    Wis: %-2d", pstats.s_wisdom); 
                wprintw(hw, "    Dex: %-2d", pstats.s_dext);
                wprintw(hw, "    Con: %-2d", pstats.s_const);
                wprintw(hw, "    Cha: %-2d", pstats.s_charisma);
                wclrtoeol(hw);
                wmove(hw, 6, 11*i + 9);
                if (do_escape == FALSE) draw(hw);

                /* Get player's input */
                if (do_escape || maximum == minimum) {
                    *our_stats[i] = maximum;
                    stat_total -= maximum;
                }
                else for (;;) {
                    ch = wgetch(hw);
                    if (ch == '\b') {   /* Backspace */
                        if (i == 0) continue;   /* Can't move back */
                        else {
                            stat_total += *our_stats[i-1];
                            *our_stats[i] = 0;
                            *our_stats[i-1] = 0;
                            i -= 2;     /* Back out */
                            break;
                        }
                    }
                    if (ch == '\033') { /* Escape */
                        /*
                         * Escape will result in using all maximums for
                         * remaining abilities.
                         */
                        do_escape = TRUE;
                        *our_stats[i] = maximum;
                        stat_total -= maximum;
                        break;
                    }

                    /* Do we have a legal digit? */
                    if (ch >= '0' && ch <= '9') {
                        ch -= '0';      /* Convert it to a number */
                        *our_stats[i] = 10 * *our_stats[i] + ch;

                        /* Is the number in range? */
                        if (*our_stats[i] >= minimum &&
                            *our_stats[i] <= maximum) {
                            stat_total -= *our_stats[i];
                            break;
                        }

                        /*
                         * If it's too small, get more - 1x is the only
                         * allowable case.
                         */
                        if (*our_stats[i] < minimum && *our_stats[i] == 1) {
                            /* Print the player's one */
                            waddch(hw, '1');
                            draw(hw);
                            continue;
                        }
                    }

                    /* Error condition */
                    putchar('\007');
                    *our_stats[i] = 0;
                    i--;        /* Rewind */
                    break;
                }
            }

            /* Discard extra points over 18 */
            if (stat_total > 18) stat_total = 18;

            /* Charisma gets what's left */
            pstats.s_charisma = stat_total;

            /* Intialize constants */
            pstats.s_lvl = 1;
            pstats.s_lvladj = 0;
            pstats.s_exp = 0L;
            strcpy(pstats.s_dmg,"2d4");
            pstats.s_carry = totalenc(&player);

            /* Get the hit points. */
            pstats.s_hpt = 12 + const_bonus();  /* Base plus bonus */

            /* Add in the component that varies according to class */
            pstats.s_hpt += char_class[player.t_ctype].hit_pts;

            /* Display the character */
            wmove(hw, 2, 0);
            wprintw(hw,"You are creating a %s.",
                        char_class[player.t_ctype].name);
            wclrtoeol(hw);

            /* Get rid of max/min line */
            wmove(hw, 4, 0);
            wclrtoeol(hw);