summaryrefslogblamecommitdiffstats
path: root/crawl-ref/source/dungeon.h
blob: 165515de3fb9ba3ab513a2aaa91e8090f6dc98ae (plain) (tree)
1
2
3
4
5
6
7
8
9
10
  
                         

                                                        





                 
                       
                    
                    
                  

                   
                 
              
                    
 

               






                                           

                                                                





                                                                      









                       
                               
 
                                  
                                                  
 








                                                                           
                                                       

                                                                       
  
 


                                                
                
 
        







                                                        




                                                             









                                            
                                   





                                                                         




                                                                        






                                                   






                                                       
     
 


                                                       
                                                            
     
 

                                                           


                                                      

  









                                 
                                






                                                                  
                                                                







                                     

                                   
                                    






                                                 


                                          

                                               
                      
 

                            
                                           
                                                                   
                                                 





                                                




                                                                                

                                                             


                                              


                                                                
                                                            
 
                                                                        

                                                            
 

                                
 

                                                                      
                                                                    

                                                     
                                                    
                                                                   
                                                                       
 
                



                                                                          
 

                                                           




                                                     


                                                                 


                                                     

                       






                                                                          
                                                                           
                                            
 



                   
 

                 
 
                                                              

     

                                  






                                                                           


                                                              




                                                        









                                                                     
                                                       
                                              

                                 


                                                          




                                                                          


                                                              



                                                                          
 
                                                                       

                              


                                              


                                                           
      
/*
 *  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 <vector>
#include <set>
#include <algorithm>

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> 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<coord_def> 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<std::string> Level_Unique_Maps;
extern std::set<std::string> Level_Unique_Tags;

extern std::vector<vault_placement> Level_Vaults;
extern std::vector<vault_placement> 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_type> dungeon_feature_set;
extern dungeon_feature_set dgn_Vault_Excavatable_Feats;

#endif