/*
 * Rogue definitions and variable declarations
 *
 * @(#)rogue.h	5.2 (Berkeley) 5/10/82
 *
 * Rogue: Exploring the Dungeons of Doom
 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
 * All rights reserved.
 *
 * See the file LICENSE.TXT for full copyright and licensing information.
 */

typedef struct { 
    const char *st_name;
    const int   st_value;
} STONE;
   
extern const char *rainbow[];
extern const STONE stones[];
extern const char *sylls[];
extern const char *wood[];
extern const char *metal[];

#define NCOLORS 27
#define NSYLLS  159
#define NSTONES 26
#define NWOOD   33
#define NMETAL  22

/*
 * Maximum number of different things
 */
#define MAXDAEMONS  20
#define MAXROOMS	9
#define MAXTHINGS	9
#define MAXOBJ		9
#define MAXPACK		23
#define MAXTRAPS	10
#define AMULETLEVEL	26
#define	NUMTHINGS	7	/* number of types of things */
#define MAXPASS		13	/* upper limit on number of passages */

/*
 * return values for get functions
 */
#define	NORM	0	/* normal exit */
#define	QUIT	1	/* quit option setting */
#define	MINUS	2	/* back up one option */

/*
 * All the fun defines
 */
#define shint		char		/* short integer (for very small #s) */
#define when		break;case
#define otherwise	break;default
#define until(expr)	while(!(expr))
#define next(ptr)	(*ptr).l_next
#define prev(ptr)	(*ptr).l_prev
#define winat(y,x)	(moat(y,x) != NULL ? moat(y,x)->t_disguise : chat(y,x))
#define DISTANCE(y1, x1, y2, x2) ((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))
#define ce(a,b)		((a).x == (b).x && (a).y == (b).y)
#define hero		player.t_pos
#define pstats		player.t_stats
#define pack		player.t_pack
#define proom		player.t_room
#define max_hp		player.t_stats.s_maxhp
#define attach(a,b)	_attach(&a,b)
#define detach(a,b)	_detach(&a,b)
#define free_list(a)	_free_list(&a)
#ifndef max
#define max(a,b)	((a) > (b) ? (a) : (b))
#endif
#define on(thing,flag)	(((thing).t_flags & (flag)) != 0)
#undef CTRL
#define CTRL(ch)	(ch & 037)
#define GOLDCALC	(rnd(50 + 10 * level) + 2)
#define ISRING(h,r)	(cur_ring[h] != NULL && cur_ring[h]->o_which == r)
#define ISWEARING(r)	(ISRING(LEFT, r) || ISRING(RIGHT, r))
#define ISMULT(type) 	(type==POTION || type==SCROLL || type==FOOD || type==GOLD)
#define INDEX(y,x)	(((x) << 5) + (y))
#define chat(y,x)	(_level[((x) << 5) + (y)])
#define flat(y,x)	(_flags[((x) << 5) + (y)])
#define moat(y,x)	(_monst[((x) << 5) + (y)])
#define unc(cp)		(cp).y, (cp).x
#ifdef WIZARD
#define debug		if (wizard) msg
#endif

/*
 * Things that appear on the screens
 */
#define PASSAGE		'#'
#define DOOR		'+'
#define FLOOR		'.'
#define PLAYER		'@'
#define TRAP		'^'
#define STAIRS		'%'
#define GOLD		'*'
#define POTION		'!'
#define SCROLL		'?'
#define MAGIC		'$'
#define FOOD		':'
#define WEAPON		')'
#define ARMOR		']'
#define AMULET		','
#define RING		'='
#define STICK		'/'
#define CALLABLE	-1

int spread(int nm);
/*
 * Various constants
 */
