/* File: borg.h */

/* Purpose: an "automatic" player -BEN- */
/* Added some goodies needed for my spellcasting routines -FRITS-;
   This file is otherwise the first part of angband 2.7.5's borg.c */

#include "angband.h"

#ifdef AUTO_PLAY

#ifndef EXTERN
#define EXTERN extern
#endif

/* #define FRITS */
/* #define FRITSDEBUG */
#ifdef FRITSDEBUG
EXTERN FILE *logfile;
EXTERN int logging = 0;
#endif /* FRITSDEBUG */

/*
 * This function provides support for an "automatic" Angband player.  For
 * historical reasons, this player is known as a "Borg", though it is not
 * intended for interactive use except when denugging.
 *
 * The initialization routine grabs the "Term_xtra()" hook of the main "Term",
 * allowing the Borg to notice when the game is asking for keypresses, and to
 * send its own keys to the keypress queue, while still allowing (occasional)
 * keys to be accepted from the user.  The keys from the user should probably
 * be single keycodes, to prevent interlace with the Borg keypresses.
 *
 * Once the Borg has been initialized, the user can choose to start
 * the Borg or ask it questions via the "Borg interrupt key" (control-Z).
 * This key will stop the Borg (if necessary) and invoke the "borg_mode()"
 * function, which allows the user to restart ("z") or resume ("r") or
 * continue with new goals ("w") or query the main map ("c"/"g"/"s").
 * You can use the interupt key plus escape to just stop the Borg.
 *
 * Note that the Borg interrupt key may easily be remapped via the
 * keymapper or command-macro systems, in fact, you are best off defining
 * a single key macro which expands to "\e\e\e\e\e^Z", or you may find
 * yourself unable to actually interupt the Borg.
 *
 * The Borg is only supposed to "know" what is visible on the screen, which
 * it learns by using the "term.c" screen access function "Term_what()", and
 * the cursor location function "Term_locate()", and a hack to access the
 * cursor visibility using "Term_show/hide_cursor()".  It is only allowed to
 * send keypresses to the "Term" like a normal user, by using the standard
 * "Term_keypress()" routine.  It only thinks and sends keys when it catches
 * a request to "Term_xtra(TERM_XTRA_EVENT)", which the "term.c" file uses
 * to wait for a keypress (or other event) from the user.
 *
 * Thus, the Borg COULD be written as a separate process which runs Angband
 * in a pseudo-terminal and "examines" the "screen" and sends keypresses
 * directly (as with a terminal emulator), although it would then have
 * to explicitly "wait" to make sure that the game was completely done
 * sending information (though it might be able to use the same "cursor
 * visibility hack" that it currently uses to detect "command mode").
 *
 * That is, if if were not for the "cheats" currently used (see below).
 */


