after map transforms are applied.
Fixed conflicts in bison grammar.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1669 c06c8d41-db1a-0410-9941-cceddc491573
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC XEZ76QETN2I5KWNSGQPNNPH2K55DPRAXDYZ6UGHOPI3E5V2OCOUAC PM2AFCUMNJD4UBWQ4GQPETHSE4T2C75JB5B4RHN3DBD6KTX3VBLQC NTFA3ZSJFTVLTTKI6ONJE33PGGDW36IVGWMO6GXRA4ZG57TOWNFAC Y67JTRJI2257JT6OAZGAOREMVPR6JNAQNAFKKS4ZME5VYGORBPIAC RRADDS444JWSL4KOJKNZFAIMWMZRLFR4KZPC2MJBCJPEPINC5CPQC EIZC76IFTDKBNDJOX6YPFBOAOVAY6RSXH3JUWFLLGCZ3PYJMW3GQC 6JGTYQKIAHVHQIBZ6RKSLIRIQHE3EJZUEY4IOXU5TTN654JV7KHAC JDPJS5SNW6ZTY5DYV5QUBG2WVJ45FJ4CAOK6KDJKPEI2HLIHVLRQC RGHXFBNIULRVRYLBGG5JZDMYVM2E2JJ2Y5KQPMU6PUS3V26G6ZXQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC JDM27QE4HR52AYFSQE763BFF57ANOTF5MXKMO377PP5EXMN7SAOAC W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC KXUQB3WNWC5IFL6VFWADEPQMMU3VV3NDI5FLA666PGOEWFYUHCLQC 34C4U6EQWERY75GZJKUCM5KVGU2OUICETS5LGZF6RMKMZT4R5SQAC JTTHP2BEYEPBQMSDM7IKANTMKRPY6ACGL2JN4D3OBZ7HFXKAYEGQC WW6THKR7JN447YC23YYHYYNH7ABMCFFSECNUFTIJBZX6JHX6W7TAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC RC6L3CIBLJEH4GWRFD7UQNGI6PZT74FRUVOYHSAN2XCC74NZUASQC SCWXQW5H65OXUP2MEJ2MEEAVPSRJDT3RQGKYCMKVTORS2334PQSQC TAHSTXR7ROOMDFUSBUU4ZAIEWQLAS5CIRCTARLD4Q2BGNLSL7E5QC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC KZNUAHJQUBM6MEVUSSWG734AXZ3NZYMRJ2XFQLRGXJ3MSTBV7ELQC A3CO4KBFTFU3ZSHWRY2OPPX3MMTFV7OUCZGL7Q4Y2FU7JO4AP7MAC ZJLJGSB2XSBQU42OFQMXL3EG4CXAQGOYAU6YTV2SAWZEJIPFH2CAC NCDWWDJQLAU5ORSAQGZKJJ5E22VTDGGPJMVVBWQFHQ2B3U3UFHDQC KFJEFN377VIZ7OH2XCYOGCELNEGO4CIOOP7DNXEMX3LFKIKWXVTAC B3SRWSFITQMJRVEBHGQQJARETYPSSDV6XKMQSSUTXEHTXRZKIQJQC AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC ILOED4VB4I6VPAUTR75ZWX6MXDYXB5DO2EDK2UH67O3HNKWV23RQC Z3RI4XAN7J2GUABAQ5G6YIOQYMBOAEQFFGRBWHMUEB2A2QYXO5MQC XY77S75KH5KV54MZVAPMUC64TVRE2QM2KVJAAGJGCIBGQEC5GUTQC XAFFD52IHN6FWFR2TT5F2KCUS7HAVCBI5CWTFMKPQG77GGTGAHLAC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC EEPNZ3SHGXQ4NKLSWHI7X2WK3LU3AR2EDZZFFDGOXQQBK5LO5OYAC Q2FZIIGQECGP2FKKWLGDBBQVGCFZ4JTY53PFPJP6X7YKC23AQGFQC AVSMB4Y6F6ZMMNNPOAQQZ34OWC6N5JOURTEWFTUKDWMIIMLWWJUAC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC int glyph_at(const coord_def &c) const;public:struct map_feature_finder{map_def ↦map_feature_finder(map_def &map_) : map(map_) { }// This may actually modify the underlying map by fixing KFEAT:// feature slots, but that's fine by us.dungeon_feature_type operator () (const coord_def &c) const{return (map_feature(&map, c, -1));}};struct map_bounds_check{map_def ↦map_bounds_check(map_def &map_) : map(map_) { }bool operator () (const coord_def &c) const{return (c.x >= 0 && c.x < map.map.width()&& c.y >= 0 && c.y < map.map.height());}};
std::vector<coord_def> map_def::find_glyph(int glyph) const{std::vector<coord_def> points;for (int y = map.height() - 1; y >= 0; --y){for (int x = map.width() - 1; x >= 0; --x){const coord_def c(x, y);if (map(c) == glyph)points.push_back(c);}}return (points);}coord_def map_def::find_first_glyph(int glyph) const{for (int y = 0, height = map.height(); y < height; ++y){for (int x = 0, width = map.width(); x < width; ++x){const coord_def c(x, y);if (map(c) == glyph)return (c);}}return coord_def(-1, -1);}
static int dgn_points_connected(lua_State *ls){MAP(ls, 1, map);const int nargs = lua_gettop(ls);if (nargs < 5)return luaL_error(ls,"Not enough points to test connectedness ""(need at least two)");map_def::map_feature_finder feat_finder(*map);map_def::map_bounds_check bounds_checker(*map);flood_find<map_def::map_feature_finder, map_def::map_bounds_check>finder(feat_finder, bounds_checker);
for (int i = 4; i < nargs; i += 2){const coord_def c(luaL_checkint(ls, i),luaL_checkint(ls, i + 1));finder.add_point(c);}const coord_def pos(luaL_checkint(ls, 2), luaL_checkint(ls, 3));const bool connected = finder.points_connected_from(pos);PLUARET(boolean, connected);}static void dlua_push_coord(lua_State *ls, const coord_def &c){lua_pushnumber(ls, c.x);lua_pushnumber(ls, c.y);}static int dgn_gly_point(lua_State *ls){MAP(ls, 1, map);coord_def c = map->find_first_glyph(*luaL_checkstring(ls, 2));if (c.x != -1 && c.y != -1){dlua_push_coord(ls, c);return (2);}return (0);}static int dgn_gly_points(lua_State *ls){MAP(ls, 1, map);std::vector<coord_def> cs = map->find_glyph(*luaL_checkstring(ls, 2));for (int i = 0, size = cs.size(); i < size; ++i)dlua_push_coord(ls, cs[i]);return (cs.size() * 2);}static int dgn_original_map(lua_State *ls){MAP(ls, 1, map);if (map->original)clua_push_map(ls, map->original);elselua_pushnil(ls);return (1);}
void place_spec_shop(int level_number, unsigned char shop_x,unsigned char shop_y, unsigned char force_s_type,bool representative = false );
//////////////////////////////////////////////////////////////////////////template <typename fgrd, typename bound_check>class flood_find : public travel_pathfind{public:flood_find(const fgrd &f, const bound_check &bc);
bool unforbidden(const coord_def &c, const dgn_region_list &forbidden);
void add_feat(int feat);void add_point(const coord_def &pos);coord_def find_first_from(const coord_def &c, const dgn_region_list &vlts);bool points_connected_from(const coord_def &start);bool did_leave_vault() const { return left_vault; }protected:bool path_flood(const coord_def &c, const coord_def &dc);protected:bool point_hunt;bool needed_features[NUM_FEATURES];std::vector<coord_def> needed_points;bool left_vault;dgn_region_list vaults;const fgrd &fgrid;const bound_check &bcheck;};template <typename fgrd, typename bound_check>flood_find<fgrd, bound_check>::flood_find(const fgrd &f, const bound_check &bc): travel_pathfind(), point_hunt(false), needed_features(),needed_points(), left_vault(true), vaults(),fgrid(f), bcheck(bc){memset(needed_features, false, sizeof needed_features);}template <typename fgrd, typename bound_check>void flood_find<fgrd, bound_check>::add_feat(int feat){if (feat >= 0 && feat < NUM_FEATURES)needed_features[feat] = true;}template <typename fgrd, typename bound_check>coord_defflood_find<fgrd, bound_check>::find_first_from(const coord_def &c,const dgn_region_list &vlts){set_floodseed(c);vaults = vlts;return pathfind(RMODE_EXPLORE);}template <typename fgrd, typename bound_check>void flood_find<fgrd, bound_check>::add_point(const coord_def &c){needed_points.push_back(c);}template <typename fgrd, typename bound_check>bool flood_find<fgrd, bound_check>::points_connected_from(const coord_def &sp){if (needed_points.empty())return (true);set_floodseed(sp);pathfind(RMODE_EXPLORE);return (needed_points.empty());}template <typename fgrd, typename bound_check>bool flood_find<fgrd, bound_check>::path_flood(const coord_def &c,const coord_def &dc){if (!bcheck(dc))return (false);if (!needed_points.empty()){std::vector<coord_def>::iterator i =std::find(needed_points.begin(), needed_points.end(), dc);if (i != needed_points.end()){needed_points.erase(i);if (needed_points.empty())return (true);}}const dungeon_feature_type grid = fgrid(dc);if (needed_features[ grid ]){unexplored_place = dc;unexplored_dist = traveled_distance;return (true);}if (!is_traversable(grid)&& grid != DNGN_SECRET_DOOR&& !grid_is_trap(grid)){return (false);}if (!left_vault && unforbidden(dc, vaults))left_vault = true;good_square(dc);return (false);}//////////////////////////////////////////////////////////////////////////
class feature_find : public travel_pathfind{public:feature_find();void add_feat(int feat);coord_def find_first_from(const coord_def &c);bool did_leave_vault() const { return left_vault; }protected:bool path_flood(const coord_def &c, const coord_def &dc);protected:bool needed_features[NUM_FEATURES];bool left_vault;dgn_region_list vaults;};
feature_find::feature_find(): travel_pathfind(), needed_features(), left_vault(true), vaults(){memset(needed_features, false, sizeof needed_features);}void feature_find::add_feat(int feat){if (feat >= 0 && feat < NUM_FEATURES)needed_features[feat] = true;}coord_def feature_find::find_first_from(const coord_def &c){set_floodseed(c);for (int i = 0, size = level_vaults.size(); i < size; ++i){const vault_placement &p = level_vaults[i];vaults.push_back( dgn_region(p.x, p.y, p.width, p.height) );}return pathfind(RMODE_EXPLORE);}bool feature_find::path_flood(const coord_def &c, const coord_def &dc){if (!in_bounds(dc))return (false);const dungeon_feature_type grid = grd(dc);if (needed_features[ grid ]){unexplored_place = dc;unexplored_dist = traveled_distance;return (true);}if (!is_travelsafe_square(dc.x, dc.y, false, true)&& grid != DNGN_SECRET_DOOR&& !grid_is_trap(grid)){return (false);}if (!left_vault && unforbidden(dc, vaults))left_vault = true;good_square(dc);return (false);}
}// Grr, keep this in sync with vault_grid.dungeon_feature_type map_feature(map_def *map, const coord_def &c, int rawfeat){if (rawfeat == -1)rawfeat = map->glyph_at(c);keyed_mapspec *mapsp = map? map->mapspec_for_key(rawfeat) : NULL;if (mapsp){const feature_spec f = mapsp->get_feat();if (f.feat >= 0)return static_cast<dungeon_feature_type>(f.feat);else if (f.glyph >= 0)return map_feature(NULL, c, rawfeat);else if (f.shop >= 0)return (DNGN_ENTER_SHOP);else if (f.trap >= 0)return (DNGN_UNDISCOVERED_TRAP);return (DNGN_FLOOR);}return ((rawfeat == 'x') ? DNGN_ROCK_WALL :(rawfeat == 'X') ? DNGN_PERMAROCK_WALL :(rawfeat == 'c') ? DNGN_STONE_WALL :(rawfeat == 'v') ? DNGN_METAL_WALL :(rawfeat == 'b') ? DNGN_GREEN_CRYSTAL_WALL :(rawfeat == 'a') ? DNGN_WAX_WALL :(rawfeat == '+') ? DNGN_CLOSED_DOOR :(rawfeat == '=') ? DNGN_SECRET_DOOR :(rawfeat == 'w') ? DNGN_DEEP_WATER :(rawfeat == 'W') ? DNGN_SHALLOW_WATER :(rawfeat == 'l') ? DNGN_LAVA :(rawfeat == '>') ? DNGN_ROCK_STAIRS_DOWN :(rawfeat == '<') ? DNGN_ROCK_STAIRS_UP :(rawfeat == '}') ? DNGN_STONE_STAIRS_DOWN_I :(rawfeat == '{') ? DNGN_STONE_STAIRS_UP_I :(rawfeat == ')') ? DNGN_STONE_STAIRS_DOWN_II :(rawfeat == '(') ? DNGN_STONE_STAIRS_UP_II :(rawfeat == ']') ? DNGN_STONE_STAIRS_DOWN_III :(rawfeat == '[') ? DNGN_STONE_STAIRS_UP_III :(rawfeat == 'A') ? DNGN_STONE_ARCH :(rawfeat == 'B') ? DNGN_ALTAR_ZIN :(rawfeat == 'C') ? pick_an_altar() : // f(x) elsewhere {dlb}(rawfeat == 'F') ? DNGN_GRANITE_STATUE :(rawfeat == 'I') ? DNGN_ORCISH_IDOL :(rawfeat == 'S') ? DNGN_SILVER_STATUE :(rawfeat == 'G') ? DNGN_GRANITE_STATUE :(rawfeat == 'H') ? DNGN_ORANGE_CRYSTAL_STATUE :(rawfeat == 'T') ? DNGN_BLUE_FOUNTAIN :(rawfeat == 'U') ? DNGN_SPARKLING_FOUNTAIN :(rawfeat == 'V') ? DNGN_PERMADRY_FOUNTAIN :(rawfeat == '\0')? DNGN_ROCK_WALL :DNGN_FLOOR); // includes everything else
endend--------------------------------------------------------------------function dgn.places_connected(map, map_glyph, test_connect, ...)local points = { }for _, glyph in ipairs( { ... } ) dolocal x, y = map_glyph(map, glyph)if x and y thentable.insert(points, x)table.insert(points, y)elseerror("Can't find coords for '" .. glyph .. "'")endendreturn test_connect(map, unpack(points))endfunction dgn.glyphs_connected(map, ...)return dgn.places_connected(map, dgn.gly_point, dgn.points_connected, ...)endfunction dgn.orig_glyphs_connected(map, ...)return dgn.places_connected(map, dgn.orig_gly_point,dgn.points_connected, ...)endfunction dgn.orig_fn(map, fnx, ...)local original = dgn.original_map(map)if not original thenerror("Can't find original map for map '" .. dgn.name(map) .. "'")