diff xrogue/init.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xrogue/init.c	Tue Apr 21 08:55:20 2015 -0400
@@ -0,0 +1,825 @@
+/*
+    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 "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
+ */
+
+badcheck(name, magic, bound)
+char *name;
+register struct magic_item *magic;
+register 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
+ */
+
+init_colors()
+{
+    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
+ */
+
+init_foods()
+{
+    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
+ */
+
+init_materials()
+{
+    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
+ */
+
+init_misc()
+{
+    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
+ */
+
+init_names()
+{
+    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
+ */
+
+init_player()
+{
+    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;
+