/*
 * Must be careful of:
 *   Level changing (intentionally or accidentally)
 *   Gold (or objects) embedded in walls (need to tunnel)
 *   Objects with 's' or ',' symbols (look like monsters)
 *   Mimic monsters (look like objects) or invisible monsters
 *   Traps (disarm), Doors (open/bash), Rubble (tunnel)
 *   Stores (enter via movement, exit via escape)
 *   Stores (limited commands, such as no "throw" command)
 *   Must discard junk before trying to pick up more junk
 *   Must be very careful not to run out of food/light
 *   Should use "identify" cleverly to obtain knowledge/money
 *   Do not attempt to throw away cursed artifacts (oops)
 *   Do not sell junk or cursed/damaged items to any stores
 *   Do not attempt to buy something with insufficient funds
 *   Use the non-optimal stairs if stuck on a level
 *
 * Should be careful of:
 *   Do not throw away cursed artifacts (non-warrior types)
 *   If wounded, must run away from monsters, then rest
 *   Invisible monsters causing damage while trying to rest
 *   Darkness is "ignored" after the first encounter
 *   Objects are remembered, but not actually sought after
 *   Try to use a shovel/pick to help with tunnelling
 *   Becoming "blind" (map may be no longer valid)
 *   Becoming "afraid" (attacking takes a turn for no effect)
 *   Becoming "confused" or "cut" or "stunned" (try healing)
 *   Earthquake (or destruction) of already mapped grids
 *   Search for secret doors if stuck on a level
 *   Out of depth player ghosts (in the town)
 *   Be VERY careful not to access illegal locations!
 *
 * Memory usage:
 *   Total: 300K total
 *   Largest chunk: 42K
 *   Static: minimal compared to code itself
 *   Rooms: (200*70/8)*24 = 42K
 *   Each row of Grids: 200*16 = 3K
 *   All rows of Grids: 70*3K = 210K
 *   Inventory: 36*132 = 5K
 *   Current Shop: 24*132 = 3K
 *
 *
 * Currently, the auto-player "cheats" in a few situations.  Oops.
 *
 * The "big" cheat is that we "build" an inventory listing without
 * parsing the screen.  This is mainly for efficiency, and to prevent
 * constant screen flashing, since we do know how to parse the store.
 * It might be interesting to try and use the "choice" window (!) if
 * available.
 *
 * Cheats "required" by implementation:
 *   Direct use of "current screen image" / "keypress queue"
 *   Knowledge of when we are being asked for a keypress.
 *   The "space" character can only be used for "darkness".
 *
 * Cheats that could be "overcome" with complex routines:
 *   Use of "py"/"px" (could acquire via "L" command)
 *   Direct modification of the "current options" (could require them)
 *
 * Cheats that could be avoided by annoying (or slow) code:
 *   Use of the "player_has_los_bold()" macro
 *   Direct construction of "inven/equip" lists
 *
 * Cheats that could be avoided by duplicating code:
 *   Direct access to the "r_list" and "k_list" arrays
 *   Direct access to the "v_list" and "ego_name" arrays
 *
 * Cheats that would simplify the Borg:
 *   Unique attr/char codes for every monster and object
 *   Ring of See invisible, Ring of Free Action, Helm of Seeing
 */
 
 
/*
 * Problem rooms (see "build_room()" algorithm):
 *
 *   #########
 *   ##.....##		Currently this room is parsed as two
 *   #.......#		large overlapping rectangles.  We should
 *   #.......#		probably consider finding the intersection
 *   #.......#		of those rooms, and subtracting out the rest
 *   ##.....##		resulting in four small and one large room.
 *   #########
 *
 * Note that the "room builder" will automatically find the largest
 * rectangle, and will automatically "absorb" enclosed rooms.  Now
 * all we need to do is "notice" when we are "crossing" another room.
 * As long as we do not cross TWO rooms, we should be fine (?).  But
 * observe the following room:
 *
 *   #########
 *   ###...###		Assume that (somehow) the two "horizontal" rooms
 *   ###...###		are constructed first, and then the "vertical"
 *   #.......#		room is discovered.  Now the room crosses TWO
 *   #.......#		other rooms, and we would like to "extract"
 *   ###...###		from this union all NINE resulting rectangles...
 *   ###...###
 *   #.......#		Note that crossing corridors do NOT have this
 *   #.......#		problem, except when "new holes" are made in
 *   ###...###		the middle of existing corridors.  That is
 *   ###...###		something we might consider noticing.
 *   #########
 *
 * Another question to ask is whether we would rather have:
 *   (1) rooms that cross each other
 *   (2) no crossing rooms, but some "touching" rooms
 *   (3) no crossing rooms and no touching rooms
 *
 * Note that #2 seems to allow for the "nicest" treatment of corridors.
 *
 * Note that a room is NEVER built including "unknown" grids.
 *
 * Also note that corridors are handled by a special routine, and rooms
 * are only constructed out of at least a 2x2 block of grids.
 */





#define GOAL_GOTO	11
#define GOAL_TAKE	21
#define GOAL_KILL	31
#define GOAL_FLOW	91

#define STATE_START	1	/* Analyze "dungeon" screen */
#define STATE_INVEN	2	/* Analyze "inventory" screen */
#define STATE_EQUIP	3	/* Analyze "equipment" screen */
#ifdef FRITS
#define STATE_BOOKCHECK	4	/* Analyze "browse spellbook" screen */
#endif /* FRITS */
#define STATE_STORE	10	/* Analyze "store" screens */
#define STATE_THINK	20	/* Actually choose an action */


/*
 * Screen location info from "misc.c"
 */
 
