From bd7a961334fbcc180bfb39501bd7948dc961868c Mon Sep 17 00:00:00 2001 From: Johanna Ploog Date: Mon, 11 Jan 2010 20:46:21 +0100 Subject: Implement rltiles %weight command and skewed dngn tile probabilities. In dc-dngn.txt you can now use the %weight command to specify the probability of a given tile whenever a variant is chosen randomly from a set of variant tiles. Example: %weight 5 floor/floor_sand_stone0 FLOOR_SAND_STONE floor/floor_sand_stone1 floor/floor_sand_stone2 floor/floor_sand_stone3 %weight 2 floor/floor_sand_stone4 floor/floor_sand_stone5 floor/floor_sand_stone7 %weight 1 floor/floor_sand_stone6 ... will make plain sand more likely than the rocky versions and the big rock rarer than the smaller ones. This is not visible from the dngn.png but you can check the (cumulative) weights in tiledef-dngn.cc. Aside from the above, this is also used for the brick wall in all its colorations. (The repeat command also repeats the weight settings.) --- crawl-ref/source/rltiles/dc-dngn.txt | 10 ++++- .../source/rltiles/tool/tile_list_processor.cc | 47 +++++++++++++++++++++- .../source/rltiles/tool/tile_list_processor.h | 1 + crawl-ref/source/rltiles/tool/tile_page.cc | 1 + crawl-ref/source/rltiles/tool/tile_page.h | 1 + crawl-ref/source/tilepick.cc | 26 ++++++++++-- 6 files changed, 79 insertions(+), 7 deletions(-) (limited to 'crawl-ref') diff --git a/crawl-ref/source/rltiles/dc-dngn.txt b/crawl-ref/source/rltiles/dc-dngn.txt index ef8e062e57..ed69c900b6 100644 --- a/crawl-ref/source/rltiles/dc-dngn.txt +++ b/crawl-ref/source/rltiles/dc-dngn.txt @@ -9,13 +9,16 @@ dngn_unseen DNGN_UNSEEN # Multiple tile definitions are STATIC, that is they may change between # saves but are otherwise fixed. +%weight 5 wall/brick_brown0 WALL_NORMAL WALL_BRICK WALL_BRICK_BROWN wall/brick_brown1 wall/brick_brown2 -wall/brick_brown3 wall/brick_brown4 wall/brick_brown5 +%weight 2 +wall/brick_brown3 wall/brick_brown6 +%weight 1 wall/brick_brown7 %variation WALL_BRICK blue @@ -604,14 +607,17 @@ floor/rough_red3 %repeat FLOOR_ROUGH FLOOR_ROUGH_WHITE %resetcol +%weight 5 floor/floor_sand_stone0 FLOOR_SAND_STONE floor/floor_sand_stone1 floor/floor_sand_stone2 floor/floor_sand_stone3 +%weight 2 floor/floor_sand_stone4 floor/floor_sand_stone5 -floor/floor_sand_stone6 floor/floor_sand_stone7 +%weight 1 +floor/floor_sand_stone6 wall/wall_yellow_rock0 WALL_YELLOW_ROCK wall/wall_yellow_rock1 diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.cc b/crawl-ref/source/rltiles/tool/tile_list_processor.cc index 9a21af3c19..7138ab5408 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.cc +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.cc @@ -19,7 +19,8 @@ tile_list_processor::tile_list_processor() : m_prefix("TILE"), m_start_value("0"), m_variation_idx(-1), - m_variation_col(-1) + m_variation_col(-1), + m_weight(1) { } @@ -455,6 +456,20 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, CHECK_ARG(1); m_sdir = m_args[1]; } + else if (strcmp(arg, "weight") == 0) + { + CHECK_ARG(1); + int tmp = atoi(m_args[1]); + + if (tmp <= 0) + { + fprintf(stderr, "Error (%s:%d): weight must be >= 1.\n", + list_file, line); + return (false); + } + + m_weight = tmp; + } else if (strcmp(arg, "shrink") == 0) { CHECK_ARG(1); @@ -592,11 +607,14 @@ bool tile_list_processor::process_line(char *read_line, const char *list_file, int cnt = m_page.m_counts[idx]; + int old_w = 0; for (int i = 0; i < cnt; ++i) { tile img; img.copy(*m_page.m_tiles[idx + i]); recolour(img); + m_weight = m_page.m_probs[idx + i] - old_w; + old_w = m_page.m_probs[idx + i]; add_image(img, (i == 0 && m_args[2]) ? m_args[2] : NULL); } @@ -690,10 +708,15 @@ void tile_list_processor::add_image(tile &img, const char *enumname) m_page.m_tiles.push_back(new_img); m_page.m_counts.push_back(1); + int weight = m_weight; if (enumname) m_last_enum = m_page.m_counts.size() - 1; else if (m_last_enum < m_page.m_counts.size()) + { m_page.m_counts[m_last_enum]++; + weight += m_page.m_probs[m_page.m_probs.size() - 1]; + } + m_page.m_probs.push_back(weight); if (m_categories.size() > 0) m_ctg_counts[m_categories.size()-1]++; @@ -833,6 +856,11 @@ bool tile_list_processor::write_data() fprintf(fp, " %s_%s_MAX\n};\n\n", m_prefix.c_str(), ucname.c_str()); fprintf(fp, "int tile_%s_count(unsigned int idx);\n", lcname.c_str()); + if (strcmp(m_name.c_str(), "dngn") == 0) + { + fprintf(fp, "int tile_%s_probs(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", @@ -898,6 +926,23 @@ bool tile_list_processor::write_data() lcname.c_str(), m_start_value.c_str()); fprintf(fp, "}\n\n"); + if (strcmp(m_name.c_str(), "dngn") == 0) + { + fprintf(fp, "int _tile_%s_probs[%s - %s] =\n{\n", + lcname.c_str(), max.c_str(), m_start_value.c_str()); + for (unsigned int i = 0; i < m_page.m_probs.size(); i++) + fprintf(fp, " %d,\n", m_page.m_probs[i]); + fprintf(fp, "};\n\n"); + + fprintf(fp, "int tile_%s_probs(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_probs[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++) diff --git a/crawl-ref/source/rltiles/tool/tile_list_processor.h b/crawl-ref/source/rltiles/tool/tile_list_processor.h index 5e95d1815b..6135d044cd 100644 --- a/crawl-ref/source/rltiles/tool/tile_list_processor.h +++ b/crawl-ref/source/rltiles/tool/tile_list_processor.h @@ -41,6 +41,7 @@ protected: tile m_compose; int m_variation_idx; int m_variation_col; + int m_weight; typedef std::pair palette_entry; typedef std::vector palette_list; diff --git a/crawl-ref/source/rltiles/tool/tile_page.cc b/crawl-ref/source/rltiles/tool/tile_page.cc index 3c90dcfce8..c155e16097 100644 --- a/crawl-ref/source/rltiles/tool/tile_page.cc +++ b/crawl-ref/source/rltiles/tool/tile_page.cc @@ -16,6 +16,7 @@ tile_page::~tile_page() m_tiles.clear(); m_counts.clear(); + m_probs.clear(); } bool tile_page::place_images() diff --git a/crawl-ref/source/rltiles/tool/tile_page.h b/crawl-ref/source/rltiles/tool/tile_page.h index c63ae43a5a..4556281558 100644 --- a/crawl-ref/source/rltiles/tool/tile_page.h +++ b/crawl-ref/source/rltiles/tool/tile_page.h @@ -23,6 +23,7 @@ public: std::vector m_counts; std::vector m_texcoords; std::vector m_offsets; + std::vector m_probs; protected: int m_width; diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc index d56139759a..999a8d38ca 100644 --- a/crawl-ref/source/tilepick.cc +++ b/crawl-ref/source/tilepick.cc @@ -4510,6 +4510,26 @@ void tile_init_flavour() tile_init_flavour(*ri); } +static int _pick_random_dngn_tile(unsigned int idx) +{ + ASSERT(idx >= 0 && idx < TILE_DNGN_MAX); + const int count = tile_dngn_count(idx); + if (count == 1) + return (idx); + + const int total = tile_dngn_probs(idx + count - 1); + const int rand = random2(total); + + for (int i = 0; i < count; ++i) + { + int curr = idx + i; + if (rand < tile_dngn_probs(curr)) + return (curr); + } + + return (idx); +} + void tile_init_flavour(const coord_def &gc) { if (!map_bounds(gc)) @@ -4521,8 +4541,7 @@ void tile_init_flavour(const coord_def &gc) int colour = env.grid_colours(gc); if (colour) floor_base = tile_dngn_coloured(floor_base, colour); - int floor_rnd = random2(tile_dngn_count(floor_base)); - env.tile_flv(gc).floor = floor_base + floor_rnd; + env.tile_flv(gc).floor = _pick_random_dngn_tile(floor_base); } if (!env.tile_flv(gc).wall) @@ -4531,8 +4550,7 @@ void tile_init_flavour(const coord_def &gc) int colour = env.grid_colours(gc); if (colour) wall_base = tile_dngn_coloured(wall_base, colour); - int wall_rnd = random2(tile_dngn_count(wall_base)); - env.tile_flv(gc).wall = wall_base + wall_rnd; + env.tile_flv(gc).wall = _pick_random_dngn_tile(wall_base); } if (feat_is_door(grd(gc))) -- cgit v1.2.3-54-g00ecf