#define	PASSWD		"mTuZ7WUV9RWkQ"
#define BEARTIME	spread(3)
#define SLEEPTIME	spread(5)
#define HEALTIME	spread(30)
#define HOLDTIME	spread(2)
#define WANDERTIME	spread(70)
#define BEFORE		spread(1)
#define AFTER		spread(2)
#define HUHDURATION	spread(20)
#define SEEDURATION	spread(850)
#define HUNGERTIME	spread(1300)
#define MORETIME	150
#define STOMACHSIZE	2000
#define STARVETIME	850
#define ESCAPE		27
#define LEFT		0
#define RIGHT		1
#define BOLT_LENGTH	6
#define LAMPDIST	3

/*
 * Save against things
 */
#define VS_POISON	00
#define VS_PARALYZATION	00
#define VS_DEATH	00
#define VS_BREATH	02
#define VS_MAGIC	03

/*
 * Various flag bits
 */
/* flags for rooms */
#define ISDARK	0000001		/* room is dark */
#define ISGONE	0000002		/* room is gone (a corridor) */

/* flags for objects */
#define ISCURSED 000001		/* object is cursed */
#define ISKNOW	0000002		/* player knows details about the object */
#define ISMISL	0000004		/* object is a missile type */
#define ISMANY	0000010		/* object comes in groups */

/* flags for creatures */
#define CANHUH	0000001		/* creature can confuse */
#define CANSEE	0000002		/* creature can see invisible creatures */
#define ISBLIND	0000004		/* creature is blind */
#define ISCANC	0000010		/* creature has special qualities cancelled */
#define ISFOUND	0000020		/* creature has been seen (used for objects) */
#define ISGREED	0000040		/* creature runs to protect gold */
#define ISHASTE	0000100		/* creature has been hastened */
#define ISHELD	0000400		/* creature has been held */
#define ISHUH	0001000		/* creature is confused */
#define ISINVIS	0002000		/* creature is invisible */
#define ISMEAN	0004000		/* creature can wake when player enters room */
#define ISREGEN	0010000		/* creature can regenerate */
#define ISRUN	0020000		/* creature is running at the player */
#define SEEMONST 040000		/* hero can detect unseen monsters */
#define ISSLOW	0100000		/* creature has been slowed */

/*
 * Flags for level map
 */
#define F_PASS		0x80		/* is a passageway */
#define F_SEEN		0x40		/* have seen this corridor before */
#define F_DROPPED	0x20		/* object was dropped here */
#define F_LOCKED	0x20		/* door is locked */
#define F_REAL		0x10		/* what you see is what you get */
#define F_PNUM		0x0f		/* passage number mask */
#define F_TMASK		0x07		/* trap number mask */

/*
 * Trap types
 */
#define T_DOOR	00
#define T_ARROW	01
#define T_SLEEP	02
#define T_BEAR	03
#define T_TELEP	04
#define T_DART	05
#define NTRAPS	6

/*
 * Potion types
 */
#define P_CONFUSE	0
#define P_PARALYZE	1
#define P_POISON	2
#define P_STRENGTH	3
#define P_SEEINVIS	4
#define P_HEALING	5
#define P_MFIND		6
#define	P_TFIND 	7
#define	P_RAISE		8
#define P_XHEAL		9
#define P_HASTE		10
#define P_RESTORE	11
#define P_BLIND		12
#define P_NOP		13
#define MAXPOTIONS	14

/*
 * Scroll types
 */
#define S_CONFUSE	0
#define S_MAP		1
#define S_HOLD		2
#define S_SLEEP		3
#define S_ARMOR		4
#define S_IDENT		5
#define S_SCARE		6
#define S_GFIND		7
#define S_TELEP		8
#define S_ENCH		9
#define S_CREATE	10
#define S_REMOVE	11
#define S_AGGR		12
#define S_NOP		13
#define S_GENOCIDE	14
#define MAXSCROLLS	15

/*
 * Weapon types
 */
#define MACE		0
#define SWORD		1
#define BOW		2
#define ARROW		3
#define DAGGER		4
#define TWOSWORD	5
#define DART		6
#define CROSSBOW	7
#define BOLT		8
#define SPEAR		9
#define FLAME		10	/* fake entry for dragon breath (ick) */
#define MAXWEAPONS	10	/* this should equal FLAME */

