git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7520 c06c8d41-db1a-0410-9941-cceddc491573
X7MFMKQTNZ2IWBFVGS6WQV7NRNKJ3DWQAW2X7IQMFQQXW24AHPZQC
JRTQYLX2MPF4LAIM3VRTWWOMRHTUSWLNXHTJMQZ62UCOPWFOEQFQC
J7GPW2YXLT6FGSKJ24FGQ24GTRZ6A2BDYM6CIXV4R6YBEHP6BGPAC
4MM33ZOXDXGHQEBINUXPTCJ5ROBEDU7G4KDUYRMKTDY27S6ZS2UAC
JPFT2IRK2624J6QS72PSRMPYJQRIWSV567GFLC2JOJD7246XHOTAC
77MES6I23O3FEVX45F5L7LGABFIDYZA2CLESQBXALSVIHS5E2G6AC
RN242L3YZK35BFY7JRTCSYWD6FWDCRFUFDI7PKYFUCA2UPX6ZEAQC
KFH3JPHHQLBY3V5VEJWME6ZDMI6TZSF2TDYRF726FAYVNYGMPA5AC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
LH4OYDEWEON5QNUCM74R7MNBJDP7O4XRETY74ZMYSXUXYQV427PAC
AM7QPHDAWNXHLUEVUHVRHG2RO2DOIEFFU4GV3DCIROW6O5HW7H4AC
TLO257LZSB6ZO36STDUEWJBO2LETXFKTFGXELA6Y4BZBVAEIIINAC
PSCYVKJ7DGXAL3V5U4O6AJTRV6Q3N3SHQWAZ73VIPRTE4W64F2XAC
JGKYRZ34S3I23PMJX6IUBR7EHEFD6I4XXEGXNT7GKT2M2VIRBSMQC
L4RYVF46EQKMVOEADGRG4WMPVTQ6NNFGYMU4SHAH6XJIKWVHT77QC
VXSORUQOM2VZA4CAZDC6KPAY373NQIN3UT7CXQXTRCYXO2WM62DAC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
I67HCZISOEMUYFEUA6VOJOO2L4TYK73IB4FSTY4CHDR7GZD6CS6QC
5BJPWUPLJFS34FUTFJVKA4A52YMIGV6EWDXLNSDCWBJWBGVSQFGQC
W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC
GQL5SIGBHLU3FMCE54XVGLRY5AZHRM6DUEB722REA2DPLGJSN6EQC
IVVTHLTTLOP5TSULXJWUSSXHOKYWVU3OWKYVK45A7RIB6V34MYQAC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
RGHXFBNIULRVRYLBGG5JZDMYVM2E2JJ2Y5KQPMU6PUS3V26G6ZXQC
PRG7UT7G56GT4W3FQ3KG5JRPGMKKJBFDLVHDLYFQK6IZW25JQLBQC
G277QSURADDFZIIO5PIMBA4YWHYULQCEGNMNI6TLBWZXHQOOP6FAC
ZLQAAP55CJ77XIJN3DZVPT4GTTVLIBFJLIJJKI6L5UBSHX7VUK6AC
ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC
SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC
EJ4GIPFSSQCQASUMRF4CR2WPUQOTEHFRGLOYEZ7BH6YEMIR6DN4QC
TLA5UN6LZPXGKERI27EFY4HKIIU3VU5Y7ZU54WXL6ANBUV2VOTMQC
AO3KHGKGSX2ZR24KJVIOTUY7EHYHMMI5W4HN3CAG4YGQHBOHLGDQC
3UKFCWWS5BLFQWZRB5FUA46CE2XGX5VRCEWC3K3XH5RCGQK64N2AC
S7T5CO7QMCIK6QSVVB76GNOAQ6QNJOOINGMLFWRC26VK276R3QCAC
FSD7GIK3YLZXWLEH37BU6KV3IUCFGXPQL6IZ7H65YWNRBEKDBX5AC
UHDT225XZQLYFE7S4LZECR5C2QSI6PNDTP2WWLCIGHAJ3YNFHPXQC
2WRXQTGYDBLV46WRNVIUKGNA5QS563XZNNW3N2L6PVOCHIP2YGHQC
S34LKQDIQJLIWVIPASOJBBZ6ZCXDHP5KPS7TRBZJSCDRVNCLK6UAC
W52PTX4I7TUG2LS36FJHLZ72DWCVXGUCTUIKPI3IGEYO5KWL6OVAC
HNXKX6ZDQJV33E7UKZOLBYWJMRZ4QLEMXVXJZNRCTOIG2KVRTIEAC
FQ7XALBL6NZAGBKKYIFHYQ7MUWIHR4TEU4TCS33EG4I3JTND5SQAC
UBQTNLYGD3SNWMUNGWUPX7EXEGQXOXCFCPWIVWBFE7ID7DJLPFWAC
KTF2SZLDR2NGPWSFAWDYV2X3UP4V5VDNTIGDGQ6G24HUNABFYR2QC
44YRMW5JNVUBYX3M6UFQOPENNHGO7G2CRZ7SGPIIUTQGYWTRWENAC
W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC
ZJLJGSB2XSBQU42OFQMXL3EG4CXAQGOYAU6YTV2SAWZEJIPFH2CAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
you.level_type_name = newtype;
if (you.level_type_tag.empty() || !newtype.empty()
|| you.level_type != LEVEL_PORTAL_VAULT)
{
you.level_type_tag = newtype;
}
if (!you.level_type_tag.empty() && you.level_type_name.empty())
you.level_type_name = you.level_type_tag;
static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx)
{
dungeon_feature_type feat = (dungeon_feature_type)0;
if (lua_isnumber(ls, idx))
feat = (dungeon_feature_type)luaL_checkint(ls, idx);
else if (lua_isstring(ls, idx))
feat = dungeon_feature_by_name(luaL_checkstring(ls, idx));
else
luaL_argerror(ls, idx, "Feature must be a string or a feature index.");
return feat;
}
static dungeon_feature_type _check_lua_feature(lua_State *ls, int idx)
{
const dungeon_feature_type f = _get_lua_feature(ls, idx);
if (!f)
luaL_argerror(ls, idx, "Invalid dungeon feature");
return (f);
}
#define COORDS(c, p1, p2) \
coord_def c; \
c.x = luaL_checkint(ls, p1); \
c.y = luaL_checkint(ls, p2); \
if (!in_bounds(c)) \
luaL_error( \
ls, \
make_stringf("Point (%d,%d) is out of map bounds", \
c.x, c.y).c_str());
#define FEAT(f, pos) \
dungeon_feature_type f = _check_lua_feature(ls, pos)
if (lua_gettop(ls) != 3 || !lua_isstring(ls, 2) || !lua_isfunction(ls, 3))
luaL_error(ls, "Expected marker key and marker function.");
if (lua_gettop(ls) != 3 || !lua_isstring(ls, 2)
|| (!lua_isfunction(ls, 3) && !lua_istable(ls, 3)))
{
luaL_error(ls, "Expected marker key and marker function/table.");
}
const int x = luaL_checkint(ls, 1), y = luaL_checkint(ls, 2);
if (!map_bounds(x, y))
luaL_error(ls,
make_stringf("(%d,%d) is out of bounds (%d-%d,%d-%d)",
x, y,
X_BOUND_1, X_BOUND_2,
Y_BOUND_1, Y_BOUND_2).c_str());
if (lua_isnumber(ls, 3))
grd[x][y] = static_cast<dungeon_feature_type>(luaL_checkint(ls, 3));
PLUARET(number, grd[x][y]);
COORDS(c, 1, 2);
const dungeon_feature_type feat = _get_lua_feature(ls, 3);
if (feat)
grd(c) = feat;
PLUARET(number, grd(c));
static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx)
{
dungeon_feature_type feat = (dungeon_feature_type)0;
if (lua_isnumber(ls, idx))
feat = (dungeon_feature_type)luaL_checkint(ls, idx);
else if (lua_isstring(ls, idx))
feat = dungeon_feature_by_name(luaL_checkstring(ls, idx));
else
luaL_argerror(ls, idx, "Feature must be a string or a feature index.");
dungeon_feature_type search = _get_lua_feature(ls, 5);
if (!search)
{
luaL_argerror(ls, 5, "Invalid feature.");
return 0;
}
dungeon_feature_type replace = _get_lua_feature(ls, 6);
if (!replace)
{
luaL_argerror(ls, 6, "Invalid feature.");
return 0;
}
dungeon_feature_type search = _check_lua_feature(ls, 5);
dungeon_feature_type replace = _check_lua_feature(ls, 6);
dungeon_feature_type search = _get_lua_feature(ls, 5);
if (!search)
{
luaL_argerror(ls, 5, "Invalid feature.");
lua_pushboolean(ls, false);
return 1;
}
dungeon_feature_type replace = _get_lua_feature(ls, 6);
if (!replace)
{
luaL_argerror(ls, 6, "Invalid feature.");
lua_pushboolean(ls, false);
return 1;
}
dungeon_feature_type search = _check_lua_feature(ls, 5);
dungeon_feature_type replace = _check_lua_feature(ls, 6);
dungeon_feature_type search = _get_lua_feature(ls, 1);
if (!search)
{
luaL_argerror(ls, 1, "Invalid feature.");
return 0;
}
dungeon_feature_type replace = _get_lua_feature(ls, 2);
if (!replace)
{
luaL_argerror(ls, 2, "Invalid feature.");
return 0;
}
dungeon_feature_type search = _check_lua_feature(ls, 1);
dungeon_feature_type replace = _check_lua_feature(ls, 2);
static int dgn_register_lua_marker(lua_State *ls)
{
COORDS(c, 1, 2);
if (!lua_istable(ls, 3) && !lua_isfunction(ls, 3))
return luaL_argerror(ls, 3, "Expected marker table or function");
lua_datum table(CLua::get_vm(ls), 3, false);
map_marker *marker = new map_lua_marker(table);
marker->pos = c;
env.markers.add(marker);
return (0);
}
if (vgrid[ri->y][ri->x] == ' ')
continue;
// NOTE: assumes *no* previous item (I think) or monster (definitely)
// placement.
for ( rectangle_iterator ri(place.pos, place.pos + place.size - 1);
ri; ++ri )
{
if (vgrid[ri->y][ri->x] == ' ')
continue;
const dungeon_feature_type oldgrid = grd(*ri);
altar_count = _vault_grid( place, level_number, *ri, altar_count,
acq_item_class,
vgrid[ri->y][ri->x],
target_connections,
num_runes,
rune_subst );
if (!generating_level)
{
// Have to link items each square at a time, or
// dungeon_terrain_changed could blow up.
link_items();
const dungeon_feature_type newgrid = grd(*ri);
grd(*ri) = oldgrid;
dungeon_terrain_changed(*ri, newgrid, true, true);
env.markers.remove_markers_at(*ri, MAT_ANY);
const dungeon_feature_type oldgrid = grd(*ri);
altar_count = _vault_grid( place, level_number, *ri, altar_count,
acq_item_class,
vgrid[ri->y][ri->x],
target_connections,
num_runes,
rune_subst );
if (!generating_level)
{
// Have to link items each square at a time, or
// dungeon_terrain_changed could blow up.
link_items();
const dungeon_feature_type newgrid = grd(*ri);
grd(*ri) = oldgrid;
dungeon_terrain_changed(*ri, newgrid, true, true);
env.markers.remove_markers_at(*ri, MAT_ANY);
}
env.map(*ri).property |= FPROP_VAULT;
// Last attempt: look for marker.
const coord_def pos(_dgn_find_feature_marker(stair_to_find));
if (in_bounds(pos))
return (pos);
// Still hosed? If we're in a portal vault, convert to a search for
// any stone arch.
if (you.level_type == LEVEL_PORTAL_VAULT
&& stair_to_find != DNGN_STONE_ARCH)
{
return dgn_find_nearby_stair(DNGN_STONE_ARCH, base_pos, find_closest);
}
###############################################################################
# ziggurat.des - Ziggurat entry vaults and ziggurat layouts.
###############################################################################
# Most ziggurat code is in ziggurat.lua.
# XXX: Ziggurat code is incomplete.
: dofile("clua/ziggurat.lua")
NAME: enter_the_ziggurat
# Disabled; ziggurat is still incomplete.
WEIGHT: 0
: ziggurat_portal(_G)
MAP
O
ENDMAP
NAME: ziggurat1
: ziggurat_level(_G)
MAP
ENDMAP
#############################################################################
# Multilevel portal vault structure:
# This is how a multilevel portal vault should be laid out. All stairs are
# one-way; the player cannot return to a level once left.
NAME: multilevel_portal_vault_entry
# Demo vault, disabled.
WEIGHT: 0
MARKER: O = lua:one_way_stair { \
dst="multilevel portal vault", \
desc="An entrance to a multilevel portal vault" \
}
KFEAT: O = enter_portal_vault
MAP
O
ENDMAP
NAME: portal_level_1
TAGS: multilevel_portal_vault
: portal_vault(_G, "multilevel_portal_vault")
# portal_next() links all downstairs to the vault with the specified tag.
: portal_next(_G, "multilevel_portal_vault_b")
MAP
xxxxxx
xA..]x
xxxxxx
ENDMAP
NAME: portal_level_2
: portal_vault(_G, "multilevel_portal_vault_b")
: portal_next(_G, "multilevel_portal_vault_c")
MAP
xxxxxx
xAWW]x
xxxxxx
ENDMAP
NAME: portal_level_3
: portal_vault(_G, "multilevel_portal_vault_c")
KFEAT: < = exit_portal_vault
MAP
xxxxxxx
xlllllx
xA...<x
xlllllx
xxxxxxx
ENDMAP
------------------------------------------------------------------------------
-- ziggurat.lua:
--
-- Code for ziggurats.
--
-- Important notes:
-- ----------------
-- Functions that are attached to Lua markers' onclimb properties
-- cannot be closures, because Lua markers must be saved and closure
-- upvalues cannot (yet) be saved.
------------------------------------------------------------------------------
function zig()
if not dgn.persist.ziggurat then
dgn.persist.ziggurat = { }
end
return dgn.persist.ziggurat
end
-- Returns a function that changes the depth in the ziggurat to the depth
-- specified.
local function zig_depth_increment()
return function (...)
zig().depth = zig().depth + 1
end
end
function ziggurat_initializer()
local z = zig()
z.depth = 1
z.builder = ziggurat_choose_builder()
end
-- Returns the current depth in the ziggurat.
local function zig_depth()
return zig().depth or 0
end
-- Common setup for ziggurat entry vaults.
function ziggurat_portal(e)
local function stair()
return one_way_stair {
desc = "gateway to a ziggurat",
dst = "ziggurat",
floor = "stone_arch",
onclimb = ziggurat_initializer
}
end
e.lua_marker("O", stair)
e.kfeat("O = enter_portal_vault")
end
-- Common setup for ziggurat levels.
function ziggurat_level(e)
e.tags("ziggurat")
e.tags("allow_dup")
e.orient("encompass")
ziggurat_build_level(e)
end
-----------------------------------------------------------------------------
-- Ziggurat level builders.
function ziggurat_build_level(e)
local builder = zig().builder
if builder then
return ziggurat_builder_map[builder](e)
end
end
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
-- Creates a Lua marker table that increments ziggurat depth.
local function zig_go_deeper()
return one_way_stair {
onclimb = zig_depth_increment()
}
end
local function ziggurat_rectangle_builder(e)
local grid = dgn.grid
-- FIXME: Cool code goes here.
local x1, y1 = 20, 20
local x2, y2 = dgn.GXM - 20, dgn.GYM - 20
dgn.fill_area(x1, y1, x2, y2, "floor")
local my = math.floor((y1 + y2) / 2)
zigstair(x1, my, "stone_arch", "stone_stairs_up_i")
zigstair(x2, my, "stone_stairs_down_i", zig_go_deeper)
grid(x2, my + 1, "exit_portal_vault")
crawl.mpr("Ziggurat depth is now " .. zig_depth())
end
----------------------------------------------------------------------
ziggurat_builder_map = {
rectangle = ziggurat_rectangle_builder
}
local ziggurat_builders = { }
for key, val in pairs(ziggurat_builder_map) do
table.insert(ziggurat_builders, key)
end
function ziggurat_choose_builder()
return ziggurat_builders[crawl.random_range(1, #ziggurat_builders)]
end
end
end
----------------------------------------------------------------------
-- Convenience functions for vaults.
-- Returns a marker table that sets the destination tag for that square,
-- usually used to set a destination tag for a portal or a stair in a
-- portal vault.
function portal_stair_dst(dst)
return one_way_stair { dst = dst }
end
-- Common initialisation for portal vaults.
function portal_vault(e, tag)
if tag then
e.tags(tag)
}
#define LUA_CHECK_TYPE(check) \
lua_stack_cleaner clean(lua); \
push(); \
return check(lua, -1)
bool lua_datum::is_table() const
{
LUA_CHECK_TYPE(lua_istable);
}
bool lua_datum::is_function() const
{
LUA_CHECK_TYPE(lua_isfunction);
}
bool lua_datum::is_number() const
{
LUA_CHECK_TYPE(lua_isnumber);
bool lua_datum::is_string() const
{
LUA_CHECK_TYPE(lua_isstring);
}
bool lua_datum::is_udata() const
{
LUA_CHECK_TYPE(lua_isuserdata);
}