#define ROW_RACE	1
#define ROW_CLASS	2
#define ROW_TITLE	3

#define ROW_LEVEL	4
#define COL_LEVEL	6

#define ROW_EXP		5
#define COL_EXP		4

#define ROW_STAT	7
#define COL_STAT	6

#define ROW_AC		14
#define COL_AC		6

#define ROW_CURHP	15
#define COL_CURHP	6

#define ROW_MAXHP	16
#define COL_MAXHP	6

#define ROW_MANA	17
#define COL_MANA	6

#define ROW_GOLD	18
#define COL_GOLD	3

#define ROW_WINNER	19
#define ROW_EQUIPPY	20

#define ROW_CUT		21
#define ROW_STUN	22

#define ROW_HUNGRY	23

#define COL_HUNGRY	0	/* "Hungry" or "Weak" */
#define COL_BLIND	7	/* "Blind" */
#define COL_CONFUSED	12	/* "Confused" */
#define COL_AFRAID	22	/* "Afraid" */
#define COL_POISONED	29	/* "Poisoned" */
#define COL_STATE	38	/* "Paralyzed!" or "Searching " or <state> */
#define COL_SPEED	49	/* "Slow (-N)" or "Fast (+N)" */
#define COL_STUDY	64	/* "Study" */
#define COL_DEPTH	70	/* "Lev N" or "N ft" (right justified) */



/*
 * Hack -- Some special objects
 */

#define OBJ_SCROLL_IDENTIFY	176
#define OBJ_POTION_CRITICAL	241
#ifdef FRITS
#define OBJ_PBOOK_1		334
#define OBJ_PBOOK_2		(334+1)
#define OBJ_PBOOK_3		(334+2)
#define OBJ_PBOOK_4		(334+3)
#define OBJ_PBOOK_5		384
#define OBJ_PBOOK_6		(384+1)
#define OBJ_PBOOK_7		(384+2)
#define OBJ_PBOOK_8		(384+3)
#define OBJ_PBOOK_9		(384+4)

#define OBJ_SBOOK_1		330
#define OBJ_SBOOK_2		(330+1)
#define OBJ_SBOOK_3		(330+2)
#define OBJ_SBOOK_4		(330+3)
#define OBJ_SBOOK_5		379
#define OBJ_SBOOK_6		(379+1)
#define OBJ_SBOOK_7		(379+2)
#define OBJ_SBOOK_8		(379+3)
#define OBJ_SBOOK_9		(379+4)

#define OBJ_POTION_STR		225
#define OBJ_POTION_INT		228
#define OBJ_POTION_WIS		231
#define OBJ_POTION_DEX		251
#define OBJ_POTION_CON		243
#define OBJ_POTION_CHR		234
#define OBJ_POTION_EXP		244
#define OBJ_POTION_AUGMENT	418
#define OBJ_POTION__ENLIGHT	422
#define OBJ_SCROLL_ENCHANT_HIT	173
#define OBJ_SCROLL_ENCHANT_DAM	174
#define OBJ_SCROLL_ENCHANT_AC	175
#define OBJ_SCROLL_ENCHANT__WE	212
#define OBJ_SCROLL_ENCHANT__AC	214
#define OBJ_POTION_REST_STR	227
#define OBJ_POTION_REST_INT	230
#define OBJ_POTION_REST_WIS	233
#define OBJ_POTION_REST_DEX	252
#define OBJ_POTION_REST_CON	253
#define OBJ_POTION_REST_CHR	236
#define OBJ_POTION_REST_LIFE	260

#define OBJ_RING_STR		132
#define OBJ_RING_DEX		133
#define OBJ_RING_CON		134
#define OBJ_RING_INT		135
#define OBJ_RING_SPEED		136
#define OBJ_RING_SEARCH		137
#define OBJ_RING_DAM		151
#define OBJ_RING_HIT		152
#define OBJ_RING_PROT		153
#define OBJ_RING_SEE_INVIS	155
#define OBJ_RING_SLAYING	162

EXTERN int protevil;
EXTERN int drained_stat;
EXTERN int auto_stat[6];

EXTERN int books[9];
EXTERN int current_book;
EXTERN int known_spells;
EXTERN bool spells_known[9][9];

