summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/develop/levels/syntax.txt4
-rw-r--r--crawl-ref/source/mapdef.cc12
-rw-r--r--crawl-ref/source/mapdef.h8
-rw-r--r--crawl-ref/source/tilepick.cc71
4 files changed, 87 insertions, 8 deletions
diff --git a/crawl-ref/docs/develop/levels/syntax.txt b/crawl-ref/docs/develop/levels/syntax.txt
index c755b46b03..76de981bdb 100644
--- a/crawl-ref/docs/develop/levels/syntax.txt
+++ b/crawl-ref/docs/develop/levels/syntax.txt
@@ -854,6 +854,10 @@ TILE: x = wall_flesh
Like COLOUR and FTILE, this should be used sparingly and to good
effect.
+ To override doors, use the specific tile set in combination with the
+ "no_random" specifier. Example:
+ + = no_random dngn_fleshy_orifice
+
SHUFFLE: def, 12/3?
This allows you to randomly permute glyphs on the map. There are
two ways:
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 493e79bb91..7076afe316 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -522,7 +522,11 @@ void map_lines::apply_grid_overlay(const coord_def &c)
else if (grd(gc) == DNGN_ROCK_WALL && !rock)
env.tile_flv(gc).wall = tile + offset;
else
+ {
+ if ((*overlay)(x, y).no_random)
+ offset = 0;
env.tile_flv(gc).feat = tile + offset;
+ }
}
#endif
}
@@ -1212,6 +1216,8 @@ void map_lines::overlay_tiles(tile_spec &spec)
(*overlay)(pos, y).tile = spec.get_tile();
else
(*overlay)(pos, y).rocktile = spec.get_tile();
+
+ (*overlay)(pos, y).no_random = spec.no_random;
++pos;
}
}
@@ -1739,11 +1745,13 @@ std::string map_lines::add_tile(const std::string &sub, bool is_floor, bool is_f
if (s.empty())
return ("");
+ bool no_random = strip_tag(s, "no_random");
+
int sep = 0;
std::string key;
std::string substitute;
- std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute, -1);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &substitute, -1);
if (!err.empty())
return (err);
@@ -1752,7 +1760,7 @@ std::string map_lines::add_tile(const std::string &sub, bool is_floor, bool is_f
if (!err.empty())
return (err);
- tile_spec spec(key, sep == ':', is_floor, is_feat, list);
+ tile_spec spec(key, sep == ':', no_random, is_floor, is_feat, list);
overlay_tiles(spec);
return ("");
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 3420b0d1b2..3ef19e0eeb 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -189,8 +189,8 @@ public:
class tile_spec
{
public:
- tile_spec(const std::string &_key, bool _fix, bool _floor, bool _feat, const map_tile_list &_tiles)
- : key(_key), fix(_fix), chose_fixed(false), floor(_floor), feat(_feat),
+ tile_spec(const std::string &_key, bool _fix, bool _rand, bool _floor, bool _feat, const map_tile_list &_tiles)
+ : key(_key), fix(_fix), chose_fixed(false), no_random(_rand), floor(_floor), feat(_feat),
fixed_tile(0), tiles(_tiles)
{
}
@@ -201,6 +201,7 @@ public:
std::string key;
bool fix;
bool chose_fixed;
+ bool no_random;
bool floor;
bool feat;
int fixed_tile;
@@ -428,11 +429,12 @@ private:
struct overlay_def
{
overlay_def() : colour(0), rocktile(0), floortile(0), tile(0),
- property(0), keyspec_idx(0) {}
+ no_random(false), property(0), keyspec_idx(0) {}
int colour;
int rocktile;
int floortile;
int tile;
+ bool no_random;
int property;
int keyspec_idx;
};
diff --git a/crawl-ref/source/tilepick.cc b/crawl-ref/source/tilepick.cc
index 258ce242ba..4b15342183 100644
--- a/crawl-ref/source/tilepick.cc
+++ b/crawl-ref/source/tilepick.cc
@@ -2425,7 +2425,7 @@ static int _tileidx_shop(coord_def where)
int tileidx_feature(dungeon_feature_type feat, int gx, int gy)
{
int override = env.tile_flv[gx][gy].feat;
- if (override)
+ if (override && !feat_is_door(grd[gx][gy]))
return override;
switch (feat)
@@ -3067,6 +3067,60 @@ int tileidx_spell(spell_type spell)
}
}
+// Specifically for vault-overwritten doors. We have three "sets" of tiles that
+// can be dealt with. The tile sets should be 2, 3, 8 and 9 respectively. They
+// are:
+// 2. Closed, open.
+// 3. Detected, closed, open.
+// 8. Closed, open, gate left closed, gate middle closed, gate right closed,
+// gate left open, gate middle open, gate right open.
+// 9. Detected, closed, open, gate left closed, gate middle closed, gate right
+// closed, gate left open, gate middle open, gate right open.
+int _get_door_offset (int base_tile, bool opened = false,
+ bool detected = false, int gateway_type = 0)
+{
+ int count = tile_dngn_count(base_tile);
+ if (count == 1)
+ return 0;
+
+ // The location of the default "closed" tile.
+ int offset;
+
+ switch (count)
+ {
+ case 2:
+ return ((opened) ? 1: 0);
+ case 3:
+ if (opened)
+ return 2;
+ else if (detected)
+ return 0;
+ else
+ return 1;
+ case 8:
+ // But is BASE_TILE for others.
+ offset = 0;
+ break;
+ case 9:
+ // It's located at BASE_TILE+1 for tile sets with detected doors
+ offset = 1;
+ break;
+ default:
+ // Passed a non-door tile base, pig out now.
+ ASSERT(false);
+ }
+
+ // If we've reached this point, we're dealing with a gate.
+ // Don't believe gateways deal differently with detection.
+ if (detected)
+ return 0;
+
+ if (!opened && !detected && gateway_type == 0)
+ return 0;
+
+ return offset + gateway_type;
+}
+
// Modify wall tile index depending on floor/wall flavour.
static inline void _finalise_tile(unsigned int *tile,
unsigned char wall_flv,
@@ -3093,7 +3147,18 @@ static inline void _finalise_tile(unsigned int *tile,
else if (orig == TILE_WALL_NORMAL)
(*tile) = wall_flv;
else if (orig == TILE_DNGN_CLOSED_DOOR || orig == TILE_DNGN_OPEN_DOOR)
- (*tile) = orig + std::min((int)special_flv, 3);
+ {
+ int override = env.tile_flv(gc).feat;
+ if (override)
+ {
+ // XXX: This doesn't deal properly with detected doors.
+ bool opened = (orig == TILE_DNGN_OPEN_DOOR);
+ int offset = _get_door_offset(override, opened, false, special_flv);
+ (*tile) = override + offset;
+ }
+ else
+ (*tile) = orig + std::min((int)special_flv, 3);
+ }
else if (orig < TILE_DNGN_MAX)
{
// Some tiles may change from turn to turn, but only if in view.
@@ -4356,7 +4421,7 @@ void tile_init_flavour(const coord_def &gc)
env.tile_flv(gc).wall = env.tile_default.wall + wall_rnd;
}
- if (grd(gc) == DNGN_OPEN_DOOR || feat_is_closed_door(grd(gc)))
+ if (feat_is_door(grd(gc)))
{
// Check for horizontal gates.