/*
 * Armor types
 */
#define LEATHER		0
#define RING_MAIL	1
#define STUDDED_LEATHER	2
#define SCALE_MAIL	3
#define CHAIN_MAIL	4
#define SPLINT_MAIL	5
#define BANDED_MAIL	6
#define PLATE_MAIL	7
#define MAXARMORS	8

/*
 * Ring types
 */
#define R_PROTECT	0
#define R_ADDSTR	1
#define R_SUSTSTR	2
#define R_SEARCH	3
#define R_SEEINVIS	4
#define R_NOP		5
#define R_AGGR		6
#define R_ADDHIT	7
#define R_ADDDAM	8
#define R_REGEN		9
#define R_DIGEST	10
#define R_TELEPORT	11
#define R_STEALTH	12
#define R_SUSTARM	13
#define MAXRINGS	14

/*
 * Rod/Wand/Staff types
 */

#define WS_LIGHT	0
#define WS_HIT		1
#define WS_ELECT	2
#define WS_FIRE		3
#define WS_COLD		4
#define WS_POLYMORPH	5
#define WS_MISSILE	6
#define WS_HASTE_M	7
#define WS_SLOW_M	8
#define WS_DRAIN	9
#define WS_NOP		10
#define WS_TELAWAY	11
#define WS_TELTO	12
#define WS_CANCEL	13
#define MAXSTICKS	14

/*
 * Now we define the structures and types
 */

/*
 * Help list
 */

struct h_list {
    char h_ch;
    char *h_desc;
};

/*
 * Coordinate data type
 */
typedef struct {
    shint x;
    shint y;
} coord;

/* daemon/fuse data type */

struct delayed_action {
    int d_type;
    void (*d_func)();
    int d_arg;
    int d_time;
};

/**/

typedef unsigned int str_t;

/*
 * Stuff about magic items
 */

struct magic_item {
    const char *mi_name;
    shint mi_prob;
    short mi_worth;
};

/*
 * Room structure
 */
struct room {
    coord r_pos;			/* Upper left corner */
    coord r_max;			/* Size of room */
    coord r_gold;			/* Where the gold is */
    int r_goldval;			/* How much the gold is worth */
    short r_flags;			/* Info about the room */
    shint r_nexits;			/* Number of exits */
    coord r_exit[12];			/* Where the exits are */
};

/*
 * Structure describing a fighting being
 */
struct stats {
    str_t s_str;			/* Strength */
    long s_exp;				/* Experience */
    shint s_lvl;			/* Level of mastery */
    shint s_arm;			/* Armor class */
    short s_hpt;			/* Hit points */
    char s_dmg[16];			/* String describing damage done */
    shint s_maxhp;			/* Max hit points */
};

/*
 * Structure for monsters and player
 */
union thing {
    struct {
	union thing *_l_next, *_l_prev;	/* Next pointer in link */
	coord _t_pos;			/* Position */
	bool _t_turn;			/* If slowed, is it a turn to move */
	unsigned char _t_type;		/* What it is */
	char _t_disguise;		/* What mimic looks like */
	char _t_oldch;			/* Character that was where it was */
	coord *_t_dest;			/* Where it is running to */
	short _t_flags;			/* State word */
	struct stats _t_stats;		/* Physical description */
	struct room *_t_room;		/* Current room for thing */
	union thing *_t_pack;		/* What the thing is carrying */
    int  _t_reserved;
    } _t;
    struct {
	union thing *_l_next, *_l_prev;	/* Next pointer in link */
	shint _o_type;			/* What kind of object it is */
	coord _o_pos;			/* Where it lives on the screen */
	char *_o_text;			/* What it says if you read it */
	char _o_launch;			/* What you need to launch it */
	char _o_damage[8];		/* Damage if used like sword */
	char _o_hurldmg[8];		/* Damage if thrown */
	shint _o_count;			/* Count for plural objects */
	shint _o_which;			/* Which object of a type it is */
	shint _o_hplus;			/* Plusses to hit */
	shint _o_dplus;			/* Plusses to damage */
	short _o_ac;			/* Armor class */
	short _o_flags;			/* Information about objects */
	shint _o_group;			/* Group number for this object */
    } _o;
};