#ifdef MAIN_ROUTINE
EXTERN char statstring[6][4] = {"STR\0","INT\0","WIS\0","DEX\0","CON\0","CHR\0"};
#else
EXTERN char statstring[6][4];
#endif /* MAIN_ROUTINE */

/* player class */
#define PCLASS_WARRIOR	0
#define PCLASS_MAGE	1
#define PCLASS_PRIEST	2
#define PCLASS_ROGUE	3
#define PCLASS_RANGER	4
#define PCLASS_PALADIN	5

EXTERN int pclass;

/* spellbooks class */
#define SCLASS_NONE	0
#define SCLASS_MAGE	1
#define SCLASS_PRIEST	2

EXTERN int sclass;


/* this static data is from tables.c, spell_type.
   ordering there is struct {slevel,smana,sfail,sxtra,sexp} [class][book']['spell]
*/
#ifdef MAIN_ROUTINE
/* manacost[class][book][spell] */
int manacost[6][9][9]=
{
  /* warrior; none */
  {
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  },
  /** mage **/
  {
    /* Magik for Beginners */
    {   1,   1,   2,   2, 999,   3, 999,   3,   3 },
    /* Conjurings and Tricks */
    {   4,   4,   5,   5,   5,   6,   6,   6,   7 },
    /* Incantations and Illusions */
    {   7,   7,   7,   7,   7,   7,   7,   9,   9 },
    /* Exorcism and Dispelling */
    {  12,  12,  12,  12,  18,  21,  25, 999, 999 },
    /* Resistance of Scarabtarices */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Mordenkainen's Escapes */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /*  */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /*  */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Raal's Tome of Destruction */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  },
  /** priest **/
  { 
    /* Beginners Handbook */
    {   1,   2,   2,   2,   2,   3,   3,   3, 999 },
    /* Words of Wisdom */
    {   4,   4,   4,   5,   5,   5,   6,   7, 999 },
    /* Chants and Blessings */
    {   6,   7,   7,   8,   8,   9,  10,  11,  12 },
    /* Exorcism and Dispelling */
    {  14,  14,  16,  20,  55,  32, 999, 999, 999 },
    /* Ethereal Openings */
    {   3,  10,  20,  10,  50, 999, 999, 999, 999 },
    /* Godly Insights */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Holy Infusions */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Purifications and Healing */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Wrath of God */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  },
  /** rogue **/
  {
    /* Magik for Beginners */
    { 999,   1,   2,   3,   3,   4,   4,   5, 999 },
    /* Conjurings and Tricks */
    {   6, 999,   7,   8,   9,   9,  10, 999,  11 },
    /* Incantations and Illusions */
    {  12,  15, 999, 999,  18, 999, 999, 999, 999 },
    /* Exorcism and Dispelling */
    { 999, 999, 999,  25, 999, 999, 999, 999, 999 },
    /* Resistance of Scarabtarices */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Mordenkainen's Escapes */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /*  */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /*  */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Raal's Tome of Destruction */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  },
  /** ranger **/
  {
    /* Magik for Beginners */
    {   1,   2,   2,   3, 999,   3, 999,   4,   5 },
    /* Conjurings and Tricks */
    {   6,   7,   8,   8,   9,  10,  11,  12,  13 },
    /* Incantations and Illusions */
    {  17,  17,  17,  19,  25,  20,  20,  21, 999 },
    /* Exorcism and Dispelling */
    {  21,  23,  25,  25,  25,  30, 999, 999, 999 },
    /* Resistance of Scarabtarices */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Mordenkainen's Escapes */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Kelek's Grimoire of Power */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Tenser's Transformations */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Raal's Tome of Destruction */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  },
  /** paladin **/
  { 
    /* Beginners Handbook */
    {   1,   2,   3,   3,   4,   5,   5,   7, 999 },
    /* Words of Wisdom */
    {   7,   8,   9,  10,  10,  10,  11,  13, 999 },
    /* Chants and Blessings */
    {  15,  15,  15,  15,  15,  17,  17,  20,  21 },
    /* Exorcism and Dispelling */
    {  22,  24,  28,  32,  70,  38, 999, 999, 999 },
    /* Ethereal Openings */
    {   5,  15,  25,  15,  55, 999, 999, 999, 999 },
    /* Godly Insights */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Holy Infusions */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Purifications and Healing */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 },
    /* Wrath of God */
    { 999, 999, 999, 999, 999, 999, 999, 999, 999 }
  }
};
#else
EXTERN int manacost[6][9][9];
#endif /* MAIN_ROUTINE */

