summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/view.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/view.cc')
-rw-r--r--crawl-ref/source/view.cc403
1 files changed, 60 insertions, 343 deletions
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 057591bbba..87e18225a7 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -88,26 +88,20 @@
#define MC_MONS 0x02
crawl_view_geometry crawl_view;
-FixedArray < unsigned int, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER > Show_Backup;
extern int stealth; // defined in acr.cc
screen_buffer_t colour_code_map( const coord_def& p, bool item_colour = false,
bool travel_colour = false, bool on_level = true );
-void cloud_grid(void);
-void monster_grid(bool do_updates);
-
static void _get_symbol( const coord_def& where,
- int object, unsigned *ch,
+ show_type object, unsigned *ch,
unsigned short *colour,
bool magic_mapped = false );
-static unsigned _get_symbol(int object, unsigned short *colour = NULL,
+static unsigned _get_symbol(show_type object, unsigned short *colour = NULL,
bool magic_mapped = false);
-static int _get_item_dngn_code(const item_def &item);
-static void _set_show_backup( int ex, int ey );
-static int _get_viewobj_flags(int viewobj);
+static int _get_viewobj_flags(show_type viewobj);
unsigned map_cell::glyph() const
{
@@ -141,7 +135,7 @@ unsigned get_envmap_char(int x, int y)
return env.map[x][y].glyph();
}
-int get_envmap_obj(int x, int y)
+show_type get_envmap_obj(int x, int y)
{
return (env.map[x][y].object);
}
@@ -172,7 +166,7 @@ bool is_envmap_detected_mons(int x, int y)
return (env.map[x][y].flags & MAP_DETECTED_MONSTER);
}
-void set_envmap_glyph(int x, int y, int object, int col)
+void set_envmap_glyph(int x, int y, show_type object, int col)
{
map_cell &c = env.map[x][y];
c.object = object;
@@ -182,12 +176,12 @@ void set_envmap_glyph(int x, int y, int object, int col)
#endif
}
-void set_envmap_glyph(const coord_def& c, int object, int col)
+void set_envmap_glyph(const coord_def& c, show_type object, int col)
{
set_envmap_glyph(c.x, c.y, object, col);
}
-void set_envmap_obj( const coord_def& where, int obj )
+void set_envmap_obj(const coord_def& where, show_type obj)
{
env.map(where).object = obj;
#ifdef USE_TILE
@@ -398,14 +392,14 @@ unsigned real_colour(unsigned raw_colour)
return (raw_colour);
}
-static int _get_viewobj_flags(int object)
+static int _get_viewobj_flags(show_type object)
{
// Check for monster glyphs.
- if (object >= DNGN_START_OF_MONSTERS)
+ if (object.cls == SH_MONSTER)
return (MC_MONS);
// Check for item glyphs.
- if (object >= DNGN_ITEM_ORB && object < DNGN_CLOUD)
+ if (object.cls == SH_ITEM)
return (MC_ITEM);
// We don't care to look further; we could check for
@@ -413,7 +407,7 @@ static int _get_viewobj_flags(int object)
return (0);
}
-static unsigned _get_symbol(int object, unsigned short *colour,
+static unsigned _get_symbol(show_type object, unsigned short *colour,
bool magic_mapped)
{
unsigned ch;
@@ -450,24 +444,23 @@ static unsigned short _tree_colour(const coord_def& where)
}
static void _get_symbol( const coord_def& where,
- int object, unsigned *ch,
+ show_type object, unsigned *ch,
unsigned short *colour,
bool magic_mapped )
{
ASSERT( ch != NULL );
- if (object < NUM_FEATURES)
+ if (object.cls < SH_MONSTER)
{
- const dungeon_feature_type feat =
- static_cast<dungeon_feature_type>(object);
- const feature_def &fdef = get_feature_def(feat);
+ const feature_def &fdef = get_feature_def(object);
*ch = magic_mapped? fdef.magic_symbol
: fdef.symbol;
// Don't recolor items
- if (colour && object < NUM_REAL_FEATURES)
+ if (colour && object.cls == SH_FEATURE)
{
+ dungeon_feature_type feat = object.feat;
const int colmask = *colour & COLFLAG_MASK;
// TODO: consolidate with feat_is_stair etc.
@@ -553,13 +546,14 @@ static void _get_symbol( const coord_def& where,
// Note anything we see that's notable
if (!where.origin() && fdef.is_notable())
{
- seen_notable_thing(feat, where);
+ if (object.cls == SH_FEATURE) // other notable things?
+ seen_notable_thing(object.feat, where);
}
}
else
{
- ASSERT(object >= DNGN_START_OF_MONSTERS);
- *ch = mons_char(object - DNGN_START_OF_MONSTERS);
+ ASSERT(object.cls == SH_MONSTER);
+ *ch = mons_char(object.mons);
}
if (colour)
@@ -575,41 +569,19 @@ unsigned grid_character_at(const coord_def &c)
return glych;
}
-void get_item_symbol(unsigned int object, unsigned *ch,
- unsigned short *colour)
-{
- if (object < NUM_FEATURES)
- {
- dungeon_feature_type feat = static_cast<dungeon_feature_type>(object);
- *ch = get_feature_def(feat).symbol;
-
- // Don't clobber with BLACK, because the colour should be already set.
- if (get_feature_def(feat).colour != BLACK)
- *colour = get_feature_def(feat).colour;
- }
- *colour = real_colour(*colour);
-
-}
-
-dungeon_char_type get_feature_dchar( dungeon_feature_type feat )
+dungeon_char_type get_feature_dchar(dungeon_feature_type feat)
{
return (get_feature_def(feat).dchar);
}
-unsigned get_sightmap_char(dungeon_feature_type feature)
+unsigned get_sightmap_char(dungeon_feature_type feat)
{
- if (feature < NUM_FEATURES)
- return (get_feature_def(feature).symbol);
-
- return (0);
+ return (get_feature_def(feat).symbol);
}
-unsigned get_magicmap_char(dungeon_feature_type feature)
+unsigned get_magicmap_char(dungeon_feature_type feat)
{
- if (feature < NUM_FEATURES)
- return (get_feature_def(feature).magic_symbol);
-
- return (0);
+ return (get_feature_def(feat).magic_symbol);
}
static char _get_travel_colour( const coord_def& p )
@@ -721,9 +693,9 @@ screen_buffer_t colour_code_map(const coord_def& p, bool item_colour,
dungeon_feature_type feat_value = grd(p);
if (!see_cell(p))
{
- const int remembered = get_envmap_obj(p);
- if (remembered < NUM_REAL_FEATURES)
- feat_value = static_cast<dungeon_feature_type>(remembered);
+ const show_type remembered = get_envmap_obj(p);
+ if (remembered.cls == SH_FEATURE)
+ feat_value = remembered.feat;
}
unsigned tc = travel_colour ? _get_travel_colour(p) : DARKGREY;
@@ -770,7 +742,7 @@ screen_buffer_t colour_code_map(const coord_def& p, bool item_colour,
const int olddist = grid_distance(you.pos(), mon.pos());
const int newdist = grid_distance(p, mon.pos());
- if (olddist < newdist || !see_cell(env.show, p, mon.pos()))
+ if (olddist < newdist || !see_cell(env.show_los, p, mon.pos()))
{
blocked_movement = true;
break;
@@ -847,19 +819,19 @@ void clear_map(bool clear_detected_items, bool clear_detected_monsters)
continue;
#endif
- set_envmap_obj(p, is_terrain_seen(p) || is_terrain_mapped(p)
- ? grd(p) : DNGN_UNSEEN);
+ set_envmap_obj(p, show_type(is_terrain_seen(p) || is_terrain_mapped(p)
+ ? grd(p) : DNGN_UNSEEN));
set_envmap_detected_mons(p, false);
set_envmap_detected_item(p, false);
#ifdef USE_TILE
if (is_terrain_mapped(p))
{
- unsigned int feature = grd(p);
+ dungeon_feature_type feature = grd(p);
unsigned int feat_symbol;
unsigned short feat_colour;
- get_item_symbol(feature, &feat_symbol, &feat_colour);
+ get_show_symbol(show_type(feature), &feat_symbol, &feat_colour);
unsigned int fg;
unsigned int bg;
@@ -1329,58 +1301,6 @@ void force_monster_shout(monsters* monster)
}
#endif
-inline static bool _update_monster_grid(const monsters *monster)
-{
- const coord_def e = grid2show(monster->pos());
-
- if (!monster->visible_to(&you))
- {
- // ripple effect?
- if (grd(monster->pos()) == DNGN_SHALLOW_WATER
- && !mons_flies(monster)
- && env.cgrid(monster->pos()) == EMPTY_CLOUD)
- {
- _set_show_backup(e.x, e.y);
- env.show(e) = DNGN_INVIS_EXPOSED;
-
- // Translates between colours used for shallow and deep water,
- // if not using the normal LIGHTCYAN / BLUE. The ripple uses
- // the deep water colour.
- unsigned short base_colour = env.grid_colours(monster->pos());
-
- static const unsigned short ripple_table[] =
- {BLUE, // BLACK => BLUE (default)
- BLUE, // BLUE => BLUE
- GREEN, // GREEN => GREEN
- CYAN, // CYAN => CYAN
- RED, // RED => RED
- MAGENTA, // MAGENTA => MAGENTA
- BROWN, // BROWN => BROWN
- DARKGREY, // LIGHTGREY => DARKGREY
- DARKGREY, // DARKGREY => DARKGREY
- BLUE, // LIGHTBLUE => BLUE
- GREEN, // LIGHTGREEN => GREEN
- BLUE, // LIGHTCYAN => BLUE
- RED, // LIGHTRED => RED
- MAGENTA, // LIGHTMAGENTA => MAGENTA
- BROWN, // YELLOW => BROWN
- LIGHTGREY}; // WHITE => LIGHTGREY
-
- env.show_col(e) = ripple_table[base_colour & 0x0f];
- }
- return (false);
- }
-
- // Mimics are always left on map.
- if (!mons_is_mimic( monster->type ))
- _set_show_backup(e.x, e.y);
-
- env.show(e) = monster->type + DNGN_START_OF_MONSTERS;
- env.show_col(e) = get_mons_colour( monster );
-
- return (true);
-}
-
void monster_grid(bool do_updates)
{
do_updates = do_updates && !crawl_state.arena;
@@ -1415,7 +1335,7 @@ void monster_grid(bool do_updates)
mgrd(monster->pos()) = s;
}
- if (!_update_monster_grid(monster))
+ if (!env.show.update_monster(monster))
continue;
#ifdef USE_TILE
@@ -1558,197 +1478,18 @@ bool check_awaken(monsters* monster)
return (false);
}
-static void _set_show_backup( int ex, int ey )
-{
- // Must avoid double setting it.
- // We want the base terrain/item, not the cloud or monster that replaced it.
- if (!Show_Backup[ex][ey])
- Show_Backup[ex][ey] = env.show[ex][ey];
-}
-
-static int _get_item_dngn_code(const item_def &item)
-{
- switch (item.base_type)
- {
- case OBJ_ORBS: return (DNGN_ITEM_ORB);
- case OBJ_WEAPONS: return (DNGN_ITEM_WEAPON);
- case OBJ_MISSILES: return (DNGN_ITEM_MISSILE);
- case OBJ_ARMOUR: return (DNGN_ITEM_ARMOUR);
- case OBJ_WANDS: return (DNGN_ITEM_WAND);
- case OBJ_FOOD: return (DNGN_ITEM_FOOD);
- case OBJ_SCROLLS: return (DNGN_ITEM_SCROLL);
- case OBJ_JEWELLERY:
- return (jewellery_is_amulet(item)? DNGN_ITEM_AMULET : DNGN_ITEM_RING);
- case OBJ_POTIONS: return (DNGN_ITEM_POTION);
- case OBJ_BOOKS: return (DNGN_ITEM_BOOK);
- case OBJ_STAVES: return (DNGN_ITEM_STAVE);
- case OBJ_MISCELLANY: return (DNGN_ITEM_MISCELLANY);
- case OBJ_CORPSES: return (DNGN_ITEM_CORPSE);
- case OBJ_GOLD: return (DNGN_ITEM_GOLD);
- default: return (DNGN_ITEM_ORB); // bad item character
- }
-}
-
-inline static void _update_item_grid(const coord_def &gp, const coord_def &ep)
-{
- const item_def &eitem = mitm[igrd(gp)];
- unsigned short &ecol = env.show_col(ep);
-
- const dungeon_feature_type feat = grd(gp);
- if (Options.feature_item_brand && is_critical_feature(feat))
- ecol |= COLFLAG_FEATURE_ITEM;
- else if (Options.trap_item_brand && feat_is_trap(feat))
- ecol |= COLFLAG_TRAP_ITEM;
- else
- {
- const unsigned short gcol = env.grid_colours(gp);
- ecol = (feat == DNGN_SHALLOW_WATER) ?
- (gcol != BLACK ? gcol : CYAN) : eitem.colour;
- if (eitem.link != NON_ITEM && !crawl_state.arena)
- ecol |= COLFLAG_ITEM_HEAP;
- env.show(ep) = _get_item_dngn_code( eitem );
- }
-
-#ifdef USE_TILE
- int idx = igrd(gp);
- if (feat_is_stair(feat))
- tile_place_item_marker(ep.x, ep.y, idx);
- else
- tile_place_item(ep.x, ep.y, idx);
-#endif
-}
-
-void item_grid()
-{
- const coord_def c(crawl_view.glosc());
- const coord_def offset(ENV_SHOW_OFFSET, ENV_SHOW_OFFSET);
- for (radius_iterator ri(c, LOS_RADIUS, true, false); ri; ++ri)
- {
- if (igrd(*ri) != NON_ITEM)
- {
- const coord_def ep = *ri - c + offset;
- if (env.show(ep))
- _update_item_grid(*ri, ep);
- }
- }
-}
-
-void get_item_glyph( const item_def *item, unsigned *glych,
- unsigned short *glycol )
+void get_item_glyph(const item_def *item, unsigned *glych,
+ unsigned short *glycol)
{
*glycol = item->colour;
- _get_symbol( coord_def(0,0), _get_item_dngn_code( *item ), glych, glycol );
-}
-
-void get_mons_glyph( const monsters *mons, unsigned *glych,
- unsigned short *glycol )
-{
- *glycol = get_mons_colour( mons );
- _get_symbol( coord_def(0,0), mons->type + DNGN_START_OF_MONSTERS,
- glych, glycol );
-}
-
-inline static void _update_cloud_grid(int cloudno)
-{
- int which_colour = LIGHTGREY;
- const coord_def e = grid2show(env.cloud[cloudno].pos);
-
- switch (env.cloud[cloudno].type)
- {
- case CLOUD_FIRE:
- case CLOUD_FOREST_FIRE:
- if (env.cloud[cloudno].decay <= 20)
- which_colour = RED;
- else if (env.cloud[cloudno].decay <= 40)
- which_colour = LIGHTRED;
- else if (one_chance_in(4))
- which_colour = RED;
- else if (one_chance_in(4))
- which_colour = LIGHTRED;
- else
- which_colour = YELLOW;
- break;
-
- case CLOUD_STINK:
- which_colour = GREEN;
- break;
-
- case CLOUD_COLD:
- if (env.cloud[cloudno].decay <= 20)
- which_colour = BLUE;
- else if (env.cloud[cloudno].decay <= 40)
- which_colour = LIGHTBLUE;
- else if (one_chance_in(4))
- which_colour = BLUE;
- else if (one_chance_in(4))
- which_colour = LIGHTBLUE;
- else
- which_colour = WHITE;
- break;
-
- case CLOUD_POISON:
- which_colour = (one_chance_in(3) ? LIGHTGREEN : GREEN);
- break;
-
- case CLOUD_BLUE_SMOKE:
- which_colour = LIGHTBLUE;
- break;
-
- case CLOUD_PURP_SMOKE:
- which_colour = MAGENTA;
- break;
-
- case CLOUD_MIASMA:
- case CLOUD_BLACK_SMOKE:
- which_colour = DARKGREY;
- break;
-
- case CLOUD_RAIN:
- case CLOUD_MIST:
- which_colour = ETC_MIST;
- break;
-
- case CLOUD_CHAOS:
- which_colour = ETC_RANDOM;
- break;
-
- case CLOUD_MUTAGENIC:
- which_colour = ETC_MUTAGENIC;
- break;
-
- default:
- which_colour = LIGHTGREY;
- break;
- }
-
- _set_show_backup(e.x, e.y);
- env.show(e) = DNGN_CLOUD;
- env.show_col(e) = which_colour;
-
-#ifdef USE_TILE
- tile_place_cloud(e.x, e.y, env.cloud[cloudno].type,
- env.cloud[cloudno].decay);
-#endif
+ _get_symbol(coord_def(0,0), show_type(*item), glych, glycol);
}
-void cloud_grid(void)
+void get_mons_glyph(const monsters *mons, unsigned *glych,
+ unsigned short *glycol)
{
- int mnc = 0;
-
- for (int s = 0; s < MAX_CLOUDS; s++)
- {
- // can anyone explain this??? {dlb}
- // its an optimization to avoid looking past the last cloud -bwr
- if (mnc >= env.cloud_no)
- break;
-
- if (env.cloud[s].type != CLOUD_NONE)
- {
- mnc++;
- if (see_cell(env.cloud[s].pos))
- _update_cloud_grid(s);
- }
- }
+ *glycol = get_mons_colour(mons);
+ _get_symbol(coord_def(0,0), show_type(mons), glych, glycol);
}
// Noisy now has a messenging service for giving messages to the
@@ -3391,18 +3132,18 @@ unsigned get_screen_glyph( int x, int y )
return get_screen_glyph(coord_def(x,y));
}
-unsigned get_screen_glyph( const coord_def& p )
+unsigned get_screen_glyph(const coord_def& p)
{
const coord_def ep = view2show(grid2view(p));
- int object = show_appearance(ep);
- unsigned short colour = env.show_col(ep);
+ show_type object = env.show(ep);
+ unsigned short colour = object.colour;
unsigned ch;
if (!object)
return get_envmap_char(p.x, p.y);
- _get_symbol( p, object, &ch, &colour );
+ _get_symbol(p, object, &ch, &colour);
return (ch);
}
@@ -3436,7 +3177,7 @@ std::string screenshot(bool fullscreen)
char_table_bk = Options.char_table;
init_char_table(CSET_ASCII);
- init_feature_table();
+ init_show_table();
int firstnonspace = -1;
int firstpopline = -1;
@@ -3461,7 +3202,7 @@ std::string screenshot(bool fullscreen)
if (ch && !isprint(ch))
{
// [ds] Evil hack time again. Peek at grid, use that character.
- int object = grid_appearance(gc);
+ show_type object = show_type(grid_appearance(gc));
unsigned glych;
unsigned short glycol = 0;
@@ -3494,7 +3235,7 @@ std::string screenshot(bool fullscreen)
// Restore char and feature tables.
Options.char_table = char_table_bk;
- init_feature_table();
+ init_show_table();
std::ostringstream ss;
if (firstpopline != -1 && lastpopline != -1)
@@ -3524,27 +3265,6 @@ static int _viewmap_flash_colour()
return (BLACK);
}
-static void _update_env_show(const coord_def &gp, const coord_def &ep)
-{
- // The sequence is grid, items, clouds, monsters.
- env.show(ep) = grd(gp);
- env.show_col(ep) = 0;
-
- if (igrd(gp) != NON_ITEM)
- _update_item_grid(gp, ep);
-
- const int cloud = env.cgrid(gp);
- if (cloud != EMPTY_CLOUD && env.cloud[cloud].type != CLOUD_NONE
- && env.cloud[cloud].pos == gp)
- {
- _update_cloud_grid(cloud);
- }
-
- const monsters *mons = monster_at(gp);
- if (mons && mons->alive())
- _update_monster_grid(mons);
-}
-
// Updates one square of the view area. Should only be called for square
// in LOS.
void view_update_at(const coord_def &pos)
@@ -3554,14 +3274,14 @@ void view_update_at(const coord_def &pos)
const coord_def vp = grid2view(pos);
const coord_def ep = view2show(vp);
- _update_env_show(pos, ep);
+ env.show.update_at(pos, ep);
- int object = show_appearance(ep);
+ show_type object = env.show(ep);
if (!object)
return;
- unsigned short colour = env.show_col(ep);
+ unsigned short colour = object.colour;
unsigned ch = 0;
_get_symbol( pos, object, &ch, &colour );
@@ -3680,12 +3400,9 @@ void viewwindow(bool draw_it, bool do_updates)
mcache.clear_nonref();
#endif
- env.show_col.init(LIGHTGREY);
- Show_Backup.init(0);
+ env.show.init();
- item_grid(); // Must be done before cloud and monster.
- cloud_grid();
- monster_grid( do_updates );
+ monster_grid(true);
#ifdef USE_TILE
tile_draw_rays(true);
@@ -3769,8 +3486,8 @@ void viewwindow(bool draw_it, bool do_updates)
else if (gc == you.pos() && !crawl_state.arena
&& !crawl_state.arena_suspended)
{
- int object = env.show(ep);
- unsigned short colour = env.show_col(ep);
+ show_type object = env.show(ep);
+ unsigned short colour = object.colour;
unsigned ch;
_get_symbol(gc, object, &ch, &colour);
@@ -3810,8 +3527,8 @@ void viewwindow(bool draw_it, bool do_updates)
}
else
{
- int object = show_appearance(ep);
- unsigned short colour = env.show_col(ep);
+ show_type object = env.show(ep);
+ unsigned short colour = object.colour;
unsigned ch;
_get_symbol( gc, object, &ch, &colour );
@@ -3868,11 +3585,11 @@ void viewwindow(bool draw_it, bool do_updates)
// to the grid before monsters and clouds were
// added otherwise.
if (Options.clean_map
- && Show_Backup(ep)
+ && env.show.get_backup(ep)
&& is_terrain_seen(gc))
{
- _get_symbol(gc, Show_Backup(ep), &ch, &colour);
- set_envmap_glyph(gc, Show_Backup(ep), colour);
+ _get_symbol(gc, env.show.get_backup(ep), &ch, &colour);
+ set_envmap_glyph(gc, env.show.get_backup(ep), colour);
}
// Now we get to filling in both the unseen