summaryrefslogblamecommitdiffstats
path: root/crawl-ref/source/map_knowledge.cc
blob: 8990ef2c10ca35fa2e2f29bedde036bbee4d3d8f (plain) (tree)
1
2
3
4
5
6
7
8
9
10

                   
                          
 



                     

                     
                  
                    
                    
                 
                     







                                                                   
                                                                       



                                    



                                






                                                                           

 




                                           




                                     









                                                
                                             
 
                                           

 
                                             
 
                                            

 
                                                                 

                 
     
                                                           

                                                                             
        
                                                            

 
                                                 
 
                                                               

 
                                                                 

                 
     
                                                              

                                                                                
        
                                                               

 
                                                 
 
                                                                  

 
                                                                 
 
                                          




                                           
                                        
 
                                                           

 
                                        
 
                                                              

 
                                             
 
                                                       



                                     
                                             



                                         
                                          



                                    
                                                           



                                       
                                                              



                                          
                                                                




                                                                          
                                                      





                                                                         



                                                                   
















                                                              
                                                










                                                                       
                                 
                     
                                     
                     
                                                                       
                     
                                                                          


                     
                                                                       


                     

                                                                 

                                                  

               
                                                         

                                 

                            
                                                               


























                                                             
                                                              





                                                
                                              

                                               
                                       





























                                                                           

                                           

      


                                                                    

 
                                                   
 
                                 

 
                                             
 
                                    
 
#include "AppHdr.h"

#include "map_knowledge.h"

#include "coordit.h"
#include "dgnevent.h"
#include "directn.h"
#include "env.h"
#include "feature.h"
#include "mon-util.h"
#include "notes.h"
#include "options.h"
#include "overmap.h"
#include "show.h"
#include "showsymb.h"
#include "stuff.h"
#include "terrain.h"
#include "view.h"

// These are hidden from the rest of the world... use the functions
// below to get information about the map grid.
#define MAP_MAGIC_MAPPED_FLAG   0x01
#define MAP_SEEN_FLAG           0x02
#define MAP_CHANGED_FLAG        0x04 // FIXME: this doesn't belong here
#define MAP_DETECTED_MONSTER    0x08
#define MAP_DETECTED_ITEM       0x10
#define MAP_GRID_KNOWN          0xFF

unsigned map_cell::glyph() const
{
    if (!object)
        return (' ');
    if (object.cls < SH_MONSTER)
    {
        const feature_def &fdef = get_feature_def(object);
        return ((flags & MAP_SEEN_FLAG) ? fdef.symbol : fdef.magic_symbol);
    }
    else
        return (mons_char(object.mons));
}

dungeon_feature_type map_cell::feat() const
{
    return (object.feat);
}

show_item_type map_cell::item() const
{
    return (object.item);
}

bool map_cell::known() const
{
    return (object && (flags & MAP_GRID_KNOWN));
}

bool map_cell::seen() const
{
    return (object && (flags & MAP_SEEN_FLAG));
}

unsigned get_map_knowledge_char(int x, int y)
{
    return env.map_knowledge[x][y].glyph();
}

show_type get_map_knowledge_obj(int x, int y)
{
    return (env.map_knowledge[x][y].object);
}

void set_map_knowledge_detected_item(int x, int y, bool detected)
{
    if (detected)
    {
        env.map_knowledge[x][y].flags |= MAP_DETECTED_ITEM;
        env.map_knowledge[x][y].object.colour = Options.detected_item_colour;
    }
    else
        env.map_knowledge[x][y].flags &= ~MAP_DETECTED_ITEM;
}

bool is_map_knowledge_detected_item(int x, int y)
{
    return (env.map_knowledge[x][y].flags & MAP_DETECTED_ITEM);
}

void set_map_knowledge_detected_mons(int x, int y, bool detected)
{
    if (detected)
    {
        env.map_knowledge[x][y].flags |= MAP_DETECTED_MONSTER;
        env.map_knowledge[x][y].object.colour = Options.detected_monster_colour;
    }
    else
        env.map_knowledge[x][y].flags &= ~MAP_DETECTED_MONSTER;
}

bool is_map_knowledge_detected_mons(int x, int y)
{
    return (env.map_knowledge[x][y].flags & MAP_DETECTED_MONSTER);
}

void set_map_knowledge_obj(const coord_def& where, show_type obj)
{
    env.map_knowledge(where).object = obj;
#ifdef USE_TILE
    tiles.update_minimap(where.x, where.y);
#endif
}

bool is_map_knowledge_item(int x, int y)
{
    return (env.map_knowledge[x][y].object.cls == SH_ITEM);
}

bool is_map_knowledge_mons(int x, int y)
{
    return (env.map_knowledge[x][y].object.cls == SH_MONSTER);
}

int get_map_knowledge_col(const coord_def& p)
{
    return (env.map_knowledge[p.x][p.y].object.colour);
}

bool is_terrain_known( int x, int y )
{
    return (env.map_knowledge[x][y].known());
}

bool is_terrain_known(const coord_def &p)
{
    return (env.map_knowledge(p).known());
}

bool is_terrain_seen( int x, int y )
{
    return (env.map_knowledge[x][y].flags & MAP_SEEN_FLAG);
}

bool is_terrain_changed( int x, int y )
{
    return (env.map_knowledge[x][y].flags & MAP_CHANGED_FLAG);
}

