summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/show.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/show.cc')
-rw-r--r--crawl-ref/source/show.cc224
1 files changed, 224 insertions, 0 deletions
diff --git a/crawl-ref/source/show.cc b/crawl-ref/source/show.cc
new file mode 100644
index 0000000000..3a5e8908c4
--- /dev/null
+++ b/crawl-ref/source/show.cc
@@ -0,0 +1,224 @@
+#include "AppHdr.h"
+
+#include "show.h"
+
+#include "cloud.h"
+#include "coordit.h"
+#include "directn.h"
+#include "feature.h"
+#include "mon-util.h"
+#include "monster.h"
+#include "options.h"
+#include "state.h"
+#include "terrain.h"
+#include "view.h"
+
+void get_show_symbol(show_type object, unsigned *ch,
+ unsigned short *colour)
+{
+ if (object.cls < SH_MONSTER)
+ {
+ *ch = get_feature_def(object).symbol;
+
+ // Don't clobber with BLACK, because the colour should be already set.
+ if (get_feature_def(object).colour != BLACK)
+ *colour = get_feature_def(object).colour;
+ }
+ *colour = real_colour(*colour);
+}
+
+show_type::show_type(const monsters* m)
+ : cls(SH_MONSTER), mons(m->type) {}
+
+show_type::show_type(dungeon_feature_type f)
+ : cls(SH_FEATURE), feat(f) {}
+
+static show_item_type _item_to_show_code(const item_def &item);
+
+show_type::show_type(const item_def &it)
+ : cls(SH_ITEM), item(_item_to_show_code(it)) {}
+
+show_type::show_type(show_item_type t)
+ : cls(SH_ITEM), item(t) {}
+
+bool show_type::operator < (const show_type &other) const
+{
+ if (cls < other.cls)
+ return (false);
+ else if (cls > other.cls)
+ return (true);
+ switch (cls)
+ {
+ case SH_FEATURE:
+ return (feat < other.feat);
+ case SH_ITEM:
+ return (item < other.item);
+ case SH_MONSTER:
+ return (mons < other.mons);
+ default:
+ return (false);
+ }
+}
+
+void show_def::_set_backup(const coord_def &ep)
+{
+ backup(ep) = grid(ep);
+}
+
+void show_def::_update_feat_at(const coord_def &gp, const coord_def &ep)
+{
+ grid(ep).cls = SH_FEATURE;
+ grid(ep).feat = grid_appearance(gp);
+ grid(ep).colour = 0;
+}
+
+static show_item_type _item_to_show_code(const item_def &item)
+{
+ switch (item.base_type)
+ {
+ case OBJ_ORBS: return (SHOW_ITEM_ORB);
+ case OBJ_WEAPONS: return (SHOW_ITEM_WEAPON);
+ case OBJ_MISSILES: return (SHOW_ITEM_MISSILE);
+ case OBJ_ARMOUR: return (SHOW_ITEM_ARMOUR);
+ case OBJ_WANDS: return (SHOW_ITEM_WAND);
+ case OBJ_FOOD: return (SHOW_ITEM_FOOD);
+ case OBJ_SCROLLS: return (SHOW_ITEM_SCROLL);
+ case OBJ_JEWELLERY:
+ return (jewellery_is_amulet(item)? SHOW_ITEM_AMULET : SHOW_ITEM_RING);
+ case OBJ_POTIONS: return (SHOW_ITEM_POTION);
+ case OBJ_BOOKS: return (SHOW_ITEM_BOOK);
+ case OBJ_STAVES: return (SHOW_ITEM_STAVE);
+ case OBJ_MISCELLANY: return (SHOW_ITEM_MISCELLANY);
+ case OBJ_CORPSES: return (SHOW_ITEM_CORPSE);
+ case OBJ_GOLD: return (SHOW_ITEM_GOLD);
+ default: return (SHOW_ITEM_ORB); // bad item character
+ }
+}
+
+void show_def::_update_item_at(const coord_def &gp, const coord_def &ep)
+{
+ const item_def &eitem = mitm[igrd(gp)];
+ unsigned short &ecol = grid(ep).colour;
+
+ 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;
+ grid(ep).cls = SH_ITEM;
+ grid(ep).item = _item_to_show_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 show_def::_update_cloud(int cloudno)
+{
+ const coord_def e = grid2show(env.cloud[cloudno].pos);
+ int which_colour = get_cloud_colour(cloudno);
+ _set_backup(e);
+ grid(e).cls = SH_CLOUD;
+ grid(e).colour = which_colour;
+
+#ifdef USE_TILE
+ tile_place_cloud(e.x, e.y, env.cloud[cloudno].type,
+ env.cloud[cloudno].decay);
+#endif
+}
+
+bool show_def::update_monster(const monsters* mons)
+{
+ const coord_def e = grid2show(mons->pos());
+
+ if (!mons->visible_to(&you))
+ {
+ // ripple effect?
+ if (grd(mons->pos()) == DNGN_SHALLOW_WATER
+ && !mons_flies(mons)
+ && env.cgrid(mons->pos()) == EMPTY_CLOUD)
+ {
+ _set_backup(e);
+ grid(e).cls = SH_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(mons->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
+
+ grid(e).colour = ripple_table[base_colour & 0x0f];
+ }
+ return (false);
+ }
+
+ // Mimics are always left on map.
+ if (!mons_is_mimic(mons->type))
+ _set_backup(e);
+
+ grid(e).cls = SH_MONSTER;
+ grid(e).mons = mons->type;
+ grid(e).colour = get_mons_colour(mons);
+
+ return (true);
+}
+
+void show_def::update_at(const coord_def &gp, const coord_def &ep)
+{
+ grid(ep).cls = SH_NOTHING;
+
+ // The sequence is grid, items, clouds, monsters.
+ _update_feat_at(gp, ep);
+
+ if (igrd(gp) != NON_ITEM)
+ _update_item_at(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(cloud);
+ }
+
+ const monsters *mons = monster_at(gp);
+ if (mons && mons->alive())
+ update_monster(mons);
+}
+
+void show_def::init()
+{
+ grid.init(show_type());
+ backup.init(show_type());
+
+ for (radius_iterator ri(you.pos(), LOS_RADIUS); ri; ++ri)
+ update_at(*ri, grid2show(*ri));
+}