typedef union thing THING;

#define l_next		_t._l_next
#define l_prev		_t._l_prev
#define t_pos		_t._t_pos
#define t_turn		_t._t_turn
#define t_type		_t._t_type
#define t_disguise	_t._t_disguise
#define t_oldch		_t._t_oldch
#define t_dest		_t._t_dest
#define t_flags		_t._t_flags
#define t_stats		_t._t_stats
#define t_pack		_t._t_pack
#define t_room		_t._t_room
#define t_reserved      _t._t_reserved
#define o_type		_o._o_type
#define o_pos		_o._o_pos
#define o_text		_o._o_text
#define o_launch	_o._o_launch
#define o_damage	_o._o_damage
#define o_hurldmg	_o._o_hurldmg
#define o_count		_o._o_count
#define o_which		_o._o_which
#define o_hplus		_o._o_hplus
#define o_dplus		_o._o_dplus
#define o_ac		_o._o_ac
#define o_charges	o_ac
#define o_goldval	o_ac
#define o_flags		_o._o_flags
#define o_group		_o._o_group
#define o_reserved      _o._o_reserved

/*
 * Array containing information on all the various types of mosnters
 */
struct monster {
    const char *m_name;			/* What to call the monster */
    const shint m_carry;			/* Probability of carrying something */
    const short m_flags;			/* Things about the monster */
    struct stats m_stats;		/* Initial stats */
};

/*
 * External variables
 */

extern struct delayed_action d_list[20];

extern THING	*_monst[], *cur_armor, *cur_ring[], *cur_weapon,
		*lvl_obj, *mlist, player;

extern coord	delta, oldpos;

extern struct h_list	helpstr[];

extern struct room	*oldrp, passages[], rooms[];

extern struct stats	max_stats;

extern struct monster	monsters[];

extern struct magic_item	p_magic[], r_magic[], s_magic[],
				things[], ws_magic[];

/*
 * Function types
 */

coord	*find_dest(), *rndmove();

THING	*find_mons(), *find_obj(), *get_item(), *new_item(),
	*new_thing(), *wake_monster();

struct room	*roomin(coord *cp);

