/* * File: dungeon.h * Summary: Functions used when building new levels. * Written by: Linley Henzell */ #ifndef DUNGEON_H #define DUNGEON_H #include "fixedarray.h" #include "externs.h" #include "terrain.h" #include "stuff.h" #include "mapdef.h" #include #include #include class map_mask; #define BUILD_METHOD_KEY "build_method_key" #define LAYOUT_TYPE_KEY "layout_type_key" #define LEVEL_VAULTS_KEY "level_vaults_key" #define TEMP_VAULTS_KEY "temp_vaults_key" #define LEVEL_EXTRAS_KEY "level_extras_key" #define LEVEL_ID_KEY "level_id_key" #define YOU_PORTAL_VAULT_NAMES_KEY "you_portal_vault_names_key" // See _build_overflow_temples() in dungeon.cc for details on overflow // temples. #define TEMPLE_GODS_KEY "temple_gods_key" #define OVERFLOW_TEMPLES_KEY "overflow_temples_key" #define TEMPLE_MAP_KEY "temple_map_key" enum portal_type { PORTAL_NONE = 0, PORTAL_LABYRINTH, PORTAL_HELL, PORTAL_ABYSS, PORTAL_PANDEMONIUM, NUM_PORTALS }; const int MAKE_GOOD_ITEM = 351; // Should be the larger of GXM/GYM #define MAP_SIDE ( (GXM) > (GYM) ? (GXM) : (GYM) ) // Map mask constants. enum map_mask_type { MMT_NONE = 0x0, MMT_VAULT = 0x01, // This is a square in a vault. MMT_NO_ITEM = 0x02, // Random items should not be placed here. MMT_NO_MONS = 0x04, // Random monsters should not be placed here. MMT_NO_POOL = 0x08, // Pool fixup should not be applied here. MMT_NO_DOOR = 0x10, // No secret-doorisation. MMT_NO_WALL = 0x20, // Wall fixup should not be applied here. MMT_OPAQUE = 0x40 // Vault may impede connectivity. }; class dgn_region; typedef std::vector dgn_region_list; class dgn_region { public: // pos is top-left corner. coord_def pos, size; dgn_region(int left, int top, int width, int height) : pos(left, top), size(width, height) { } dgn_region(const coord_def &_pos, const coord_def &_size) : pos(_pos), size(_size) { } dgn_region() : pos(-1, -1), size() { } coord_def end() const { return pos + size - coord_def(1, 1); } coord_def random_edge_point() const; coord_def random_point() const; static dgn_region absolute(int left, int top, int right, int bottom) { return dgn_region(left, top, right - left + 1, bottom - top + 1); } static dgn_region absolute(const coord_def &c1, const coord_def &c2) { return dgn_region(c1.x, c1.y, c2.x, c2.y); } static bool between(int val, int low, int high) { return (val >= low && val <= high); } bool contains(const coord_def &p) const { return contains(p.x, p.y); } bool contains(int xp, int yp) const { return (xp >= pos.x && xp < pos.x + size.x && yp >= pos.y && yp < pos.y + size.y); } bool fully_contains(const coord_def &p) const { return (p.x > pos.x && p.x < pos.x + size.x - 1 && p.y > pos.y && p.y < pos.y + size.y - 1); } bool overlaps(const dgn_region &other) const; bool overlaps_any(const dgn_region_list &others) const; bool overlaps(const dgn_region_list &others, const map_mask &dgn_map_mask) const; bool overlaps(const map_mask &dgn_map_mask) const; }; struct vault_placement { public: coord_def pos; coord_def size; int orient; map_def map; std::vector exits; int level_number, num_runes; // If we're not placing runes, this is the substitute feature. int rune_subst; public: vault_placement() : pos(-1, -1), size(0, 0), orient(0), map(), exits(), level_number(0), num_runes(0), rune_subst(-1) { } void reset(); void apply_grid(); void draw_at(const coord_def &c); }; extern bool Generating_Level; extern std::string dgn_Layout_Type; extern std::string dgn_Build_Method; extern std::set Level_Unique_Maps; extern std::set Level_Unique_Tags; extern std::vector Level_Vaults; extern std::vector Temp_Vaults; void init_level_connectivity(); void read_level_connectivity(reader &th); void write_level_connectivity(writer &th); bool builder(int level_number, int level_type); void dgn_veto_level(); void dgn_flush_map_memory(); double dgn_degrees_to_radians(int degrees); bool dgn_has_adjacent_feat(coord_def c, dungeon_feature_type feat); coord_def dgn_random_point_in_margin(int margin); coord_def dgn_random_point_in_bounds( dungeon_feature_type searchfeat, unsigned mapmask = MMT_VAULT, dungeon_feature_type adjacent = DNGN_UNSEEN, bool monster_free = false, int tries = 1500); coord_def dgn_random_point_from(const coord_def &c, int radius, int margin = 1); coord_def dgn_random_point_visible_from(const coord_def &c, int radius, int margin = 1, int tries = 5); coord_def dgn_find_feature_marker(dungeon_feature_type feat); // Generate 3 stone stairs in both directions. void dgn_place_stone_stairs(); // Set floor/wall colour based on the mons_alloc array. Used for // Abyss and Pan. void dgn_set_colours_from_monsters(); void dgn_set_grid_colour_at(const coord_def &c, int colour); bool dgn_place_map(const map_def *map, bool clobber, bool make_no_exits, const coord_def &pos = coord_def(-1, -1), int rune_subst = -1); void level_clear_vault_memory(); void level_welcome_messages(); bool place_specific_trap(const coord_def& where, trap_type spec_type); void place_spec_shop(int level_number, const coord_def& where, int force_s_type, bool representative = false); bool seen_replace_feat(dungeon_feature_type replace, dungeon_feature_type feature); bool unforbidden(const coord_def &c, unsigned mask); coord_def dgn_find_nearby_stair(dungeon_feature_type stair_to_find, coord_def base_pos, bool find_closest); class mons_spec; int dgn_place_monster(mons_spec &mspec, int monster_level, const coord_def& where, bool force_pos = false, bool generate_awake = false, bool patrolling = false); dungeon_feature_type dgn_tree_base_feature_at(coord_def c); class item_list; void dgn_place_multiple_items(item_list &list, const coord_def& where, int level); bool set_level_flags(unsigned long flags, bool silent = false); bool unset_level_flags(unsigned long flags, bool silent = false); void dgn_set_lt_callback(std::string level_type_name, std::string callback_name); void dgn_reset_level(); // Returns true if the given square is okay for use by any character, // but always false for squares in non-transparent vaults. This // function returns sane results only immediately after dungeon generation // (specifically, saving and restoring a game discards information on the // vaults used in the current level). bool dgn_square_is_passable(const coord_def &c); void dgn_register_place(const vault_placement &place, bool register_vault); void dgn_register_vault(const map_def &map); struct spec_room { bool created; bool hooked_up; coord_def tl; coord_def br; spec_room() : created(false), hooked_up(false), tl(), br() { } coord_def random_spot() const; }; bool join_the_dots(const coord_def &from, const coord_def &to, unsigned mmask, bool early_exit = false); void spotty_level(bool seeded, int iterations, bool boxy); void smear_feature(int iterations, bool boxy, dungeon_feature_type feature, int x1, int y1, int x2, int y2); int process_disconnected_zones(int x1, int y1, int x2, int y2, bool choose_stairless, dungeon_feature_type fill); bool octa_room(spec_room &sr, int oblique_max, dungeon_feature_type type_floor); int count_feature_in_box(int x0, int y0, int x1, int y1, dungeon_feature_type feat); void dgn_replace_area(const coord_def& p1, const coord_def& p2, dungeon_feature_type replace, dungeon_feature_type feature, unsigned mmask = 0, bool needs_update = false); void dgn_replace_area(int sx, int sy, int ex, int ey, dungeon_feature_type replace, dungeon_feature_type feature, unsigned mmask = 0, bool needs_update = false); void dgn_excavate(coord_def dig_at, coord_def dig_dir); void dgn_dig_vault_loose(vault_placement &vp); coord_def dgn_random_direction(); bool dgn_ensure_vault_placed(bool vault_success, bool disable_further_vaults); inline int count_feature_in_box( const coord_def& p1, const coord_def& p2, dungeon_feature_type feat ) { return count_feature_in_box(p1.x, p1.y, p2.x, p2.y, feat); } int count_antifeature_in_box(int x0, int y0, int x1, int y1, dungeon_feature_type feat); int count_neighbours(int x, int y, dungeon_feature_type feat); inline int count_neighbours(const coord_def& p, dungeon_feature_type feat) { return count_neighbours(p.x, p.y, feat); } void remember_vault_placement(std::string key, vault_placement &place); std::string dump_vault_maps(); bool dgn_square_travel_ok(const coord_def &c); typedef std::set dungeon_feature_set; extern dungeon_feature_set dgn_Vault_Excavatable_Feats; #endif