diff xrogue/rogue.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 1fbdefa82533
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/xrogue/rogue.c	Tue Apr 21 08:55:20 2015 -0400
@@ -0,0 +1,658 @@
+/*
+    rogue.c  -  Global game variables
+    
+    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 <ctype.h>
+#include <curses.h>
+#include "rogue.h"
+
+/*
+ * Now all the global variables
+ */
+
+struct trap traps[MAXTRAPS];
+struct room rooms[MAXROOMS];            /* One for each room -- A level */
+struct room *oldrp;                     /* Roomin(&player.t_oldpos) */
+struct thing player;                    /* The rogue */
+struct object *cur_armor;               /* What a well dresssed rogue wears */
+struct object *cur_ring[NUM_FINGERS];   /* Which rings are being worn */
+struct object  *cur_misc[NUM_MM];       /* which MM's are in use */
+int cur_relic[MAXRELIC];                /* Currently used relics */
+struct linked_list *lvl_obj = NULL; 
+struct linked_list *mlist = NULL;
+struct linked_list *rlist = NULL;       /* list of dead monsters to be reaped */
+struct linked_list *tlist = NULL;       /* list of monsters fallen down traps */
+struct linked_list *monst_dead = NULL;  /* monster killed by monster    */
+struct object *cur_weapon = NULL;
+int char_type = -1;                     /* what type of character is player */
+int foodlev = 1;                        /* how fast he eats food */
+int ntraps;                             /* Number of traps on this level */
+int trader = 0;                         /* no. of purchases */
+int curprice = -1;                      /* current price of item */
+int seed;                               /* Random number seed */
+int max_level;                          /* Deepest player has gone ever */
+int cur_max;                            /* Deepest player has gone currently */
+int prev_max;                           /* A flag indicating worm hole */
+int move_free = 0;                      /* Movement check (io.c & actions.c) */
+int mpos = 0;
+int level = 0;
+long purse = 0;
+int inpack = 0;
+int total = 0;
+int no_food = 0;                        /* how long has he gone with no food */
+int foods_this_level = 0;               /* foods made per level */
+int count = 0;
+int food_left = STOMACHSIZE-MORETIME-1;
+int group = 1;
+int hungry_state = F_OKAY;
+int infest_dam=0;
+int lost_str=0;
+int lastscore = -1;
+int hold_count = 0;
+int trap_tries = 0;
+int chant_time = 0;
+int pray_time = 0;
+int spell_power = 0;
+long turns = 0;                         /* Number of turns player has taken */
+int quest_item = 0;                     /* Item player is looking for */
+int cols = 0;                           /* number of columns in terminal */
+int lines = 0;                          /* number of lines on the terminal */
+int nfloors = -1;                       /* Number of floors in this dungeon */
+char curpurch[LINELEN];                 /* name of item ready to buy */
+char PLAYER = VPLAYER;                  /* what the player looks like */
+char take;                              /* Thing the rogue is taking */
+char prbuf[LINELEN*2];                  /* Buffer for sprintfs */
+char runch;                             /* Direction player is running */
+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 *ws_made[MAXSTICKS];               /* What sticks are made of */
+char whoami[LINELEN];                   /* Name of player */
+char huh[LINELEN];                       /* The last message printed */
+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 *m_guess[MAXMM];                   /* Players guess at what MM is */
+char *ws_type[MAXSTICKS];               /* Is it a wand or a staff */
+char file_name[LINELEN];                /* Save file name */
+char score_file[LINELEN];               /* Score file name */
+char home[LINELEN];                     /* User's home directory */
+WINDOW *cw;                             /* Window that the player sees */
+WINDOW *hw;                             /* Used for the help command */
+WINDOW *mw;                             /* Used to store monsters */
+WINDOW *msgw;                           /* Used to display messages */
+bool pool_teleport = FALSE;             /* just teleported from a pool */
+bool inwhgt = FALSE;                    /* true if from wghtchk() */
+bool after;                             /* True if we want after daemons */
+bool waswizard;                         /* Was a wizard sometime */
+bool s_know[MAXSCROLLS];                /* Does he know what a scroll does */
+bool p_know[MAXPOTIONS];                /* Does he know what a potion does */
+bool r_know[MAXRINGS];                  /* Does he know what a ring does */
+bool ws_know[MAXSTICKS];                /* Does he know what a stick does */
+bool m_know[MAXMM];                     /* Does he know what a MM does */
+
+/* options */
+bool playing = TRUE;        /* Defaults */
+bool running = FALSE; 
+bool wizard = FALSE;
+bool notify = TRUE; 
+bool fight_flush = FALSE;
+bool terse = FALSE; 
+bool auto_pickup = FALSE;
+bool def_attr = FALSE;      /* default attributes */
+bool menu_overlay = TRUE;
+bool door_stop = TRUE;
+bool jump = TRUE; 
+bool slow_invent = FALSE; 
+bool firstmove = FALSE; 
+bool askme = TRUE;
+bool in_shell = FALSE; 
+bool daytime = TRUE;
+bool funfont = FALSE;
+
+LEVTYPE levtype;           /* what type of level am i'm on? */
+
+char *nothing  =  "Nothing seems to happen. ";
+char *spacemsg =  "--Press space to continue--";
+char *morestr  =  " --More--";
+char *retstr   =  "[Press return to continue]";
+
+/* 
+ * This lays out all the class specific details
+ *
+ * Here are the beginning experience levels for all players.
+ * All further experience levels are computed by muliplying by 2
+ * up through MAXDOUBLE. Then exp pts are calculated by adding
+ * in the cap figure. You must change MAXDOUBLE if you change the 
+ * cap figure. 
+ */
+
+struct character_types char_class[NUM_CHARTYPES] = {
+/* name         exppts  cap     hitpts  Base   Maxlvl, Factor, Offset, Range */
+{ "fighter",    90,    1310720,  13,    10,     30,     2,      1,      3 },
+{ "ranger",     110,   2293760,  10,    10,     22,     2,      1,      2 },
+{ "paladin",    110,   1966080,  10,    10,     23,     2,      1,      2 },
+{ "magician",   105,   2129920,   9,    10,     24,     2,      1,      2 },
+{ "cleric",     105,   1802240,   9,    10,     24,     2,      1,      2 },
+{ "thief",      95,    1228800,  11,    10,     28,     2,      1,      3 },
+{ "assassin",   95,    1392640,  11,    10,     26,     2,      1,      3 },
+{ "druid",      105,   1638400,   9,    10,     24,     2,      1,      2 },
+{ "monk",       100,   1556480,  10,    10,     25,     2,      1,      2 },
+{ "monster",    0,     0,         8,    10,     20,     1,      0,      2 },
+};
+
+/*
+ * This array lists the names of the character's abilities.  It must be ordered
+ * according to the ability definitions in rogue.h.
+ */
+
+struct words abilities[NUMABILITIES] = {
+  "Intelligence", "Strength", "Wisdom", "Dexterity", "Constitution", "Charisma"
+};
+
+/*
+ * NOTE: the ordering of the points in this array is critical. They MUST
+ *       be listed in the following sequence:
+ *
+ *              7   4   6
+ *              1   0   2
+ *              5   3   8
+ */
+
+coord grid[9] = {{0,0},
+                 { 0,-1}, { 0, 1}, {-1, 0}, { 1, 0},
+                 {-1,-1}, { 1, 1}, { 1,-1}, {-1, 1}
+                };
+
+struct death_type deaths[DEATHNUM] = {
+    { D_ARROW,          "an arrow"},
+    { D_DART,           "a dart"},
+    { D_BOLT,           "a bolt"},
+    { D_POISON,         "poison"},
+    { D_POTION,         "a cursed potion"},
+    { D_PETRIFY,        "petrification"},
+    { D_SUFFOCATION,    "suffocation"},
+    { D_INFESTATION,    "a parasite"},
+    { D_DROWN,          "drowning"},
+    { D_ROT,            "body rot"},
+    { D_CONSTITUTION,   "poor health"},
+    { D_STRENGTH,       "being too weak"},
+    { D_SIGNAL,         "a bug"},
+    { D_CHOKE,          "dust of choking"},
+    { D_STRANGLE,       "strangulation"},
+    { D_FALL,           "a fall"},
+    { D_RELIC,          "an artifact's wrath"},
+    { D_STARVATION,     "starvation"},
+    { D_FOOD_CHOKE,     "choking on food"},
+    { D_SCROLL,         "reading a scroll"},
+    { D_FRIGHT,         "being too frightened"},
+    { D_CRYSTAL,        "being absorbed"},
+    { D_CARD,           "the face of death"},
+};
+
+/*
+ * weapons and their attributes
+ */
+
+struct init_weps weaps[MAXWEAPONS] = {
+    { "mace",           "2d10","2d10", NONE,     ISMETAL, 6, 150, 15 },
+    { "long sword",     "3d4",  "2d8", NONE,     ISMETAL, 5, 200, 25 },
+    { "short bow",      "1d1",  "1d1", NONE,     0, 8, 50, 4 },
+    { "arrow",          "2d4",  "1d6", BOW,      ISMANY|ISMISL, 1, 5, 4 },
+    { "dagger",         "2d8",  "1d6", NONE,     ISMETAL|ISMISL|ISMANY, 2,10,7},
+    { "rock",           "2d4",  "1d6", SLING,    ISMANY|ISMISL, 1, 20, 3 },
+    { "two-handed sword","3d10","3d8", NONE,     ISMETAL, 4, 250, 40 },
+    { "sling",          "1d1",  "1d1", NONE,     0, 8, 25, 3 },
+    { "dart",           "2d4",  "2d6", NONE,     ISMANY|ISMISL, 2, 15, 7 },
+    { "crossbow",       "1d1",  "1d1", NONE,     0, 8, 75, 5 },
+    { "crossbow bolt",  "2d4",  "2d4", CROSSBOW, ISMANY|ISMISL, 1, 10, 5 },
+    { "spear",          "2d6", "3d10", NONE,     ISMISL,  7, 100, 15 },
+    { "trident",        "3d6",  "3d4", NONE,     ISMETAL, 4, 200, 30 },
+    { "spetum",         "2d6",  "2d8", NONE,     ISMETAL, 6, 150, 20 },
+    { "bardiche",       "3d4", "2d10", NONE,     ISMETAL, 5, 150, 25 },
+    { "pike",           "2d8",  "2d8", NONE,     ISMETAL, 7, 100, 15 },
+    { "bastard sword",  "3d8",  "3d6", NONE,     ISMETAL, 4, 175, 30 },
+    { "halberd",        "2d8",  "2d4", NONE,     ISMETAL, 6, 100, 10 },
+    { "battle axe",     "2d8",  "3d8", NONE,     ISMETAL, 5, 150, 15 },
+} ;
+ 
+struct init_armor armors[MAXARMORS] = {
+        { "leather armor",          10, 8, 200, 100 },
+        { "ring mail",              20, 7, 250, 200 },
+        { "studded leather armor",  30, 5, 320, 250 },
+        { "scale mail",             40, 7, 280, 250 },
+        { "padded armor",           50, 6, 350, 300 },
+        { "chain mail",             60, 6, 350, 600 },
+        { "splint mail",            70, 5, 370, 400 },
+        { "banded mail",            80, 5, 370, 350 },
+        { "plate mail",             90, 4, 400, 400 },
+        { "plate armor",           100, 3, 500, 450 },
+};
+
+struct magic_item things[NUMTHINGS] = {
+    { "potion",                 220,   10 },    /* potion               */
+    { "scroll",                 220,   30 },    /* scroll               */
+    { "food",                   190,   20 },    /* food                 */
+    { "weapon",                  90,    0 },    /* weapon               */
+    { "armor",                   90,    0 },    /* armor                */
+    { "ring",                    70,    5 },    /* ring                 */
+    { "stick",                   70,    0 },    /* stick                */
+    { "miscellaneous magic",     50,   50 },    /* miscellaneous magic  */
+    { "artifact",                 0,   10 },    /* artifact             */
+};
+
+struct magic_item s_magic[MAXSCROLLS] = {
+    { "monster confusion",       40, 125,  0,  0 },
+    { "magic mapping",           60, 150,  0,  5 },
+    { "light",                   60, 100, 15, 15 },
+    { "hold monster",            30, 200, 20, 20 },
+    { "sleep",                   20, 150, 25,  0 },
+    { "enchantment",            130, 200, 15, 15 },
+    { "identify",               170, 100,  0, 20 },
+    { "scare monster",           40, 250, 20, 30 },
+    { "gold detection",          30, 110,  0,  0 },
+    { "teleportation",           60, 165, 20, 20 },
+    { "create monster",          20,  75,  0,  0 },
+    { "remove curse",            80, 120, 15, 15 },
+    { "petrification",           30, 185,  0,  0 },
+    { "genocide",                10, 300,  0,  0 },
+    { "cure disease",            80, 160,  0,  0 },
+    { "acquirement",             10, 700,  0,  5 },
+    { "protection",              30, 190, 10,  0 },
+    { "trap finding",            50, 180,  0,  0 },
+    { "runes",                   20,  50,  0,  0 },
+    { "charm monster",           30, 275,  0, 20 },
+};
+
+struct magic_item p_magic[MAXPOTIONS] = {
+    { "clear thought",           50, 180, 10,  5 },
+    { "gain ability",           160, 210, 10, 10 },
+    { "see invisible",           40, 150, 20, 20 },
+    { "healing",                140, 130, 15, 15 },
+    { "monster detection",       40, 120,  0,  0 },
+    { "magic detection",         70, 105,  0,  0 },
+    { "raise level",             10, 450, 10,  5 },
+    { "haste self",              50, 180, 20,  5 },
+    { "restore abilities",      130, 140,  0, 15 },
+    { "phasing",                 60, 210, 10, 10 },
+    { "invisibility",            20, 230,  0, 10 },
+    { "flying",                  50, 130,  0, 15 },
+    { "food detection",          20, 150,  0,  0 },
+    { "skill",                   10, 200, 20,  5 },
+    { "fire resistance",         40, 250, 10,  5 },
+    { "cold resistance",         40, 250, 10,  5 },
+    { "lightning protection",    40, 250, 20,  5 },
+    { "poison",                  30, 205, 25,  0 },
+};
+
+struct magic_item r_magic[MAXRINGS] = {
+    { "protection",              60, 200,  25, 25 },
+    { "add strength",            50, 200,  25, 25 },
+    { "sustain ability",         50, 500,   0,  0 },
+    { "searching",               40, 400,   0,  0 },
+    { "extra sight",             60, 350,   0,  0 },
+    { "alertness",               40, 380,   0,  0 },
+    { "aggravate monster",       30, 100, 100,  0 },
+    { "dexterity",               50, 220,  25, 25 },
+    { "increase damage",         60, 220,  25, 25 },
+    { "regeneration",            40, 600,   0,  0 },
+    { "slow digestion",          50, 240,  20, 20 },
+    { "teleportation",           20, 100,  90,  0 },
+    { "stealth",                 20, 300,   0,  0 },
+    { "add intelligence",        50, 240,  25, 25 },
+    { "increase wisdom",         40, 220,  25, 25 },
+    { "sustain health",          80, 500,   0,  0 },
+    { "carrying",                10, 100,  90,  0 },
+    { "illumination",            30, 520,   0,  0 },
+    { "delusion",                10, 100, 100,  0 },
+    { "fear",                    20, 100,  75,  0 },
+    { "heroism",                 50, 390,   0,  0 },
+    { "fire resistance",         40, 400,   0,  0 },
+    { "warmth",                  40, 400,   0,  0 },
+    { "vampiric regeneration",   10,1000,   0,  0 },
+    { "free action",             40, 370,   0,  0 },
+    { "teleport control",        10, 700,   0,  0 },
+};
+
+struct magic_item ws_magic[MAXSTICKS] = {
+    { "light",                   80, 120, 15, 15 },
+    { "striking",                50, 115,  0,  0 },
+    { "lightning",               40, 200,  0,  0 },
+    { "fire",                    30, 200,  0,  0 },
+    { "cold",                    30, 200,  0,  0 },
+    { "polymorph",               80, 150,  0,  0 },
+    { "magic missile",           90, 170,  0,  0 },
+    { "slow",                    70, 220, 20, 10 },
+    { "drain life",              50, 210, 20,  0 },
+    { "charging",                70, 400,  0,  0 },
+    { "teleport",                90, 140, 20, 10 },
+    { "cancellation",            50, 130,  0,  0 },
+    { "confusion",               30, 100, 20,  0 },
+    { "disintegration",          20, 300, 25,  0 },
+    { "petrification",           30, 240,  0,  0 },
+    { "paralyzation",            30, 180, 10,  0 },
+    { "degeneration",            30, 250, 20,  0 },
+    { "curing",                  50, 250, 20,  5 },
+    { "wonder",                  40, 110, 20, 20 },
+    { "fear",                    40, 180,  0,  0 },
+};
+
+/*
+ * WARNING: unique miscellaneous magic items must be put at the end
+ *          of this list. They MUST be the last items. The function
+ *          create_obj() in wizard.c depends on it.
+ */
+
+struct magic_item m_magic[MAXMM] = {
+    { "alchemy jug",               40,  240,   0,  0 },
+    { "beaker of potions",         60,  300,   0,  0 },
+    { "book of spells",            60,  300,   0,  0 },
+    { "boots of elvenkind",        50,  500,   0,  0 },
+    { "bracers of defense",        80,  400,  20, 10 },
+    { "chime of opening",          30,  250,   0,  0 },
+    { "chime of hunger",           20,  100, 100,  0 },
+    { "cloak of displacement",     60,  500,   0,  0 },
+    { "cloak of protection",       80,  400,  20, 10 },
+    { "drums of panic",            60,  350,   0,  0 },
+    { "dust of disappearance",     30,  300,   0,  0 },
+    { "dust of choking",           30,  100, 100,  0 },
+    { "gauntlets of dexterity",    40,  600,  25,  0 },
+    { "gauntlets of ogre power",   40,  600,  25,  0 },
+    { "jewel of attacks",          50,  150, 100,  0 },
+    { "keoghtoms ointment",        60,  350,   0,  0 },
+    { "robe of powerlessness",     20,  100, 100,  0 },
+    { "gauntlets of fumbling",     30,  100, 100,  0 },
+    { "necklace of adaptation",    50,  500,   0,  0 },
+    { "necklace of strangulation", 30,  110, 100,  0 },
+    { "boots of dancing",          40,  120, 100,  0 },
+    { "book of skills",            30,  650,   0,  0 },
+    { "medicine crystal",          10,  800,  25,  5 },
+};
+
+struct magic_item rel_magic[MAXRELIC] = {
+    { "Daggers of Musty Doit",     0, 50000,  0, 0},
+    { "Cloak of Emori",            0, 50000,  0, 0},
+    { "Ankh of Heil",              0, 50000,  0, 0},
+    { "Staff of Ming",             0, 50000,  0, 0},
+    { "Wand of Orcus",             0, 50000,  0, 0},
+    { "Rod of Asmodeus",           0, 50000,  0, 0},
+    { "Amulet of Yendor",          0, 50000,  0, 0},
+    { "Mandolin of Brian",         0, 50000,  0, 0},
+    { "Horn of Geryon",            0, 50000,  0, 0},
+    { "Morning Star of Hruggek",   0, 50000,  0, 0},
+    { "Flail of Yeenoghu",         0, 50000,  0, 0},
+    { "Eye of Vecna",              0, 50000,  0, 0},
+    { "Axe of Aklad",              0, 50000,  0, 0},
+    { "Quill of Nagrom",           0, 50000,  0, 0},
+    { "Amulet of Stonebones",      0, 50000,  0, 0},
+    { "Ring of Surtur",            0, 50000,  0, 0},
+    { "Card of Alteran",           0, 50000,  0, 0},
+};
+
+/*
+ * food and fruits that you get
+ */
+struct magic_item foods[MAXFOODS] = {
+
+    { "food ration",    690, 50, 750,  0},
+    { "apple",           10, 20, 300,  0},
+    { "banana",          30, 20, 300,  0},
+    { "blueberry",       30, 20, 300,  0},
+    { "candleberry",     10, 20, 300,  0},
+    { "caprifig",        20, 20, 300,  0},
+    { "dewberry",        10, 20, 300,  0},
+    { "elderberry",      30, 20, 300,  0},
+    { "gooseberry",      20, 20, 300,  0},
+    { "guanabana",       30, 20, 300,  0},
+    { "hagberry",        10, 20, 300,  0},
+    { "jaboticaba",      10, 20, 300,  0},
+    { "peach",           10, 20, 300,  0},
+    { "pitanga",         10, 20, 300,  0},
+    { "prickly pear",    10, 20, 300,  0},
+    { "rambutan",        10, 20, 300,  0},
+    { "sapodilla",       10, 20, 300,  0},
+    { "soursop",         10, 20, 300,  0},
+    { "strawberry",      10, 20, 300,  0},
+    { "sweetsop",        10, 20, 300,  0},
+    { "whortleberry",    10, 20, 300,  0},
+    { "slime-mold",      10, 10, 100,  0},
+};
+
+/*
+ * these are the spells that a magician can cast
+ */
+
+struct spells magic_spells[MAXSPELLS] = {
+        { P_TFIND,         3,     TYP_POTION,   0         },
+        { S_IDENT,         5,     TYP_SCROLL,   0         },
+        { S_LIGHT,         7,     TYP_SCROLL,   ISBLESSED },
+        { S_REMOVE,       10,     TYP_SCROLL,   0         },
+        { S_FINDTRAPS,    15,     TYP_SCROLL,   0         },
+        { P_FLY,          20,     TYP_POTION,   0         },
+        { S_TELEP,        25,     TYP_SCROLL,   0         },
+        { S_SLEEP,        30,     TYP_SCROLL,   0         },
+        { P_SEEINVIS,     35,     TYP_POTION,   ISBLESSED },
+        { P_CLEAR,        40,     TYP_POTION,   0         },
+        { WS_COLD,        45,     TYP_STICK,    0         },
+        { P_PHASE,        50,     TYP_POTION,   0         },
+        { WS_FIRE,        55,     TYP_STICK,    0         },
+        { P_HASTE,        60,     TYP_POTION,   ISBLESSED },
+        { WS_ELECT,       65,     TYP_STICK,    0         },
+        { S_HOLD,         70,     TYP_SCROLL,   ISBLESSED },
+};
+
+/*
+ * these are the spells that a cleric can cast
+ */
+
+struct spells cleric_spells[MAXPRAYERS] = {
+        { P_MFIND,         3,     TYP_POTION,   0         },
+        { P_TFIND,         5,     TYP_POTION,   0         },
+        { S_LIGHT,         7,     TYP_SCROLL,   ISBLESSED },
+        { S_REMOVE,       10,     TYP_SCROLL,   0         },
+        { P_FFIND,        15,     TYP_POTION,   0         },
+        { P_FLY,          20,     TYP_POTION,   0         },
+        { P_HEALING,      25,     TYP_POTION,   0         },
+        { S_CURING,       30,     TYP_SCROLL,   0         },
+        { P_RESTORE,      35,     TYP_POTION,   0         },
+        { S_MAP,          40,     TYP_SCROLL,   0         },
+        { P_SEEINVIS,     45,     TYP_POTION,   ISBLESSED },
+        { P_CLEAR,        50,     TYP_POTION,   0         },
+        { P_PHASE,        55,     TYP_POTION,   0         },
+        { WS_CURING,      60,     TYP_STICK,    ISBLESSED },
+        { WS_PARALYZE,    65,     TYP_STICK,    0         },
+        { S_ALLENCH,      70,     TYP_SCROLL,   0         },
+};
+
+/*
+ * these are the spells that a druid can chant
+ */
+
+struct spells druid_spells[MAXCHANTS] = {
+        { P_MFIND,         3,     TYP_POTION,   0         },
+        { P_TFIND,         5,     TYP_POTION,   0         },
+        { S_LIGHT,         7,     TYP_SCROLL,   ISBLESSED },
+        { S_REMOVE,       10,     TYP_SCROLL,   0         },
+        { S_FINDTRAPS,    15,     TYP_SCROLL,   0         },
+        { S_CONFUSE,      20,     TYP_SCROLL,   0         },
+        { P_FFIND,        25,     TYP_POTION,   0         },
+        { P_HEALING,      30,     TYP_POTION,   0         },
+        { S_MAP,          35,     TYP_SCROLL,   0         },
+        { P_CLEAR,        40,     TYP_POTION,   0         },
+        { P_COLD,         45,     TYP_POTION,   0         },
+        { P_FIRE,         50,     TYP_POTION,   0         },
+        { P_PHASE,        55,     TYP_POTION,   0         },
+        { P_LIGHTNING,    60,     TYP_POTION,   0         },
+        { S_CHARM,        65,     TYP_SCROLL,   ISBLESSED },
+        { S_HOLD,         70,     TYP_SCROLL,   ISBLESSED },
+};
+
+/*
+ * these are the scrolls that a quill can write
+ */
+
+struct spells quill_scrolls[MAXQUILL] = {
+        { S_GFIND,       5,   },
+        { S_IDENT,       10,  },
+        { S_LIGHT,       10,  },
+        { S_REMOVE,      15,  },
+        { S_MAP,         20,  },
+        { S_CONFUSE,     25,  },
+        { S_SLEEP,       30,  },
+        { S_CURING,      40,  },
+        { S_TELEP,       50,  },
+        { S_SCARE,       60,  },
+        { S_HOLD,        70,  },
+        { S_PETRIFY,     80,  },
+        { S_PROTECT,     90,  },
+        { S_ALLENCH,     100, },
+};
+
+/*
+ * Experience-level names of each character  (see NUM_CNAMES in rogue.h)
+ */
+
+const char *cnames[NUM_CHARTYPES-1][NUM_CNAMES] = {
+{       "Veteran",                      "Fighter",              /* Fighter */
+        "Ruffian",                      "Tussler",
+        "Swordsman",                    "Hero",