#ifdef MAIN_ROUTINE
int splevel[6][9][9]= {
  /* warrior; none */
  {
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  },
  /** mage **/
  {
    /* Magik for Beginners */
    {  1,  1,  1,  1, 99,  3, 99,  3,  3 },
    /* Conjurings and Tricks */
    {  3,  5,  5,  5,  5,  7,  7,  7,  9 },
    /* Incantations and Illusions */
    {  9,  9,  9, 11, 11, 13, 15, 17, 99 },
    /* Sorcery and Evocations */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Resistance of Scarabtarices */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Mordenkainen's Escapes */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /*  */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /*  */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Raal's Tome of Destruction */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  },
  /** priest **/
  { 
    /* Beginners Handbook */
    {  1,  1,  1,  1,  3,  3,  3,  3, 99 },
    /* Words of Wisdom */
    {  5,  5,  5,  5,  7,  7,  7,  7, 99 },
    /* Chants and Blessings */
    {  9,  9,  9, 11, 11, 11, 13, 13, 15 },
    /* Exorcism and Dispelling */
    { 15, 17, 21, 25, 33, 39, 99, 99, 99 },
    /* Ethereal Openings */
    {  3, 10, 20, 25, 35, 99, 99, 99, 99 },
    /* Godly Insights */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Holy Infusions */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Purifications and Healing */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Wrath of God */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  },
  /** rogue **/
  {
    /* Magik for Beginners */
    { 99,  5,  7,  9, 10, 11, 12, 13, 99 },
    /* Conjurings and Tricks */
    { 15, 99, 17, 19, 21, 22, 23, 99, 24 },
    /* Incantations and Illusions */
    { 25, 27, 99, 99, 28, 99, 99, 99, 99 },
    /* Sorcery and Evocations */
    { 99, 99, 99, 32, 99, 99, 99, 99, 99 },
    /* Resistance of Scarabtarices */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Mordenkainen's Escapes */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /*  */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /*  */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Raal's Tome of Destruction */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  },
  /** ranger **/
  {
    /* Magik for Beginners */
    {  3,  3,  3,  5, 99,  5, 99,  5,  7 },
    /* Conjurings and Tricks */
    {  7,  9,  9, 11, 11, 13, 13, 15, 15 },
    /* Incantations and Illusions */
    { 17, 17, 21, 21, 23, 23, 25, 25, 99 },
    /* Sorcery and Evocations */
    { 27, 29, 31, 33, 35, 37, 99, 99, 99 },
    /* Resistance of Scarabtarices */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Mordenkainen's Escapes */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Kelek's Grimoire of Power */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Tenser's Transformations */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Raal's Tome of Destruction */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  },
  /** paladin **/
  { 
    /* Beginners Handbook */
    {  1,  2,  3,  3,  4,  5,  5,  7, 99 },
    /* Words of Wisdom */
    {  7,  8,  9, 10, 10, 10, 11, 13, 99 },
    /* Chants and Blessings */
    { 15, 15, 15, 15, 15, 17, 17, 20, 21 },
    /* Exorcism and Dispelling */
    { 23, 25, 27, 29, 31, 33, 35, 37, 39 },
    /* Ethereal Openings */
    {  5, 15, 25, 30, 37, 99, 99, 99, 99 },
    /* Godly Insights */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Holy Infusions */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Purifications and Healing */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 },
    /* Wrath of God */
    { 99, 99, 99, 99, 99, 99, 99, 99, 99 }
  }
};
#else
EXTERN int splevel[6][9][9];
#endif /* MAIN_ROUTINE */


#endif /* FRITS */


/*
 * Maximum possible dungeon size
 */
#define AUTO_MAX_X	MAX_WID
#define AUTO_MAX_Y	MAX_HGT

/*
 * Maximum number of rooms (could be too small)
 */
