There should only be two changes in behavior: arogue7/fight.c, arogue7/fight.c: a to-hit bonus is now correctly applied to characters who are not monks instead of monks who are not empty-handed. urogue/fight.c: fixed an interaction with the "debug" macro that could cause the wrong message to be displayed.
597 lines
15 KiB
C
597 lines
15 KiB
C
/*
|
|
* global variable initializaton
|
|
*
|
|
* @(#)init.c 3.33 (Berkeley) 6/15/81
|
|
*
|
|
* 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 <stdlib.h>
|
|
#include "machdep.h"
|
|
#include "rogue.h"
|
|
|
|
int playing = TRUE, running = FALSE, wizard = FALSE;
|
|
int notify = TRUE, fight_flush = FALSE, terse = FALSE, door_stop = FALSE;
|
|
int jump = FALSE, slow_invent = FALSE, firstmove = FALSE, askme = TRUE;
|
|
int use_savedir = FALSE;
|
|
int amulet = FALSE;
|
|
int in_shell = FALSE;
|
|
struct linked_list *lvl_obj = NULL, *mlist = NULL;
|
|
struct object *cur_weapon = NULL;
|
|
int mpos = 0, no_move = 0, no_command = 0, level = 1, purse = 0, inpack = 0;
|
|
int total = 0, no_food = 0, count = 0, fung_hit = 0, quiet = 0;
|
|
int food_left = HUNGERTIME, group = 1, hungry_state = 0;
|
|
int lastscore = -1;
|
|
|
|
struct thing player;
|
|
struct room rooms[MAXROOMS];
|
|
struct room *oldrp;
|
|
struct stats max_stats;
|
|
struct object *cur_armor;
|
|
struct object *cur_ring[2];
|
|
int after;
|
|
int waswizard;
|
|
coord oldpos; /* Position before last look() call */
|
|
coord delta; /* Change indicated to get_dir() */
|
|
|
|
int s_know[MAXSCROLLS]; /* Does he know what a scroll does */
|
|
int p_know[MAXPOTIONS]; /* Does he know what a potion does */
|
|
int r_know[MAXRINGS]; /* Does he know what a ring does
|
|
*/
|
|
int ws_know[MAXSTICKS]; /* Does he know what a stick does */
|
|
|
|
int take; /* Thing the rogue is taking */
|
|
int runch; /* Direction player is running */
|
|
char whoami[80]; /* Name of player */
|
|
char fruit[80]; /* Favorite fruit */
|
|
char huh[80]; /* The last message printed */
|
|
int dnum; /* Dungeon number */
|
|
char *s_names[MAXSCROLLS]; /* Names of the scrolls */
|
|
char *p_colors[MAXPOTIONS]; /* Colors of the potions */
|
|
char *r_stones[MAXRINGS]; /* Stone settings of the rings */
|
|
char *a_names[MAXARMORS]; /* Names of armor types */
|
|
char *ws_made[MAXSTICKS]; /* What sticks are made of */
|
|
char *s_guess[MAXSCROLLS]; /* Players guess at what scroll is */
|
|
char *p_guess[MAXPOTIONS]; /* Players guess at what potion is */
|
|
char *r_guess[MAXRINGS]; /* Players guess at what ring is */
|
|
char *ws_guess[MAXSTICKS]; /* Players guess at what wand is */
|
|
char *ws_type[MAXSTICKS]; /* Is it a wand or a staff */
|
|
char file_name[256]; /* Save file name */
|
|
char home[PATH_MAX]; /* User's home directory */
|
|
char prbuf[80]; /* Buffer for sprintfs */
|
|
int max_hp; /* Player's max hit points */
|
|
int ntraps; /* Number of traps on this level */
|
|
int max_level; /* Deepest player has gone */
|
|
int seed; /* Random number seed */
|
|
|
|
struct trap traps[MAXTRAPS];
|
|
|
|
|
|
#define ___ 1
|
|
#define _x {1,1}
|
|
struct monster monsters[26] = {
|
|
/* Name CARRY FLAG str, exp, lvl, amr, hpt, dmg */
|
|
{ "giant ant", 0, ISMEAN, { _x, 10, 2, 3, ___, "1d6" } },
|
|
{ "bat", 0, 0, { _x, 1, 1, 3, ___, "1d2" } },
|
|
{ "centaur", 15, 0, { _x, 15, 4, 4, ___, "1d6/1d6" } },
|
|
{ "dragon", 100, ISGREED,{ _x,9000, 10, -1, ___, "1d8/1d8/3d10" } },
|
|
{ "floating eye",0, 0, { _x, 5, 1, 9, ___, "0d0" } },
|
|
{ "violet fungi",0, ISMEAN, { _x, 85, 8, 3, ___, "000d0" } },
|
|
{ "gnome", 10, 0, { _x, 8, 1, 5, ___, "1d6" } },
|
|
{ "hobgoblin", 0, ISMEAN, { _x, 3, 1, 5, ___, "1d8" } },
|
|
{ "invisible stalker",0,ISINVIS,{ _x,120, 8, 3, ___, "4d4" } },
|
|
{ "jackal", 0, ISMEAN, { _x, 2, 1, 7, ___, "1d2" } },
|
|
{ "kobold", 0, ISMEAN, { _x, 1, 1, 7, ___, "1d4" } },
|
|
{ "leprechaun", 0, 0, { _x, 10, 3, 8, ___, "1d1" } },
|
|
{ "mimic", 30, 0, { _x,140, 7, 7, ___, "3d4" } },
|
|
{ "nymph", 100, 0, { _x, 40, 3, 9, ___, "0d0" } },
|
|
{ "orc", 15, ISBLOCK,{ _x, 5, 1, 6, ___, "1d8" } },
|
|
{ "purple worm", 70, 0, { _x,7000, 15, 6, ___, "2d12/2d4" } },
|
|
{ "quasit", 30, ISMEAN, { _x, 35, 3, 2, ___, "1d2/1d2/1d4" } },
|
|
{ "rust monster",0, ISMEAN, { _x, 25, 5, 2, ___, "0d0/0d0" } },
|
|
{ "snake", 0, ISMEAN, { _x, 3, 1, 5, ___, "1d3" } },
|
|
{ "troll", 50, ISREGEN|ISMEAN,{ _x, 55, 6, 4, ___, "1d8/1d8/2d6" } },
|
|
{ "umber hulk", 40, ISMEAN, { _x,130, 8, 2, ___, "3d4/3d4/2d5" } },
|
|
{ "vampire", 20, ISREGEN|ISMEAN,{ _x,380, 8, 1, ___, "1d10" } },
|
|
{ "wraith", 0, 0, { _x, 55, 5, 4, ___, "1d6" } },
|
|
{ "xorn", 0, ISMEAN, { _x,120, 7, -2, ___, "1d3/1d3/1d3/4d6" } },
|
|
{ "yeti", 30, 0, { _x, 50, 4, 6, ___, "1d6/1d6" } },
|
|
{ "zombie", 0, ISMEAN, { _x, 7, 2, 8, ___, "1d8" } }
|
|
};
|
|
#undef ___
|
|
|
|
/*
|
|
* init_player:
|
|
* roll up the rogue
|
|
*/
|
|
|
|
void
|
|
init_player()
|
|
{
|
|
pstats.s_lvl = 1;
|
|
pstats.s_exp = 0L;
|
|
max_hp = pstats.s_hpt = 12;
|
|
if (rnd(100) == 7)
|
|
{
|
|
pstats.s_str.st_str = 18;
|
|
pstats.s_str.st_add = rnd(100) + 1;
|
|
}
|
|
else
|
|
{
|
|
pstats.s_str.st_str = 16;
|
|
pstats.s_str.st_add = 0;
|
|
}
|
|
strcpy(pstats.s_dmg,"1d4");
|
|
pstats.s_arm = 10;
|
|
max_stats = pstats;
|
|
pack = NULL;
|
|
}
|
|
|
|
/*
|
|
* Contains defintions and functions for dealing with things like
|
|
* potions and scrolls
|
|
*/
|
|
|
|
char *rainbow[] = {
|
|
"red",
|
|
"blue",
|
|
"green",
|
|
"yellow",
|
|
"black",
|
|
"brown",
|
|
"orange",
|
|
"pink",
|
|
"purple",
|
|
"grey",
|
|
"white",
|
|
"silver",
|
|
"gold",
|
|
"violet",
|
|
"clear",
|
|
"vermilion",
|
|
"ecru",
|
|
"turquoise",
|
|
"magenta",
|
|
"amber",
|
|
"topaz",
|
|
"plaid",
|
|
"tan",
|
|
"tangerine"
|
|
};
|
|
|
|
#define NCOLORS (sizeof rainbow / sizeof (char *))
|
|
int cNCOLORS = NCOLORS;
|
|
|
|
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", "nes", "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",
|
|
"carnelian",
|
|
"diamond",
|
|
"emerald",
|
|
"granite",
|
|
"jade",
|
|
"kryptonite",
|
|
"lapus lazuli",
|
|
"moonstone",
|
|
"obsidian",
|
|
"onyx",
|
|
"opal",
|
|
"pearl",
|
|
"ruby",
|
|
"saphire",
|
|
"tiger eye",
|
|
"topaz",
|
|
"turquoise",
|
|
};
|
|
|
|
#define NSTONES (sizeof stones / sizeof (char *))
|
|
int cNSTONES = NSTONES;
|
|
|
|
char *wood[] = {
|
|
"avocado wood",
|
|
"balsa",
|
|
"banyan",
|
|
"birch",
|
|
"cedar",
|
|
"cherry",
|
|
"cinnibar",
|
|
"driftwood",
|
|
"ebony",
|
|
"eucalyptus",
|
|
"hemlock",
|
|
"ironwood",
|
|
"mahogany",
|
|
"manzanita",
|
|
"maple",
|
|
"oak",
|
|
"persimmon wood",
|
|
"redwood",
|
|
"rosewood",
|
|
"teak",
|
|
"walnut",
|
|
"zebra wood",
|
|
};
|
|
|
|
#define NWOOD (sizeof wood / sizeof (char *))
|
|
int cNWOOD = NWOOD;
|
|
|
|
char *metal[] = {
|
|
"aluminium",
|
|
"bone",
|
|
"brass",
|
|
"bronze",
|
|
"copper",
|
|
"iron",
|
|
"lead",
|
|
"pewter",
|
|
"steel",
|
|
"tin",
|
|
"zinc",
|
|
};
|
|
|
|
#define NMETAL (sizeof metal / sizeof (char *))
|
|
int cNMETAL = NMETAL;
|
|
|
|
struct magic_item things[NUMTHINGS] = {
|
|
{ "", 27, 0 }, /* potion */
|
|
{ "", 27, 0 }, /* scroll */
|
|
{ "", 18, 0 }, /* food */
|
|
{ "", 9, 0 }, /* weapon */
|
|
{ "", 9, 0 }, /* armor */
|
|
{ "", 5, 0 }, /* ring */
|
|
{ "", 5, 0 }, /* stick */
|
|
};
|
|
|
|
struct magic_item s_magic[MAXSCROLLS] = {
|
|
{ "monster confusion", 8, 170 },
|
|
{ "magic mapping", 5, 180 },
|
|
{ "light", 10, 100 },
|
|
{ "hold monster", 2, 200 },
|
|
{ "sleep", 5, 50 },
|
|
{ "enchant armor", 8, 130 },
|
|
{ "identify", 21, 100 },
|
|
{ "scare monster", 4, 180 },
|
|
{ "gold detection", 4, 110 },
|
|
{ "teleportation", 7, 175 },
|
|
{ "enchant weapon", 10, 150 },
|
|
{ "create monster", 5, 75 },
|
|
{ "remove curse", 8, 105 },
|
|
{ "aggravate monsters", 1, 60 },
|
|
{ "blank paper", 1, 50 },
|
|
{ "genocide", 1, 200 },
|
|
};
|
|
|
|
struct magic_item p_magic[MAXPOTIONS] = {
|
|
{ "confusion", 8, 50 },
|
|
{ "paralysis", 10, 50 },
|
|
{ "poison", 8, 50 },
|
|
{ "gain strength", 15, 150 },
|
|
{ "see invisible", 2, 170 },
|
|
{ "healing", 15, 130 },
|
|
{ "monster detection", 6, 120 },
|
|
{ "magic detection", 6, 105 },
|
|
{ "raise level", 2, 220 },
|
|
{ "extra healing", 5, 180 },
|
|
{ "haste self", 4, 200 },
|
|
{ "restore strength", 14, 120 },
|
|
{ "blindness", 4, 50 },
|
|
{ "thirst quenching", 1, 50 },
|
|
};
|
|
|
|
struct magic_item r_magic[MAXRINGS] = {
|
|
{ "protection", 9, 200 },
|
|
{ "add strength", 9, 200 },
|
|
{ "sustain strength", 5, 180 },
|
|
{ "searching", 10, 200 },
|
|
{ "see invisible", 10, 175 },
|
|
{ "adornment", 1, 100 },
|
|
{ "aggravate monster", 11, 100 },
|
|
{ "dexterity", 8, 220 },
|
|
{ "increase damage", 8, 220 },
|
|
{ "regeneration", 4, 260 },
|
|
{ "slow digestion", 9, 240 },
|
|
{ "teleportation", 9, 100 },
|
|
{ "stealth", 7, 100 },
|
|
};
|
|
|
|
struct magic_item ws_magic[MAXSTICKS] = {
|
|
{ "light", 12, 120 },
|
|
{ "striking", 9, 115 },
|
|
{ "lightning", 3, 200 },
|
|
{ "fire", 3, 200 },
|
|
{ "cold", 3, 200 },
|
|
{ "polymorph", 15, 210 },
|
|
{ "magic missile", 10, 170 },
|
|
{ "haste monster", 9, 50 },
|
|
{ "slow monster", 11, 220 },
|
|
{ "drain life", 9, 210 },
|
|
{ "nothing", 1, 70 },
|
|
{ "teleport away", 5, 140 },
|
|
{ "teleport to", 5, 60 },
|
|
{ "cancellation", 5, 130 },
|
|
};
|
|
|
|
int a_class[MAXARMORS] = {
|
|
8,
|
|
7,
|
|
7,
|
|
6,
|
|
5,
|
|
4,
|
|
4,
|
|
3,
|
|
};
|
|
|
|
char *a_names[MAXARMORS] = {
|
|
"leather armor",
|
|
"ring mail",
|
|
"studded leather armor",
|
|
"scale mail",
|
|
"chain mail",
|
|
"splint mail",
|
|
"banded mail",
|
|
"plate mail",
|
|
};
|
|
|
|
int a_chances[MAXARMORS] = {
|
|
20,
|
|
35,
|
|
50,
|
|
63,
|
|
75,
|
|
85,
|
|
95,
|
|
100
|
|
};
|
|
|
|
#define MAX3(a,b,c) (a > b ? (a > c ? a : c) : (b > c ? b : c))
|
|
static int used[MAX3(NCOLORS, NSTONES, NWOOD)];
|
|
|
|
/*
|
|
* init_things
|
|
* Initialize the probabilities for types of things
|
|
*/
|
|
void
|
|
init_things()
|
|
{
|
|
struct magic_item *mp;
|
|
|
|
for (mp = &things[1]; mp <= &things[NUMTHINGS-1]; mp++)
|
|
mp->mi_prob += (mp-1)->mi_prob;
|
|
badcheck("things", things, NUMTHINGS);
|
|
}
|
|
|
|
/*
|
|
* init_colors:
|
|
* Initialize the potion color scheme for this time
|
|
*/
|
|
|
|
void
|
|
init_colors()
|
|
{
|
|
int i, j;
|
|
|
|
for (i = 0; i < NCOLORS; i++)
|
|
used[i] = 0;
|
|
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);
|
|
}
|
|
|
|
/*
|
|
* init_names:
|
|
* Generate the names of the various scrolls
|
|
*/
|
|
|
|
void
|
|
init_names()
|
|
{
|
|
int nsyl;
|
|
char *cp, *sp;
|
|
int i, nwords;
|
|
|
|
for (i = 0; i < MAXSCROLLS; i++)
|
|
{
|
|
cp = prbuf;
|
|
nwords = rnd(4)+2;
|
|
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_stones:
|
|
* Initialize the ring stone setting scheme for this time
|
|
*/
|
|
|
|
void
|
|
init_stones()
|
|
{
|
|
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_materials:
|
|
* Initialize the construction materials for wands and staffs
|
|
*/
|
|
|
|
void
|
|
init_materials()
|
|
{
|
|
int i, j;
|
|
static int 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])
|
|
{
|
|
metused[j] = TRUE;
|
|
ws_made[i] = metal[j];
|
|
ws_type[i] = "wand";
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
j = rnd(NWOOD);
|
|
if (!used[j])
|
|
{
|
|
used[j] = TRUE;
|
|
ws_made[i] = wood[j];
|
|
ws_type[i] = "staff";
|
|
break;
|
|
}
|
|
}
|
|
|
|
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);
|
|
}
|
|
|
|
void
|
|
badcheck(char *name, struct magic_item *magic, int bound)
|
|
{
|
|
struct magic_item *end;
|
|
|
|
if (magic[bound - 1].mi_prob == 100)
|
|
return;
|
|
printf("\nBad percentages for %s:\n", name);
|
|
for (end = &magic[bound]; magic < end; magic++)
|
|
printf("%3d%% %s\n", magic->mi_prob, magic->mi_name);
|
|
printf("[hit RETURN to continue]");
|
|
fflush(stdout);
|
|
while (getchar() != '\n')
|
|
continue;
|
|
}
|
|
|
|
struct h_list helpstr[] = {
|
|
{ '?', " prints help" },
|
|
{ '/', " identify object" },
|
|
{ 'h', " left" },
|
|
{ 'j', " down" },
|
|
{ 'k', " up" },
|
|
{ 'l', " right" },
|
|
{ 'y', " up & left" },
|
|
{ 'u', " up & right" },
|
|
{ 'b', " down & left" },
|
|
{ 'n', " down & right" },
|
|
{ 'H', " run left" },
|
|
{ 'J', " run down" },
|
|
{ 'K', " run up" },
|
|
{ 'L', " run right" },
|
|
{ 'Y', " run up & left" },
|
|
{ 'U', " run up & right" },
|
|
{ 'B', " run down & left" },
|
|
{ 'N', " run down & right" },
|
|
{ 't', "<dir> throw something" },
|
|
{ 'f', "<dir> forward until find something" },
|
|
{ 'p', "<dir> zap a wand in a direction" },
|
|
{ 'z', " zap a wand or staff" },
|
|
{ '>', " go down a staircase" },
|
|
{ 's', " search for trap/secret door" },
|
|
{ '.', " rest for a turn" },
|
|
{ 'i', " inventory" },
|
|
{ 'I', " inventory single item" },
|
|
{ 'q', " quaff potion" },
|
|
{ 'r', " read paper" },
|
|
{ 'e', " eat food" },
|
|
{ 'w', " wield a weapon" },
|
|
{ 'W', " wear armor" },
|
|
{ 'T', " take armor off" },
|
|
{ 'P', " put on ring" },
|
|
{ 'R', " remove ring" },
|
|
{ 'd', " drop object" },
|
|
{ 'c', " call object" },
|
|
{ 'o', " examine/set options" },
|
|
{ CTRL('L'), " redraw screen" },
|
|
{ CTRL('R'), " repeat last message" },
|
|
{ ESCAPE, " cancel command" },
|
|
{ 'v', " print program version number" },
|
|
{ '!', " shell escape" },
|
|
{ 'S', " save game" },
|
|
{ 'Q', " quit" },
|
|
{ 0, 0 }
|
|
};
|