diff options
Diffstat (limited to 'crawl-ref/source')
28 files changed, 1536 insertions, 1088 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc index bb8f286177..39377bddc8 100644 --- a/crawl-ref/source/abyss.cc +++ b/crawl-ref/source/abyss.cc @@ -839,12 +839,12 @@ static void _corrupt_square(const crawl_environment &oenv, const coord_def &c) if (feat == DNGN_ROCK_WALL) { env.tile_flv(c).wall = TILE_WALL_UNDEAD - + random2(tile_dngn_count[TILE_WALL_UNDEAD]); + + random2(tile_dngn_count(TILE_WALL_UNDEAD)); } else if (feat == DNGN_FLOOR) { env.tile_flv(c).floor = TILE_FLOOR_NERVES - + random2(tile_dngn_count[TILE_FLOOR_NERVES]); + + random2(tile_dngn_count(TILE_FLOOR_NERVES)); } #endif } diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h index 96952719ca..9e252c7330 100644 --- a/crawl-ref/source/enum.h +++ b/crawl-ref/source/enum.h @@ -1802,6 +1802,7 @@ enum monster_type // (int) menv[].type // BCR - end second batch of uniques. MONS_DRACONIAN, + MONS_FIRST_DRACONIAN = MONS_DRACONIAN, // If adding more drac colours, sync up colour names in // mon-util.cc. @@ -1823,6 +1824,8 @@ enum monster_type // (int) menv[].type MONS_DRACONIAN_KNIGHT, MONS_DRACONIAN_SCORCHER, + MONS_LAST_DRACONIAN = MONS_DRACONIAN_SCORCHER, + MONS_MURRAY, MONS_TIAMAT, diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h index 2fa78812ee..8626972a11 100644 --- a/crawl-ref/source/externs.h +++ b/crawl-ref/source/externs.h @@ -44,6 +44,20 @@ struct tile_flavour // Used as a random value or for special cases e.g. (bazaars, gates). unsigned char special; }; + +// A glorified unsigned int that assists with ref-counting the mcache. +class tile_fg_store +{ +public: + tile_fg_store() : m_tile(0) {} + tile_fg_store(unsigned int tile) : m_tile(tile) {} + operator unsigned int() { return m_tile; } + unsigned int operator=(unsigned int tile); +protected: + unsigned int m_tile; +}; + + #endif #define INFO_SIZE 200 // size of message buffers @@ -1446,8 +1460,8 @@ public: #ifdef USE_TILE // indexed by grid coords - FixedArray<unsigned int,GXM, GYM> tile_bk_fg; // tile fg - FixedArray<unsigned int,GXM, GYM> tile_bk_bg; // tile bg + FixedArray<tile_fg_store, GXM, GYM> tile_bk_fg; // tile fg + FixedArray<unsigned int, GXM, GYM> tile_bk_bg; // tile bg FixedArray<tile_flavour, GXM, GYM> tile_flv; // indexed by (show-1) coords FixedArray<unsigned int,ENV_SHOW_DIAMETER-2,ENV_SHOW_DIAMETER-2> tile_fg; diff --git a/crawl-ref/source/makefile_tiles.mgw b/crawl-ref/source/makefile_tiles.mgw index 558cc58f22..dabf6cec74 100644 --- a/crawl-ref/source/makefile_tiles.mgw +++ b/crawl-ref/source/makefile_tiles.mgw @@ -48,7 +48,6 @@ PCRELIBA := lib$(PCRELIB).a RLTILES = rltiles EXTRA_INCLUDES += -I$(RLTILES) OBJECTS += \ - $(RLTILES)/tiledef-demon.o \ $(RLTILES)/tiledef-dngn.o \ $(RLTILES)/tiledef-main.o \ $(RLTILES)/tiledef-player.o @@ -56,8 +55,7 @@ OBJECTS += \ TILEFILES = \ main.png \ player.png \ - dngn.png \ - demon.png + dngn.png DESTTILEFILES = $(TILEFILES:%=dat/tiles/%) @@ -78,7 +76,7 @@ CFOTHERS := -fsigned-char \ CFLAGS := $(INCLUDES) $(CFWARN) $(CFOTHERS) $(SDL_CFLAGS) YCFLAGS := $(INCLUDES) $(CFOTHERS) -OBJECTS := $(OBJECTS) libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o +OBJECTS := $(OBJECTS) libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o LDFLAGS = diff --git a/crawl-ref/source/makefile_tiles.unix b/crawl-ref/source/makefile_tiles.unix index dd379e0b95..bd3148a931 100644 --- a/crawl-ref/source/makefile_tiles.unix +++ b/crawl-ref/source/makefile_tiles.unix @@ -10,7 +10,7 @@ GAME = crawl # it will make a variable called OBJECTS that contains all the libraries include makefile.obj -OBJECTS += libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o +OBJECTS += libgui.o tilepick.o tile2.o tilereg.o tilesdl.o tilefont.o tiletex.o tilemcache.o SDL_CFLAGS := $(shell sdl-config --cflags) SDL_LDFLAGS := $(shell sdl-config --libs) -lSDLmain @@ -104,12 +104,11 @@ endif RLTILES = rltiles EXTRA_INCLUDES += -I$(RLTILES) -OBJECTS += $(RLTILES)/tiledef-demon.o $(RLTILES)/tiledef-dngn.o $(RLTILES)/tiledef-main.o $(RLTILES)/tiledef-player.o +OBJECTS += $(RLTILES)/tiledef-dngn.o $(RLTILES)/tiledef-main.o $(RLTILES)/tiledef-player.o TILEFILES = \ main.png \ player.png \ - demon.png \ dngn.png DESTTILEFILES = $(TILEFILES:%=dat/tiles/%) diff --git a/crawl-ref/source/mon-util.cc b/crawl-ref/source/mon-util.cc index 024676cb51..703b9c343b 100644 --- a/crawl-ref/source/mon-util.cc +++ b/crawl-ref/source/mon-util.cc @@ -5001,9 +5001,6 @@ void monsters::slow_down(int strength) void monsters::set_ghost(const ghost_demon &g) { -#ifdef USE_TILE - TileGhostInit(g); -#endif ghost.reset( new ghost_demon(g) ); mname = ghost->name; } diff --git a/crawl-ref/source/rltiles/dc-demon.txt b/crawl-ref/source/rltiles/dc-demon.txt index 8a3239277c..340860ac09 100644 --- a/crawl-ref/source/rltiles/dc-demon.txt +++ b/crawl-ref/source/rltiles/dc-demon.txt @@ -1,6 +1,3 @@ -%name demon -%prefix TILE - %rim 1 %sdir dc-mon/demon diff --git a/crawl-ref/source/rltiles/dc-dngn.txt b/crawl-ref/source/rltiles/dc-dngn.txt index c3dcd4dc5e..053cbed0bd 100644 --- a/crawl-ref/source/rltiles/dc-dngn.txt +++ b/crawl-ref/source/rltiles/dc-dngn.txt @@ -344,7 +344,6 @@ gate_open_left DNGN_GATE_OPEN_LEFT gate_open_middle DNGN_GATE_OPEN_MIDDLE gate_open_right DNGN_GATE_OPEN_RIGHT dngn_orcish_idol DNGN_ORCISH_IDOL -dngn_silver_statue DNGN_SILVER_STATUE dngn_granite_statue DNGN_GRANITE_STATUE %rim 1 diff --git a/crawl-ref/source/rltiles/dc-main.txt b/crawl-ref/source/rltiles/dc-main.txt index 2b41b50195..71038a0656 100644 --- a/crawl-ref/source/rltiles/dc-main.txt +++ b/crawl-ref/source/rltiles/dc-main.txt @@ -7,8 +7,6 @@ dc-dngn/dngn_unseen ## Set black rim
## Items
%include dc-item.txt
-## Monsters
-%include dc-mon.txt
## Clear black rim
%rim 0
diff --git a/crawl-ref/source/rltiles/dc-misc.txt b/crawl-ref/source/rltiles/dc-misc.txt index 0972fdc71e..1b28fad328 100644 --- a/crawl-ref/source/rltiles/dc-misc.txt +++ b/crawl-ref/source/rltiles/dc-misc.txt @@ -57,7 +57,6 @@ poison POISON %rim 0
may_stab_brand MAY_STAB_BRAND
stab_brand STAB_BRAND
-unseen PLAYER
out_of_sight MESH
magicmap MAGIC_MAP_MESH
something_under SOMETHING_UNDER
@@ -85,6 +84,3 @@ slot_eq ITEM_SLOT_EQUIP slot_cursed ITEM_SLOT_CURSED
slot_eq_cursed ITEM_SLOT_EQUIP_CURSED
ray ITEM_SLOT_SELECTED
-
-%back unseen
-dc-misc/unseen_monster MCACHE_START
diff --git a/crawl-ref/source/rltiles/dc-mon.txt b/crawl-ref/source/rltiles/dc-mon.txt index 36ddecb904..4cbdc25071 100644 --- a/crawl-ref/source/rltiles/dc-mon.txt +++ b/crawl-ref/source/rltiles/dc-mon.txt @@ -453,6 +453,11 @@ mermaid_water MONS_MERMAID_WATER rock_worm MONS_ROCK_WORM
%sdir dc-dngn
-dngn_orange_crystal_statue DNGN_ORANGE_CRYSTAL_STATUE
-dngn_ice_statue DNGN_ICE_STATUE
+dngn_orange_crystal_statue ORANGE_CRYSTAL_STATUE
+dngn_ice_statue ICE_STATUE
+dngn_silver_statue SILVER_STATUE
%sdir dc-mon
+
+dc-misc/unseen PLAYER
+dc-misc/unseen_monster MONS_UNKNOWN
+dc-misc/unseen_monster MCACHE_START
diff --git a/crawl-ref/source/rltiles/dc-player.txt b/crawl-ref/source/rltiles/dc-player.txt index 44d285e423..c6a60c56fb 100644 --- a/crawl-ref/source/rltiles/dc-player.txt +++ b/crawl-ref/source/rltiles/dc-player.txt @@ -1,6 +1,10 @@ %name player
+%startvalue TILE_MAIN_MAX tiledef-main.h
%prefix TILEP
+%include dc-demon.txt
+%include dc-mon.txt
+
%rim 1
###BASE
@@ -845,3 +849,4 @@ drchead_purple PURPLE drchead_red RED
drchead_white WHITE
%end
+
diff --git a/crawl-ref/source/rltiles/makefile.mgw b/crawl-ref/source/rltiles/makefile.mgw index 2707002797..edeeb30a56 100644 --- a/crawl-ref/source/rltiles/makefile.mgw +++ b/crawl-ref/source/rltiles/makefile.mgw @@ -20,7 +20,7 @@ DELETE = del /q TOOLDIR := tool TILEGEN := $(TOOLDIR)\\tilegen.elf -INPUTS := main dngn player demon +INPUTS := main dngn player INPUTFILES := $(INPUTS:%=dc-%.txt) HEADERS := $(INPUTS:%=tiledef-%.h) SOURCE := $(INPUTS:%=tiledef-%.cc) diff --git a/crawl-ref/source/rltiles/makefile.unix b/crawl-ref/source/rltiles/makefile.unix index b7096a7bd7..f64bfe42d9 100644 --- a/crawl-ref/source/rltiles/makefile.unix +++ b/crawl-ref/source/rltiles/makefile.unix @@ -19,7 +19,7 @@ DELETE = rm -f TOOLDIR := tool TILEGEN := $(TOOLDIR)/tilegen.elf -INPUTS := main dngn player demon +INPUTS := main dngn player INPUTFILES := $(INPUTS:%=dc-%.txt) HEADERS := $(INPUTS:%=tiledef-%.h) SOURCE := $(INPUTS:%=tiledef-%.cc) diff --git a/crawl-ref/source/rltiles/tiledef_defines.h b/crawl-ref/source/rltiles/tiledef_defines.h index 9882db3053..882cf03830 100644 --- a/crawl-ref/source/rltiles/tiledef_defines.h +++ b/crawl-ref/source/rltiles/tiledef_defines.h @@ -43,4 +43,8 @@ public: unsigned short ey; }; +typedef unsigned int (tile_count_func)(unsigned int); +typedef const char *(tile_name_func)(unsigned int); +typedef tile_info &(tile_info_func)(unsigned int); + #endif diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.cc b/crawl-ref/source/rltiles/tool/tile_list_processor.cc index e1cf1191ad..80d17bcc11 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.cc +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.cc @@ -10,7 +10,8 @@ tile_list_processor::tile_list_processor() : m_corpsify(false), m_composing(false), m_shrink(true), - m_prefix("TILE") + m_prefix("TILE"), + m_start_value("0") { } @@ -192,8 +193,8 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, return false; \ } - #define CHECK_ARG1 \ - if (m_args.size() <= 1) \ + #define CHECK_ARG(x) \ + if (m_args.size() <= x) \ { \ fprintf(stderr, "Error (%s:%d): " \ "missing arg following '%s'.\n", \ @@ -203,7 +204,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, if (strcmp(arg, "back") == 0) { - CHECK_ARG1; + CHECK_ARG(1); for (unsigned int i = 0; i < m_back.size(); i++) { @@ -231,7 +232,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "compose") == 0) { - CHECK_ARG1; + CHECK_ARG(1); if (!m_composing) { fprintf(stderr, "Error (%s:%d): not composing yet.\n", @@ -271,7 +272,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "corpse") == 0) { - CHECK_ARG1; + CHECK_ARG(1); m_corpsify = (bool)atoi(m_args[1]); } else if (strcmp(arg, "end") == 0) @@ -325,7 +326,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "include") == 0) { - CHECK_ARG1; + CHECK_ARG(1); if (!process_list(m_args[1])) { fprintf(stderr, "Error (%s:%d): include failed.\n", @@ -335,7 +336,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "name") == 0) { - CHECK_ARG1; + CHECK_ARG(1); if (m_name != "") { @@ -349,7 +350,7 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "parts_ctg") == 0) { - CHECK_ARG1; + CHECK_ARG(1); for (unsigned int i = 0; i < m_categories.size(); i++) { @@ -368,22 +369,22 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, } else if (strcmp(arg, "prefix") == 0) { - CHECK_ARG1; + CHECK_ARG(1); m_prefix = m_args[1]; } else if (strcmp(arg, "rim") == 0) { - CHECK_ARG1; + CHECK_ARG(1); m_rim = (bool)atoi(m_args[1]); } else if (strcmp(arg, "sdir") == 0) { - CHECK_ARG1; + CHECK_ARG(1); m_sdir = m_args[1]; } else if (strcmp(arg, "shrink") == 0) { - CHECK_ARG1; + CHECK_ARG(1); m_shrink = (bool)atoi(m_args[1]); } else if (strcmp(arg, "start") == 0) @@ -399,6 +400,14 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, m_composing = true; m_compose.unload(); } + else if (strcmp(arg, "startvalue") == 0) + { + CHECK_ARG(2); + CHECK_NO_ARG(3); + + m_start_value = m_args[1]; + m_include = m_args[2]; + } else { fprintf(stderr, "Error (%s:%d): unknown command '%%%s'\n", @@ -542,28 +551,38 @@ bool tile_list_processor::write_data() ucname.c_str(), ucname.c_str()); fprintf(fp, "#include \"tiledef_defines.h\"\n\n"); + if (!m_include.empty()) + { + fprintf(fp, "#include \"%s\"\n\n", m_include.c_str()); + } + fprintf(fp, "enum tile_%s_type\n{\n", lcname.c_str()); + std::string start_val = " = "; + start_val += m_start_value; + for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) { const std::string &enumname = m_page.m_tiles[i]->enumname(); const std::string &parts_ctg = m_page.m_tiles[i]->parts_ctg(); if (enumname.empty()) { - fprintf(fp, " %s_%s_FILLER_%d,\n", m_prefix.c_str(), - ucname.c_str(), i); + fprintf(fp, " %s_%s_FILLER_%d%s,\n", m_prefix.c_str(), + ucname.c_str(), i, start_val.c_str()); } else if (parts_ctg.empty()) { - fprintf(fp, " %s_%s,\n", m_prefix.c_str(), - enumname.c_str()); + fprintf(fp, " %s_%s%s,\n", m_prefix.c_str(), + enumname.c_str(), start_val.c_str()); } else { - fprintf(fp, " %s_%s_%s,\n", m_prefix.c_str(), - parts_ctg.c_str(), enumname.c_str()); + fprintf(fp, " %s_%s_%s%s,\n", m_prefix.c_str(), + parts_ctg.c_str(), enumname.c_str(), start_val.c_str()); } + start_val = ""; + if (!parts_ctg.empty()) { int idx; @@ -580,12 +599,11 @@ bool tile_list_processor::write_data() fprintf(fp, " %s_%s_MAX\n};\n\n", m_prefix.c_str(), ucname.c_str()); - fprintf(fp, "extern int tile_%s_count[%s];\n", - lcname.c_str(), max.c_str()); - fprintf(fp, "extern const char *tile_%s_name[%s];\n", - lcname.c_str(), max.c_str()); - fprintf(fp, "extern tile_info tile_%s_info[%s];\n", - lcname.c_str(), max.c_str()); + fprintf(fp, "int tile_%s_count(unsigned int idx);\n", lcname.c_str()); + fprintf(fp, "const char *tile_%s_name(unsigned int idx);\n", + lcname.c_str()); + fprintf(fp, "tile_info &tile_%s_info(unsigned int idx);\n", + lcname.c_str()); if (m_categories.size() > 0) { @@ -624,14 +642,21 @@ bool tile_list_processor::write_data() fprintf(fp, "// This file has been automatically generated.\n\n"); fprintf(fp, "#include \"tiledef-%s.h\"\n\n", lcname.c_str()); - fprintf(fp, "int tile_%s_count[%s] =\n{\n", - lcname.c_str(), max.c_str()); + fprintf(fp, "int _tile_%s_count[%s - %s] =\n{\n", + lcname.c_str(), max.c_str(), m_start_value.c_str()); for (unsigned int i = 0; i < m_page.m_counts.size(); i++) fprintf(fp, " %d,\n", m_page.m_counts[i]); fprintf(fp, "};\n\n"); - fprintf(fp, "const char *tile_%s_name[%s] =\n{\n", - lcname.c_str(), max.c_str()); + fprintf(fp, "int tile_%s_count(unsigned int idx)\n{\n", lcname.c_str()); + fprintf(fp, " assert(idx >= %s && idx < %s);\n", + m_start_value.c_str(), max.c_str()); + fprintf(fp, " return _tile_%s_count[idx - %s];\n", + lcname.c_str(), m_start_value.c_str()); + fprintf(fp, "}\n\n"); + + fprintf(fp, "const char *_tile_%s_name[%s - %s] =\n{\n", + lcname.c_str(), max.c_str(), m_start_value.c_str()); for (unsigned int i = 0; i < m_page.m_tiles.size(); i++) { const std::string &enumname = m_page.m_tiles[i]->enumname(); @@ -642,8 +667,16 @@ bool tile_list_processor::write_data() } fprintf(fp, "};\n\n"); - fprintf(fp, "tile_info tile_%s_info[%s] =\n{\n", - lcname.c_str(), max.c_str()); + fprintf(fp, "const char *tile_%s_name(unsigned int idx)\n{\n", + lcname.c_str()); + fprintf(fp, " assert(idx >= %s && idx < %s);\n", + m_start_value.c_str(), max.c_str()); + fprintf(fp, " return _tile_%s_name[idx - %s];\n", + lcname.c_str(), m_start_value.c_str()); + fprintf(fp, "}\n\n"); + + fprintf(fp, "tile_info _tile_%s_info[%s - %s] =\n{\n", + lcname.c_str(), max.c_str(), m_start_value.c_str()); for (unsigned int i = 0; i < m_page.m_offsets.size(); i+=4) { fprintf(fp, " tile_info(%d, %d, %d, %d, %d, %d, %d, %d),\n", @@ -654,6 +687,14 @@ bool tile_list_processor::write_data() } fprintf(fp, "};\n\n"); + fprintf(fp, "tile_info &tile_%s_info(unsigned int idx)\n{\n", + lcname.c_str()); + fprintf(fp, " assert(idx >= %s && idx < %s);\n", + m_start_value.c_str(), max.c_str()); + fprintf(fp, " return _tile_%s_info[idx - %s];\n", + lcname.c_str(), m_start_value.c_str()); + fprintf(fp, "}\n\n"); + if (m_categories.size() > 0) { fprintf(fp, "int tile_%s_part_count[%s] =\n{\n", @@ -671,7 +712,7 @@ bool tile_list_processor::write_data() for (int i = 0; i < m_categories.size(); i++) { - fprintf(fp, " %d,\n", part_min[i]); + fprintf(fp, " %d+%s,\n", part_min[i], m_start_value.c_str()); } fprintf(fp, "};\n\n"); diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.h b/crawl-ref/source/rltiles/tool/tile_list_processor.h index 0c718a8044..74b199b5ef 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.h +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.h @@ -33,6 +33,8 @@ protected: std::string m_parts_ctg; std::string m_sdir; std::string m_prefix; + std::string m_start_value; + std::string m_include; std::vector<std::string> m_categories; std::vector<int> m_ctg_counts; tile m_compose; diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc index 3c9ca7606f..d9991d58e9 100644 --- a/crawl-ref/source/tags.cc +++ b/crawl-ref/source/tags.cc @@ -87,6 +87,7 @@ #include "stuff.h" #include "tags.h" #include "tiles.h" +#include "tilemcache.h" #include "travel.h" // defined in overmap.cc @@ -1856,7 +1857,7 @@ void tag_construct_level_tiles(writer &th) unsigned int last_tile = 0; // tile routine subversion - marshallShort(th, 71); + marshallShort(th, TILETAG_CURRENT); // Map grids. // how many X? @@ -1935,6 +1936,8 @@ void tag_construct_level_tiles(writer &th) marshallByte(th, env.tile_flv[count_x][count_y].special); } + mcache.construct(th); + #endif } @@ -2251,6 +2254,11 @@ void tag_read_level_tiles(struct reader &th) env.tile_flv[x][y].special = unmarshallByte(th); } + if (ver > TILETAG_PRE_MCACHE) + mcache.read(th); + else + mcache.clear_all(); + #endif } @@ -2267,6 +2275,7 @@ static void tag_missing_level_tiles() env.tile_bk_fg[i][j] = 0; } + mcache.clear_all(); #endif } diff --git a/crawl-ref/source/tile2.cc b/crawl-ref/source/tile2.cc index 3de5276d92..3e6b3bed3f 100644 --- a/crawl-ref/source/tile2.cc +++ b/crawl-ref/source/tile2.cc @@ -365,12 +365,12 @@ void TileLoadWall(bool wizard) WallIdx(wall_tile_idx, floor_tile_idx, special_tile_idx); // Number of flavors are generated automatically... - floor_flavors = tile_dngn_count[floor_tile_idx]; - wall_flavors = tile_dngn_count[wall_tile_idx]; + floor_flavors = tile_dngn_count(floor_tile_idx); + wall_flavors = tile_dngn_count(wall_tile_idx); if (special_tile_idx != -1) { - special_flavors = tile_dngn_count[special_tile_idx]; + special_flavors = tile_dngn_count(special_tile_idx); } else { @@ -384,6 +384,7 @@ void TileLoadWall(bool wizard) #define TILEP_SELECT_DOLL 20 static dolls_data current_doll; +#if 0 static int current_gender = 0; static void _load_doll_data(const char *fn, dolls_data *dolls, int max, @@ -468,6 +469,7 @@ static void _load_doll_data(const char *fn, dolls_data *dolls, int max, current_gender = dolls[cur0].parts[TILEP_PART_BASE] % 2; } +#endif void TilePlayerEdit() { @@ -670,8 +672,8 @@ void TilePlayerEdit() ImgCopy(DollCacheImg, 0, 0, TILE_X, TILE_Y, DollsListImg, cur_doll*TILE_X, 0, 1); - _ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1); - _ImgCopyFromTileImg(TILE_PLAYER, ScrBufImg, 8*TILE_X, 8*TILE_Y, 0); + _ImgCopyToTileImg(TILEP_PLAYER, DollCacheImg, 0, 0, 1); + _ImgCopyFromTileImg(TILEP_PLAYER, ScrBufImg, 8*TILE_X, 8*TILE_Y, 0); ImgCopy(DollsListImg, 0, 0, ImgWidth(DollsListImg), ImgHeight(DollsListImg), ScrBufImg, 3 * TILE_X, PARTS_Y, 0); @@ -909,7 +911,7 @@ void TilePlayerEdit() current_doll = dolls[cur_doll]; _draw_doll(DollCacheImg, ¤t_doll); - _ImgCopyToTileImg(TILE_PLAYER, DollCacheImg, 0, 0, 1); + _ImgCopyToTileImg(TILEP_PLAYER, DollCacheImg, 0, 0, 1); std::string dollsTxtString = datafile_path("dolls.txt", false, true); const char *dollsTxt = (dollsTxtString.c_str()[0] == 0) ? @@ -932,7 +934,7 @@ void TilePlayerEdit() ImgDestroy(DollsListImg); ImgClear(ScrBufImg); - _redraw_spx_tcache(TILE_PLAYER); + _redraw_spx_tcache(TILEP_PLAYER); for (x = 0; x < TILE_DAT_XMAX + 2; x++) { @@ -953,272 +955,13 @@ void TilePlayerEdit() #endif } -void TileGhostInit(const struct ghost_demon &ghost) -{ -#if 0 - dolls_data doll; - int x, y; - unsigned int pseudo_rand = ghost.max_hp * 54321 * 54321; - char mask[TILE_X*TILE_Y]; - int g_gender = (pseudo_rand >> 8) & 1; - - for (x = 0; x < TILE_X; x++) - for (y = 0; y < TILE_X; y++) - mask[x + y*TILE_X] = (x+y)&1; - - for (x = 0; x < TILEP_PART_MAX; x++) - { - doll.parts[x] = 0; - current_parts[x] = 0; - } - tilep_race_default(ghost.species, g_gender, - ghost.xl, doll.parts); - tilep_job_default (ghost.job, g_gender, doll.parts); - - for (x = TILEP_PART_CLOAK; x < TILEP_PART_MAX; x++) - { - if (doll.parts[x] == TILEP_SHOW_EQUIP) - { - doll.parts[x] = 1 + (pseudo_rand % tilep_parts_total[x]); - - if (x == TILEP_PART_BODY) - { - int p = 0; - int ac = ghost.ac; - ac *= (5 + (pseudo_rand/11) % 11); - ac /= 10; - - if (ac > 25) - p = TILEP_BODY_PLATE_BLACK; - else if (ac > 20) - p = TILEP_BODY_BANDED; - else if (ac > 15) - p = TILEP_BODY_SCALEMAIL; - else if (ac > 10) - p = TILEP_BODY_CHAINMAIL; - else if (ac > 5 ) - p = TILEP_BODY_LEATHER_HEAVY; - else - p = TILEP_BODY_ROBE_BLUE; - doll.parts[x] = p; - } - } - } - - int sk = ghost.best_skill; - int dam = ghost.damage; - int p = 0; - - dam *= (5 + pseudo_rand % 11); - dam /= 10; - - switch (sk) - { - case SK_MACES_FLAILS: - if (dam > 30) - p = TILEP_HAND1_GREAT_FRAIL; - else if (dam > 25) - p = TILEP_HAND1_GREAT_MACE; - else if (dam > 20) - p = TILEP_HAND1_SPIKED_FRAIL; - else if (dam > 15) - p = TILEP_HAND1_MORNINGSTAR; - else if (dam > 10) - p = TILEP_HAND1_FRAIL; - else if (dam > 5) - p = TILEP_HAND1_MACE; - else - p = TILEP_HAND1_CLUB_SLANT; - - doll.parts[TILEP_PART_HAND1] = p; - break; - - case SK_SHORT_BLADES: - if (dam > 20) - p = TILEP_HAND1_SABRE; - else if (dam > 10) - p = TILEP_HAND1_SHORT_SWORD_SLANT; - else - p = TILEP_HAND1_DAGGER_SLANT; - - doll.parts[TILEP_PART_HAND1] = p; - break; - - case SK_LONG_BLADES: - if (dam > 25) - p = TILEP_HAND1_GREAT_SWORD_SLANT; - else if (dam > 20) - p = TILEP_HAND1_KATANA_SLANT; - else if (dam > 15) - p = TILEP_HAND1_SCIMITAR; - else if (dam > 10) - p = TILEP_HAND1_LONG_SWORD_SLANT; - else - p = TILEP_HAND1_FALCHION; - - doll.parts[TILEP_PART_HAND1] = p; - break; - - case SK_AXES: - if (dam > 30) - p = TILEP_HAND1_EXECUTIONERS_AXE; - else if (dam > 20) - p = TILEP_HAND1_BATTLEAXE; - else if (dam > 15) - p = TILEP_HAND1_BROAD_AXE; - else if (dam > 10) - p = TILEP_HAND1_WAR_AXE; - else - p = TILEP_HAND1_HAND_AXE; - - doll.parts[TILEP_PART_HAND1] = p; - break; - - case SK_POLEARMS: - if (dam > 30) - p = TILEP_HAND1_GLAIVE; - else if (dam > 20) - p = TILEP_HAND1_SCYTHE; - else if (dam > 15) - p = TILEP_HAND1_HALBERD; - else if (dam > 10) - p = TILEP_HAND1_TRIDENT2; - else if (dam > 10) - p = TILEP_HAND1_HAMMER; - else - p = TILEP_HAND1_SPEAR; - - doll.parts[TILEP_PART_HAND1] = p; - break; - - case SK_BOWS: - doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW2; - break; - - case SK_CROSSBOWS: - doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CROSSBOW; - break; - - case SK_SLINGS: - doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SLING; - break; - - case SK_UNARMED_COMBAT: - default: - doll.parts[TILEP_PART_HAND1] = doll.parts[TILEP_PART_HAND2] = 0; - break; - } - - ImgClear(DollCacheImg); - // Clear - _ImgCopyToTileImg(TILE_MONS_PLAYER_GHOST, DollCacheImg, 0, 0, 1); - - _draw_doll(DollCacheImg, &doll); - _ImgCopyToTileImg(TILE_MONS_PLAYER_GHOST, DollCacheImg, 0, 0, 1, mask, false); - _redraw_spx_tcache(TILE_MONS_PLAYER_GHOST); -#endif -} - -void tile_get_monster_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y) -{ - ofs_x = 0; - ofs_y = 0; - - switch (mon_tile) - { - case TILE_MONS_ORC: - case TILE_MONS_URUG: - case TILE_MONS_BLORK_THE_ORC: - case TILE_MONS_ORC_WARRIOR: - case TILE_MONS_ORC_KNIGHT: - case TILE_MONS_ORC_WARLORD: - ofs_y = 2; - break; - case TILE_MONS_GOBLIN: - case TILE_MONS_IJYB: - ofs_y = 4; - break; - case TILE_MONS_GNOLL: - ofs_x = -1; - break; - case TILE_MONS_BOGGART: - ofs_y = 2; - break; - case TILE_MONS_DEEP_ELF_FIGHTER: - case TILE_MONS_DEEP_ELF_SOLDIER: - ofs_y = 2; - break; - case TILE_MONS_DEEP_ELF_KNIGHT: - ofs_y = 1; - break; - case TILE_MONS_KOBOLD: - ofs_x = 3; - ofs_y = 4; - break; - case TILE_MONS_KOBOLD_DEMONOLOGIST: - ofs_y = -10; - break; - case TILE_MONS_BIG_KOBOLD: - ofs_x = 2; - ofs_y = 3; - break; - case TILE_MONS_MIDGE: - ofs_y = -2; - break; - case TILE_MONS_NAGA: - case TILE_MONS_GREATER_NAGA: - case TILE_MONS_NAGA_WARRIOR: - case TILE_MONS_GUARDIAN_NAGA: - case TILE_MONS_NAGA_MAGE: - ofs_y = 1; - break; - case TILE_MONS_HELL_KNIGHT: - ofs_x = -1; - ofs_y = 3; - break; - case TILE_MONS_RED_DEVIL: - ofs_x = 2; - ofs_y = -3; - break; - case TILE_MONS_WIZARD: - ofs_x = 2; - ofs_y = -2; - break; - case TILE_MONS_HUMAN: - ofs_x = 5; - ofs_y = 2; - break; - case TILE_MONS_ELF: - ofs_y = 1; - ofs_x = 4; - break; - case TILE_MONS_OGRE_MAGE: - ofs_y = -2; - ofs_x = -4; - break; - case TILE_MONS_DEEP_ELF_MAGE: - case TILE_MONS_DEEP_ELF_SUMMONER: - case TILE_MONS_DEEP_ELF_CONJURER: - case TILE_MONS_DEEP_ELF_PRIEST: - case TILE_MONS_DEEP_ELF_HIGH_PRIEST: - case TILE_MONS_DEEP_ELF_DEMONOLOGIST: - case TILE_MONS_DEEP_ELF_ANNIHILATOR: - case TILE_MONS_DEEP_ELF_SORCERER: - ofs_x = -1; - ofs_y = -2; - break; - case TILE_MONS_DEEP_ELF_DEATH_MAGE: - ofs_x = -1; - break; - } -} - int get_clean_map_idx(int tile_idx) { + // TODO enne - need to separate TILEP from non-TILEP... int idx = tile_idx & TILE_FLAG_MASK; if (idx >= TILE_CLOUD_FIRE_0 && idx <= TILE_CLOUD_PURP_SMOKE || - idx >= TILE_MONS_SHADOW && idx <= TILE_MONS_WATER_ELEMENTAL || - idx >= TILE_MCACHE_START) + idx >= TILEP_MONS_SHADOW && idx <= TILEP_MONS_WATER_ELEMENTAL || + idx >= TILEP_MCACHE_START) { return 0; } diff --git a/crawl-ref/source/tilemcache.cc b/crawl-ref/source/tilemcache.cc new file mode 100644 index 0000000000..046e4ed08f --- /dev/null +++ b/crawl-ref/source/tilemcache.cc @@ -0,0 +1,856 @@ +#include "tilemcache.h" +#include "tags.h" +#include "ghost.h" +#include "mon-util.h" + +mcache_manager mcache; + +// Used internally for streaming +enum mcache_type +{ + MCACHE_MONSTER, + MCACHE_DRACO, + MCACHE_GHOST, + MCACHE_DEMON, + MCACHE_MAX, + + MCACHE_NULL +}; + +// Custom marshall/unmarshall functions. +static void unmarshallDoll(reader &th, dolls_data &doll) +{ + for (unsigned int i = 0; i < TILEP_PART_MAX; i++) + { + doll.parts[i] = unmarshallLong(th); + } +} + +static void marshallDoll(writer &th, const dolls_data &doll) +{ + for (unsigned int i = 0; i < TILEP_PART_MAX; i++) + { + marshallLong(th, doll.parts[i]); + } +} + +static void unmarshallDemon(reader &th, demon_data &demon) +{ + demon.head = unmarshallLong(th); + demon.body = unmarshallLong(th); + demon.wings = unmarshallLong(th); +} + +static void marshallDemon(writer &th, const demon_data &demon) +{ + marshallLong(th, demon.head); + marshallLong(th, demon.body); + marshallLong(th, demon.wings); +} + +// Internal mcache classes. The mcache_manager creates these internally. +// The only access external clients need is through the virtual +// info function. + +class mcache_monster : public mcache_entry +{ +public: + mcache_monster(const monsters *mon); + mcache_monster(reader &th); + + virtual unsigned int info(tile_draw_info *dinfo) const; + + static bool valid(const monsters *mon); + + static bool get_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y); + + virtual void construct(writer &th); + +protected: + int m_mon_tile; + int m_equ_tile; +}; + +class mcache_draco : public mcache_entry +{ +public: + mcache_draco(const monsters *mon); + mcache_draco(reader &th); + + virtual const dolls_data *doll() const; + + static bool valid(const monsters *mon); + + virtual void construct(writer &th); + +protected: + dolls_data m_doll; +}; + +class mcache_ghost : public mcache_entry +{ +public: + mcache_ghost(const monsters *mon); + mcache_ghost(reader &th); + + virtual const dolls_data *doll() const; + + static bool valid(const monsters *mon); + + virtual void construct(writer &th); + +protected: + dolls_data m_doll; +}; + +class mcache_demon : public mcache_entry +{ +public: + mcache_demon(const monsters *mon); + mcache_demon(reader &th); + + virtual unsigned int info(tile_draw_info *dinfo) const; + + static bool valid(const monsters *mon); + + virtual void construct(writer &th); + +protected: + demon_data m_demon; +}; + +///////////////////////////////////////////////////////////////////////////// +// tile_fg_store + +unsigned int tile_fg_store::operator=(unsigned int tile) +{ + if (tile & TILE_FLAG_MASK == m_tile & TILE_FLAG_MASK) + { + // update, as flags may have changed. + m_tile = tile; + return m_tile; + } + + mcache_entry *old_entry = mcache.get(m_tile); + if (old_entry) + old_entry->dec_ref(); + + m_tile = tile; + + mcache_entry *new_entry = mcache.get(m_tile); + if (new_entry) + new_entry->inc_ref(); + + return m_tile; +} + + +///////////////////////////////////////////////////////////////////////////// +// mcache_manager + +mcache_manager::~mcache_manager() +{ + clear_all(); +} + +unsigned int mcache_manager::register_monster(const monsters *mon) +{ + assert(mon); + if (!mon) + return 0; + + // TODO enne - is it worth it to search against all mcache entries? + // TODO enne - pool mcache types to avoid too much alloc/dealloc? + + mcache_entry *entry; + + if (mcache_demon::valid(mon)) + { + entry = new mcache_demon(mon); + } + else if (mcache_ghost::valid(mon)) + { + entry = new mcache_ghost(mon); + } + else if (mcache_draco::valid(mon)) + { + entry = new mcache_draco(mon); + } + else if (mcache_monster::valid(mon)) + { + entry = new mcache_monster(mon); + } + else + { + return 0; + } + + unsigned int idx = ~0; + + for (unsigned int i = 0; i < m_entries.size(); i++) + { + if (!m_entries[i]) + { + m_entries[i] = entry; + idx = i; + break; + } + } + + if (idx > m_entries.size()) + { + idx = m_entries.size(); + m_entries.push_back(entry); + } + + return TILEP_MCACHE_START + idx; +} + +void mcache_manager::clear_nonref() +{ + for (unsigned int i = 0; i < m_entries.size(); i++) + { + if (!m_entries[i] || m_entries[i]->ref_count() > 0) + continue; + + delete m_entries[i]; + m_entries[i] = NULL; + } +} + +void mcache_manager::clear_all() +{ + for (unsigned int i = 0; i < m_entries.size(); i++) + { + delete m_entries[i]; + } + m_entries.resize(0); +} + +mcache_entry *mcache_manager::get(unsigned int tile) +{ + unsigned int idx = tile & TILE_FLAG_MASK; + if (idx < TILEP_MCACHE_START) + return NULL; + + if (idx >= TILEP_MCACHE_START + m_entries.size()) + return NULL; + + mcache_entry *entry = m_entries[idx - TILEP_MCACHE_START]; + return (entry); +} + +void mcache_manager::read(reader &th) +{ + unsigned int size = unmarshallLong(th); + m_entries.reserve(size); + m_entries.clear(); + + for (unsigned int i = 0; i < size; i++) + { + char type = unmarshallByte(th); + + mcache_entry *entry; + switch (type) + { + case MCACHE_MONSTER: + entry = new mcache_monster(th); + break; + case MCACHE_DRACO: + entry = new mcache_draco(th); + break; + case MCACHE_GHOST: + entry = new mcache_ghost(th); + break; + case MCACHE_DEMON: + entry = new mcache_demon(th); + break; + default: + ASSERT(!"Invalid streamed mcache type."); + case MCACHE_NULL: + entry = NULL; + break; + } + + m_entries.push_back(entry); + } +} + +void mcache_manager::construct(writer &th) +{ + marshallLong(th, m_entries.size()); + for (unsigned int i = 0; i < m_entries.size(); i++) + { + if (m_entries[i] == NULL) + { + marshallByte(th, MCACHE_NULL); + continue; + } + + if (dynamic_cast<mcache_monster*>(m_entries[i])) + marshallByte(th, MCACHE_MONSTER); + else if (dynamic_cast<mcache_draco*>(m_entries[i])) + marshallByte(th, MCACHE_DRACO); + else if (dynamic_cast<mcache_ghost*>(m_entries[i])) + marshallByte(th, MCACHE_GHOST); + else if (dynamic_cast<mcache_demon*>(m_entries[i])) + marshallByte(th, MCACHE_DEMON); + else + { + marshallByte(th, MCACHE_NULL); + continue; + } + + m_entries[i]->construct(th); + } +} + +///////////////////////////////////////////////////////////////////////////// +// mcache_entry + +mcache_entry::mcache_entry(reader &th) +{ + m_ref_count = unmarshallLong(th); +} + +void mcache_entry::construct(writer &th) +{ + marshallLong(th, m_ref_count); +} + +///////////////////////////////////////////////////////////////////////////// +// mcache_monster + +mcache_monster::mcache_monster(const monsters *mon) +{ + assert(mcache_monster::valid(mon)); + + m_mon_tile = tileidx_monster(mon, false) & TILE_FLAG_MASK; + + int mon_wep = mon->inv[MSLOT_WEAPON]; + m_equ_tile = tilep_equ_weapon(mitm[mon_wep]); +} + +bool mcache_monster::get_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y) +{ + switch (mon_tile) + { + case TILEP_MONS_VAULT_GUARD: + case TILEP_MONS_HOBGOBLIN: + case TILEP_MONS_DEEP_ELF_MASTER_ARCHER: + case TILEP_MONS_IMP: + case TILEP_MONS_ANGEL: + case TILEP_MONS_NORRIS: + case TILEP_MONS_MAUD: + case TILEP_MONS_DUANE: + case TILEP_MONS_EDMUND: + case TILEP_MONS_FRANCES: + case TILEP_MONS_HAROLD: + case TILEP_MONS_JOSEPH: + case TILEP_MONS_JOZEF: + case TILEP_MONS_RUPERT: + case TILEP_MONS_TERENCE: + case TILEP_MONS_WAYNE: + case TILEP_MONS_FREDERICK: + case TILEP_MONS_RAKSHASA: + case TILEP_MONS_RAKSHASA_FAKE: + case TILEP_MONS_VAMPIRE_KNIGHT: + case TILEP_MONS_SKELETAL_WARRIOR: + case TILEP_MONS_MERMAID: + case TILEP_MONS_MERMAID_WATER: + case TILEP_MONS_MERFOLK_FIGHTER: + case TILEP_MONS_MERFOLK_FIGHTER_WATER: + ofs_x = 0; + ofs_y = 0; + break; + case TILEP_MONS_ORC: + case TILEP_MONS_URUG: + case TILEP_MONS_BLORK_THE_ORC: + case TILEP_MONS_ORC_WARRIOR: + case TILEP_MONS_ORC_KNIGHT: + case TILEP_MONS_ORC_WARLORD: + ofs_x = 0; + ofs_y = 2; + break; + case TILEP_MONS_GOBLIN: + case TILEP_MONS_IJYB: + ofs_x = 0; + ofs_y = 4; + break; + case TILEP_MONS_GNOLL: + ofs_x = -1; + ofs_y = 0; + break; + case TILEP_MONS_BOGGART: + case TILEP_MONS_DEEP_ELF_FIGHTER: + case TILEP_MONS_DEEP_ELF_SOLDIER: + ofs_x = 0; + ofs_y = 2; + break; + case TILEP_MONS_DEEP_ELF_KNIGHT: + ofs_x = 0; + ofs_y = 1; + break; + case TILEP_MONS_KOBOLD: + ofs_x = 3; + ofs_y = 4; + break; + case TILEP_MONS_KOBOLD_DEMONOLOGIST: + ofs_x = 0; + ofs_y = -10; + break; + case TILEP_MONS_BIG_KOBOLD: + ofs_x = 2; + ofs_y = 3; + break; + case TILEP_MONS_MIDGE: + ofs_x = 0; + ofs_y = -2; + break; + case TILEP_MONS_NAGA: + case TILEP_MONS_GREATER_NAGA: + case TILEP_MONS_NAGA_WARRIOR: + case TILEP_MONS_GUARDIAN_NAGA: + case TILEP_MONS_NAGA_MAGE: + ofs_x = 0; + ofs_y = 1; + break; + case TILEP_MONS_HELL_KNIGHT: + ofs_x = -1; + ofs_y = 3; + break; + case TILEP_MONS_RED_DEVIL: + ofs_x = 2; + ofs_y = -3; + break; + case TILEP_MONS_WIZARD: + ofs_x = 2; + ofs_y = -2; + break; + case TILEP_MONS_HUMAN: + ofs_x = 5; + ofs_y = 2; + break; + case TILEP_MONS_ELF: + ofs_y = 1; + ofs_x = 4; + break; + case TILEP_MONS_OGRE_MAGE: + ofs_y = -2; + ofs_x = -4; + break; + case TILEP_MONS_DEEP_ELF_MAGE: + case TILEP_MONS_DEEP_ELF_SUMMONER: + case TILEP_MONS_DEEP_ELF_CONJURER: + case TILEP_MONS_DEEP_ELF_PRIEST: + case TILEP_MONS_DEEP_ELF_HIGH_PRIEST: + case TILEP_MONS_DEEP_ELF_DEMONOLOGIST: + case TILEP_MONS_DEEP_ELF_ANNIHILATOR: + case TILEP_MONS_DEEP_ELF_SORCERER: + ofs_x = -1; + ofs_y = -2; + break; + case TILEP_MONS_DEEP_ELF_DEATH_MAGE: + ofs_x = -1; + ofs_y = 0; + break; + default: + // This monster cannot be displayed with a weapon. + return false; + } + + return true; +} + +unsigned int mcache_monster::info(tile_draw_info *dinfo) const +{ + int ofs_x, ofs_y; + get_weapon_offset(m_mon_tile, ofs_x, ofs_y); + + dinfo[0].set(m_mon_tile); + dinfo[1].set(m_equ_tile, ofs_x, ofs_y); + + // In some cases, overlay a second weapon tile... + if (m_mon_tile == TILEP_MONS_DEEP_ELF_BLADEMASTER) + { + int eq2; + switch (m_equ_tile) + { + case TILEP_HAND1_DAGGER: + eq2 = TILEP_HAND2_DAGGER; + break; + case TILEP_HAND1_SABRE: + eq2 = TILEP_HAND2_SABRE; + break; + default: + case TILEP_HAND1_SHORT_SWORD_SLANT: + eq2 = TILEP_HAND2_SHORT_SWORD_SLANT; + break; + }; + + dinfo[2].set(eq2, -ofs_x, ofs_y); + + return 3; + } + else + { + return 2; + } +} + +bool mcache_monster::valid(const monsters *mon) +{ + if (!mon) + return false; + int mon_wep = mon->inv[MSLOT_WEAPON]; + if (mon_wep == NON_ITEM) + return false; + + int mon_tile = tileidx_monster(mon, false) & TILE_FLAG_MASK; + + int ox, oy; + return get_weapon_offset(mon_tile, ox, oy); +} + +mcache_monster::mcache_monster(reader &th) : mcache_entry(th) +{ + m_mon_tile = unmarshallLong(th); + m_equ_tile = unmarshallLong(th); +} + +void mcache_monster::construct(writer &th) +{ + mcache_entry::construct(th); + + marshallLong(th, m_mon_tile); + marshallLong(th, m_equ_tile); +} + +///////////////////////////////////////////////////////////////////////////// +// mcache_draco + +mcache_draco::mcache_draco(const monsters *mon) +{ + assert(mcache_draco::valid(mon)); + + int draco = draco_subspecies(mon); + int colour; + switch (draco) + { + default: + case MONS_DRACONIAN: colour = 0; break; + case MONS_BLACK_DRACONIAN: colour = 1; break; + case MONS_YELLOW_DRACONIAN: colour = 2; break; + case MONS_GREEN_DRACONIAN: colour = 4; break; + case MONS_MOTTLED_DRACONIAN:colour = 5; break; + case MONS_PALE_DRACONIAN: colour = 6; break; + case MONS_PURPLE_DRACONIAN: colour = 7; break; + case MONS_RED_DRACONIAN: colour = 8; break; + case MONS_WHITE_DRACONIAN: colour = 9; break; + } + + m_doll.parts[TILEP_PART_SHADOW] = TILEP_SHADOW_SHADOW; + m_doll.parts[TILEP_PART_BASE] = TILEP_BASE_DRACONIAN + colour * 2; + m_doll.parts[TILEP_PART_DRCWING] = + tile_player_part_start[TILEP_PART_DRCWING] + colour; + m_doll.parts[TILEP_PART_DRCHEAD] = + tile_player_part_start[TILEP_PART_DRCHEAD] + colour; + + int mon_wep = mon->inv[MSLOT_WEAPON]; + int equ_tile = (mon_wep != NON_ITEM) ? tilep_equ_weapon(mitm[mon_wep]) : 0; + + switch (mon->type) + { + case MONS_DRACONIAN_CALLER: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_EVIL; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_YELLOW; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_BROWN; + break; + + case MONS_DRACONIAN_MONK: + m_doll.parts[TILEP_PART_ARM] = TILEP_ARM_GLOVE_SHORT_BLUE; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_KARATE2; + break; + + case MONS_DRACONIAN_ZEALOT: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MACE; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_CYAN; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_MONK_BLUE; + break; + + case MONS_DRACONIAN_SHIFTER: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_LARGE; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_GREEN; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_CYAN; + break; + + case MONS_DRACONIAN_ANNIHILATOR: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_STAFF_RUBY; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_FIRE_CYAN; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_GREEN_GOLD; + break; + + case MONS_DRACONIAN_KNIGHT: + m_doll.parts[TILEP_PART_HAND1] = equ_tile; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_SHIELD_KNIGHT_GRAY; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_BPLATE_METAL1; + m_doll.parts[TILEP_PART_LEG] = TILEP_LEG_BELT_GRAY; + break; + + case MONS_DRACONIAN_SCORCHER: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FIRE_RED; + m_doll.parts[TILEP_PART_HAND2] = TILEP_HAND2_BOOK_RED; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_ROBE_RED; + break; + + default: + m_doll.parts[TILEP_PART_HAND1] = equ_tile; + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_BELT2; + m_doll.parts[TILEP_PART_LEG] = TILEP_LEG_LOINCLOTH_RED; + break; + } +} + +const dolls_data *mcache_draco::doll() const +{ + return &m_doll; +} + +bool mcache_draco::valid(const monsters *mon) +{ + return (mon && mon->type >= MONS_FIRST_DRACONIAN + && mon->type <= MONS_LAST_DRACONIAN); +} + +mcache_draco::mcache_draco(reader &th) : mcache_entry(th) +{ + unmarshallDoll(th, m_doll); +} + +void mcache_draco::construct(writer &th) +{ + mcache_entry::construct(th); + + marshallDoll(th, m_doll); +} + +///////////////////////////////////////////////////////////////////////////// +// mcache_ghost + +mcache_ghost::mcache_ghost(const monsters *mon) +{ + assert(mcache_ghost::valid(mon)); + + const struct ghost_demon &ghost = *mon->ghost; + + unsigned int pseudo_rand = ghost.max_hp * 54321 * 54321; + int gender = (pseudo_rand >> 8) & 1; + + tilep_race_default(ghost.species, gender, + ghost.xl, m_doll.parts); + tilep_job_default(ghost.job, gender, m_doll.parts); + + for (int p = TILEP_PART_CLOAK; p < TILEP_PART_MAX; p++) + { + if (m_doll.parts[p] == TILEP_SHOW_EQUIP) + { + int part_offset = pseudo_rand % tile_player_part_count[p]; + m_doll.parts[p] = tile_player_part_start[p] + part_offset; + } + } + + int ac = ghost.ac; + ac *= (5 + (pseudo_rand / 11) % 11); + ac /= 10; + + if (ac > 25) + m_doll.parts[TILEP_PART_BODY] = TILEP_BODY_PLATE_BLACK; + else if (ac > 20) + m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_BANDED; + else if (ac > 15) + m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_SCALEMAIL; + else if (ac > 10) + m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_CHAINMAIL; + else if (ac > 5 ) + m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_LEATHER_HEAVY; + else + m_doll.parts[TILEP_PART_BODY]= TILEP_BODY_ROBE_BLUE; + + int sk = ghost.best_skill; + int dam = ghost.damage; + dam *= (5 + pseudo_rand % 11); + dam /= 10; + + switch (sk) + { + case SK_MACES_FLAILS: + if (dam > 30) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_FRAIL; + else if (dam > 25) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_MACE; + else if (dam > 20) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SPIKED_FRAIL; + else if (dam > 15) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MORNINGSTAR; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FRAIL; + else if (dam > 5) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_MACE; + else + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CLUB_SLANT; + break; + + case SK_SHORT_BLADES: + if (dam > 20) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SABRE; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SHORT_SWORD_SLANT; + else + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_DAGGER_SLANT; + break; + + case SK_LONG_BLADES: + if (dam > 25) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GREAT_SWORD_SLANT; + else if (dam > 20) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_KATANA_SLANT; + else if (dam > 15) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCIMITAR; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_LONG_SWORD_SLANT; + else + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_FALCHION; + break; + + case SK_AXES: + if (dam > 30) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_EXECUTIONERS_AXE; + else if (dam > 20) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BATTLEAXE; + else if (dam > 15) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BROAD_AXE; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_WAR_AXE; + else + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAND_AXE; + break; + + case SK_POLEARMS: + if (dam > 30) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_GLAIVE; + else if (dam > 20) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SCYTHE; + else if (dam > 15) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HALBERD; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_TRIDENT2; + else if (dam > 10) + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_HAMMER; + else + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SPEAR; + break; + + case SK_BOWS: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_BOW2; + break; + + case SK_CROSSBOWS: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_CROSSBOW; + break; + + case SK_SLINGS: + m_doll.parts[TILEP_PART_HAND1] = TILEP_HAND1_SLING; + break; + + case SK_UNARMED_COMBAT: + default: + m_doll.parts[TILEP_PART_HAND1] = m_doll.parts[TILEP_PART_HAND2] = 0; + break; + } +} + +const dolls_data *mcache_ghost::doll() const +{ + return &m_doll; +} + +bool mcache_ghost::valid(const monsters *mon) +{ + return (mon && mon->type == MONS_PLAYER_GHOST); +} + +mcache_ghost::mcache_ghost(reader &th) : mcache_entry(th) +{ + unmarshallDoll(th, m_doll); +} + +void mcache_ghost::construct(writer &th) +{ + mcache_entry::construct(th); + + marshallDoll(th, m_doll); +} + +///////////////////////////////////////////////////////////////////////////// +// mcache_demon + +mcache_demon::mcache_demon(const monsters *mon) +{ + assert(mcache_demon::valid(mon)); + + const struct ghost_demon &ghost = *mon->ghost; + + unsigned int pseudo_rand1 = ghost.max_hp * 54321 * 54321; + unsigned int pseudo_rand2 = ghost.ac * 54321 * 54321; + unsigned int pseudo_rand3 = ghost.ev * 54321 * 54321; + + int head_offset = pseudo_rand1 % tile_player_count(TILEP_DEMON_HEAD); + m_demon.head = TILEP_DEMON_HEAD + head_offset; + + int body_offset = pseudo_rand2 % tile_player_count(TILEP_DEMON_BODY); + m_demon.body = TILEP_DEMON_BODY + body_offset; + + if (ghost.ev % 2) + { + int wings_offset = pseudo_rand3 % tile_player_count(TILEP_DEMON_WINGS); + m_demon.wings = TILEP_DEMON_WINGS + wings_offset; + } + else + { + m_demon.wings = 0; + } +} + +unsigned int mcache_demon::info(tile_draw_info *dinfo) const +{ + if (m_demon.wings) + { + dinfo[0].set(m_demon.wings); + dinfo[1].set(m_demon.body); + dinfo[2].set(m_demon.head); + return 3; + } + else + { + dinfo[0].set(m_demon.body); + dinfo[1].set(m_demon.head); + return 2; + } +} + +bool mcache_demon::valid(const monsters *mon) +{ + return (mon && mon->type == MONS_PANDEMONIUM_DEMON); +} + +mcache_demon::mcache_demon(reader &th) : mcache_entry(th) +{ + unmarshallDemon(th, m_demon); +} + +void mcache_demon::construct(writer &th) +{ + mcache_entry::construct(th); + + marshallDemon(th, m_demon); +} diff --git a/crawl-ref/source/tilemcache.h b/crawl-ref/source/tilemcache.h new file mode 100644 index 0000000000..d170ae7de2 --- /dev/null +++ b/crawl-ref/source/tilemcache.h @@ -0,0 +1,80 @@ +/* + * File: tilemcache.h + * Summary: Monster cache support + * Written by: Enne Walker + */ + +#ifdef USE_TILE +#ifndef TILEMCACHE_H +#define TILEMCACHE_H + +#include "AppHdr.h" +#include "debug.h" +#include <vector> + +// The monster cache is designed to hold extra information about monsters that +// can't be contained in a single tile. This is usually for equipment, +// doll parts, or demon parts. +// +// Monster cache entries for monsters that are out of sight are ref-counted +// that they can be drawn even if that monster no longer exists. When no +// out-of-sight tiles refer to them, they can be deleted. + +class tile_draw_info +{ +public: + tile_draw_info() : idx(~0), ofs_x(0), ofs_y(0) {} + + void set(unsigned int _idx, int _ofs_x = 0, int _ofs_y = 0) + { idx = _idx; _ofs_x = ofs_x; _ofs_y = ofs_y; } + + unsigned int idx; + int ofs_x; + int ofs_y; +}; + +class mcache_entry +{ +public: + mcache_entry() : m_ref_count(0) {} + virtual ~mcache_entry() {} + + void inc_ref() { m_ref_count++; } + void dec_ref() { m_ref_count--; ASSERT(m_ref_count >= 0); } + int ref_count() { return m_ref_count; } + + virtual unsigned int info(tile_draw_info *dinfo) const { return 0; } + virtual const dolls_data *doll() const { return NULL; } + + virtual void construct(writer &th); + +protected: + mcache_entry(reader &th); + + // ref count in backstore + int m_ref_count; +}; + +class mcache_manager +{ +public: + ~mcache_manager(); + + unsigned int register_monster(const monsters *mon); + mcache_entry *get(unsigned int idx); + + void clear_nonref(); + void clear_all(); + + void read(reader &th); + void construct(writer &th); + +protected: + std::vector<mcache_entry*> m_entries; +}; + +// The global monster cache. +extern mcache_manager mcache; + +#endif +#endif diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index 695281c990..00afc11192 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -24,64 +24,12 @@ #include "stuff.h" #include "terrain.h" #include "tiles.h" +#include "tilemcache.h" #include "tiledef-dngn.h" #include "traps.h" #include "travel.h" #include "view.h" -struct mcache_entry -{ - int mon_tile; - int equ_tile; - int draco; -}; - -static std::vector<mcache_entry> mcache; - -int get_base_idx_from_mcache(int tile_idx) -{ - int mcache_idx = tile_idx - TILE_MCACHE_START; - if (mcache_idx >= 0 && mcache_idx < (int)mcache.size()) - { - return mcache[mcache_idx].mon_tile; - } - - return tile_idx; -} - -bool get_mcache_entry(int tile_idx, int &mon_idx, int &equ_tile, int &draco) -{ - int mcache_idx = tile_idx - TILE_MCACHE_START; - if (mcache_idx >= 0 && (unsigned int)mcache_idx < mcache.size()) - { - mon_idx = mcache[mcache_idx].mon_tile; - equ_tile = mcache[mcache_idx].equ_tile; - draco = mcache[mcache_idx].draco; - - return true; - } - - return false; -} - -static int _mcache_register(int mon_tile, int equ_tile, int draco = 0) -{ - mcache_entry entry; - entry.mon_tile = mon_tile; - entry.equ_tile = equ_tile; - entry.draco = draco; - - mcache.push_back(entry); - - int idx = TILE_MCACHE_START + mcache.size() - 1; - return idx; -} - -void tile_mcache_unlock() -{ - mcache.clear(); -} - static inline bool _is_bazaar() { return (you.level_type == LEVEL_PORTAL_VAULT @@ -154,9 +102,8 @@ int tile_unseen_flag(const coord_def& gc) } } -static int _tileidx_monster_base(int mon_idx, bool detected) +static int _tileidx_monster_base(const monsters* mon, bool detected) { - const monsters* mon = &menv[mon_idx]; int grid = grd(mon->pos()); bool in_water = (grid == DNGN_SHALLOW_WATER || grid == DNGN_DEEP_WATER); @@ -169,633 +116,633 @@ static int _tileidx_monster_base(int mon_idx, bool detected) switch (type) { case MONS_GIANT_ANT: - return TILE_MONS_GIANT_ANT; + return TILEP_MONS_GIANT_ANT; case MONS_GIANT_BAT: - return TILE_MONS_GIANT_BAT; + return TILEP_MONS_GIANT_BAT; case MONS_CENTAUR: - return TILE_MONS_CENTAUR; + return TILEP_MONS_CENTAUR; case MONS_RED_DEVIL: - return TILE_MONS_RED_DEVIL; + return TILEP_MONS_RED_DEVIL; case MONS_ETTIN: - return TILE_MONS_ETTIN; + return TILEP_MONS_ETTIN; case MONS_FUNGUS: - return TILE_MONS_FUNGUS; + return TILEP_MONS_FUNGUS; case MONS_GOBLIN: - return TILE_MONS_GOBLIN; + return TILEP_MONS_GOBLIN; case MONS_HOUND: - return TILE_MONS_HOUND; + return TILEP_MONS_HOUND; case MONS_IMP: - return TILE_MONS_IMP; + return TILEP_MONS_IMP; case MONS_JACKAL: - return TILE_MONS_JACKAL; + return TILEP_MONS_JACKAL; case MONS_KILLER_BEE: - return TILE_MONS_KILLER_BEE; + return TILEP_MONS_KILLER_BEE; case MONS_KILLER_BEE_LARVA: - return TILE_MONS_KILLER_BEE_LARVA; + return TILEP_MONS_KILLER_BEE_LARVA; case MONS_MANTICORE: - return TILE_MONS_MANTICORE; + return TILEP_MONS_MANTICORE; case MONS_NECROPHAGE: - return TILE_MONS_NECROPHAGE; + return TILEP_MONS_NECROPHAGE; case MONS_ORC: - return TILE_MONS_ORC; + return TILEP_MONS_ORC; case MONS_PHANTOM: - return TILE_MONS_PHANTOM; + return TILEP_MONS_PHANTOM; case MONS_QUASIT: - return TILE_MONS_QUASIT; + return TILEP_MONS_QUASIT; case MONS_RAT: - return TILE_MONS_RAT; + return TILEP_MONS_RAT; case MONS_SCORPION: - return TILE_MONS_SCORPION; + return TILEP_MONS_SCORPION; case MONS_UGLY_THING : - return TILE_MONS_UGLY_THING ; + return TILEP_MONS_UGLY_THING ; case MONS_FIRE_VORTEX: - return TILE_MONS_FIRE_VORTEX; + return TILEP_MONS_FIRE_VORTEX; case MONS_WORM: - return TILE_MONS_WORM; + return TILEP_MONS_WORM; case MONS_ABOMINATION_SMALL: - return TILE_MONS_ABOMINATION_SMALL; + return TILEP_MONS_ABOMINATION_SMALL; case MONS_YELLOW_WASP: - return TILE_MONS_YELLOW_WASP; + return TILEP_MONS_YELLOW_WASP; case MONS_ZOMBIE_SMALL: - return TILE_MONS_ZOMBIE_SMALL; + return TILEP_MONS_ZOMBIE_SMALL; case MONS_ANGEL: - return TILE_MONS_ANGEL; + return TILEP_MONS_ANGEL; case MONS_GIANT_BEETLE: - return TILE_MONS_GIANT_BEETLE; + return TILEP_MONS_GIANT_BEETLE; case MONS_CYCLOPS: - return TILE_MONS_CYCLOPS; + return TILEP_MONS_CYCLOPS; case MONS_DRAGON: - return TILE_MONS_DRAGON; + return TILEP_MONS_DRAGON; case MONS_TWO_HEADED_OGRE: - return TILE_MONS_TWO_HEADED_OGRE; + return TILEP_MONS_TWO_HEADED_OGRE; case MONS_FIEND: - return TILE_MONS_FIEND; + return TILEP_MONS_FIEND; case MONS_GIANT_SPORE: - return TILE_MONS_GIANT_SPORE; + return TILEP_MONS_GIANT_SPORE; case MONS_HOBGOBLIN: - return TILE_MONS_HOBGOBLIN; + return TILEP_MONS_HOBGOBLIN; case MONS_ICE_BEAST: - return TILE_MONS_ICE_BEAST; + return TILEP_MONS_ICE_BEAST; case MONS_JELLY: - return TILE_MONS_JELLY; + return TILEP_MONS_JELLY; case MONS_KOBOLD: - return TILE_MONS_KOBOLD; + return TILEP_MONS_KOBOLD; case MONS_LICH: - return TILE_MONS_LICH; + return TILEP_MONS_LICH; case MONS_MUMMY: - return TILE_MONS_MUMMY; + return TILEP_MONS_MUMMY; case MONS_GUARDIAN_NAGA: - return TILE_MONS_GUARDIAN_NAGA; + return TILEP_MONS_GUARDIAN_NAGA; case MONS_OGRE: - return TILE_MONS_OGRE; + return TILEP_MONS_OGRE; case MONS_PLANT: - return TILE_MONS_PLANT; + return TILEP_MONS_PLANT; case MONS_QUEEN_BEE: - return TILE_MONS_QUEEN_BEE; + return TILEP_MONS_QUEEN_BEE; case MONS_RAKSHASA: - return TILE_MONS_RAKSHASA; + return TILEP_MONS_RAKSHASA; case MONS_SNAKE: - return TILE_MONS_SNAKE; + return TILEP_MONS_SNAKE; case MONS_TROLL: - return TILE_MONS_TROLL; + return TILEP_MONS_TROLL; case MONS_UNSEEN_HORROR: - return TILE_MONS_UNSEEN_HORROR; + return TILEP_MONS_UNSEEN_HORROR; case MONS_VAMPIRE: - return TILE_MONS_VAMPIRE; + return TILEP_MONS_VAMPIRE; case MONS_WRAITH: - return TILE_MONS_WRAITH; + return TILEP_MONS_WRAITH; case MONS_ABOMINATION_LARGE: - return TILE_MONS_ABOMINATION_LARGE + ((mon->colour)%7); + return TILEP_MONS_ABOMINATION_LARGE + ((mon->colour)%7); case MONS_YAK: - return TILE_MONS_YAK; + return TILEP_MONS_YAK; case MONS_ZOMBIE_LARGE: - return TILE_MONS_ZOMBIE_LARGE; + return TILEP_MONS_ZOMBIE_LARGE; case MONS_ORC_WARRIOR: - return TILE_MONS_ORC_WARRIOR; + return TILEP_MONS_ORC_WARRIOR; case MONS_KOBOLD_DEMONOLOGIST: - return TILE_MONS_KOBOLD_DEMONOLOGIST; + return TILEP_MONS_KOBOLD_DEMONOLOGIST; case MONS_ORC_WIZARD: - return TILE_MONS_ORC_WIZARD; + return TILEP_MONS_ORC_WIZARD; case MONS_ORC_KNIGHT: - return TILE_MONS_ORC_KNIGHT; + return TILEP_MONS_ORC_KNIGHT; case MONS_WYVERN: - return TILE_MONS_WYVERN; + return TILEP_MONS_WYVERN; case MONS_BIG_KOBOLD: - return TILE_MONS_BIG_KOBOLD; + return TILEP_MONS_BIG_KOBOLD; case MONS_GIANT_EYEBALL: - return TILE_MONS_GIANT_EYEBALL; + return TILEP_MONS_GIANT_EYEBALL; case MONS_WIGHT: - return TILE_MONS_WIGHT; + return TILEP_MONS_WIGHT; case MONS_OKLOB_PLANT: - return TILE_MONS_OKLOB_PLANT; + return TILEP_MONS_OKLOB_PLANT; case MONS_WOLF_SPIDER: - return TILE_MONS_WOLF_SPIDER; + return TILEP_MONS_WOLF_SPIDER; case MONS_SHADOW: - return TILE_MONS_SHADOW; + return TILEP_MONS_SHADOW; case MONS_HUNGRY_GHOST: - return TILE_MONS_HUNGRY_GHOST; + return TILEP_MONS_HUNGRY_GHOST; case MONS_EYE_OF_DRAINING: - return TILE_MONS_EYE_OF_DRAINING; + return TILEP_MONS_EYE_OF_DRAINING; case MONS_BUTTERFLY: - return TILE_MONS_BUTTERFLY + ((mon->colour)%7); + return TILEP_MONS_BUTTERFLY + ((mon->colour)%7); case MONS_WANDERING_MUSHROOM: - return TILE_MONS_WANDERING_MUSHROOM; + return TILEP_MONS_WANDERING_MUSHROOM; case MONS_EFREET: - return TILE_MONS_EFREET; + return TILEP_MONS_EFREET; case MONS_BRAIN_WORM: - return TILE_MONS_BRAIN_WORM; + return TILEP_MONS_BRAIN_WORM; case MONS_GIANT_ORANGE_BRAIN: - return TILE_MONS_GIANT_ORANGE_BRAIN; + return TILEP_MONS_GIANT_ORANGE_BRAIN; case MONS_BOULDER_BEETLE: - return TILE_MONS_BOULDER_BEETLE; + return TILEP_MONS_BOULDER_BEETLE; case MONS_FLYING_SKULL: - return TILE_MONS_FLYING_SKULL; + return TILEP_MONS_FLYING_SKULL; case MONS_HELL_HOUND: - return TILE_MONS_HELL_HOUND; + return TILEP_MONS_HELL_HOUND; case MONS_MINOTAUR: - return TILE_MONS_MINOTAUR; + return TILEP_MONS_MINOTAUR; case MONS_ICE_DRAGON: - return TILE_MONS_ICE_DRAGON; + return TILEP_MONS_ICE_DRAGON; case MONS_SLIME_CREATURE: - return TILE_MONS_SLIME_CREATURE; + return TILEP_MONS_SLIME_CREATURE; case MONS_FREEZING_WRAITH: - return TILE_MONS_FREEZING_WRAITH; + return TILEP_MONS_FREEZING_WRAITH; case MONS_RAKSHASA_FAKE: - return TILE_MONS_RAKSHASA_FAKE; + return TILEP_MONS_RAKSHASA_FAKE; case MONS_GREAT_ORB_OF_EYES: - return TILE_MONS_GREAT_ORB_OF_EYES; + return TILEP_MONS_GREAT_ORB_OF_EYES; case MONS_HELLION: - return TILE_MONS_HELLION; + return TILEP_MONS_HELLION; case MONS_ROTTING_DEVIL: - return TILE_MONS_ROTTING_DEVIL; + return TILEP_MONS_ROTTING_DEVIL; case MONS_TORMENTOR: - return TILE_MONS_TORMENTOR; + return TILEP_MONS_TORMENTOR; case MONS_REAPER: - return TILE_MONS_REAPER; + return TILEP_MONS_REAPER; case MONS_SOUL_EATER: - return TILE_MONS_SOUL_EATER; + return TILEP_MONS_SOUL_EATER; case MONS_HAIRY_DEVIL: - return TILE_MONS_HAIRY_DEVIL; + return TILEP_MONS_HAIRY_DEVIL; case MONS_ICE_DEVIL: - return TILE_MONS_ICE_DEVIL; + return TILEP_MONS_ICE_DEVIL; case MONS_BLUE_DEVIL: - return TILE_MONS_BLUE_DEVIL; + return TILEP_MONS_BLUE_DEVIL; case MONS_BEAST: - return TILE_MONS_BEAST; + return TILEP_MONS_BEAST; case MONS_IRON_DEVIL: - return TILE_MONS_IRON_DEVIL; + return TILEP_MONS_IRON_DEVIL; case MONS_GLOWING_SHAPESHIFTER: - return TILE_MONS_GLOWING_SHAPESHIFTER; + return TILEP_MONS_GLOWING_SHAPESHIFTER; case MONS_SHAPESHIFTER: - return TILE_MONS_SHAPESHIFTER; + return TILEP_MONS_SHAPESHIFTER; case MONS_GIANT_MITE: - return TILE_MONS_GIANT_MITE; + return TILEP_MONS_GIANT_MITE; case MONS_STEAM_DRAGON: - return TILE_MONS_STEAM_DRAGON; + return TILEP_MONS_STEAM_DRAGON; case MONS_VERY_UGLY_THING: - return TILE_MONS_VERY_UGLY_THING; + return TILEP_MONS_VERY_UGLY_THING; case MONS_ORC_SORCERER: - return TILE_MONS_ORC_SORCERER; + return TILEP_MONS_ORC_SORCERER; case MONS_HIPPOGRIFF: - return TILE_MONS_HIPPOGRIFF; + return TILEP_MONS_HIPPOGRIFF; case MONS_GRIFFON: - return TILE_MONS_GRIFFON; + return TILEP_MONS_GRIFFON; case MONS_HYDRA: // Number of heads - return TILE_MONS_HYDRA + std::min((int)mon->number, 7) - 1; + return TILEP_MONS_HYDRA + std::min((int)mon->number, 7) - 1; case MONS_SKELETON_SMALL: - return TILE_MONS_SKELETON_SMALL; + return TILEP_MONS_SKELETON_SMALL; case MONS_SKELETON_LARGE: - return TILE_MONS_SKELETON_LARGE; + return TILEP_MONS_SKELETON_LARGE; case MONS_HELL_KNIGHT: - return TILE_MONS_HELL_KNIGHT; + return TILEP_MONS_HELL_KNIGHT; case MONS_NECROMANCER: - return TILE_MONS_NECROMANCER; + return TILEP_MONS_NECROMANCER; case MONS_WIZARD: - return TILE_MONS_WIZARD; + return TILEP_MONS_WIZARD; case MONS_ORC_PRIEST: - return TILE_MONS_ORC_PRIEST; + return TILEP_MONS_ORC_PRIEST; case MONS_ORC_HIGH_PRIEST: - return TILE_MONS_ORC_HIGH_PRIEST; + return TILEP_MONS_ORC_HIGH_PRIEST; case MONS_HUMAN: - return TILE_MONS_HUMAN; + return TILEP_MONS_HUMAN; case MONS_GNOLL: - return TILE_MONS_GNOLL; + return TILEP_MONS_GNOLL; case MONS_CLAY_GOLEM: - return TILE_MONS_CLAY_GOLEM; + return TILEP_MONS_CLAY_GOLEM; case MONS_WOOD_GOLEM: - return TILE_MONS_WOOD_GOLEM; + return TILEP_MONS_WOOD_GOLEM; case MONS_STONE_GOLEM: - return TILE_MONS_STONE_GOLEM; + return TILEP_MONS_STONE_GOLEM; case MONS_IRON_GOLEM: - return TILE_MONS_IRON_GOLEM; + return TILEP_MONS_IRON_GOLEM; case MONS_CRYSTAL_GOLEM: - return TILE_MONS_CRYSTAL_GOLEM; + return TILEP_MONS_CRYSTAL_GOLEM; case MONS_TOENAIL_GOLEM: - return TILE_MONS_TOENAIL_GOLEM; + return TILEP_MONS_TOENAIL_GOLEM; case MONS_MOTTLED_DRAGON: - return TILE_MONS_MOTTLED_DRAGON; + return TILEP_MONS_MOTTLED_DRAGON; case MONS_EARTH_ELEMENTAL: - return TILE_MONS_EARTH_ELEMENTAL; + return TILEP_MONS_EARTH_ELEMENTAL; case MONS_FIRE_ELEMENTAL: - return TILE_MONS_FIRE_ELEMENTAL; + return TILEP_MONS_FIRE_ELEMENTAL; case MONS_AIR_ELEMENTAL: - return TILE_MONS_AIR_ELEMENTAL; + return TILEP_MONS_AIR_ELEMENTAL; case MONS_ICE_FIEND: - return TILE_MONS_ICE_FIEND; + return TILEP_MONS_ICE_FIEND; case MONS_SHADOW_FIEND: - return TILE_MONS_SHADOW_FIEND; + return TILEP_MONS_SHADOW_FIEND; case MONS_BROWN_SNAKE: - return TILE_MONS_BROWN_SNAKE; + return TILEP_MONS_BROWN_SNAKE; case MONS_GIANT_LIZARD: - return TILE_MONS_GIANT_LIZARD; + return TILEP_MONS_GIANT_LIZARD; case MONS_SPECTRAL_WARRIOR: - return TILE_MONS_SPECTRAL_WARRIOR; + return TILEP_MONS_SPECTRAL_WARRIOR; case MONS_PULSATING_LUMP: - return TILE_MONS_PULSATING_LUMP; + return TILEP_MONS_PULSATING_LUMP; case MONS_STORM_DRAGON: - return TILE_MONS_STORM_DRAGON; + return TILEP_MONS_STORM_DRAGON; case MONS_YAKTAUR: - return TILE_MONS_YAKTAUR; + return TILEP_MONS_YAKTAUR; case MONS_DEATH_YAK: - return TILE_MONS_DEATH_YAK; + return TILEP_MONS_DEATH_YAK; case MONS_ROCK_TROLL: - return TILE_MONS_ROCK_TROLL; + return TILEP_MONS_ROCK_TROLL; case MONS_STONE_GIANT: - return TILE_MONS_STONE_GIANT; + return TILEP_MONS_STONE_GIANT; case MONS_FLAYED_GHOST: - return TILE_MONS_FLAYED_GHOST; + return TILEP_MONS_FLAYED_GHOST; case MONS_BUMBLEBEE: - return TILE_MONS_BUMBLEBEE; + return TILEP_MONS_BUMBLEBEE; case MONS_REDBACK: - return TILE_MONS_REDBACK; + return TILEP_MONS_REDBACK; case MONS_INSUBSTANTIAL_WISP: - return TILE_MONS_INSUBSTANTIAL_WISP; + return TILEP_MONS_INSUBSTANTIAL_WISP; case MONS_VAPOUR: - return TILE_MONS_VAPOUR; + return TILEP_MONS_VAPOUR; case MONS_OGRE_MAGE: - return TILE_MONS_OGRE_MAGE; + return TILEP_MONS_OGRE_MAGE; case MONS_SPINY_WORM: - return TILE_MONS_SPINY_WORM; + return TILEP_MONS_SPINY_WORM; case MONS_DANCING_WEAPON: { // Use item tile - item_def item = mitm[menv[mon_idx].inv[MSLOT_WEAPON]]; + item_def item = mitm[mon->inv[MSLOT_WEAPON]]; return tileidx_item(item) | TILE_FLAG_ANIM_WEP; } case MONS_TITAN: - return TILE_MONS_TITAN; + return TILEP_MONS_TITAN; case MONS_GOLDEN_DRAGON: - return TILE_MONS_GOLDEN_DRAGON; + return TILEP_MONS_GOLDEN_DRAGON; case MONS_ELF: - return TILE_MONS_ELF; + return TILEP_MONS_ELF; case MONS_LINDWURM: - return TILE_MONS_LINDWURM; + return TILEP_MONS_LINDWURM; case MONS_ELEPHANT_SLUG: - return TILE_MONS_ELEPHANT_SLUG; + return TILEP_MONS_ELEPHANT_SLUG; case MONS_WAR_DOG: - return TILE_MONS_WAR_DOG; + return TILEP_MONS_WAR_DOG; case MONS_GREY_RAT: - return TILE_MONS_GREY_RAT; + return TILEP_MONS_GREY_RAT; case MONS_GREEN_RAT: - return TILE_MONS_GREEN_RAT; + return TILEP_MONS_GREEN_RAT; case MONS_ORANGE_RAT: - return TILE_MONS_ORANGE_RAT; + return TILEP_MONS_ORANGE_RAT; case MONS_BLACK_SNAKE: - return TILE_MONS_BLACK_SNAKE; + return TILEP_MONS_BLACK_SNAKE; case MONS_SHEEP: - return TILE_MONS_SHEEP; + return TILEP_MONS_SHEEP; case MONS_GHOUL: - return TILE_MONS_GHOUL; + return TILEP_MONS_GHOUL; case MONS_HOG: - return TILE_MONS_HOG; + return TILEP_MONS_HOG; case MONS_GIANT_MOSQUITO: - return TILE_MONS_GIANT_MOSQUITO; + return TILEP_MONS_GIANT_MOSQUITO; case MONS_GIANT_CENTIPEDE: - return TILE_MONS_GIANT_CENTIPEDE; + return TILEP_MONS_GIANT_CENTIPEDE; case MONS_IRON_TROLL: - return TILE_MONS_IRON_TROLL; + return TILEP_MONS_IRON_TROLL; case MONS_NAGA: - return TILE_MONS_NAGA; + return TILEP_MONS_NAGA; case MONS_FIRE_GIANT: - return TILE_MONS_FIRE_GIANT; + return TILEP_MONS_FIRE_GIANT; case MONS_FROST_GIANT: - return TILE_MONS_FROST_GIANT; + return TILEP_MONS_FROST_GIANT; case MONS_FIREDRAKE: - return TILE_MONS_FIREDRAKE; + return TILEP_MONS_FIREDRAKE; case MONS_SHADOW_DRAGON: - return TILE_MONS_SHADOW_DRAGON; + return TILEP_MONS_SHADOW_DRAGON; case MONS_YELLOW_SNAKE: - return TILE_MONS_YELLOW_SNAKE; + return TILEP_MONS_YELLOW_SNAKE; case MONS_GREY_SNAKE: - return TILE_MONS_GREY_SNAKE; + return TILEP_MONS_GREY_SNAKE; case MONS_DEEP_TROLL: - return TILE_MONS_DEEP_TROLL; + return TILEP_MONS_DEEP_TROLL; case MONS_GIANT_BLOWFLY: - return TILE_MONS_GIANT_BLOWFLY; + return TILEP_MONS_GIANT_BLOWFLY; case MONS_RED_WASP: - return TILE_MONS_RED_WASP; + return TILEP_MONS_RED_WASP; case MONS_SWAMP_DRAGON: - return TILE_MONS_SWAMP_DRAGON; + return TILEP_MONS_SWAMP_DRAGON; case MONS_SWAMP_DRAKE: - return TILE_MONS_SWAMP_DRAKE; + return TILEP_MONS_SWAMP_DRAKE; case MONS_SOLDIER_ANT: - return TILE_MONS_SOLDIER_ANT; + return TILEP_MONS_SOLDIER_ANT; case MONS_HILL_GIANT: - return TILE_MONS_HILL_GIANT; + return TILEP_MONS_HILL_GIANT; case MONS_QUEEN_ANT: - return TILE_MONS_QUEEN_ANT; + return TILEP_MONS_QUEEN_ANT; case MONS_ANT_LARVA: - return TILE_MONS_ANT_LARVA; + return TILEP_MONS_ANT_LARVA; case MONS_GIANT_FROG: - return TILE_MONS_GIANT_FROG; + return TILEP_MONS_GIANT_FROG; case MONS_GIANT_BROWN_FROG: - return TILE_MONS_GIANT_BROWN_FROG; + return TILEP_MONS_GIANT_BROWN_FROG; case MONS_SPINY_FROG: - return TILE_MONS_SPINY_FROG; + return TILEP_MONS_SPINY_FROG; case MONS_BLINK_FROG: - return TILE_MONS_BLINK_FROG; + return TILEP_MONS_BLINK_FROG; case MONS_GIANT_COCKROACH: - return TILE_MONS_GIANT_COCKROACH; + return TILEP_MONS_GIANT_COCKROACH; case MONS_SMALL_SNAKE: - return TILE_MONS_SMALL_SNAKE; + return TILEP_MONS_SMALL_SNAKE; case MONS_SHUGGOTH: return TILE_TODO; case MONS_WOLF: - return TILE_MONS_WOLF; + return TILEP_MONS_WOLF; case MONS_WARG: - return TILE_MONS_WARG; + return TILEP_MONS_WARG; case MONS_BEAR: - return TILE_MONS_BEAR; + return TILEP_MONS_BEAR; case MONS_GRIZZLY_BEAR: - return TILE_MONS_GRIZZLY_BEAR; + return TILEP_MONS_GRIZZLY_BEAR; case MONS_POLAR_BEAR: - return TILE_MONS_POLAR_BEAR; + return TILEP_MONS_POLAR_BEAR; case MONS_BLACK_BEAR: - return TILE_MONS_BLACK_BEAR; + return TILEP_MONS_BLACK_BEAR; case MONS_SIMULACRUM_SMALL: - return TILE_MONS_SIMULACRUM_SMALL; + return TILEP_MONS_SIMULACRUM_SMALL; case MONS_SIMULACRUM_LARGE: - return TILE_MONS_SIMULACRUM_LARGE; + return TILEP_MONS_SIMULACRUM_LARGE; case MONS_WHITE_IMP: - return TILE_MONS_WHITE_IMP; + return TILEP_MONS_WHITE_IMP; case MONS_LEMURE: - return TILE_MONS_LEMURE; + return TILEP_MONS_LEMURE; case MONS_UFETUBUS: - return TILE_MONS_UFETUBUS; + return TILEP_MONS_UFETUBUS; case MONS_MANES: - return TILE_MONS_MANES; + return TILEP_MONS_MANES; case MONS_MIDGE: - return TILE_MONS_MIDGE; + return TILEP_MONS_MIDGE; case MONS_NEQOXEC: - return TILE_MONS_NEQOXEC; + return TILEP_MONS_NEQOXEC; case MONS_ORANGE_DEMON: - return TILE_MONS_ORANGE_DEMON; + return TILEP_MONS_ORANGE_DEMON; case MONS_HELLWING: - return TILE_MONS_HELLWING; + return TILEP_MONS_HELLWING; case MONS_SMOKE_DEMON: - return TILE_MONS_SMOKE_DEMON; + return TILEP_MONS_SMOKE_DEMON; case MONS_YNOXINUL: - return TILE_MONS_YNOXINUL; + return TILEP_MONS_YNOXINUL; case MONS_EXECUTIONER: - return TILE_MONS_EXECUTIONER; + return TILEP_MONS_EXECUTIONER; case MONS_GREEN_DEATH: - return TILE_MONS_GREEN_DEATH; + return TILEP_MONS_GREEN_DEATH; case MONS_BLUE_DEATH: - return TILE_MONS_BLUE_DEATH; + return TILEP_MONS_BLUE_DEATH; case MONS_BALRUG: - return TILE_MONS_BALRUG; + return TILEP_MONS_BALRUG; case MONS_CACODEMON: - return TILE_MONS_CACODEMON; + return TILEP_MONS_CACODEMON; case MONS_DEMONIC_CRAWLER: - return TILE_MONS_DEMONIC_CRAWLER; + return TILEP_MONS_DEMONIC_CRAWLER; case MONS_SUN_DEMON: - return TILE_MONS_SUN_DEMON; + return TILEP_MONS_SUN_DEMON; case MONS_SHADOW_IMP: - return TILE_MONS_SHADOW_IMP; + return TILEP_MONS_SHADOW_IMP; case MONS_SHADOW_DEMON: - return TILE_MONS_SHADOW_DEMON; + return TILEP_MONS_SHADOW_DEMON; case MONS_LOROCYPROCA: - return TILE_MONS_LOROCYPROCA; + return TILEP_MONS_LOROCYPROCA; case MONS_SHADOW_WRAITH: - return TILE_MONS_SHADOW_WRAITH; + return TILEP_MONS_SHADOW_WRAITH; case MONS_GIANT_AMOEBA: - return TILE_MONS_GIANT_AMOEBA; + return TILEP_MONS_GIANT_AMOEBA; case MONS_GIANT_SLUG: - return TILE_MONS_GIANT_SLUG; + return TILEP_MONS_GIANT_SLUG; case MONS_GIANT_SNAIL: - return TILE_MONS_GIANT_SNAIL; + return TILEP_MONS_GIANT_SNAIL; case MONS_SPATIAL_VORTEX: - return TILE_MONS_SPATIAL_VORTEX; + return TILEP_MONS_SPATIAL_VORTEX; case MONS_PIT_FIEND: - return TILE_MONS_PIT_FIEND; + return TILEP_MONS_PIT_FIEND; case MONS_BORING_BEETLE: - return TILE_MONS_BORING_BEETLE; + return TILEP_MONS_BORING_BEETLE; case MONS_GARGOYLE: - return TILE_MONS_GARGOYLE; + return TILEP_MONS_GARGOYLE; case MONS_METAL_GARGOYLE: - return TILE_MONS_METAL_GARGOYLE; + return TILEP_MONS_METAL_GARGOYLE; case MONS_MOLTEN_GARGOYLE: - return TILE_MONS_MOLTEN_GARGOYLE; + return TILEP_MONS_MOLTEN_GARGOYLE; case MONS_PROGRAM_BUG: - return TILE_MONS_PROGRAM_BUG; + return TILEP_MONS_PROGRAM_BUG; case MONS_MNOLEG: - return TILE_MONS_MNOLEG; + return TILEP_MONS_MNOLEG; case MONS_LOM_LOBON: - return TILE_MONS_LOM_LOBON; + return TILEP_MONS_LOM_LOBON; case MONS_CEREBOV: - return TILE_MONS_CEREBOV; + return TILEP_MONS_CEREBOV; case MONS_GLOORX_VLOQ: - return TILE_MONS_GLOORX_VLOQ; + return TILEP_MONS_GLOORX_VLOQ; case MONS_MOLLUSC_LORD: return TILE_TODO; case MONS_NAGA_MAGE: - return TILE_MONS_NAGA_MAGE; + return TILEP_MONS_NAGA_MAGE; case MONS_NAGA_WARRIOR: - return TILE_MONS_NAGA_WARRIOR; + return TILEP_MONS_NAGA_WARRIOR; case MONS_ORC_WARLORD: - return TILE_MONS_ORC_WARLORD; + return TILEP_MONS_ORC_WARLORD; case MONS_DEEP_ELF_SOLDIER: - return TILE_MONS_DEEP_ELF_SOLDIER; + return TILEP_MONS_DEEP_ELF_SOLDIER; case MONS_DEEP_ELF_FIGHTER: - return TILE_MONS_DEEP_ELF_FIGHTER; + return TILEP_MONS_DEEP_ELF_FIGHTER; case MONS_DEEP_ELF_KNIGHT: - return TILE_MONS_DEEP_ELF_KNIGHT; + return TILEP_MONS_DEEP_ELF_KNIGHT; case MONS_DEEP_ELF_MAGE: - return TILE_MONS_DEEP_ELF_MAGE; + return TILEP_MONS_DEEP_ELF_MAGE; case MONS_DEEP_ELF_SUMMONER: - return TILE_MONS_DEEP_ELF_SUMMONER; + return TILEP_MONS_DEEP_ELF_SUMMONER; case MONS_DEEP_ELF_CONJURER: - return TILE_MONS_DEEP_ELF_CONJURER; + return TILEP_MONS_DEEP_ELF_CONJURER; case MONS_DEEP_ELF_PRIEST: - return TILE_MONS_DEEP_ELF_PRIEST; + return TILEP_MONS_DEEP_ELF_PRIEST; case MONS_DEEP_ELF_HIGH_PRIEST: - return TILE_MONS_DEEP_ELF_HIGH_PRIEST; + return TILEP_MONS_DEEP_ELF_HIGH_PRIEST; case MONS_DEEP_ELF_DEMONOLOGIST: - return TILE_MONS_DEEP_ELF_DEMONOLOGIST; + return TILEP_MONS_DEEP_ELF_DEMONOLOGIST; case MONS_DEEP_ELF_ANNIHILATOR: - return TILE_MONS_DEEP_ELF_ANNIHILATOR; + return TILEP_MONS_DEEP_ELF_ANNIHILATOR; case MONS_DEEP_ELF_SORCERER: - return TILE_MONS_DEEP_ELF_SORCERER; + return TILEP_MONS_DEEP_ELF_SORCERER; case MONS_DEEP_ELF_DEATH_MAGE: - return TILE_MONS_DEEP_ELF_DEATH_MAGE; + return TILEP_MONS_DEEP_ELF_DEATH_MAGE; case MONS_BROWN_OOZE: - return TILE_MONS_BROWN_OOZE; + return TILEP_MONS_BROWN_OOZE; case MONS_AZURE_JELLY: - return TILE_MONS_AZURE_JELLY; + return TILEP_MONS_AZURE_JELLY; case MONS_DEATH_OOZE: - return TILE_MONS_DEATH_OOZE; + return TILEP_MONS_DEATH_OOZE; case MONS_ACID_BLOB: - return TILE_MONS_ACID_BLOB; + return TILEP_MONS_ACID_BLOB; case MONS_ROYAL_JELLY: - return TILE_MONS_ROYAL_JELLY; + return TILEP_MONS_ROYAL_JELLY; case MONS_TERENCE: - return TILE_MONS_TERENCE; + return TILEP_MONS_TERENCE; case MONS_JESSICA: - return TILE_MONS_JESSICA; + return TILEP_MONS_JESSICA; case MONS_IJYB: - return TILE_MONS_IJYB; + return TILEP_MONS_IJYB; case MONS_SIGMUND: - return TILE_MONS_SIGMUND; + return TILEP_MONS_SIGMUND; case MONS_BLORK_THE_ORC: - return TILE_MONS_BLORK_THE_ORC; + return TILEP_MONS_BLORK_THE_ORC; case MONS_EDMUND: - return TILE_MONS_EDMUND; + return TILEP_MONS_EDMUND; case MONS_PSYCHE: - return TILE_MONS_PSYCHE; + return TILEP_MONS_PSYCHE; case MONS_EROLCHA: - return TILE_MONS_EROLCHA; + return TILEP_MONS_EROLCHA; case MONS_DONALD: - return TILE_MONS_DONALD; + return TILEP_MONS_DONALD; case MONS_URUG: - return TILE_MONS_URUG; + return TILEP_MONS_URUG; case MONS_MICHAEL: - return TILE_MONS_MICHAEL; + return TILEP_MONS_MICHAEL; case MONS_JOSEPH: - return TILE_MONS_JOSEPH; + return TILEP_MONS_JOSEPH; case MONS_SNORG: - return TILE_MONS_SNORG; + return TILEP_MONS_SNORG; case MONS_ERICA: - return TILE_MONS_ERICA; + return TILEP_MONS_ERICA; case MONS_JOSEPHINE: - return TILE_MONS_JOSEPHINE; + return TILEP_MONS_JOSEPHINE; case MONS_HAROLD: - return TILE_MONS_HAROLD; + return TILEP_MONS_HAROLD; case MONS_NORBERT: - return TILE_MONS_NORBERT; + return TILEP_MONS_NORBERT; case MONS_JOZEF: - return TILE_MONS_JOZEF; + return TILEP_MONS_JOZEF; case MONS_AGNES: - return TILE_MONS_AGNES; + return TILEP_MONS_AGNES; case MONS_MAUD: - return TILE_MONS_MAUD; + return TILEP_MONS_MAUD; case MONS_LOUISE: - return TILE_MONS_LOUISE; + return TILEP_MONS_LOUISE; case MONS_FRANCIS: - return TILE_MONS_FRANCIS; + return TILEP_MONS_FRANCIS; case MONS_FRANCES: - return TILE_MONS_FRANCES; + return TILEP_MONS_FRANCES; case MONS_RUPERT: - return TILE_MONS_RUPERT; + return TILEP_MONS_RUPERT; case MONS_WAYNE: - return TILE_MONS_WAYNE; + return TILEP_MONS_WAYNE; case MONS_DUANE: - return TILE_MONS_DUANE; + return TILEP_MONS_DUANE; case MONS_XTAHUA: - return TILE_MONS_XTAHUA; + return TILEP_MONS_XTAHUA; case MONS_NORRIS: - return TILE_MONS_NORRIS; + return TILEP_MONS_NORRIS; case MONS_FREDERICK: - return TILE_MONS_FREDERICK; + return TILEP_MONS_FREDERICK; case MONS_MARGERY: - return TILE_MONS_MARGERY; + return TILEP_MONS_MARGERY; case MONS_POLYPHEMUS: - return TILE_MONS_POLYPHEMUS; + return TILEP_MONS_POLYPHEMUS; case MONS_BORIS: - return TILE_MONS_BORIS; + return TILEP_MONS_BORIS; // Draconians handled above case MONS_MURRAY: - return TILE_MONS_MURRAY; + return TILEP_MONS_MURRAY; case MONS_TIAMAT: - return TILE_MONS_TIAMAT; + return TILEP_MONS_TIAMAT; case MONS_DEEP_ELF_BLADEMASTER: - return TILE_MONS_DEEP_ELF_BLADEMASTER; + return TILEP_MONS_DEEP_ELF_BLADEMASTER; case MONS_DEEP_ELF_MASTER_ARCHER: - return TILE_MONS_DEEP_ELF_MASTER_ARCHER; + return TILEP_MONS_DEEP_ELF_MASTER_ARCHER; case MONS_GERYON: - return TILE_MONS_GERYON; + return TILEP_MONS_GERYON; case MONS_DISPATER: - return TILE_MONS_DISPATER; + return TILEP_MONS_DISPATER; case MONS_ASMODEUS: - return TILE_MONS_ASMODEUS; + return TILEP_MONS_ASMODEUS; case MONS_ANTAEUS: - return TILE_MONS_ANTAEUS; + return TILEP_MONS_ANTAEUS; case MONS_ERESHKIGAL: - return TILE_MONS_ERESHKIGAL; + return TILEP_MONS_ERESHKIGAL; case MONS_ANCIENT_LICH: - return TILE_MONS_ANCIENT_LICH; + return TILEP_MONS_ANCIENT_LICH; case MONS_OOZE: - return TILE_MONS_OOZE; + return TILEP_MONS_OOZE; case MONS_VAULT_GUARD: - return TILE_MONS_VAULT_GUARD; + return TILEP_MONS_VAULT_GUARD; case MONS_CURSE_SKULL: - return TILE_MONS_CURSE_SKULL; + return TILEP_MONS_CURSE_SKULL; case MONS_VAMPIRE_KNIGHT: - return TILE_MONS_VAMPIRE_KNIGHT; + return TILEP_MONS_VAMPIRE_KNIGHT; case MONS_VAMPIRE_MAGE: - return TILE_MONS_VAMPIRE_MAGE; + return TILEP_MONS_VAMPIRE_MAGE; case MONS_SHINING_EYE: - return TILE_MONS_SHINING_EYE; + return TILEP_MONS_SHINING_EYE; case MONS_ORB_GUARDIAN: - return TILE_MONS_ORB_GUARDIAN; + return TILEP_MONS_ORB_GUARDIAN; case MONS_DAEVA: - return TILE_MONS_DAEVA; + return TILEP_MONS_DAEVA; case MONS_SPECTRAL_THING: - return TILE_MONS_SPECTRAL_THING; + return TILEP_MONS_SPECTRAL_THING; case MONS_GREATER_NAGA: - return TILE_MONS_GREATER_NAGA; + return TILEP_MONS_GREATER_NAGA; case MONS_SKELETAL_DRAGON: - return TILE_MONS_SKELETAL_DRAGON; + return TILEP_MONS_SKELETAL_DRAGON; case MONS_TENTACLED_MONSTROSITY: - return TILE_MONS_TENTACLED_MONSTROSITY; + return TILEP_MONS_TENTACLED_MONSTROSITY; case MONS_SPHINX: - return TILE_MONS_SPHINX; + return TILEP_MONS_SPHINX; case MONS_ROTTING_HULK: - return TILE_MONS_ROTTING_HULK; + return TILEP_MONS_ROTTING_HULK; case MONS_GUARDIAN_MUMMY: - return TILE_MONS_GUARDIAN_MUMMY; + return TILEP_MONS_GUARDIAN_MUMMY; case MONS_GREATER_MUMMY: - return TILE_MONS_GREATER_MUMMY; + return TILEP_MONS_GREATER_MUMMY; case MONS_MUMMY_PRIEST: - return TILE_MONS_MUMMY_PRIEST; + return TILEP_MONS_MUMMY_PRIEST; case MONS_CENTAUR_WARRIOR: - return TILE_MONS_CENTAUR_WARRIOR; + return TILEP_MONS_CENTAUR_WARRIOR; case MONS_YAKTAUR_CAPTAIN: - return TILE_MONS_YAKTAUR_CAPTAIN; + return TILEP_MONS_YAKTAUR_CAPTAIN; case MONS_KILLER_KLOWN: - return TILE_MONS_KILLER_KLOWN; + return TILEP_MONS_KILLER_KLOWN; case MONS_ELECTRIC_GOLEM: - return TILE_MONS_ELECTRIC_GOLEM; + return TILEP_MONS_ELECTRIC_GOLEM; case MONS_BALL_LIGHTNING: - return TILE_MONS_BALL_LIGHTNING; + return TILEP_MONS_BALL_LIGHTNING; case MONS_ORB_OF_FIRE: - return TILE_MONS_ORB_OF_FIRE; + return TILEP_MONS_ORB_OF_FIRE; case MONS_QUOKKA: - return TILE_MONS_QUOKKA; + return TILEP_MONS_QUOKKA; case MONS_EYE_OF_DEVASTATION: - return TILE_MONS_EYE_OF_DEVASTATION; + return TILEP_MONS_EYE_OF_DEVASTATION; case MONS_MOTH_OF_WRATH: - return TILE_MONS_MOTH_OF_WRATH; + return TILEP_MONS_MOTH_OF_WRATH; case MONS_DEATH_COB: - return TILE_MONS_DEATH_COB; + return TILEP_MONS_DEATH_COB; case MONS_CURSE_TOE: - return TILE_MONS_CURSE_TOE; + return TILEP_MONS_CURSE_TOE; case MONS_GOLD_MIMIC: case MONS_WEAPON_MIMIC: @@ -810,81 +757,79 @@ static int _tileidx_monster_base(int mon_idx, bool detected) } case MONS_HELL_HOG: - return TILE_MONS_HELL_HOG; + return TILEP_MONS_HELL_HOG; case MONS_SERPENT_OF_HELL: - return TILE_MONS_SERPENT_OF_HELL; + return TILEP_MONS_SERPENT_OF_HELL; case MONS_BOGGART: - return TILE_MONS_BOGGART; + return TILEP_MONS_BOGGART; case MONS_QUICKSILVER_DRAGON: - return TILE_MONS_QUICKSILVER_DRAGON; + return TILEP_MONS_QUICKSILVER_DRAGON; case MONS_IRON_DRAGON: - return TILE_MONS_IRON_DRAGON; + return TILEP_MONS_IRON_DRAGON; case MONS_SKELETAL_WARRIOR: - return TILE_MONS_SKELETAL_WARRIOR; + return TILEP_MONS_SKELETAL_WARRIOR; case MONS_PLAYER_GHOST: - return TILE_MONS_PLAYER_GHOST; + return TILEP_MONS_PLAYER_GHOST; case MONS_PANDEMONIUM_DEMON: - return TILE_MONS_PANDEMONIUM_DEMON; + return TILEP_MONS_PANDEMONIUM_DEMON; case MONS_GIANT_NEWT: - return TILE_MONS_GIANT_NEWT; + return TILEP_MONS_GIANT_NEWT; case MONS_GIANT_GECKO: - return TILE_MONS_GIANT_GECKO; + return TILEP_MONS_GIANT_GECKO; case MONS_GIANT_IGUANA: - return TILE_MONS_GIANT_IGUANA; + return TILEP_MONS_GIANT_IGUANA; case MONS_GILA_MONSTER: - return TILE_MONS_GILA_MONSTER; + return TILEP_MONS_GILA_MONSTER; case MONS_KOMODO_DRAGON: - return TILE_MONS_KOMODO_DRAGON; + return TILEP_MONS_KOMODO_DRAGON; case MONS_LAVA_WORM: - return TILE_MONS_LAVA_WORM; + return TILEP_MONS_LAVA_WORM; case MONS_LAVA_FISH: - return TILE_MONS_LAVA_FISH; + return TILEP_MONS_LAVA_FISH; case MONS_LAVA_SNAKE: - return TILE_MONS_LAVA_SNAKE; + return TILEP_MONS_LAVA_SNAKE; case MONS_SALAMANDER: - return TILE_MONS_SALAMANDER; + return TILEP_MONS_SALAMANDER; case MONS_BIG_FISH: - return TILE_MONS_BIG_FISH; + return TILEP_MONS_BIG_FISH; case MONS_GIANT_GOLDFISH: - return TILE_MONS_GIANT_GOLDFISH; + return TILEP_MONS_GIANT_GOLDFISH; case MONS_ELECTRICAL_EEL: - return TILE_MONS_ELECTRICAL_EEL; + return TILEP_MONS_ELECTRICAL_EEL; case MONS_JELLYFISH: - return TILE_MONS_JELLYFISH; + return TILEP_MONS_JELLYFISH; case MONS_WATER_ELEMENTAL: - return TILE_MONS_WATER_ELEMENTAL; + return TILEP_MONS_WATER_ELEMENTAL; case MONS_SWAMP_WORM: - return TILE_MONS_SWAMP_WORM; + return TILEP_MONS_SWAMP_WORM; case MONS_ROCK_WORM: - return TILE_MONS_ROCK_WORM; + return TILEP_MONS_ROCK_WORM; case MONS_ORANGE_STATUE: - return TILE_DNGN_ORANGE_CRYSTAL_STATUE; + return TILEP_ORANGE_CRYSTAL_STATUE; case MONS_SILVER_STATUE: - return TILE_DNGN_SILVER_STATUE; + return TILEP_SILVER_STATUE; case MONS_ICE_STATUE: - return TILE_DNGN_ICE_STATUE; + return TILEP_ICE_STATUE; case MONS_DEATH_DRAKE: - return TILE_MONS_DEATH_DRAKE; + return TILEP_MONS_DEATH_DRAKE; case MONS_MERFOLK: if (in_water) - return TILE_MONS_MERFOLK_FIGHTER_WATER; + return TILEP_MONS_MERFOLK_FIGHTER_WATER; else - return TILE_MONS_MERFOLK_FIGHTER; + return TILEP_MONS_MERFOLK_FIGHTER; case MONS_MERMAID: if (in_water) - return TILE_MONS_MERMAID_WATER; + return TILEP_MONS_MERMAID_WATER; else - return TILE_MONS_MERMAID; + return TILEP_MONS_MERMAID; } return TILE_ERROR; } -static int _tileidx_monster(int mon_idx, bool detected) +int tileidx_monster(const monsters *mons, bool detected) { - ASSERT(mon_idx != -1); - int ch = _tileidx_monster_base(mon_idx, detected); - const monsters* mons = &menv[mon_idx]; + int ch = _tileidx_monster_base(mons, detected); if (mons_flies(mons)) ch |= TILE_FLAG_FLYING; @@ -912,6 +857,13 @@ static int _tileidx_monster(int mon_idx, bool detected) return ch; } +static int _tileidx_monster(int mon_idx, bool detected) +{ + ASSERT(mon_idx != -1); + const monsters* mons = &menv[mon_idx]; + return tileidx_monster(mons, detected); +} + static int _tileidx_fixed_artefact(int special) { switch(special) @@ -2276,19 +2228,19 @@ static int _tileidx_cloud(int type, int decay) int tileidx_player(int job) { - int ch = TILE_PLAYER; + int ch = TILEP_PLAYER; // Handle shapechange first switch (you.symbol) { - case 's': ch = TILE_MONS_WOLF_SPIDER; break; - case 'I': ch = TILE_MONS_ICE_BEAST; break; - case '8': ch = TILE_MONS_STONE_GOLEM; break; - case 'D': ch = TILE_MONS_DRAGON; break; - case 'L': ch = TILE_MONS_LICH; break; - case '#': ch = TILE_MONS_VAPOUR; break; - case 'S': ch = TILE_MONS_LAVA_SNAKE; break; - case 'b': ch = TILE_MONS_GIANT_BAT; break; + case 's': ch = TILEP_MONS_WOLF_SPIDER; break; + case 'I': ch = TILEP_MONS_ICE_BEAST; break; + case '8': ch = TILEP_MONS_STONE_GOLEM; break; + case 'D': ch = TILEP_MONS_DRAGON; break; + case 'L': ch = TILEP_MONS_LICH; break; + case '#': ch = TILEP_MONS_VAPOUR; break; + case 'S': ch = TILEP_MONS_LAVA_SNAKE; break; + case 'b': ch = TILEP_MONS_GIANT_BAT; break; } if (player_is_airborne()) @@ -2349,7 +2301,7 @@ int tileidx_unseen(int ch, const coord_def& gc) case '+': res = TILE_BOOK_PAPER_OFFSET + 15; break; case '/': res = TILE_WAND_OFFSET; break; - case '8': res = TILE_DNGN_SILVER_STATUE; break; + case '8': res = TILEP_SILVER_STATUE; break; case '<': res = TILE_DNGN_STONE_STAIRS_UP; break; case '=': res = TILE_RING_NORMAL_OFFSET + 1; break; case '>': res = TILE_DNGN_STONE_STAIRS_DOWN; break; @@ -2431,7 +2383,7 @@ static inline void _finalize_tile(unsigned int *tile, bool is_special, || orig == TILE_DNGN_LAVA || orig == TILE_DNGN_STONE_WALL) { - (*tile) = orig + (special_flv % tile_dngn_count[orig]); + (*tile) = orig + (special_flv % tile_dngn_count(orig)); } else if (orig == TILE_DNGN_CLOSED_DOOR || orig == TILE_DNGN_OPEN_DOOR) { @@ -2442,7 +2394,7 @@ static inline void _finalize_tile(unsigned int *tile, bool is_special, (*tile) |= flag; } -void tilep_calc_flags(int parts[], int flag[]) +void tilep_calc_flags(const int parts[], int flag[]) { int i; @@ -4034,7 +3986,7 @@ void tile_place_item_bk(int gx, int gy, int idx) void tile_place_tile_bk(int gx, int gy, int tileidx) { - env.tile_bk_fg[gx][gy] = get_base_idx_from_mcache(tileidx); + env.tile_bk_fg[gx][gy] = tileidx; } // Called from item() in view.cc @@ -4058,7 +4010,6 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) int t = _tileidx_monster(idx, detected); int t0 = t & TILE_FLAG_MASK; int flag = t & (~TILE_FLAG_MASK); - int mon_wep = menv[idx].inv[MSLOT_WEAPON]; if (mons_is_mimic(menv[idx].type)) { @@ -4096,120 +4047,34 @@ void tile_place_monster(int gx, int gy, int idx, bool foreground, bool detected) t0 |= TILE_FLAG_S_UNDER; } } - else if (menv[idx].type >= MONS_DRACONIAN && - menv[idx].type <= MONS_DRACONIAN_SCORCHER) - { - int race = draco_subspecies(&menv[idx]); - int cls = menv[idx].type; - int eq = 0; - if (mon_wep != NON_ITEM && - (cls == race || cls == MONS_DRACONIAN_KNIGHT)) - { - eq = tilep_equ_weapon(mitm[mon_wep]); - } - t = flag | _mcache_register(cls, eq, race); - } - else if (mon_wep != NON_ITEM) + else { - int eq = tilep_equ_weapon(mitm[mon_wep]); - switch(t0) - { - // 3D chars - case TILE_MONS_VAULT_GUARD: - - case TILE_MONS_BLORK_THE_ORC: - case TILE_MONS_ORC: - case TILE_MONS_ORC_KNIGHT: - case TILE_MONS_ORC_WARLORD: - case TILE_MONS_ORC_WARRIOR: - case TILE_MONS_URUG: - - case TILE_MONS_GOBLIN: - case TILE_MONS_IJYB: - case TILE_MONS_HOBGOBLIN: - case TILE_MONS_GNOLL: - case TILE_MONS_BOGGART: - - case TILE_MONS_KOBOLD: - case TILE_MONS_KOBOLD_DEMONOLOGIST: - case TILE_MONS_BIG_KOBOLD: - - case TILE_MONS_DEEP_ELF_FIGHTER: - case TILE_MONS_DEEP_ELF_SOLDIER: - case TILE_MONS_DEEP_ELF_KNIGHT: - case TILE_MONS_DEEP_ELF_BLADEMASTER: - case TILE_MONS_DEEP_ELF_MASTER_ARCHER: - case TILE_MONS_DEEP_ELF_MAGE: - case TILE_MONS_DEEP_ELF_SUMMONER: - case TILE_MONS_DEEP_ELF_CONJURER: - case TILE_MONS_DEEP_ELF_PRIEST: - case TILE_MONS_DEEP_ELF_HIGH_PRIEST: - case TILE_MONS_DEEP_ELF_DEMONOLOGIST: - case TILE_MONS_DEEP_ELF_ANNIHILATOR: - case TILE_MONS_DEEP_ELF_SORCERER: - case TILE_MONS_DEEP_ELF_DEATH_MAGE: - - case TILE_MONS_MIDGE: - case TILE_MONS_IMP: - - case TILE_MONS_NAGA: - case TILE_MONS_GREATER_NAGA: - case TILE_MONS_NAGA_WARRIOR: - case TILE_MONS_NAGA_MAGE: - - case TILE_MONS_OGRE_MAGE: - case TILE_MONS_RED_DEVIL: - case TILE_MONS_WIZARD: - case TILE_MONS_HUMAN: - case TILE_MONS_ELF: - - case TILE_MONS_ANGEL: - - case TILE_MONS_HELL_KNIGHT: - - case TILE_MONS_NORRIS: - case TILE_MONS_MAUD: - case TILE_MONS_DUANE: - case TILE_MONS_EDMUND: - case TILE_MONS_FRANCES: - case TILE_MONS_HAROLD: - case TILE_MONS_JOSEPH: - case TILE_MONS_JOZEF: - case TILE_MONS_RUPERT: - case TILE_MONS_TERENCE: - case TILE_MONS_WAYNE: - case TILE_MONS_FREDERICK: - - case TILE_MONS_RAKSHASA: - case TILE_MONS_RAKSHASA_FAKE: - - case TILE_MONS_VAMPIRE_KNIGHT: - - case TILE_MONS_SKELETAL_WARRIOR: - case TILE_MONS_MERMAID: - case TILE_MONS_MERMAID_WATER: - case TILE_MONS_MERFOLK_FIGHTER: - case TILE_MONS_MERFOLK_FIGHTER_WATER: - - if (eq != 0 ) - t = flag | _mcache_register(t0, eq); - break; - - } + unsigned int mcache_idx = mcache.register_monster(&menv[idx]); + t = flag | (mcache_idx ? mcache_idx : t0); } if (foreground) { env.tile_fg[ep.x-1][ep.y-1] = t; - if (menv[idx].is_named() && !mons_friendly(&menv[idx])) + if (menv[idx].is_named() && !mons_friendly(&menv[idx]) + && menv[idx].type != MONS_PANDEMONIUM_DEMON) { - tiles.add_text_tag(TAG_NAMED_MONSTER, - menv[idx].name(DESC_CAP_A), gc); + if (menv[idx].type == MONS_PLAYER_GHOST) + { + // Beautification hack. "Foo's ghost" is a little bit + // verbose as a tag. "Foo" on its own should be sufficient. + tiles.add_text_tag(TAG_NAMED_MONSTER, menv[idx].mname, gc); + } + else + { + tiles.add_text_tag(TAG_NAMED_MONSTER, + menv[idx].name(DESC_CAP_A), gc); + } } } else { - env.tile_bk_fg[gc.x][gc.y] = get_base_idx_from_mcache(t0); + env.tile_bk_fg[gc.x][gc.y] = t0; } } diff --git a/crawl-ref/source/tilereg.cc b/crawl-ref/source/tilereg.cc index 972856f93d..fa27a506bb 100644 --- a/crawl-ref/source/tilereg.cc +++ b/crawl-ref/source/tilereg.cc @@ -31,6 +31,7 @@ #include "tiles.h" #include "tilefont.h" #include "tilesdl.h" +#include "tilemcache.h" #include <SDL_opengl.h> @@ -281,7 +282,7 @@ void DungeonRegion::draw_background(unsigned int bg, unsigned int x, unsigned in if (bg & TILE_FLAG_BLOOD) { tile_flavour &flv = env.tile_flv[x + m_cx_to_gx][y + m_cy_to_gy]; - unsigned int offset = flv.special % tile_dngn_count[TILE_BLOOD]; + unsigned int offset = flv.special % tile_dngn_count(TILE_BLOOD); add_quad(TEX_DUNGEON, TILE_BLOOD + offset, x, y); } @@ -426,31 +427,8 @@ void DungeonRegion::draw_player(unsigned int x, unsigned int y) draw_doll(result, x, y); } -bool DungeonRegion::draw_objects(unsigned int fg, unsigned int x, unsigned int y) -{ - unsigned int fg_idx = fg & TILE_FLAG_MASK; - - // handled elsewhere - if (fg_idx == TILE_PLAYER) - return false; - - int equ_tile; - int draco; - int mon_tile; - if (get_mcache_entry(fg_idx, mon_tile, equ_tile, draco)) - { - if (!draco) - add_quad(TEX_DEFAULT, get_base_idx_from_mcache(fg_idx), x, y); - return true; - } - else if (fg_idx) - { - add_quad(TEX_DEFAULT, fg_idx, x, y); - } - return false; -} - -void DungeonRegion::draw_doll(dolls_data &doll, unsigned int x, unsigned int y) +void DungeonRegion::draw_doll(const dolls_data &doll, unsigned int x, + unsigned int y) { int p_order[TILEP_PART_MAX] = { @@ -499,152 +477,31 @@ void DungeonRegion::draw_doll(dolls_data &doll, unsigned int x, unsigned int y) } } -void DungeonRegion::draw_draco(int colour, int mon_idx, int equ_tile, unsigned int x, unsigned int y) +void DungeonRegion::draw_mcache(mcache_entry *entry, unsigned int x, unsigned int y) { - dolls_data doll; - - int armour = 0; - int armour2 = 0; - int weapon = 0; - int weapon2 = 0; - int arm = 0; - - for (int i = 0; i < TILEP_PART_MAX; i++) - doll.parts[i] = 0; - - doll.parts[TILEP_PART_SHADOW] = TILEP_SHADOW_SHADOW; - doll.parts[TILEP_PART_BASE] = TILEP_BASE_DRACONIAN + colour * 2; - doll.parts[TILEP_PART_DRCWING] = tile_player_part_start[TILEP_PART_DRCWING] - + colour; - doll.parts[TILEP_PART_DRCHEAD] = tile_player_part_start[TILEP_PART_DRCHEAD] - + colour; - - switch (mon_idx) - { - case MONS_DRACONIAN_CALLER: - weapon = TILEP_HAND1_STAFF_EVIL; - weapon2 = TILEP_HAND2_BOOK_YELLOW; - armour = TILEP_BODY_ROBE_BROWN; - break; - - case MONS_DRACONIAN_MONK: - arm = TILEP_ARM_GLOVE_SHORT_BLUE; - armour = TILEP_BODY_KARATE2; - break; - - case MONS_DRACONIAN_ZEALOT: - weapon = TILEP_HAND1_MACE; - weapon2 = TILEP_HAND2_BOOK_CYAN; - armour = TILEP_BODY_MONK_BLUE; - break; - - case MONS_DRACONIAN_SHIFTER: - weapon = TILEP_HAND1_STAFF_LARGE; - armour = TILEP_BODY_ROBE_CYAN; - weapon2 = TILEP_HAND2_BOOK_GREEN; - break; + ASSERT(entry); - case MONS_DRACONIAN_ANNIHILATOR: - weapon = TILEP_HAND1_STAFF_RUBY; - weapon2 = TILEP_HAND2_FIRE_CYAN; - armour = TILEP_BODY_ROBE_GREEN_GOLD; - break; - - case MONS_DRACONIAN_KNIGHT: - weapon = equ_tile; - weapon2 = TILEP_HAND2_SHIELD_KNIGHT_GRAY; - armour = TILEP_BODY_BPLATE_METAL1; - armour2 = TILEP_LEG_BELT_GRAY; - break; - - case MONS_DRACONIAN_SCORCHER: - weapon = TILEP_HAND1_FIRE_RED; - weapon2 = TILEP_HAND2_BOOK_RED; - armour = TILEP_BODY_ROBE_RED; - break; - - default: - weapon = equ_tile; - armour = TILEP_BODY_BELT2; - armour2 = TILEP_LEG_LOINCLOTH_RED; - break; - } + const dolls_data *doll = entry->doll(); + if (doll) + draw_doll(*doll, x, y); - doll.parts[TILEP_PART_HAND1] = weapon; - doll.parts[TILEP_PART_HAND2] = weapon2; - doll.parts[TILEP_PART_BODY] = armour; - doll.parts[TILEP_PART_LEG] = armour2; - doll.parts[TILEP_PART_ARM] = arm; + tile_draw_info dinfo[3]; + unsigned int draw_info_count = entry->info(&dinfo[0]); + ASSERT(draw_info_count <= sizeof(dinfo) / (sizeof(dinfo[0]))); - draw_doll(doll, x, y); + for (unsigned int i = 0; i < draw_info_count; i++) + add_quad(TEX_DOLL, dinfo[i].idx, x, y, dinfo[i].ofs_x, dinfo[i].ofs_y); } -void DungeonRegion::draw_monster(unsigned int fg, unsigned int x, unsigned int y) +void DungeonRegion::draw_foreground(unsigned int bg, unsigned int fg, unsigned int x, unsigned int y) { - // Currently, monsters only get displayed weapons (no armour) unsigned int fg_idx = fg & TILE_FLAG_MASK; - if (fg_idx < TILE_MCACHE_START) - return; - - int equ_tile; - int draco; - int mon_tile; - - if (!get_mcache_entry(fg_idx, mon_tile, equ_tile, draco)) - return; + unsigned int bg_idx = bg & TILE_FLAG_MASK; - if (draco == 0) + if (fg_idx && fg_idx <= TILE_MAIN_MAX) { - int ofs_x, ofs_y; - tile_get_monster_weapon_offset(mon_tile, ofs_x, ofs_y); - - add_quad(TEX_DOLL, equ_tile, x, y, ofs_x, ofs_y, true, TILE_Y); - - // In some cases, overlay a second weapon tile... - if (mon_tile == TILE_MONS_DEEP_ELF_BLADEMASTER) - { - int eq2; - switch (equ_tile) - { - case TILEP_HAND1_DAGGER: - eq2 = TILEP_HAND2_DAGGER; - break; - case TILEP_HAND1_SABRE: - eq2 = TILEP_HAND2_SABRE; - break; - default: - case TILEP_HAND1_SHORT_SWORD_SLANT: - eq2 = TILEP_HAND2_SHORT_SWORD_SLANT; - break; - }; - add_quad(TEX_DOLL, eq2, x, y, -ofs_x, ofs_y, true, TILE_Y); - } - } - else - { - int colour; - switch (draco) - { - default: - case MONS_DRACONIAN: colour = 0; break; - case MONS_BLACK_DRACONIAN: colour = 1; break; - case MONS_YELLOW_DRACONIAN: colour = 2; break; - case MONS_GREEN_DRACONIAN: colour = 4; break; - case MONS_MOTTLED_DRACONIAN:colour = 5; break; - case MONS_PALE_DRACONIAN: colour = 6; break; - case MONS_PURPLE_DRACONIAN: colour = 7; break; - case MONS_RED_DRACONIAN: colour = 8; break; - case MONS_WHITE_DRACONIAN: colour = 9; break; - } - - draw_draco(colour, mon_tile, equ_tile, x, y); + add_quad(TEX_DEFAULT, fg_idx, x, y); } -} - -void DungeonRegion::draw_foreground(unsigned int bg, unsigned int fg, unsigned int x, unsigned int y) -{ - unsigned int fg_idx = fg & TILE_FLAG_MASK; - unsigned int bg_idx = bg & TILE_FLAG_MASK; if (fg_idx && !(fg & TILE_FLAG_FLYING)) { @@ -786,47 +643,30 @@ void DungeonRegion::render() tile = 0; m_verts.clear(); - int player_x = -1; - int player_y = -1; - bool need_doll = false; for (int y = 0; y < crawl_view.viewsz.y; y++) + { for (int x = 0; x < crawl_view.viewsz.x; x++) { - unsigned int fg = m_tileb[tile]; - need_doll |= draw_objects(fg, x, y); - - if ((fg & TILE_FLAG_MASK) == TILE_PLAYER) + unsigned int fg = m_tileb[tile] & TILE_FLAG_MASK; + if (fg >= TILEP_MCACHE_START) { - player_x = x; - player_y = y; + mcache_entry *entry = mcache.get(fg); + if (entry) + draw_mcache(entry, x, y); + else + add_quad(TEX_DOLL, TILEP_MONS_UNKNOWN, x, y); + } + else if (fg == TILEP_PLAYER) + { + draw_player(x, y); + } + else if (fg >= TILE_MAIN_MAX) + { + add_quad(TEX_DOLL, fg, x, y); } tile += 2; } - - if (m_verts.size() > 0) - { - m_image->m_textures[TEX_DEFAULT].bind(); - glVertexPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].pos_x); - glTexCoordPointer(2, GL_FLOAT, sizeof(tile_vert), &m_verts[0].tex_x); - glDrawArrays(GL_QUADS, 0, m_verts.size()); - } - - tile = 0; - m_verts.clear(); - if (player_x != -1) - draw_player(player_x, player_y); - - if (need_doll) - { - for (int y = 0; y < crawl_view.viewsz.y; y++) - for (int x = 0; x < crawl_view.viewsz.x; x++) - { - unsigned int fg = m_tileb[tile]; - draw_monster(fg, x, y); - - tile += 2; - } } if (m_verts.size() > 0) @@ -2394,8 +2234,8 @@ bool ImageManager::load_textures() if (!m_textures[TEX_TITLE].load_texture("title.png", mip)) return false; - m_textures[TEX_DUNGEON].set_info(TILE_DNGN_MAX, &tile_dngn_info[0]); - m_textures[TEX_DOLL].set_info(TILEP_PLAYER_MAX, &tile_player_info[0]); + m_textures[TEX_DUNGEON].set_info(TILE_DNGN_MAX, &tile_dngn_info); + m_textures[TEX_DOLL].set_info(TILEP_PLAYER_MAX, &tile_player_info); return true; } @@ -2469,8 +2309,8 @@ static void _copy_into(unsigned char *dest, unsigned char *pixels, static bool _copy_under(unsigned char *pixels, unsigned int width, unsigned int height, int idx_under, int idx_over) { - const tile_info &under = tile_main_info[idx_under]; - const tile_info &over = tile_main_info[idx_over]; + const tile_info &under = tile_main_info(idx_under); + const tile_info &over = tile_main_info(idx_over); if (over.width != under.width || over.height != under.height) return false; @@ -2547,7 +2387,7 @@ bool ImageManager::load_item_texture() GenericTexture::MipMapOptions mip = GenericTexture::MIPMAP_CREATE; bool success = m_textures[TEX_DEFAULT].load_texture("main.png", mip, &_process_item_image); - m_textures[TEX_DEFAULT].set_info(TILE_MAIN_MAX, &tile_main_info[0]); + m_textures[TEX_DEFAULT].set_info(TILE_MAIN_MAX, tile_main_info); return success; } diff --git a/crawl-ref/source/tilereg.h b/crawl-ref/source/tilereg.h index 31b7728f0b..74a14b42e8 100644 --- a/crawl-ref/source/tilereg.h +++ b/crawl-ref/source/tilereg.h @@ -12,6 +12,7 @@ #include "tiletex.h" #include "tiles.h" #include <vector> +class mcache_entry; class ImageManager { @@ -246,12 +247,10 @@ public: protected: void draw_background(unsigned int bg, unsigned int x, unsigned int y); - bool draw_objects(unsigned int fg, unsigned int x, unsigned int y); + void draw_mcache(mcache_entry *entry, unsigned int x, unsigned int y); void draw_player(unsigned int x, unsigned int y); - void draw_monster(unsigned int fg, unsigned int x, unsigned int y); void draw_foreground(unsigned int bg, unsigned int fg, unsigned int x, unsigned int y); - void draw_doll(dolls_data &doll, unsigned int x, unsigned int y); - void draw_draco(int colour, int mon_idx, int equ_tile, unsigned int x, unsigned int y); + void draw_doll(const dolls_data &doll, unsigned int x, unsigned int y); void draw_cursor(cursor_type type, unsigned int tile); int get_buffer_index(const coord_def &gc); diff --git a/crawl-ref/source/tiles.h b/crawl-ref/source/tiles.h index 7fa011ed17..77978a8e3b 100644 --- a/crawl-ref/source/tiles.h +++ b/crawl-ref/source/tiles.h @@ -11,12 +11,17 @@ #ifdef USE_TILE #include "tiledef-main.h" -#include "tiledef-demon.h" #include "tiledef-dngn.h" #include "tiledef-player.h" #include "beam.h" +enum tag_version +{ + TILETAG_PRE_MCACHE = 71, + TILETAG_CURRENT = 72 +}; + struct dolls_data { dolls_data() { memset(parts, 0, sizeof(parts)); } @@ -24,6 +29,15 @@ struct dolls_data int parts[TILEP_PART_MAX]; }; +struct demon_data +{ + demon_data() { head = body = wings = 0; } + + int head; + int body; + int wings; +}; + //*tile1.cc: get data from core part and drives tile drawing codes //**convert in-game data to tile index @@ -37,11 +51,12 @@ int tileidx_bolt(const bolt &bolt); int tileidx_zap(int colour); int tile_idx_unseen_terrain(int x, int y, int what); int tile_unseen_flag(const coord_def& gc); +int tileidx_monster(const monsters *mon, bool detected); // Player tile related void tilep_race_default(int race, int gender, int level, int *parts); void tilep_job_default(int job, int gender, int *parts); -void tilep_calc_flags(int parts[], int flag[]); +void tilep_calc_flags(const int parts[], int flag[]); void tilep_part_to_str(int number, char *buf); int tilep_str_to_part(char *str); @@ -104,12 +119,6 @@ void TileNewLevel(bool first_time); // edit player tile void TilePlayerEdit(); -// init ghost tile -void TileGhostInit(const struct ghost_demon &gs); -// init pandem demon tile (only in iso mode) -void TilePandemInit(struct ghost_demon &gs); -// edit pandem tile (debug) -void TileEditPandem(); int item_unid_type(const item_def &item); @@ -118,11 +127,6 @@ void TileLoadWall(bool wizard); void TileDrawTitle(); -// monster+weapon tile -void tile_mcache_unlock(); -int get_base_idx_from_mcache(int tile_idx); -void tile_get_monster_weapon_offset(int mon_tile, int &ofs_x, int &ofs_y); -bool get_mcache_entry(int tile_idx, int &mon_idx, int &equ_tile, int &draco); int get_clean_map_idx(int tile_idx); /* Flags for drawing routines */ @@ -169,15 +173,14 @@ enum TILEI_FLAG_CURSOR = 0x2000 }; -#define TILEP_SHOW_EQUIP 0x1000 - -#define TILEP_GENDER_MALE 0 -#define TILEP_GENDER_FEMALE 1 - -#define TILEP_M_DEFAULT 0 -#define TILEP_M_LOADING 1 +enum +{ + TILEP_GENDER_MALE = 0, + TILEP_GENDER_FEMALE = 1, + TILEP_SHOW_EQUIP = 0x1000 +}; -enum TilePlayerFlagCut +enum tile_player_flag_cut { TILEP_FLAG_HIDE, TILEP_FLAG_NORMAL, @@ -185,16 +188,12 @@ enum TilePlayerFlagCut TILEP_FLAG_CUT_NAGA }; -#ifdef TILEP_DEBUG -const char *get_ctg_name(int part); -int get_ctg_idx(char *name); -const char *get_parts_name(int part, int idx); -int get_parts_idx(int part, char *name); -#endif - // normal tile size in px -#define TILE_X 32 -#define TILE_Y 32 +enum +{ + TILE_X = 32, + TILE_Y = 32 +}; #endif // USE_TILES #endif diff --git a/crawl-ref/source/tiletex.cc b/crawl-ref/source/tiletex.cc index b8d80d9704..c1a7ce63c4 100644 --- a/crawl-ref/source/tiletex.cc +++ b/crawl-ref/source/tiletex.cc @@ -240,14 +240,14 @@ void GenericTexture::bind() } TilesTexture::TilesTexture() : - GenericTexture(), m_tile_max(0), m_tile_info(NULL) + GenericTexture(), m_tile_max(0), m_info_func(NULL) { } -void TilesTexture::set_info(int _max, tile_info *_info) +void TilesTexture::set_info(int tile_max, tile_info_func *info_func) { - m_tile_max = _max; - m_tile_info = _info; + m_tile_max = tile_max; + m_info_func = info_func; } diff --git a/crawl-ref/source/tiletex.h b/crawl-ref/source/tiletex.h index 8d90803ef0..0003395bc8 100644 --- a/crawl-ref/source/tiletex.h +++ b/crawl-ref/source/tiletex.h @@ -56,7 +56,7 @@ class TilesTexture : public GenericTexture public: TilesTexture(); - void set_info(int max, tile_info *info); + void set_info(int max, tile_info_func *info); inline const tile_info &get_info(int idx); inline void get_coords(int idx, int ofs_x, int ofs_y, float &pos_sx, float &pos_sy, @@ -67,13 +67,12 @@ public: protected: int m_tile_max; - tile_info *m_tile_info; + tile_info_func *m_info_func; }; inline const tile_info &TilesTexture::get_info(int idx) { - assert(idx < m_tile_max); - return m_tile_info[idx]; + return m_info_func(idx); } inline void TilesTexture::get_coords(int idx, int ofs_x, int ofs_y, diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc index 1500009a16..113b9f55f4 100644 --- a/crawl-ref/source/view.cc +++ b/crawl-ref/source/view.cc @@ -73,6 +73,7 @@ #include "tiles.h" #include "state.h" #include "terrain.h" +#include "tilemcache.h" #include "tilesdl.h" #include "travel.h" #include "tutorial.h" @@ -4823,7 +4824,7 @@ void viewwindow(bool draw_it, bool do_updates) #ifdef USE_TILE tile_draw_floor(); - tile_mcache_unlock(); + mcache.clear_nonref(); #endif env.show_col.init(LIGHTGREY); @@ -5010,8 +5011,7 @@ void viewwindow(bool draw_it, bool do_updates) else { env.tile_bk_fg[gc.x][gc.y] = - get_base_idx_from_mcache( - env.tile_fg[ep.x-1][ep.y-1]); + env.tile_fg[ep.x-1][ep.y-1]; } env.tile_bk_bg[gc.x][gc.y] = env.tile_bg[ep.x-1][ep.y-1]; |