#define AUTO_ROOMS	((AUTO_MAX_X * AUTO_MAX_Y) / 8)

/*
 * Maximum number of "near" grids
 */
#define NEAR_MAX	5000


/*
 * Determine if a grid is "legal"
 */
#define grid_legal(X,Y) \
    (((X) >= 0) && ((X) < AUTO_MAX_X) && ((Y) >= 0) && ((Y) < AUTO_MAX_Y))

/*
 * Obtain a pointer to the grid at a location
 */
#define grid(X,Y) \
    (&auto_grids[Y][X])

        
/*
 * Determine "twice" the distance between two points
 * This results in "diagonals" being "correctly" ranged,
 * that is, a diagonal appears "furthur" than an adjacent.
 */
#define double_distance(Y1,X1,Y2,X2) \
    (distance(((int)(Y1))<<1,((int)(X1))<<1,((int)(Y2))<<1,((int)(X2))<<1))
    



/*
 * Forward declare
 */
typedef struct _auto_room auto_room;
typedef struct _auto_grid auto_grid;
typedef struct _auto_item auto_item;


/*
 * A room in the dungeon.  24 bytes.
 */
struct _auto_room {

  u16b self;		/* Hack -- self index */
  u16b free;		/* Hack -- next free room */
  
  u32b when;		/* When last visited (if ever) */

  byte x1, y1;		/* Upper left corner */
  byte x2, y2;		/* Bottom right corner */

  u16b flow;		/* Flow cost */
  byte x, y;		/* Flow location */
  
  auto_room *prev;	/* Prev room (in flow) */
  auto_room *next;	/* Next room (in flow) */
};


/*
 * A grid in the dungeon.  8 bytes.
 *
 * A room index of "zero" means that the grid is not in any room yet
 * A room index N such that 0<N<MAX_ROOMS refers to a single room
 * A room index MAX_ROOMS+N means the grid is inside "N" different rooms
 */
struct _auto_grid {

  byte o_a;		/* Attribute when last seen */
  char o_c;		/* Character when last seen */

  byte f_a;		/* Floor attribute (if known) */
  char f_c;		/* Floor character (if known) */

  u16b room;		/* Room index, see above */

  u16b info;		/* Some info (unused?) */
};



/*
 * A structure holding information about an object in the inventory
 *
 * The "iqty" is zero if the object is "missing"
 * The "tval" is zero if the object is "bizarre" (or missing)
 * The "kind" is zero if the object is "unaware" (or bizarre, etc)
 * The "able" is zero if the object is "unknown" (or unaware, etc)
 *
 * Note that the "Special Objects" should be the only "bizarre" objects.
 * Although certain artifacts and ego weapons may match as well.
 */
struct _auto_item {

  char desc[80];	/* Actual Description		*/

  char note[20];	/* Inscription, if any		*/
  
  u16b kind;		/* Kind index			*/
  
  byte iqty;		/* Number of items		*/
  bool able;		/* True if item is identified	*/

  byte tval;		/* Item type			*/
  byte sval;		/* Item sub-type		*/
  s16b pval;		/* Item extra-info		*/
  
  s32b cost;		/* Announced Cost		*/
  
  s16b to_h;		/* Bonus to hit */
  s16b to_d;		/* Bonus to dam */
  s16b to_a;		/* Bonus to ac */
  s16b ac;		/* Armor class */
  byte dd;		/* Damage dice */
  byte ds;		/* Damage sides */

  byte name1;		/* Ego identifier */
  byte name2;		/* Artifact identifier */
  
  bool junk;		/* Item should be trashed 	*/
  bool wear;		/* Item should be worn/removed	*/
  bool cash;		/* Item should be bought/sold	*/
  bool test;		/* Item should be identified	*/
};



EXTERN int ready;        	/* Initialized */

EXTERN int state;		/* Current "state" */

EXTERN int state_store;		/* Store symbol, if any */

EXTERN int goal;		/* Current "goal" */

EXTERN int goal_level;		/* Desired stair direction (if any) */

EXTERN u32b c_t;		/* Current time */
EXTERN int c_x, c_y;		/* Current location */

EXTERN int g_x, g_y;		/* Goal location */
EXTERN byte g_a;		/* Goal attr */
EXTERN char g_c;		/* Goal char */

