diff arogue7/init.c @ 125:adfa37e67084

Import Advanced Rogue 7.7 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Fri, 08 May 2015 15:24:40 -0400
parents
children b786053d2f37
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/arogue7/init.c	Fri May 08 15:24:40 2015 -0400
@@ -0,0 +1,624 @@
+/*
+ * 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 "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
+ */
+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, 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
+ */
+
+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, 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
+ */
+
+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(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
+ */
+
+init_player()
+{
+    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
+ */
+
+init_stones()
+{
+    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
+ */
+init_things()
+{
+    register struct magic_item *mp;
+
+    for (mp = &things[1] ; mp < &things[NUMTHINGS] ; mp++)
+	mp->mi_prob += (mp-1)->mi_prob;
+    badcheck("things", things, NUMTHINGS);
+}
+
+