bool is_terrain_mapped(const coord_def &p)
{
    return (env.map_knowledge(p).flags & MAP_MAGIC_MAPPED_FLAG);
}

// Used to mark dug out areas, unset when terrain is seen or mapped again.
void set_terrain_changed( int x, int y )
{
    env.map_knowledge[x][y].flags |= MAP_CHANGED_FLAG;

    dungeon_events.fire_position_event(DET_FEAT_CHANGE, coord_def(x, y));
}

void set_terrain_mapped( int x, int y )
{
    map_cell* cell = &env.map_knowledge[x][y];
    cell->flags &= (~MAP_CHANGED_FLAG);
    cell->flags |= MAP_MAGIC_MAPPED_FLAG;
    cell->object.colour = get_feature_def(cell->object).map_colour;
#ifdef USE_TILE
    tiles.update_minimap(x, y);
#endif
}

int count_detected_mons()
{
    int count = 0;
    for (rectangle_iterator ri(BOUNDARY_BORDER - 1); ri; ++ri)
    {
        // Don't expose new dug out areas:
        // Note: assumptions are being made here about how
        // terrain can change (eg it used to be solid, and
        // thus monster/item free).
        if (is_terrain_changed(*ri))
            continue;

        if (is_map_knowledge_detected_mons(*ri))
            count++;
    }

    return (count);
}

void clear_map(bool clear_detected_items, bool clear_detected_monsters)
{
    for (rectangle_iterator ri(BOUNDARY_BORDER - 1); ri; ++ri)
    {
        const coord_def p = *ri;
        if (!is_terrain_known(p))
            continue;
        if (is_map_knowledge_item(p))
            continue;
        if (!clear_detected_items && is_map_knowledge_detected_item(p))
            continue;
        if (!clear_detected_monsters && is_map_knowledge_detected_mons(p))
            continue;

#ifdef USE_TILE
        if (is_terrain_mapped(p) && !is_map_knowledge_detected_mons(p))
            continue;
#endif

        show_type plain = show_type(env.map_knowledge(p).feat());
        set_map_knowledge_obj(p, to_knowledge(plain));
        set_map_knowledge_detected_mons(p, false);
        set_map_knowledge_detected_item(p, false);

#ifdef USE_TILE
        // FIXME: shouldn't be referencing env.grid here.
        if (is_terrain_mapped(p))
        {
            unsigned int fg;
            unsigned int bg;
            tileidx_unseen(fg, bg, get_feat_symbol(grd(p)), p);
            env.tile_bk_bg(p) = bg;
            env.tile_bk_fg(p) = fg;
        }
        else
        {
            env.tile_bk_bg(p) = is_terrain_seen(p) ?
                tile_idx_unseen_terrain(p.x, p.y, grd(p)) :
                tileidx_feature(DNGN_UNSEEN, p.x, p.y);
            env.tile_bk_fg(p) = 0;
        }
#endif
    }
}

static void _automap_from( int x, int y, int mutated )
{
    if (mutated)
        magic_mapping(8 * mutated, 25, true, false,
                      true, true, coord_def(x,y));
}

void reautomap_level( )
{
    int passive = player_mutation_level(MUT_PASSIVE_MAPPING);

    for (int x = X_BOUND_1; x <= X_BOUND_2; ++x)
        for (int y = Y_BOUND_1; y <= Y_BOUND_2; ++y)
            if (env.map_knowledge[x][y].flags & MAP_SEEN_FLAG)
                _automap_from(x, y, passive);
}

void set_terrain_seen( int x, int y )
{
    const dungeon_feature_type feat = grd[x][y];
    map_cell* cell = &env.map_knowledge[x][y];

    // First time we've seen a notable feature.
    if (!(cell->flags & MAP_SEEN_FLAG))
    {
        _automap_from(x, y, player_mutation_level(MUT_PASSIVE_MAPPING));

        const bool boring = !is_notable_terrain(feat)
            // A portal deeper into the Zigguart is boring.
            || (feat == DNGN_ENTER_PORTAL_VAULT
                && you.level_type == LEVEL_PORTAL_VAULT)
            // Altars in the temple are boring.
            || (feat_is_altar(feat)
                && player_in_branch(BRANCH_ECUMENICAL_TEMPLE))
            // Only note the first entrance to the Abyss/Pan/Hell
            // which is found.
            || ((feat == DNGN_ENTER_ABYSS || feat == DNGN_ENTER_PANDEMONIUM
                 || feat == DNGN_ENTER_HELL)
                && overmap_knows_num_portals(feat) > 1)
            // There are at least three Zot entrances, and they're always
            // on D:27, so ignore them.
            || feat == DNGN_ENTER_ZOT;

        if (!boring)
        {
            coord_def pos(x, y);
            std::string desc =
                feature_description(pos, false, DESC_NOCAP_A);

            take_note(Note(NOTE_SEEN_FEAT, 0, 0, desc.c_str()));
        }
    }

#ifdef USE_TILE
    cell->flags &= ~(MAP_DETECTED_ITEM);
    cell->flags &= ~(MAP_DETECTED_MONSTER);
#endif

    cell->flags &= (~MAP_CHANGED_FLAG);
    cell->flags |= MAP_SEEN_FLAG;
    cell->object.colour = get_feature_def(cell->object).seen_colour;
}

void clear_map_knowledge_grid( const coord_def& p )
{
    env.map_knowledge(p).clear();
}

void clear_map_knowledge_grid( int x, int y )
{
    env.map_knowledge[x][y].clear();
}