Specifically, item and monster-related functions to l_dgnit.cc and l_dgnmon.cc.
RXYHE3C7R3EGCRZEJT2ZO4ALLRDR3HF66VHZZNF7TT3DFWZ6BJCQC 34O32STE6HBHCGJASFVZ77CZ7ZH4WPWH53U7YBHJ3DHJZEZKOUOQC 63CAVB2MMXOQHGV2N7B5AE2HJKBPPSBKJDLX3EGKEZN52KUIWPQQC A2JHMM2QW2Q5OZ4DY4N3VIT53SOPTI434NJB72XBMJD67YJRI4CQC LE5U6CTXEIETQN5GOVYF2K2VCISRXR3ULORXDKIKWYDVBG5GS3WAC RJIGO3YE7LKSLASPVA7K6CNWJAPKXD7ENJDURI5GXBGIEXFBBINAC MQ62OAMLGJVRW2QIL4PAZRAU6PC52ZVGY2FCOBIY6IWGQIHMU5CAC O6QYS2KYXUXMODO3X4SYX7SPZE7AOIFT2XJZHRABMMQFEUN4UXLAC 3A5FX3Y4RPKWQEHKKXZKXZJ7RKV6RKWT7GTR4WFE5UBWKV2HT4RQC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC ED62QWGKBPORWVKDFOQRKJXEIWZVNGR3O4KWQBDSRNPT36AYOQYAC AUXHSGS4EFOPZ6TVZYWNVOUDO7NYKUKE3HBKGQQWTALSVFOE3HAAC ZLQAAP55CJ77XIJN3DZVPT4GTTVLIBFJLIJJKI6L5UBSHX7VUK6AC NKONHW4JNY6HP2M63MNPM3H64ZWSUNUT5FX2STW4KTS4AMXJXXVQC 55PFDYPVE6JVGDYPCFUE4XS2523PVSV4CSIFRW6A2GGX4I6VWRWQC QAXFREFPBXN7YIBORITM2TAGA4QYF43XMSCLWW2BHONZFGEGMRUQC SM6YRPYZS6LMDQA6X3VAOK2PGMUFKPD7JMWJISOQSMX2CBR4ISPAC JTTHP2BEYEPBQMSDM7IKANTMKRPY6ACGL2JN4D3OBZ7HFXKAYEGQC RGHXFBNIULRVRYLBGG5JZDMYVM2E2JJ2Y5KQPMU6PUS3V26G6ZXQC ASLW3Z5PAVZSWJEMMMVZT226P44EKSAD47QS72JIFJESAI3RPN3AC EIZC76IFTDKBNDJOX6YPFBOAOVAY6RSXH3JUWFLLGCZ3PYJMW3GQC B3SRWSFITQMJRVEBHGQQJARETYPSSDV6XKMQSSUTXEHTXRZKIQJQC C22455VGUQOSUX2OORA32LROFQ7NNYDMD2ZDTTUZSAQLXK4AD6QAC GURIAIJVY6LEADNBTZF3SFBLODYJHWD6OGWFMUGEDI4L5KYO7UFAC WEPYKUZS5NJG5NHBVK5IKE55VD3EOK42JUSURMBTU4MG4SBM5ILQC 7Y5HSDFKA5TPLS2TWTRFMQVX6UXUDHXU5MUMXQSDFAIY4THQ3BIQC IVVTHLTTLOP5TSULXJWUSSXHOKYWVU3OWKYVK45A7RIB6V34MYQAC TLA5UN6LZPXGKERI27EFY4HKIIU3VU5Y7ZU54WXL6ANBUV2VOTMQC OMAUFQNBWGX4FDABHQCVPGDYRVKMDASGQJVRH7AOPPEMHAP2LQSQC X7MFMKQTNZ2IWBFVGS6WQV7NRNKJ3DWQAW2X7IQMFQQXW24AHPZQC UXAYLVZCSKTOC23AZORWJBQWYXKWC6QD2FPV2DRG7G6J5S7U2QLAC Q2NUCKXB4P7DHRXY764F5AMEJO436GV74AVVVOAVGNWKLMSVMDNQC #endif
/** File: l_dgnmon.cc* Summary: Monster-related functions in lua library "dgn".*/#include "AppHdr.h"#include "dlua.h"#include "l_libs.h"#include "dungeon.h"#include "mapdef.h"#include "mon-util.h"#include "monplace.h"#include "monstuff.h"#define MONSLIST_METATABLE "crawldgn.monster_list"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();}}void register_monslist(lua_State *ls){clua_register_metatable(ls, MONSLIST_METATABLE, NULL,lua_object_gc<mons_list>);}static int dgn_set_random_mon_list(lua_State *ls){// Don't complain if we're being called when the map is being loaded// and validated.if (you.level_type != LEVEL_PORTAL_VAULT &&!(you.start_time == 0 && !you.entering_level && !Generating_Level)){luaL_error(ls, "Can only be used in portal vaults.");return (0);}const int nargs = lua_gettop(ls);map_def *map = NULL;if (nargs > 2){luaL_error(ls, "Too many arguments.");return (0);}else if (nargs == 0){luaL_error(ls, "Too few arguments.");return (0);}else if (nargs == 2){map_def **_map =clua_get_userdata<map_def*>(ls, MAP_METATABLE, 1);map = *_map;}if (map){if (map->orient != MAP_ENCOMPASS || map->place.is_valid()|| !map->depths.empty()){luaL_error(ls, "Can only be used in portal vaults.");return (0);}}int list_pos = (map != NULL) ? 2 : 1;mons_list mlist = _lua_get_mlist(ls, list_pos);if (mlist.size() == 0){luaL_argerror(ls, list_pos, "Mon list is empty.");return (0);}if (mlist.size() > 1){luaL_argerror(ls, list_pos, "Mon list must contain only one slot.");return (0);}const int num_mons = mlist.slot_size(0);if (num_mons == 0){luaL_argerror(ls, list_pos, "Mon list is empty.");return (0);}std::vector<mons_spec> mons;int num_lords = 0;for (int i = 0; i < num_mons; i++){mons_spec mon = mlist.get_monster(0, i);// Pandemonium lords are pseudo-unique, so don't randomly generate// them.if (mon.mid == MONS_PANDEMONIUM_DEMON){num_lords++;continue;}std::string name;if (mon.place.is_valid()){if (mon.place.level_type == LEVEL_LABYRINTH|| mon.place.level_type == LEVEL_PORTAL_VAULT){std::string err;err = make_stringf("mon #%d: Can't use Lab or Portal as a ""monster place.", i + 1);luaL_argerror(ls, list_pos, err.c_str());return(0);}name = mon.place.describe();}else{if (mon.mid == RANDOM_MONSTER || mon.monbase == RANDOM_MONSTER){std::string err;err = make_stringf("mon #%d: can't use random monster in ""list specifying random monsters", i + 1);luaL_argerror(ls, list_pos, err.c_str());return(0);}if (mon.mid == -1)mon.mid = MONS_PROGRAM_BUG;name = mons_type_name(mon.mid, DESC_PLAIN);}mons.push_back(mon);if (mon.number != 0)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : number for %s ""being discarded.",name.c_str());if (mon.band)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : band request for ""%s being ignored.",name.c_str());if (mon.colour != BLACK)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : colour for ""%s being ignored.",name.c_str());if (mon.items.size() > 0)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : items for ""%s being ignored.",name.c_str());} // for (int i = 0; i < num_mons; i++)if (mons.size() == 0 && num_lords > 0){luaL_argerror(ls, list_pos,"Mon list contains only pandemonium lords.");return (0);}if (map)map->random_mons = mons;elseset_vault_mon_list(mons);return (0);}static int dgn_mons_from_index(lua_State *ls){const int index = luaL_checkint(ls, 1);monsters *mons = &menv[index];if (mons->type != -1)push_monster(ls, mons);elselua_pushnil(ls);return (1);}static int dgn_mons_at(lua_State *ls){COORDS(c, 1, 2);monsters *mon = monster_at(c);if (mon && mon->alive())push_monster(ls, mon);elselua_pushnil(ls);return (1);}static int dgn_create_monster(lua_State *ls){COORDS(c, 1, 2);mons_list mlist = _lua_get_mlist(ls, 3);for (int i = 0, size = mlist.size(); i < size; ++i){mons_spec mspec = mlist.get_monster(i);const int mid = dgn_place_monster(mspec, you.your_level, c,false, false, false);if (mid != -1){push_monster(ls, &menv[mid]);return (1);}}lua_pushnil(ls);return (1);}static int _dgn_monster_spec(lua_State *ls){const mons_list mlist = _lua_get_mlist(ls, 1);dlua_push_object_type<mons_list>(ls, MONSLIST_METATABLE, mlist);return (1);}LUARET1(_dgn_max_monsters, number, MAX_MONSTERS)LUAFN(dgn_dismiss_monsters){PLUARET(number,dismiss_monsters(lua_gettop(ls) == 0 ? "" :luaL_checkstring(ls, 1)));}const struct luaL_reg dgn_mons_lib[] ={{ "set_random_mon_list", dgn_set_random_mon_list },{ "mons_from_index", dgn_mons_from_index },{ "mons_at", dgn_mons_at },{ "create_monster", dgn_create_monster },{ "monster_spec", _dgn_monster_spec },{ "max_monsters", _dgn_max_monsters },{ "dismiss_monsters", dgn_dismiss_monsters },{ NULL, NULL }};
/** File: l_dgnit.cc* Summary: Item-related functions in lua library "dgn".*/#include "AppHdr.h"#include "dlua.h"#include "l_libs.h"#include "dungeon.h"#include "items.h"#include "mapdef.h"#define ITEMLIST_METATABLE "crawldgn.item_list"static item_list _lua_get_ilist(lua_State *ls, int ndx){if (lua_isstring(ls, ndx)){const char *spec = lua_tostring(ls, ndx);item_list ilist;const std::string err = ilist.add_item(spec);if (!err.empty())luaL_error(ls, err.c_str());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();}}void register_itemlist(lua_State *ls){clua_register_metatable(ls, ITEMLIST_METATABLE, NULL,lua_object_gc<item_list>);}static int dgn_item_from_index(lua_State *ls){const int index = luaL_checkint(ls, 1);item_def *item = &mitm[index];if (is_valid_item(*item))lua_pushlightuserdata(ls, item);elselua_pushnil(ls);return (1);}static int dgn_items_at(lua_State *ls){COORDS(c, 1, 2);lua_push_items(ls, env.igrid(c));return (1);}static int _dgn_item_spec(lua_State *ls){const item_list ilist = _lua_get_ilist(ls, 1);dlua_push_object_type<item_list>(ls, ITEMLIST_METATABLE, ilist);return (1);}static int dgn_create_item(lua_State *ls){COORDS(c, 1, 2);item_list ilist = _lua_get_ilist(ls, 3);const int level =lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level;dgn_place_multiple_items(ilist, c, level);link_items();return (0);}const struct luaL_reg dgn_item_lib[] ={{ "item_from_index", dgn_item_from_index },{ "items_at", dgn_items_at },{ "create_item", dgn_create_item },{ "item_spec", _dgn_item_spec },{ NULL, NULL }};
#define MONSLIST_METATABLE "crawldgn.monster_list"#define ITEMLIST_METATABLE "crawldgn.item_list"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();}}static item_list _lua_get_ilist(lua_State *ls, int ndx){if (lua_isstring(ls, ndx)){const char *spec = lua_tostring(ls, ndx);item_list ilist;const std::string err = ilist.add_item(spec);if (!err.empty())luaL_error(ls, err.c_str());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();}}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>);}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);}
}static int dgn_set_random_mon_list(lua_State *ls){// Don't complain if we're being called when the map is being loaded// and validated.if (you.level_type != LEVEL_PORTAL_VAULT &&!(you.start_time == 0 && !you.entering_level && !Generating_Level)){luaL_error(ls, "Can only be used in portal vaults.");return (0);}const int nargs = lua_gettop(ls);map_def *map = NULL;if (nargs > 2){luaL_error(ls, "Too many arguments.");return (0);}else if (nargs == 0){luaL_error(ls, "Too few arguments.");return (0);}else if (nargs == 2){map_def **_map =clua_get_userdata<map_def*>(ls, MAP_METATABLE, 1);map = *_map;}if (map){if (map->orient != MAP_ENCOMPASS || map->place.is_valid()|| !map->depths.empty()){luaL_error(ls, "Can only be used in portal vaults.");return (0);}}int list_pos = (map != NULL) ? 2 : 1;mons_list mlist = _lua_get_mlist(ls, list_pos);if (mlist.size() == 0){luaL_argerror(ls, list_pos, "Mon list is empty.");return (0);}if (mlist.size() > 1){luaL_argerror(ls, list_pos, "Mon list must contain only one slot.");return (0);}const int num_mons = mlist.slot_size(0);if (num_mons == 0){luaL_argerror(ls, list_pos, "Mon list is empty.");return (0);}std::vector<mons_spec> mons;int num_lords = 0;for (int i = 0; i < num_mons; i++){mons_spec mon = mlist.get_monster(0, i);// Pandemonium lords are pseudo-unique, so don't randomly generate// them.if (mon.mid == MONS_PANDEMONIUM_DEMON){num_lords++;continue;}std::string name;if (mon.place.is_valid()){if (mon.place.level_type == LEVEL_LABYRINTH|| mon.place.level_type == LEVEL_PORTAL_VAULT){std::string err;err = make_stringf("mon #%d: Can't use Lab or Portal as a ""monster place.", i + 1);luaL_argerror(ls, list_pos, err.c_str());return(0);}name = mon.place.describe();}else{if (mon.mid == RANDOM_MONSTER || mon.monbase == RANDOM_MONSTER){std::string err;err = make_stringf("mon #%d: can't use random monster in ""list specifying random monsters", i + 1);luaL_argerror(ls, list_pos, err.c_str());return(0);}if (mon.mid == -1)mon.mid = MONS_PROGRAM_BUG;name = mons_type_name(mon.mid, DESC_PLAIN);}mons.push_back(mon);if (mon.number != 0)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : number for %s ""being discarded.",name.c_str());if (mon.band)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : band request for ""%s being ignored.",name.c_str());if (mon.colour != BLACK)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : colour for ""%s being ignored.",name.c_str());if (mon.items.size() > 0)mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : items for ""%s being ignored.",name.c_str());} // for (int i = 0; i < num_mons; i++)if (mons.size() == 0 && num_lords > 0){luaL_argerror(ls, list_pos,"Mon list contains only pandemonium lords.");return (0);}if (map)map->random_mons = mons;elseset_vault_mon_list(mons);return (0);
}static int dgn_item_from_index(lua_State *ls){const int index = luaL_checkint(ls, 1);item_def *item = &mitm[index];if (is_valid_item(*item))lua_pushlightuserdata(ls, item);elselua_pushnil(ls);return (1);}static int dgn_mons_from_index(lua_State *ls){const int index = luaL_checkint(ls, 1);monsters *mons = &menv[index];if (mons->type != -1)push_monster(ls, mons);elselua_pushnil(ls);return (1);}static int dgn_mons_at(lua_State *ls){COORDS(c, 1, 2);monsters *mon = monster_at(c);if (mon && mon->alive())push_monster(ls, mon);elselua_pushnil(ls);return (1);
}static int dgn_create_monster(lua_State *ls){COORDS(c, 1, 2);mons_list mlist = _lua_get_mlist(ls, 3);for (int i = 0, size = mlist.size(); i < size; ++i){mons_spec mspec = mlist.get_monster(i);const int mid = dgn_place_monster(mspec, you.your_level, c,false, false, false);if (mid != -1){push_monster(ls, &menv[mid]);return (1);}}lua_pushnil(ls);return (1);}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)static int dgn_create_item(lua_State *ls){COORDS(c, 1, 2);item_list ilist = _lua_get_ilist(ls, 3);const int level =lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level;dgn_place_multiple_items(ilist, c, level);link_items();return (0);}
{ "monster_spec", _dgn_monster_spec },{ "item_spec", _dgn_item_spec },{ "max_monsters", _dgn_max_monsters },