void    _attach(THING **list, THING *item);
void    _detach(THING **list, THING *item);
void    _free_list(THING **ptr);
bool    add_haste(bool potion);
void    add_line(char *fmt, char *arg);
void    add_pack(THING *obj, bool silent);
void    add_str(str_t *sp, int amt);
void    addmsg(char *fmt, ...);
void    aggravate(void);
int     attack(THING *mp);
void    auto_save(int sig);
void    call_it(bool know, char **guess);
bool    cansee(int y, int x);
char   *charge_str(THING *obj);
void    check_level(void);
void    chg_str(int amt);
void    command(void);
void    death(char monst);
bool    diag_ok(coord *sp, coord *ep);
void    discard(THING *item);
void    discovered(void);
void    do_daemons(int flag);
void    do_fuses(int flag);
void    do_motion(THING *obj, int ydelta, int xdelta);
void    do_move(int dy, int dx);
void    do_passages(void);
void    do_rooms(void);
void    do_run(char ch);
void    do_zap(void);
void    doctor(void);
void    door_open(struct room *rp);
void    drop(void);
bool    dropcheck(THING *op);
void    eat(void);
int     encread(void *starta, int size, int inf);
void    encwrite(void *starta, int size, FILE *outf);
void    end_line(void);
void    endmsg(void);
void    enter_room(coord *cp);
void    extinguish(void (*func)());
void    fall(THING *obj, bool pr);
bool    fallpos(coord *pos, coord *newpos, bool pass);
void    fatal(char *s);
bool    fight(coord *mp, char mn, THING *weap, bool thrown);
THING  *find_obj(int y, int x);
void    fire_bolt(coord *start, coord *dir, char *name);
void    fix_stick(THING *cur);
void    flush_type(void);
void    fuse(void (*func)(), int arg, int time, int type);
void    genocide(void);
bool    get_dir(void);
THING  *get_item(char *purpose, int type);
int     get_str(char *opt, WINDOW *win);
void    give_pack(THING *tp);
bool    hit_monster(int y, int x, THING *obj);
void    init_check(void);
void    init_colors(void);
void    init_materials(void);
void    init_names(void);
void    init_player(void);
void    init_stones(void);
void    init_things(void);
void    init_weapon(THING *weap, char type);
char   *inv_name(THING *obj, bool drop);
bool    inventory(THING *list, int type);
void    invis_on(void);
bool    is_current(THING *obj);
bool    is_magic(THING *obj);
bool    issymlink(char *sp);
void    kill_daemon(void (*func)());
void    killed(THING *tp, bool pr);
void    leave(int sig);
void    leave_room(coord *cp);
void    lengthen(void (*func)(), int xtime);
bool    lock_sc(void);
void    look(bool wakeup);
void    missile(int ydelta, int xdelta);
void    msg(char *fmt, ...);
THING  *new_item(void);
void    new_level(void);
void    new_monster(THING *tp, char type, coord *cp);
THING  *new_thing(void);
void    nohaste(void);
char   *num(int n1, int n2, char type);
void    open_log(void);
void    open_score(void);
void    option(void);
char    pack_char(THING *obj);
void    parse_opts(char *str);
void    pick_up(char ch);
void    picky_inven(void);
void    playit(void);
void    quaff(void);
void    quit(int a);
void    raise_level(void);
char    randmonster(bool wander);
void    read_scroll(void);
int     readchar(void);
int     readcharw(WINDOW *win);
void    remove_monster(coord *mp, THING *tp, bool waskill);
bool    restore(char *file, char **envp);
int     ring_eat(int hand);
char   *ring_num(THING *obj);
void    ring_off(void);
void    ring_on(void);
int     rnd(int range);
void    rnd_pos(struct room *rp, coord *cp);
int     rnd_room(void);
coord  *rndmove(THING *who);
int     roll(int number, int sides);
void    rollwand(void);
void    runners(void);
void    runto(coord *runner, coord *spot);
bool    save(int which);
bool    save_game(void);
bool    save_throw(int which, THING *tp);
void    score(int amount, int flags, char monst);
bool    see_monst(THING *mp);
void    setup(void);
void    shell(void);
void    show_win(WINDOW *scr, char *message);
void    sight(void);
int     sign(int nm);
void    start_daemon(void (*func)(), int arg, int type);
void    start_score(void);
void    status(void);
bool    step_ok(char ch);
void    stomach(void);
void    strucpy(char *s1, char *s2, int len);
void    swander(void);
bool    swing(int at_lvl, int op_arm, int wplus);
void    take_off(void);
int     teleport(void);
void    total_winner(void);
char   *tr_name(char type);
bool    turn_see(bool turn_off);
void    turn_see_off(void);
void    unconfuse(void);
char   *unctrol(char ch);
void    unlock_sc(void);
void    unsee(void);
char   *vowelstr(const char *str);
char   *xcrypt(const char *key, const char *setting);
void    w_wait_for(WINDOW *win, char ch);
void    wait_for(char ch);
THING  *wake_monster(int y, int x);
void    wanderer(void);
void    waste_time(void);
void    wear(void);
void    whatis(bool insist);
void    wield(void);
void    writelog(int amount, int flags, char monst);

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "extern.h"

#ifndef PATH_MAX
#define PATH_MAX _MAX_PATH
#endif
