Mercurial > hg > early-roguelike
view arogue7/init.c @ 226:b922f66acf4d
Super-Rogue: begin fixing restore failures on Windows.
Start to solve the problem by calling md_init() to set _fmode. Now
reading a savefile only triggers an error handler and causes an abort
instead of a crash.
author | John "Elwin" Edwards |
---|---|
date | Thu, 03 Mar 2016 21:30:38 -0500 |
parents | f9ef86cf22b2 |
children | e52a8a7ad4c5 |
line wrap: on
line source
/* * init.c - global variable initializaton * * Advanced Rogue * Copyright (C) 1984, 1985, 1986 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. */ /* * global variable initializaton * */ #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 = "You no longer fall into trading posts. They are \ now entered like going down the stairs."; char *rainbow[] = { "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", }; #define NCOLORS (sizeof rainbow / sizeof(char *)) int cNCOLORS = NCOLORS; static char *sylls[] = { "a", "ab", "ag", "aks", "ala", "an", "ankh", "app", "arg", "arze", "ash", "ban", "bar", "bat", "bek", "bie", "bin", "bit", "bjor", "blu", "bot", "bu", "byt", "comp", "con", "cos", "cre", "dalf", "dan", "den", "do", "e", "eep", "el", "eng", "er", "ere", "erk", "esh", "evs", "fa", "fid", "for", "fri", "fu", "gan", "gar", "glen", "gop", "gre", "ha", "he", "hyd", "i", "ing", "ion", "ip", "ish", "it", "ite", "iv", "jo", "kho", "kli", "klis", "la", "lech", "man", "mar", "me", "mi", "mic", "mik", "mon", "mung", "mur", "nej", "nelg", "nep", "ner", "nes", "net", "nih", "nin", "o", "od", "ood", "org", "orn", "ox", "oxy", "pay", "pet", "ple", "plu", "po", "pot", "prok", "re", "rea", "rhov", "ri", "ro", "rog", "rok", "rol", "sa", "san", "sat", "see", "sef", "seh", "shu", "ski", "sna", "sne", "snik", "sno", "so", "sol", "sri", "sta", "sun", "ta", "tab", "tem", "ther", "ti", "tox", "trol", "tue", "turs", "u", "ulk", "um", "un", "uni", "ur", "val", "viv", "vly", "vom", "wah", "wed", "werg", "wex", "whon", "wun", "xo", "y", "yot", "yu", "zant", "zap", "zeb", "zim", "zok", "zon", "zum", }; char *stones[] = { "agate", "alexandrite", "amethyst", "azurite", "bloodstone", "cairngorm", "carnelian", "chalcedony", "chrysoberyl", "chrysolite", "chrysoprase", "citrine", "coral", "diamond", "emerald", "garnet", "heliotrope", "hematite", "hyacinth", "jacinth", "jade", "jargoon", "jasper", "kryptonite", "lapus lazuli", "malachite", "mocca stone", "moonstone", "obsidian", "olivine", "onyx", "opal", "pearl", "peridot", "quartz", "rhodochrosite", "rhodolite", "ruby", "sapphire", "sardonyx", "serpintine", "spinel", "tiger eye", "topaz", "tourmaline", "turquoise", "zircon", }; #define NSTONES (sizeof stones / sizeof(char *)) int cNSTONES = NSTONES; char *wood[] = { "avocado wood", "balsa", "banyan", "birch", "cedar", "cherry", "cinnibar", "dogwood", "driftwood", "ebony", "eucalyptus", "hemlock", "ironwood", "mahogany", "manzanita", "maple", "oak", "pine", "redwood", "rosewood", "teak", "walnut", "zebra wood", "persimmon wood", }; #define NWOOD (sizeof wood / sizeof(char *)) int cNWOOD = NWOOD; char *metal[] = { "aluminium", "bone", "brass", "bronze", "copper", "chromium", "iron", "lead", "magnesium", "pewter", "platinum", "silver", "steel", "tin", "titanium", "zinc", }; #define NMETAL (sizeof metal / sizeof(char *)) int cNMETAL = NMETAL; #define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c)) static bool used[MAX3(NCOLORS, NSTONES, NWOOD)]; /* * 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, j; for (i = 0; i < NCOLORS; i++) used[i] = FALSE; for (i = 0 ; i < MAXPOTIONS ; i++) { do j = rnd(NCOLORS); until (!used[j]); used[j] = TRUE; p_colors[i] = rainbow[j]; 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, j; register char *str; static bool metused[NMETAL]; for (i = 0; i < NWOOD; i++) used[i] = FALSE; for (i = 0; i < NMETAL; i++) metused[i] = FALSE; for (i = 0 ; i < MAXSTICKS ; i++) { for (;;) if (rnd(100) > 50) { j = rnd(NMETAL); if (!metused[j]) { ws_type[i] = "wand"; str = metal[j]; metused[j] = TRUE; break; } } else { j = rnd(NWOOD); if (!used[j]) { ws_type[i] = "staff"; str = wood[j]; used[j] = TRUE; break; } } 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(3)+1; while(nsyl--) { sp = sylls[rnd((sizeof sylls) / (sizeof (char *)))]; 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, minimum, maximum, ch, i, j; short do_escape, *our_stats[NUMABILITIES-1]; struct linked_list *weap_item, *armor_item; struct object *obj; weap_item = armor_item = NULL; if (char_type == -1) { /* 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 = 2700; switch (player.t_ctype) { case C_FIGHTER: purse += 1800; when C_THIEF: case C_ASSASIN: purse += 600; } #ifdef WIZARD /* * allow me to describe a super character */ if (wizard && strcmp(getenv("SUPER"),"YES") == 0) { pstats.s_str = 25; pstats.s_intel = 25; pstats.s_wisdom = 25; pstats.s_dext = 25; pstats.s_const = 25; pstats.s_charisma = 25; pstats.s_exp = 10000000L; pstats.s_lvladj = 0; pstats.s_lvl = 1; pstats.s_hpt = 500; pstats.s_carry = totalenc(&player); strncpy(pstats.s_dmg, "3d4", sizeof(pstats.s_dmg)); check_level(); mpos = 0; if (player.t_ctype == C_FIGHTER || player.t_ctype == C_RANGER || player.t_ctype == C_PALADIN) weap_item = spec_item(WEAPON, TWOSWORD, 5, 5); else weap_item = spec_item(WEAPON, SWORD, 5, 5); obj = OBJPTR(weap_item); obj->o_flags |= ISKNOW; add_pack(weap_item, TRUE, NULL); cur_weapon = obj; if (player.t_ctype != C_MONK) { j = PLATE_ARMOR; if (player.t_ctype == C_THIEF || player.t_ctype == C_ASSASIN) j = STUDDED_LEATHER; armor_item = spec_item(ARMOR, j, 10, 0); obj = OBJPTR(armor_item); obj->o_flags |= (ISKNOW | ISPROT); obj->o_weight = armors[j].a_wght; add_pack(armor_item, TRUE, NULL); cur_armor = obj; } purse += 10000; } else #endif { switch(player.t_ctype) { case C_MAGICIAN:round = A_INTELLIGENCE; when C_FIGHTER: round = A_STRENGTH; when C_RANGER: round = A_STRENGTH; when C_PALADIN: round = A_STRENGTH; when C_CLERIC: round = A_WISDOM; when C_DRUID: round = A_WISDOM; when C_THIEF: round = A_DEXTERITY; when C_ASSASIN: round = A_DEXTERITY; when C_MONK: round = A_DEXTERITY; } 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; strncpy(pstats.s_dmg, "1d4", sizeof(pstats.s_dmg)); 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); 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, 8, 0); wprintw(hw, " Hp: %2d", pstats.s_hpt); wclrtoeol(hw); wmove(hw, 10, 0); wprintw(hw, " Gold: %d", purse); mvwaddstr(hw, 0, 0, "Is this character okay? "); draw(hw); } while(wgetch(hw) != 'y'); } pstats.s_arm = 10; max_stats = pstats; /* Set up the initial movement rate */ player.t_action = A_NIL; player.t_movement = 6; player.t_no_move = 0; player.t_using = NULL; } /* * init_stones: * Initialize the ring stone setting scheme for this time */ void init_stones(void) { register int i, j; for (i = 0; i < NSTONES; i++) used[i] = FALSE; for (i = 0 ; i < MAXRINGS ; i++) { do j = rnd(NSTONES); until (!used[j]); used[j] = TRUE; r_stones[i] = stones[j]; r_know[i] = FALSE; r_guess[i] = NULL; if (i > 0) r_magic[i].mi_prob += r_magic[i-1].mi_prob; } badcheck("rings", r_magic, MAXRINGS); } /* * init_things * Initialize the probabilities for types of things */ void init_things(void) { register struct magic_item *mp; for (mp = &things[1] ; mp < &things[NUMTHINGS] ; mp++) mp->mi_prob += (mp-1)->mi_prob; badcheck("things", things, NUMTHINGS); }