#ifndef EXTERNS_H
#define EXTERNS_H
#include <vector>
#include <list>
#include <string>
#include <map>
#include <set>
#include <memory>
#include <cstdlib>
#include <deque>
#include <time.h>
#include "defines.h"
#include "enum.h"
#include "fixary.h"
#include "libutil.h"
#include "mpr.h"
#include "store.h"
#ifdef USE_TILE
struct tile_flavour
{
unsigned short floor;
unsigned short wall;
unsigned short special;
};
class tile_fg_store
{
public:
tile_fg_store() : m_tile(0) {}
tile_fg_store(unsigned int tile) : m_tile(tile) {}
operator unsigned int() { return m_tile; }
unsigned int operator=(unsigned int tile);
protected:
unsigned int m_tile;
};
#endif
#define INFO_SIZE 200
#define ITEMNAME_SIZE 200
#define HIGHSCORE_SIZE 800
#define MAX_NUM_GODS 21
#define BURDEN_TO_AUM 0.1f
extern char info[INFO_SIZE];
const int kNameLen = 30;
#ifdef SHORT_FILE_NAMES
const int kFileNameLen = 6;
#else
const int kFileNameLen = 250;
#endif
const int kPathLen = 256;
#define NO_BERSERK_PENALTY -1
typedef FixedArray<dungeon_feature_type, GXM, GYM> feature_grid;
typedef FixedArray<unsigned, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER>
env_show_grid;
struct item_def;
class melee_attack;
struct coord_def;
class level_id;
class player_quiver;
struct coord_def
{
int x;
int y;
explicit coord_def( int x_in = 0, int y_in = 0 ) : x(x_in), y(y_in) { }
void set(int xi, int yi)
{
x = xi;
y = yi;
}
void reset()
{
set(0, 0);
}
int distance_from(const coord_def &b) const;
bool operator == (const coord_def &other) const
{
return x == other.x && y == other.y;
}
bool operator != (const coord_def &other) const
{
return !operator == (other);
}
bool operator < (const coord_def &other) const
{
return (x < other.x) || (x == other.x && y < other.y);
}
bool operator > (const coord_def &other) const
{
return (x > other.x) || (x == other.x && y > other.y);
}
const coord_def &operator += (const coord_def &other)
{
x += other.x;
y += other.y;
return (*this);
}
const coord_def &operator += (int offset)
{
x += offset;
y += offset;
return (*this);
}
const coord_def &operator -= (const coord_def &other)
{
x -= other.x;
y -= other.y;
return (*this);
}
const coord_def &operator -= (int offset)
{
x -= offset;
y -= offset;
return (*this);
}
const coord_def &operator /= (int div)
{
x /= div;
y /= div;
return (*this);
}
const coord_def &operator *= (int mul)
{
x *= mul;
y *= mul;
return (*this);
}
coord_def operator + (const coord_def &other) const
{
coord_def copy = *this;
return (copy += other);
}
coord_def operator + (int other) const
{
coord_def copy = *this;
return (copy += other);
}
coord_def operator - (const coord_def &other) const
{
coord_def copy = *this;
return (copy -= other);
}
coord_def operator - (int other) const
{
coord_def copy = *this;
return (copy -= other);
}
coord_def operator / (int div) const
{
coord_def copy = *this;
return (copy /= div);
}
coord_def operator * (int mul) const
{
coord_def copy = *this;
return (copy *= mul);
}
int abs() const
{
return (x * x + y * y);
}
int rdist() const
{
return (std::max(std::abs(x), std::abs(y)));
}
bool origin() const
{
return (!x && !y);
}
bool zero() const
{
return origin();
}
bool equals(const int xi, const int yi) const
{
return (xi == x && yi == y);
}
};
typedef bool (*coord_predicate)(const coord_def &c);
struct run_check_dir
{
dungeon_feature_type grid;
coord_def delta;
};
struct cloud_struct
{
coord_def pos;
cloud_type type;
int decay;
unsigned char spread_rate;
kill_category whose;
killer_type killer;
cloud_struct() : pos(), type(CLOUD_NONE), decay(0), spread_rate(0),
whose(KC_OTHER), killer(KILL_NONE)
{
}
void set_whose(kill_category _whose);
void set_killer(killer_type _killer);
static kill_category killer_to_whose(killer_type killer);
static killer_type whose_to_killer(kill_category whose);
};
struct shop_struct
{
coord_def pos;
unsigned char greed;
shop_type type;
unsigned char level;
FixedVector<unsigned char, 3> keeper_name;
};
struct delay_queue_item
{
delay_type type;
int duration;
int parm1;
int parm2;
bool started;
};
class level_id
{
public:
branch_type branch; int depth; level_area_type level_type;
public:
static level_id current();
static level_id get_next_level_id(const coord_def &pos);
level_id()
: branch(BRANCH_MAIN_DUNGEON), depth(-1),
level_type(LEVEL_DUNGEON)
{
}
level_id(branch_type br, int dep, level_area_type ltype = LEVEL_DUNGEON)
: branch(br), depth(dep), level_type(ltype)
{
}
level_id(const level_id &ot)
: branch(ot.branch), depth(ot.depth), level_type(ot.level_type)
{
}
level_id(level_area_type ltype)
: branch(BRANCH_MAIN_DUNGEON), depth(-1), level_type(ltype)
{
}
static level_id parse_level_id(const std::string &s) throw (std::string);
static level_id from_packed_place(const unsigned short place);
unsigned short packed_place() const;
std::string describe(bool long_name = false, bool with_number = true) const;
void clear()
{
branch = BRANCH_MAIN_DUNGEON;
depth = -1;
level_type = LEVEL_DUNGEON;
}
int absdepth() const;
int dungeon_absdepth() const;
bool is_valid() const
{
return (branch != NUM_BRANCHES && depth != -1)
|| level_type != LEVEL_DUNGEON;
}
const level_id &operator = (const level_id &id)
{
branch = id.branch;
depth = id.depth;
level_type = id.level_type;
return (*this);
}
bool operator == ( const level_id &id ) const
{
return (level_type == id.level_type
&& (level_type != LEVEL_DUNGEON
|| (branch == id.branch && depth == id.depth)));
}
bool operator != ( const level_id &id ) const
{
return !operator == (id);
}
bool operator <( const level_id &id ) const
{
if (level_type != id.level_type)
return (level_type < id.level_type);
if (level_type != LEVEL_DUNGEON)
return (false);
return (branch < id.branch) || (branch==id.branch && depth < id.depth);
}
bool operator == ( const branch_type _branch ) const
{
return (branch == _branch && level_type == LEVEL_DUNGEON);
}
bool operator != ( const branch_type _branch ) const
{
return !operator == (_branch);
}
void save(writer&) const;
void load(reader&);
};
struct item_def
{
object_class_type base_type; unsigned char sub_type; short plus; short plus2; long special; unsigned char colour; unsigned long flags; short quantity;
coord_def pos; short link; short slot;
unsigned short orig_place;
short orig_monnum;
std::string inscription;
CrawlHashTable props;
public:
item_def() : base_type(OBJ_UNASSIGNED), sub_type(0), plus(0), plus2(0),
special(0L), colour(0), flags(0L), quantity(0),
pos(), link(NON_ITEM), slot(0), orig_place(0),
orig_monnum(0), inscription()
{
}
std::string name(description_level_type descrip,
bool terse = false, bool ident = false,
bool with_inscription = true,
bool quantity_in_words = false,
unsigned long ignore_flags = 0x0) const;
bool has_spells() const;
bool cursed() const;
int book_number() const;
zap_type zap() const;
int index() const;
int armour_rating() const;
bool launched_by(const item_def &launcher) const;
void clear()
{
*this = item_def();
}
void set_holding_monster(int midx);
monsters* holding_monster() const;
bool held_by_monster() const;
private:
std::string name_aux(description_level_type desc,
bool terse, bool ident,
unsigned long ignore_flags) const;
};
class runrest
{
public:
int runmode;
int mp;
int hp;
coord_def pos;
FixedVector<run_check_dir,3> run_check;
public:
runrest();
void initialise(int rdir, int mode);
operator int () const;
const runrest &operator = (int newrunmode);
bool is_rest() const;
bool is_explore() const;
bool is_any_travel() const;
void clear();
void stop();
void rest();
bool check_stop_running();
private:
void set_run_check(int index, int compass_dir);
bool run_grids_changed() const;
};
class PlaceInfo
{
public:
int level_type; int branch;
unsigned long num_visits;
unsigned long levels_seen;
unsigned long mon_kill_exp;
unsigned long mon_kill_exp_avail;
unsigned long mon_kill_num[KC_NCATEGORIES];
long turns_total;
long turns_explore;
long turns_travel;
long turns_interlevel;
long turns_resting;
long turns_other;
double elapsed_total;
double elapsed_explore;
double elapsed_travel;
double elapsed_interlevel;
double elapsed_resting;
double elapsed_other;
public:
PlaceInfo();
bool is_global() const;
void make_global();
void assert_validity() const;
const std::string short_name() const;
const PlaceInfo &operator += (const PlaceInfo &other);
const PlaceInfo &operator -= (const PlaceInfo &other);
PlaceInfo operator + (const PlaceInfo &other) const;
PlaceInfo operator - (const PlaceInfo &other) const;
};
typedef std::vector<delay_queue_item> delay_queue_type;
class KillMaster;
class monster_spells : public FixedVector<spell_type, NUM_MONSTER_SPELL_SLOTS>
{
public:
monster_spells()
: FixedVector<spell_type, NUM_MONSTER_SPELL_SLOTS>(SPELL_NO_SPELL)
{ }
void clear() { init(SPELL_NO_SPELL); }
};
class ghost_demon;
class actor;
class monsters;
struct trap_def
{
coord_def pos;
trap_type type;
int ammo_qty;
dungeon_feature_type category() const;
std::string name(description_level_type desc = DESC_PLAIN) const;
bool is_known(const actor* act = 0) const;
void trigger(actor& triggerer, bool flat_footed = false);
void disarm();
void destroy();
void hide();
void reveal();
void prepare_ammo();
bool type_has_ammo() const;
bool active() const;
private:
void message_trap_entry();
void shoot_ammo(actor& act, bool was_known);
item_def generate_trap_item();
int shot_damage(actor& act);
};
struct map_cell
{
short object; unsigned short flags; unsigned short colour;
unsigned long property;
map_cell() : object(0), flags(0), colour(0), property(0) { }
void clear() { flags = object = colour = 0; }
unsigned glyph() const;
bool known() const;
bool seen() const;
};
class map_marker;
class reader;
class writer;
class map_markers
{
public:
map_markers();
map_markers(const map_markers &);
map_markers &operator = (const map_markers &);
~map_markers();
void activate_all(bool verbose = true);
void add(map_marker *marker);
void remove(map_marker *marker);
void remove_markers_at(const coord_def &c, map_marker_type type = MAT_ANY);
map_marker *find(const coord_def &c, map_marker_type type = MAT_ANY);
map_marker *find(map_marker_type type);
void move(const coord_def &from, const coord_def &to);
void move_marker(map_marker *marker, const coord_def &to);
std::vector<map_marker*> get_all(map_marker_type type = MAT_ANY);
std::vector<map_marker*> get_all(const std::string &key,
const std::string &val = "");
std::vector<map_marker*> get_markers_at(const coord_def &c);
std::string property_at(const coord_def &c, map_marker_type type,
const std::string &key);
void clear();
void write(writer &) const;
void read(reader &, int minorVersion);
private:
typedef std::multimap<coord_def, map_marker *> dgn_marker_map;
typedef std::pair<coord_def, map_marker *> dgn_pos_marker;
void init_from(const map_markers &);
void unlink_marker(const map_marker *);
private:
dgn_marker_map markers;
};
struct message_filter
{
int channel; text_pattern pattern;
message_filter( int ch, const std::string &s )
: channel(ch), pattern(s)
{
}
message_filter( const std::string &s ) : channel(-1), pattern(s) { }
bool is_filtered( int ch, const std::string &s ) const {
bool channel_match = ch == channel || channel == -1;
if (!channel_match || pattern.empty())
return channel_match;
return pattern.matches(s);
}
};
struct sound_mapping
{
text_pattern pattern;
std::string soundfile;
};
struct colour_mapping
{
std::string tag;
text_pattern pattern;
int colour;
};
struct message_colour_mapping
{
message_filter message;
int colour;
};
struct feature_def
{
dungeon_char_type dchar;
unsigned symbol; unsigned magic_symbol; unsigned short colour; unsigned short map_colour; unsigned short seen_colour; unsigned short em_colour; unsigned short seen_em_colour; unsigned flags;
map_feature minimap;
bool is_notable() const { return (flags & FFT_NOTABLE); }
};
struct feature_override
{
dungeon_feature_type feat;
feature_def override;
};
class InvEntry;
typedef int (*item_sort_fn)(const InvEntry *a, const InvEntry *b);
struct item_comparator
{
item_sort_fn cmpfn;
bool negated;
item_comparator(item_sort_fn cfn, bool neg = false)
: cmpfn(cfn), negated(neg)
{
}
int compare(const InvEntry *a, const InvEntry *b) const
{
return (negated? -cmpfn(a, b) : cmpfn(a, b));
}
};
typedef std::vector<item_comparator> item_sort_comparators;
struct menu_sort_condition
{
public:
menu_type mtype;
int sort;
item_sort_comparators cmp;
public:
menu_sort_condition(menu_type mt = MT_INVLIST, int sort = 0);
menu_sort_condition(const std::string &s);
bool matches(menu_type mt) const;
private:
void set_menu_type(std::string &s);
void set_sort(std::string &s);
void set_comparators(std::string &s);
};
struct mon_display
{
monster_type type;
unsigned glyph;
unsigned colour;
mon_display(monster_type m = MONS_NO_MONSTER,
unsigned gly = 0,
unsigned col = 0) : type(m), glyph(gly), colour(col) { }
};
class InitLineInput;
struct game_options
{
public:
game_options();
void reset_startup_options();
void reset_options();
void read_option_line(const std::string &s, bool runscripts = false);
void read_options(InitLineInput &, bool runscripts,
bool clear_aliases = true);
void include(const std::string &file, bool resolve, bool runscript);
void report_error(const std::string &error);
std::string resolve_include(const std::string &file,
const char *type = "");
bool was_included(const std::string &file) const;
static std::string resolve_include(
std::string including_file,
std::string included_file,
const std::vector<std::string> *rcdirs = NULL)
throw (std::string);
public:
std::string filename; std::string basefilename; int line_num;
std::vector<feature_override> feature_overrides;
std::vector<mon_display> mon_glyph_overrides;
unsigned cset_override[NUM_CSET][NUM_DCHAR_TYPES];
std::string save_dir; std::string macro_dir; std::string morgue_dir; std::vector<std::string> additional_macro_files;
std::string player_name;
#ifdef DGL_SIMPLE_MESSAGING
bool messaging; #endif
bool suppress_startup_errors;
bool mouse_input;
int view_max_width;
int view_max_height;
int mlist_min_height;
int msg_max_height;
bool mlist_allow_alternate_layout;
int mlist_targetting; bool classic_hud;
bool msg_condense_repeats;
bool view_lock_x;
bool view_lock_y;
bool center_on_scroll;
bool symmetric_scroll;
int scroll_margin_x;
int scroll_margin_y;
bool verbose_monster_pane;
int autopickup_on;
int default_friendly_pickup;
bool show_more_prompt;
bool show_gold_turns; bool show_beam;
long autopickups; bool show_inventory_weights; bool colour_map; bool clean_map; bool show_uncursed; bool easy_open; bool easy_unequip; bool equip_unequip; bool easy_butcher; bool always_confirm_butcher; bool chunks_autopickup; bool prompt_for_swap; bool list_rotten; bool prefer_safe_chunks; bool easy_eat_chunks; bool easy_eat_gourmand; bool easy_eat_contaminated; bool default_target; bool autopickup_no_burden;
bool note_all_skill_levels; bool note_skill_max; bool note_all_spells; std::string user_note_prefix; int note_hp_percent; bool note_xom_effects; int ood_interesting; int rare_interesting; confirm_level_type easy_confirm; bool easy_quit_item_prompts; confirm_prompt_type allow_self_target;
int colour[16]; int background; int channels[NUM_MESSAGE_CHANNELS]; int target_range;
bool use_old_selection_order; int weapon; int book; int wand; int chaos_knight; int death_knight; god_type priest; bool random_pick; bool good_random; int hp_warning; int magic_point_warning; char race; char cls; bool delay_message_clear; unsigned friend_brand; unsigned neutral_brand; bool no_dark_brand; bool macro_meta_entry;
int fire_items_start; std::vector<unsigned> fire_order;
bool auto_list;
bool flush_input[NUM_FLUSH_REASONS];
char_set_type char_set;
FixedVector<unsigned, NUM_DCHAR_TYPES> char_table;
int num_colours;
std::string pizza;
#ifdef WIZARD
int wiz_mode; #endif
int sc_entries; int sc_format;
std::vector<std::pair<int, int> > hp_colour;
std::vector<std::pair<int, int> > mp_colour;
std::vector<std::pair<int, int> > stat_colour;
std::string map_file_name; std::vector<std::pair<text_pattern, bool> > force_autopickup;
std::vector<text_pattern> note_monsters; std::vector<text_pattern> note_messages; std::vector<std::pair<text_pattern, std::string> > autoinscriptions;
std::vector<text_pattern> note_items; std::vector<int> note_skill_levels;
bool autoinscribe_artefacts;
bool pickup_thrown; bool pickup_dropped; int travel_delay; int explore_delay;
int arena_delay;
bool arena_dump_msgs;
bool arena_dump_msgs_all;
bool arena_list_eq;
bool arena_force_ai;
std::vector<message_filter> travel_stop_message;
std::vector<message_filter> force_more_message;
int stash_tracking;
int tc_reachable; int tc_excluded; int tc_exclude_circle; int tc_dangerous; int tc_disconnected; std::vector<text_pattern> auto_exclude;
int travel_stair_cost;
bool show_waypoints;
bool classic_item_colours; bool item_colour;
unsigned evil_colour;
unsigned detected_monster_colour; unsigned detected_item_colour; unsigned status_caption_colour;
unsigned heap_brand; unsigned stab_brand; unsigned may_stab_brand; unsigned feature_item_brand; unsigned trap_item_brand;
bool trap_prompt;
int item_stack_summary_minimum;
int explore_stop;
int explore_stop_prompt;
bool explore_greedy;
int explore_item_greed;
bool explore_improved;
std::vector<sound_mapping> sound_mappings;
std::vector<colour_mapping> menu_colour_mappings;
std::vector<message_colour_mapping> message_colour_mappings;
bool menu_colour_prefix_class; bool menu_colour_shops;
std::vector<menu_sort_condition> sort_menus;
int dump_kill_places; int dump_message_count;
int dump_item_origins; int dump_item_origin_price;
bool dump_book_spells;
std::vector<std::string> dump_order;
bool level_map_title; bool target_zero_exp; bool target_wrap; bool target_oos; bool target_los_first; bool target_unshifted_dirs;
int drop_mode; int pickup_mode;
bool easy_exit_menu;
int assign_item_slot;
std::vector<text_pattern> drop_filter;
FixedArray<bool, NUM_DELAYS, NUM_AINTERRUPTS> activity_interrupts;
bool remember_name;
bool dos_use_background_intensity;
bool use_fake_cursor;
int level_map_cursor_step;
int kill_map[KC_NCATEGORIES];
bool rest_wait_both;
#ifdef WIZARD
long fsim_rounds;
int fsim_str, fsim_int, fsim_dex;
int fsim_xl;
std::string fsim_mons;
std::vector<std::string> fsim_kit;
#endif
#ifdef USE_TILE
char tile_show_items[20]; bool tile_title_screen; bool tile_menu_icons; char tile_player_col;
char tile_monster_col;
char tile_neutral_col;
char tile_friendly_col;
char tile_plant_col;
char tile_item_col;
char tile_unseen_col;
char tile_floor_col;
char tile_wall_col;
char tile_mapped_wall_col;
char tile_door_col;
char tile_downstairs_col;
char tile_upstairs_col;
char tile_feature_col;
char tile_trap_col;
char tile_water_col;
char tile_lava_col;
char tile_excluded_col;
char tile_excl_centre_col;
char tile_window_col;
std::string tile_font_crt_file;
int tile_font_crt_size;
std::string tile_font_msg_file;
int tile_font_msg_size;
std::string tile_font_stat_file;
int tile_font_stat_size;
std::string tile_font_lbl_file;
int tile_font_lbl_size;
std::string tile_font_tip_file;
int tile_font_tip_size;
screen_mode tile_full_screen;
int tile_window_width;
int tile_window_height;
int tile_map_pixels;
int tile_update_rate;
int tile_key_repeat_delay;
int tile_tooltip_ms;
tag_pref tile_tag_pref;
tile_display_type tile_display;
#endif
typedef std::map<std::string, std::string> opt_map;
opt_map named_options;
std::string prev_name;
char prev_race;
char prev_cls;
int prev_ck, prev_dk;
god_type prev_pr;
int prev_weapon;
int prev_book;
int prev_wand;
bool prev_randpick;
FixedVector<bool, 85> tutorial_events;
bool tut_explored;
bool tut_stashes;
bool tut_travel;
unsigned int tut_spell_counter;
unsigned int tut_throw_counter;
unsigned int tut_berserk_counter;
unsigned int tut_melee_counter;
unsigned int tut_last_healed;
unsigned int tut_seen_invisible;
bool tut_just_triggered;
unsigned int tutorial_type;
unsigned int tutorial_left;
private:
typedef std::map<std::string, std::string> string_map;
string_map aliases;
string_map variables;
std::set<std::string> constants; std::set<std::string> included;
public:
int o_int(const char *name, int def = 0) const;
long o_long(const char *name, long def = 0L) const;
bool o_bool(const char *name, bool def = false) const;
std::string o_str(const char *name, const char *def = NULL) const;
int o_colour(const char *name, int def = LIGHTGREY) const;
void fixup_options();
private:
std::string unalias(const std::string &key) const;
std::string expand_vars(const std::string &field) const;
void add_alias(const std::string &alias, const std::string &name);
void clear_feature_overrides();
void clear_cset_overrides();
void add_cset_override(char_set_type set, const std::string &overrides);
void add_cset_override(char_set_type set, dungeon_char_type dc,
unsigned symbol);
void add_feature_override(const std::string &);
void add_message_colour_mappings(const std::string &);
void add_message_colour_mapping(const std::string &);
message_filter parse_message_filter(const std::string &s);
void set_default_activity_interrupts();
void clear_activity_interrupts(FixedVector<bool, NUM_AINTERRUPTS> &eints);
void set_activity_interrupt(
FixedVector<bool, NUM_AINTERRUPTS> &eints,
const std::string &interrupt);
void set_activity_interrupt(const std::string &activity_name,
const std::string &interrupt_names,
bool append_interrupts,
bool remove_interrupts);
void set_fire_order(const std::string &full, bool add);
void add_fire_order_slot(const std::string &s);
void set_menu_sort(std::string field);
void new_dump_fields(const std::string &text, bool add = true);
void do_kill_map(const std::string &from, const std::string &to);
int read_explore_stop_conditions(const std::string &) const;
void split_parse(const std::string &s, const std::string &separator,
void (game_options::*add)(const std::string &));
void add_mon_glyph_override(monster_type mtype, mon_display &mdisp);
void add_mon_glyph_overrides(const std::string &mons, mon_display &mdisp);
void add_mon_glyph_override(const std::string &);
mon_display parse_mon_glyph(const std::string &s) const;
void set_option_fragment(const std::string &s);
static const std::string interrupt_prefix;
};
extern game_options Options;
#include "msvc.h"
#endif