git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@7679 c06c8d41-db1a-0410-9941-cceddc491573
SM6YRPYZS6LMDQA6X3VAOK2PGMUFKPD7JMWJISOQSMX2CBR4ISPAC
BNRY5YIXLFE2TDNU2JQHWWXJQVWNSEWQ52DU7XUWIT5DZWKGBDDAC
FAGA7XVY7FB5VEMJZ625GU5CPQMTY4KTX2NCIXQWFPH7ZQYJSAFAC
BYURAML2EPTULHH22Q5RPXYGDEYAJYESR6C72UMNPPYHTCJZUPFAC
IIVX5MXLMKSQOCHTQYPEL4R3GRZWPTQNONPNAZMBHG74M6VLYKZQC
Y2NYY7HWFZ2LQDK3ACSLGS37F2J2IJ5LRGCIMZYXLEOSVPD3A4DAC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
GRSLMD5WMJD2WEKMYORL5K5FBA6QT3QIO4FNQQYD5XFFCD3EOL3QC
LOC46PHUFJ3MDWOYUEH4R24TGGE4ADG7C44O2ZNB4EBF2YD6VX7QC
YSIROVP23L7IDSVTBG7OQFQWLORVWWYINH7WPWTZO2I5BH4S7YPQC
F5APHUYFFFBUYWCU3OPCE5535X5FNUHMPZQ2H4M5J2RPIJIXTNRQC
J4FEX23HNK5K75KWIVDILPIWY33F23W66CT4P5BFVZQVZMLZ42WQC
2TFYJ7D72JY4DYQW3GSPEONA2WYIVHAJXTIQ2QRDIWF65XN2QFGAC
NNG27Y5ZQAZX6UD7F7M4F6KEZBEDFXPEEC3LFUSX4ESKT7K6UJQAC
BBAFAQFU3JBSUQT7XYPKOVKGUKCOVLBLBU2YGAEMEBL52CE4MDNQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
TLA5UN6LZPXGKERI27EFY4HKIIU3VU5Y7ZU54WXL6ANBUV2VOTMQC
AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC
NKONHW4JNY6HP2M63MNPM3H64ZWSUNUT5FX2STW4KTS4AMXJXXVQC
X7MFMKQTNZ2IWBFVGS6WQV7NRNKJ3DWQAW2X7IQMFQQXW24AHPZQC
MT3256427VMCV4JUFWCN7ULY4KXSND5ZL5THDKYNWWYOXXR5DLIQC
OYTCBRC7LE44EUVRZVYTOOVKQWJ6P6YE3FXTOGUTNKEMLNWPHKSQC
HWTL2S7OVOJRJAAN66ZTT26HJDAOIW6RKAG5NFMNZJU63CTU2U5AC
7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC
DUFJKFM5KBCM4272ZKLBPGKHLMDLK6RABUNTDEWRZULTKDTHHSBAC
IHV7JHD4E67NEGLZEO3FPQGJPJF3IAV6QV5A63FPG4SU2VRFV47QC
5DECJIOSMFWX7DMDTGVNPNV6QQP6O34F3XHFHRXGCTJUZMVIXT7QC
QONBKHB7H3PF5P4LGSAC7KIZ5D6HCH677Z3AR2HU7KNSOVKDK25QC
KTRWLM6WDL4GAAJZNLQEEA3TGY2OKYZZUAAT4TCAVKRTR2NQBWUQC
4N5PW5S3OV25HFN634NNWMMYX26NA2TB6TVFG4UMYSZ2VBJWKE4QC
NCKCO6W5HW7C6OPJG4EVHKQCDX6AL7S4ACORY45STKQTNPMAJ7IQC
6IHRQWBU55WYBVB7K5HDJSBISE3J3VILUCMQ6WYOBUZ43DLOQ6VQC
44YRMW5JNVUBYX3M6UFQOPENNHGO7G2CRZ7SGPIIUTQGYWTRWENAC
W52PCSHX72WAMWKG6L4BPUBVMO6E72KYYBNKAA7554KNOTY6V7WQC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC
UEI5JAVCMN7Y2SACTEZPZSNFJWOJTC55G24Q6LKQCT4XNDH5ZQIAC
NVSFIV2ZKP44XHCSCXG6OZVGL67OIFINC34J2EMKTA4KULCERUEAC
O4SBTZHRCL5YNL4UOWUGVDI5U7FF4TB5JPQ6PRTHRCZIDJHOSKZAC
// Monster doesn't die, just goes back to wherever it came from
// This must only be called by monsters running out of time (or
// abjuration), because it uses the beam variables! Or does it???
// Monster doesn't die, just goes back to wherever it came from
// This must only be called by monsters running out of time (or
// abjuration), because it uses the beam variables! Or does it???
#ifdef UNIX
#include <sys/time.h>
#include <time.h>
#endif
#define MONSLIST_METATABLE "crawldgn.monster_list"
#define ITEMLIST_METATABLE "crawldgn.item_list"
static mons_list _lua_get_mlist(lua_State *ls, int ndx);
static item_list _lua_get_ilist(lua_State *ls, int ndx);
template <class T>
static void _push_object_type(lua_State *ls, const char *meta, const T &data)
{
T **ptr = clua_new_userdata<T*>(ls, meta);
*ptr = new T(data);
}
mons_list mlist;
const std::string err = mlist.add_mons(spec);
if (!err.empty())
luaL_error(ls, err.c_str());
for (int i = 0, size = mlist.size(); i < size; ++i)
mons_spec mspec = mlist.get_monster(i);
if (dgn_place_monster(mspec, you.your_level, c,
false, false, false))
static int _dgn_monster_spec(lua_State *ls)
{
const mons_list mlist = _lua_get_mlist(ls, 1);
_push_object_type<mons_list>(ls, MONSLIST_METATABLE, mlist);
return (1);
}
static int _dgn_item_spec(lua_State *ls)
{
const item_list ilist = _lua_get_ilist(ls, 1);
_push_object_type<item_list>(ls, ITEMLIST_METATABLE, ilist);
return (1);
}
LUARET1(_dgn_max_monsters, number, MAX_MONSTERS)
if (const char *spec = lua_tostring(ls, 3))
{
item_list ilist;
const std::string err = ilist.add_item(spec);
if (!err.empty())
luaL_error(ls, err.c_str());
const int level =
lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level;
item_list ilist = _lua_get_ilist(ls, 3);
const int level =
lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level;
#ifdef UNIX
LUAFN(_crawl_millis)
{
struct timeval tv;
struct timezone tz;
const int error = gettimeofday(&tv, &tz);
if (error)
luaL_error(ls, make_stringf("Failed to get time: %s",
strerror(error)).c_str());
lua_pushnumber(ls, tv.tv_sec * 1000 + tv.tv_usec / 1000);
return (1);
}
#endif
}
static mons_list _lua_get_mlist(lua_State *ls, int ndx)
{
if (lua_isstring(ls, ndx))
{
const char *spec = lua_tostring(ls, ndx);
mons_list mlist;
const std::string err = mlist.add_mons(spec);
if (!err.empty())
luaL_error(ls, err.c_str());
return (mlist);
}
else
{
mons_list **mlist(
clua_get_userdata<mons_list*>(ls, MONSLIST_METATABLE, ndx));
if (mlist)
return (**mlist);
luaL_argerror(ls, ndx, "Expected monster list object or string");
return mons_list();
}
return (ilist);
}
else
{
item_list **ilist(
clua_get_userdata<item_list*>(ls, ITEMLIST_METATABLE, ndx));
if (ilist)
return (**ilist);
luaL_argerror(ls, ndx, "Expected item list object or string");
return item_list();
}
}
static void _register_mapdef_tables(lua_State *ls)
{
clua_register_metatable(ls, MONSLIST_METATABLE, NULL,
lua_object_gc<mons_list>);
clua_register_metatable(ls, ITEMLIST_METATABLE, NULL,
lua_object_gc<item_list>);
}
while hd_pool > 0 do
local place = dgn.find_adjacent_point(p, mons_place_p, dgn_passable)
local mons = mfn(place.x, place.y, nth, hd_pool)
local function mons_do_place(p)
if hd_pool > 0 then
local mons = mfn(p.x, p.y, nth, hd_pool)
if mons then
nth = nth + 1
hd_pool = hd_pool - mons.hd
else
-- Can't find any suitable monster for the HD we have left.
break
if mons then
nth = nth + 1
hd_pool = hd_pool - mons.hd
if nth >= dgn.MAX_MONSTERS then
hd_pool = 0
end
else
-- Can't find any suitable monster for the HD we have left.
hd_pool = 0
end
end
end
local function mons_place(point)
if hd_pool <= 0 then
return true
elseif not dgn.mons_at(point.x, point.y) then
mons_do_place(point)
local function free_space_do(fn)
for i = 0, 20 do
local p =
dgn.find_adjacent_point(c, free_space_threshold(i), dgn_passable)
if p then
fn(p)
break
local function find_free_space(nspaces)
local spaces = { }
local function add_spaces(p)
if nspaces <= 0 then
return true
else
table.insert(spaces, p)
nspaces = nspaces - 1
end
local good_loot = dgn.item_spec("*")
local super_loot = dgn.item_spec("|")
local loot_spots = find_free_space(nloot * 4)
if #loot_spots == 0 then
return
end
local curspot = 0
local function next_loot_spot()
curspot = curspot + 1
if curspot > #loot_spots then
curspot = 1
end
return loot_spots[curspot]
end
----------------------------------------------------------
util.Timer = { }
util.Timer.__index = util.Timer
function util.Timer:new(pars)
self.__index = self
local timer = pars or { }
setmetatable(timer, self)
timer:init()
return timer
end
function util.Timer:init()
self.epoch = crawl.millis()
end
function util.Timer:mark(what)
local last = self.last or self.epoch
local now = crawl.millis()
crawl.mpr(what .. ": " .. (now - last) .. " ms")
self.last = now
inline static T *clua_get_userdata(lua_State *ls, const char *mt)
inline static T *clua_get_userdata(lua_State *ls, const char *mt, int ndx = 1)
{
return static_cast<T*>( luaL_checkudata( ls, ndx, mt ) );
}
template <class T>
static int lua_object_gc(lua_State *ls)
}
static int crawl_regex_gc(lua_State *ls)
{
text_pattern **pattern =
static_cast<text_pattern **>( lua_touserdata(ls, 1) );
if (pattern)
delete *pattern;
return (0);
static int crawl_messf_gc(lua_State *ls)
{
message_filter **pattern =
static_cast<message_filter**>( lua_touserdata(ls, 1) );
if (pattern)
delete *pattern;
return (0);
}
_clua_register_metatable(ls, REGEX_METATABLE, crawl_regex_ops,
crawl_regex_gc);
_clua_register_metatable(ls, MESSF_METATABLE, crawl_messf_ops,
crawl_messf_gc);
clua_register_metatable(ls, REGEX_METATABLE, crawl_regex_ops,
lua_object_gc<text_pattern>);
clua_register_metatable(ls, MESSF_METATABLE, crawl_messf_ops,
lua_object_gc<message_filter>);