EXTERN int o_x, o_y;		/* Location when goal began */
EXTERN u32b o_t;		/* Time when goal began */

EXTERN int auto_room_max;	/* Number of rooms (?) */


EXTERN bool cheat_inven;
EXTERN bool cheat_equip;

EXTERN u32b auto_began;		/* When this level began */
EXTERN u32b auto_shock;		/* When last "shocked" */

EXTERN u32b auto_recall;	/* When we read word of recall */

EXTERN auto_grid *pg;		/* Player grid */

EXTERN auto_grid **auto_grids;	/* Current "grid list" */

EXTERN auto_room *auto_rooms;	/* Current "room list" */

EXTERN auto_item *auto_items;	/* Current "inventory" */

EXTERN auto_item *auto_wares;	/* Current "store inventory" */


/*
 * Array of "nearby" grids.  Currently, this means that the
 * grid is on the current panel, and is viewable.  Perhaps a
 * more useful definition would be that the grid is within, say,
 * 20 grids, and can be reached if we attempt to "walk" to it.
 */

EXTERN int near_n;		/* Size of the "near" array */
EXTERN byte *near_x;		/* Near array (X locations) */
EXTERN byte *near_y;		/* Near array (Y locations) */



/*
 * Constant "item description parsers"
 */

EXTERN u16b i_size;		/* Number of entries */
EXTERN u16b *i_kind;		/* Kind index per entry */
EXTERN cptr *i_single;		/* Textual prefix for singles */
EXTERN cptr *i_plural;		/* Textual prefix for plurals */


/*
 * Constant "information" variables
 */

#ifdef MAIN_ROUTINE
cptr auto_str_take = "^+:;$*?!_-\\|/\"=~{([])},s";
cptr auto_str_kill = "ABCDEFGHIJKLMNOPQRSTUVWZYZabcdefghijklmnopqrtuvwxyz&";
#else
EXTERN cptr auto_str_take;
EXTERN cptr auto_str_kill;
#endif

/*
 * Hack -- assume "mushrooms" and "skeletons" are invisible monsters
 * standing on top of worthless items.  Otherwise, the borg will attempt
 * to pummel them to death with long range attacks.
 */





/*
 * State variables extracted from the screen
 */
 
EXTERN bool do_heal;
EXTERN bool do_food;
EXTERN bool do_starve;

EXTERN bool do_lite;
EXTERN bool do_torch;
EXTERN bool do_flask;

EXTERN bool do_blind;
EXTERN bool do_afraid;
EXTERN bool do_confused;
EXTERN bool do_poisoned;

EXTERN int auto_level;		/* Current player level */

EXTERN int auto_curhp;		/* Current hitpoints */
EXTERN int auto_maxhp;		/* Maximum hitpoints */
#ifdef FRITS
EXTERN int auto_curmana;	/* Current hitpoints */
EXTERN int auto_maxmana;	/* Maximum hitpoints */
EXTERN int auto_exp;		/* Current exp points */
EXTERN bool do_study;		/* Gain some spells */
EXTERN bool do_chest;		/* Disarm those chests */
EXTERN long do_watch_breeders;	/* Timer for breeding monsters (lice etc) */
#endif /* FRITS */

EXTERN s32b auto_gold;		/* Current "gold" */

EXTERN int auto_depth;		/* Current dungeon "level" */


/* #ifdef FRITS */
EXTERN bool borg_cast_spell(int sclass,char book,char spell);
EXTERN bool borg_cast_spell_at(int sclass,char book,char spell,int x,int y);
EXTERN bool borg_can_cast(int sclass,char book,char spell);
/* #endif ** FRITS */




/*
 * Size of Keypress buffer
 */
#define KEY_SIZE 1024

/*
 * A Queue of keypresses to be sent
 */
EXTERN char key_queue[KEY_SIZE];
EXTERN int key_head;
EXTERN int key_tail;



/*
 * Some "fake" sentinel nodes for the queue
 */
EXTERN auto_room auto_flow_head;
EXTERN auto_room auto_flow_tail;



/* proto files */
#include "borg_proto.h"

#endif /* AUTO_PLAY */

