git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7625 c06c8d41-db1a-0410-9941-cceddc491573
MT3256427VMCV4JUFWCN7ULY4KXSND5ZL5THDKYNWWYOXXR5DLIQC
TJ72NVTRNJKF55RTH5MRLTHHVPOJ2M5OOYEWF4UFLTO2PPPTU6PQC
VTJOYDSSNQZOK23N65C64NUGDTGPL6QZWGCALRQHQDQXAPYBRKMAC
Y3NLZQBRMBULLMTLNCG5VSLRZFUAD4MI6VMYN7Q3L5YMIVDN5DAQC
DTO3EUKWHZ5RJNGNCFYXSOVTIPVXPP637F2W7WFGYKJ7JK7VNKNQC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC
ISSEUTHG7EH3QTFLS23GXFIOQXCI5HJPJMK6GWNFMC6NDRD2H34QC
RLUXNEFLEICA7ERDVUOIJZJJSTPY2QLEXYN2KDEVWZSKVIV4CKPQC
RGHXFBNIULRVRYLBGG5JZDMYVM2E2JJ2Y5KQPMU6PUS3V26G6ZXQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
KCHX2F3JFEWOZT3WMJVZAAQUU2QSZ5Q7RDCD7WUJ7VE65J52JFUQC
BW6QCGQDWZ6G2UGDD4EXI5VVDZHM5S53MJIC5CKG3Q3VQ4IDQ2VQC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC
NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC
PRG7UT7G56GT4W3FQ3KG5JRPGMKKJBFDLVHDLYFQK6IZW25JQLBQC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
UU5EKED2RA2U3CFZ3UEJQEWSWHQPEU7ZD4KH3I22IIVZFHD4Y67QC
NKONHW4JNY6HP2M63MNPM3H64ZWSUNUT5FX2STW4KTS4AMXJXXVQC
44YRMW5JNVUBYX3M6UFQOPENNHGO7G2CRZ7SGPIIUTQGYWTRWENAC
4N5PW5S3OV25HFN634NNWMMYX26NA2TB6TVFG4UMYSZ2VBJWKE4QC
X7MFMKQTNZ2IWBFVGS6WQV7NRNKJ3DWQAW2X7IQMFQQXW24AHPZQC
CPBVQFT7NWEYLYD34D5VYZIEOZ32YADXYTSFMS635YNXX4OFIZVAC
CM2YC5KBTUB4JFT3CL3NRS7V5X76M7RI7SNT4XK6IOVBZA2URRKAC
QONBKHB7H3PF5P4LGSAC7KIZ5D6HCH677Z3AR2HU7KNSOVKDK25QC
W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC
JPFT2IRK2624J6QS72PSRMPYJQRIWSV567GFLC2JOJD7246XHOTAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
77MES6I23O3FEVX45F5L7LGABFIDYZA2CLESQBXALSVIHS5E2G6AC
bool feature_marker_at(const coord_def &pos, dungeon_feature_type feat)
{
std::vector<map_marker*> markers = env.markers.get_markers_at(pos);
for (int i = 0, size = markers.size(); i < size; ++i)
{
map_marker *mark = markers[i];
if (mark->get_type() == MAT_FEATURE &&
dynamic_cast<map_feature_marker*>(mark)->feat == feat)
{
return (true);
}
}
return (false);
}
coord_def map_def::float_aligned_place() const
{
const point_vector our_anchors = anchor_points();
const coord_def fail(-1, -1);
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS,
"Aligning floating vault with %lu points vs %lu reference points",
our_anchors.size(), map_anchor_points.size());
#endif
// Mismatch in the number of points we have to align, bail.
if (our_anchors.size() != map_anchor_points.size())
return (fail);
// Align first point of both vectors, then check that the others match.
const coord_def pos = map_anchor_points[0] - our_anchors[0];
for (int i = 1, psize = map_anchor_points.size(); i < psize; ++i)
if (pos + our_anchors[i] != map_anchor_points[i])
return (fail);
// Looking good, check bounds.
if (!map_bounds(pos) || !map_bounds(pos + size() - 1))
return (fail);
// Go us!
return (pos);
}
// map(<map>, x, y) = glyph at (x,y), subject to map being
// resolved and normalised.
if (lua_gettop(ls) == 3 && lua_isnumber(ls, 2) && lua_isnumber(ls, 3))
{
const int gly = map->map.glyph(luaL_checkint(ls, 2),
luaL_checkint(ls, 3));
char buf[2] = "";
buf[0] = gly;
lua_pushstring(ls, buf);
return (1);
}
static bool _lua_map_place_invalid(const map_def &map,
const coord_def &c,
const coord_def &size)
{
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS, "lua_map_place_invalid: (%d,%d) (%d,%d)",
c.x, c.y, size.x, size.y);
#endif
lua_stack_cleaner clean(_dgn_map_bad_bounds_fn->lua);
// Push the Lua function onto the stack.
_dgn_map_bad_bounds_fn->push();
lua_State *ls = _dgn_map_bad_bounds_fn->lua;
// Push map, pos.x, pos.y, size.x, size.y
clua_push_map(ls, const_cast<map_def*>(&map));
clua_push_coord(ls, c);
clua_push_coord(ls, size);
const int err = lua_pcall(ls, 5, 1, 0);
// Lua error invalidates place.
if (err)
{
mprf(MSGCH_ERROR, "Lua error: %s", lua_tostring(ls, -1));
return (true);
}
return (lua_toboolean(ls, -1));
}
LUAFN(dgn_with_map_bounds_fn)
{
CLua &vm(CLua::get_vm(ls));
if (lua_gettop(ls) != 2 || !lua_isfunction(ls, 1) || !lua_isfunction(ls, 2))
luaL_error(ls, "Expected map-bounds check fn and action fn.");
_dgn_map_bad_bounds_fn.reset(new lua_datum(vm, 1, false));
int err = 0;
{
unwind_var<map_place_check_t> mpc(map_place_invalid,
_lua_map_place_invalid);
// All set, call our friend, the second function.
ASSERT(lua_isfunction(ls, -1));
// Copy the function since pcall will pop it off.
lua_pushvalue(ls, -1);
// Use pcall to catch the error here, else unwind_var won't
// happen when lua_call does its longjmp.
err = lua_pcall(ls, 0, 1, 0);
_dgn_map_bad_bounds_fn.reset(NULL);
}
if (err)
lua_error(ls);
return (1);
}
// Accepts any number of point coordinates and a function, binds the
// points as anchors that floating vaults must match and calls the
// function, returning the return value of the function.
LUAFN(dgn_with_map_anchors)
{
const int top = lua_gettop(ls);
int err = 0;
{
unwind_var<point_vector> uanchor(map_anchor_points);
map_anchor_points.clear();
int i;
for (i = 1; i < top; i += 2)
{
if (lua_isnumber(ls, i) && lua_isnumber(ls, i + 1))
map_anchor_points.push_back(
coord_def( lua_tointeger(ls, i),
lua_tointeger(ls, i + 1) ) );
}
ASSERT(lua_isfunction(ls, -1));
lua_pushvalue(ls, -1);
err = lua_pcall(ls, 0, 1, 0);
}
if (err)
lua_error(ls);
return (1);
}
local function zigstair(x, y, stair, marker)
dgn.grid(x, y, stair)
if marker then
local t = type(marker)
if t == "function" or t == "table" then
dgn.register_lua_marker(x, y, marker)
else
dgn.register_feature_marker(x, y, marker)
end
end
end
local zigstair = dgn.gridmark
local function is_free_space(p)
return dgn.grid(p.x, p.y) == dgn.fnum("floor") and
#dgn.items_at(p.x, p.y) == 0
local function free_space_threshold(max)
local function is_free_space(p)
return dgn.grid(p.x, p.y) == dgn.fnum("floor") and
#dgn.items_at(p.x, p.y) <= max
end
return is_free_space
end
local door = dgn.fnum("closed_door")
local function passable(p)
return dgn.is_passable(p.x, p.y) and dgn.grid(p.x, p.y) ~= door
-- Closed door with the permarock wall feature marker.
dgn.gridmark(doorplace.x, doorplace.y, "closed_door", "permarock_wall")
local connect_point = doorplace + inc
local map = dgn.map_by_tag("ziggurat_loot_chamber", false)
local function loot_fallback()
crawl.mpr("Failed to create loot vault, giving up", "diagnostic")
-- FAIL, generate loot the usual way.
ziggurat_create_loot_at(exit)
end
if not map then
return loot_fallback()
end
local function place_loot_chamber()
return dgn.place_map(map, false, true)
end
local function bad_loot_bounds(map, px, py, xs, ys)
local vc = dgn.point(px + math.floor(xs / 2),
py + math.floor(ys / 2))
local linc = (vc - exit):sgn()
-- The map's positions should be at the same increment to the exit
-- as the exit is to the entrance, else reject the place.
return not (inc == linc)
end
local function connect_loot_chamber()
return dgn.with_map_bounds_fn(bad_loot_bounds, place_loot_chamber)
end
local res = dgn.with_map_anchors(connect_point.x, connect_point.y,
connect_loot_chamber)
if not res then
loot_fallback()
else
ziggurat_create_loot_at(connect_point)
end
end
local function ziggurat_create_loot(entrance, exit)
if zig().level.jelly_protect then
ziggurat_create_loot_vault(entrance, exit)
else
ziggurat_create_loot_at(exit)
end
end
static const char *_monuse_names[] =
{
"nothing", "eats_items", "open_doors", "starting_equipment",
"weapons_armour", "magic_items"
};
static const char *_monuse_to_str(mon_itemuse_type ityp)
{
ASSERT(ARRAYSZ(_monuse_names) == NUM_MONUSE);
return _monuse_names[ityp];
}
MDEF(muse)
{
if (const monsterentry *me = mons->find_monsterentry())
{
PLUARET(string, _monuse_to_str(me->gmon_use));
}
return (0);
}