From 62d3a1d12c0391b6f13e9786892571cb312f2c0a Mon Sep 17 00:00:00 2001 From: Robert Vollmert Date: Tue, 20 Oct 2009 21:26:08 +0200 Subject: Move monster libraries from clua.cc to l_mons.cc. --- crawl-ref/source/clua.cc | 238 +--------------------------------------- crawl-ref/source/l_libs.h | 1 + crawl-ref/source/l_mons.cc | 245 ++++++++++++++++++++++++++++++++++++++++++ crawl-ref/source/makefile.obj | 1 + 4 files changed, 249 insertions(+), 236 deletions(-) create mode 100644 crawl-ref/source/l_mons.cc diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc index da9cc20ecf..1c2ebcfeb7 100644 --- a/crawl-ref/source/clua.cc +++ b/crawl-ref/source/clua.cc @@ -595,7 +595,6 @@ void luaopen_item(lua_State *ls); void luaopen_food(lua_State *ls); void luaopen_file(lua_State *ls); void luaopen_options(lua_State *ls); -void luaopen_monsters(lua_State *ls); void luaopen_globals(lua_State *ls); void CLua::init_lua() @@ -624,7 +623,7 @@ void CLua::init_lua() cluaopen_crawl(_state); luaopen_file(_state); luaopen_options(_state); - luaopen_monsters(_state); + cluaopen_monsters(_state); luaopen_globals(_state); @@ -1707,193 +1706,7 @@ void luaopen_options(lua_State *ls) lua_setglobal(ls, "options"); } -///////////////////////////////////////////////////////////////////// -// Monster handling - -#define MONS_METATABLE "monster.monsaccess" -struct MonsterWrap -{ - monsters *mons; - long turn; -}; - -#define MDEF(name) \ - static int l_mons_##name(lua_State *ls, monsters *mons, \ - const char *attr) \ - -#define MDEFN(name, closure) \ - static int l_mons_##name(lua_State *ls, monsters *mons, const char *attrs) \ - { \ - lua_pushlightuserdata(ls, mons); \ - lua_pushcclosure(ls, l_mons_do_dismiss, 1); \ - return (1); \ - } - -MDEF(name) -{ - PLUARET(string, mons_type_name(mons->type, DESC_PLAIN).c_str()); -} - -MDEF(x) -{ - PLUARET(number, int(mons->pos().x) - int(you.pos().x)); -} - -MDEF(y) -{ - PLUARET(number, int(mons->pos().y) - int(you.pos().y)); -} - -MDEF(hd) -{ - PLUARET(number, mons->hit_dice); -} - -static const char *_monuse_names[] = -{ - "nothing", "open_doors", "starting_equipment", "weapons_armour", - "magic_items" -}; - -static const char *_monuse_to_str(mon_itemuse_type utyp) -{ - COMPILE_CHECK(ARRAYSZ(_monuse_names) == NUM_MONUSE, c1); - return _monuse_names[utyp]; -} - -MDEF(muse) -{ - if (const monsterentry *me = mons->find_monsterentry()) - { - PLUARET(string, _monuse_to_str(me->gmon_use)); - } - return (0); -} - -static const char *_moneat_names[] = -{ - "nothing", "items", "corpses", "food" -}; - -static const char *_moneat_to_str(mon_itemeat_type etyp) -{ - COMPILE_CHECK(ARRAYSZ(_moneat_names) == NUM_MONEAT, c1); - return _moneat_names[etyp]; -} - -MDEF(meat) -{ - if (const monsterentry *me = mons->find_monsterentry()) - { - PLUARET(string, _moneat_to_str(me->gmon_eat)); - } - return (0); -} - -static int l_mons_do_dismiss(lua_State *ls) -{ - // dismiss is only callable from dlua, not from managed VMs (i.e. - // end-user scripts cannot dismiss monsters). - ASSERT_DLUA; - monsters *mons = - util_get_userdata(ls, lua_upvalueindex(1)); - if (mons->alive()) - { - mons->flags |= MF_HARD_RESET; - monster_die(mons, KILL_DISMISSED, NON_MONSTER); - } - return (0); -} - -MDEFN(dismiss, do_dismiss) - -MDEF(experience) -{ - ASSERT_DLUA; - PLUARET(number, exper_value(mons)); -} - -struct MonsAccessor -{ - const char *attribute; - int (*accessor)(lua_State *ls, monsters *mons, const char *attr); -}; - -static MonsAccessor mons_attrs[] = -{ - { "name", l_mons_name }, - { "x" , l_mons_x }, - { "y" , l_mons_y }, - { "hd" , l_mons_hd }, - { "muse", l_mons_muse }, - { "meat", l_mons_meat }, - { "dismiss", l_mons_dismiss }, - { "experience", l_mons_experience }, -}; - -static int monster_get(lua_State *ls) -{ - MonsterWrap *mw = clua_get_userdata< MonsterWrap >(ls, MONS_METATABLE); - if (!mw || mw->turn != you.num_turns || !mw->mons) - return (0); - - const char *attr = luaL_checkstring(ls, 2); - if (!attr) - return (0); - - for (unsigned i = 0; i < sizeof(mons_attrs) / sizeof(mons_attrs[0]); ++i) - { - if (!strcmp(attr, mons_attrs[i].attribute)) - return (mons_attrs[i].accessor(ls, mw->mons, attr)); - } - - return (0); -} - -static const char *_monster_behaviour_names[] = { - "sleep", - "wander", - "seek", - "flee", - "cornered", - "panic", - "lurk" -}; - -static beh_type behaviour_by_name(const std::string &name) { - ASSERT(ARRAYSZ(_monster_behaviour_names) == NUM_BEHAVIOURS); - for (unsigned i = 0; i < ARRAYSZ(_monster_behaviour_names); ++i) - if (name == _monster_behaviour_names[i]) - return static_cast(i); - return NUM_BEHAVIOURS; -} - -static int monster_set(lua_State *ls) -{ - // Changing monster behaviour is for the dungeon builder only, - // never for user scripts. - ASSERT_DLUA; - - MonsterWrap *mw = clua_get_userdata< MonsterWrap >(ls, MONS_METATABLE); - if (!mw || !mw->mons) - return (0); - - const char *attr = luaL_checkstring(ls, 2); - if (!attr) - return (0); - - if (!strcmp(attr, "beh")) { - const beh_type beh = - lua_isnumber(ls, 3) ? - static_cast(luaL_checkint(ls, 3)) : - lua_isstring(ls, 3) ? behaviour_by_name(lua_tostring(ls, 3)) : - NUM_BEHAVIOURS; - if (beh != NUM_BEHAVIOURS) - mw->mons->behaviour = beh; - } - - return (0); -} +// Pushing various objects. static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t) { @@ -1929,13 +1742,6 @@ static int push_activity_interrupt(lua_State *ls, activity_interrupt_data *t) return 0; } -void push_monster(lua_State *ls, monsters *mons) -{ - MonsterWrap *mw = clua_new_userdata< MonsterWrap >(ls, MONS_METATABLE); - mw->turn = you.num_turns; - mw->mons = mons; -} - void clua_push_map(lua_State *ls, map_def *map) { map_def **mapref = clua_new_userdata(ls, MAP_METATABLE); @@ -1955,46 +1761,6 @@ void clua_push_dgn_event(lua_State *ls, const dgn_event *devent) *de = devent; } -static int mons_behaviour(lua_State *ls) { - if (lua_gettop(ls) < 1) - return (0); - - if (lua_isnumber(ls, 1)) { - lua_pushvalue(ls, 1); - return (1); - } - else if (lua_isstring(ls, 1)) { - const beh_type beh = behaviour_by_name(lua_tostring(ls, 1)); - if (beh != NUM_BEHAVIOURS) { - lua_pushnumber(ls, beh); - return (1); - } - } - return (0); -} - -static const struct luaL_reg mons_lib[] = -{ - { "behaviour", mons_behaviour }, - { NULL, NULL } -}; - -void luaopen_monsters(lua_State *ls) -{ - luaL_newmetatable(ls, MONS_METATABLE); - lua_pushstring(ls, "__index"); - lua_pushcfunction(ls, monster_get); - lua_settable(ls, -3); - - lua_pushstring(ls, "__newindex"); - lua_pushcfunction(ls, monster_set); - lua_settable(ls, -3); - - // Pop the metatable off the stack. - lua_pop(ls, 1); - - luaL_openlib(ls, "mons", mons_lib, 0); -} ////////////////////////////////////////////////////////////////////// // Miscellaneous globals diff --git a/crawl-ref/source/l_libs.h b/crawl-ref/source/l_libs.h index 9fe6d97eb3..4b8476c235 100644 --- a/crawl-ref/source/l_libs.h +++ b/crawl-ref/source/l_libs.h @@ -13,6 +13,7 @@ */ void cluaopen_crawl(lua_State *ls); +void cluaopen_monsters(lua_State *ls); void cluaopen_you(lua_State *ls); /* diff --git a/crawl-ref/source/l_mons.cc b/crawl-ref/source/l_mons.cc new file mode 100644 index 0000000000..459c037c60 --- /dev/null +++ b/crawl-ref/source/l_mons.cc @@ -0,0 +1,245 @@ +#include "AppHdr.h" + +#include "clua.h" +#include "l_libs.h" + +#include "delay.h" +#include "mon-util.h" +#include "monstuff.h" + +///////////////////////////////////////////////////////////////////// +// Monster handling + +#define MONS_METATABLE "monster.monsaccess" + +struct MonsterWrap +{ + monsters *mons; + long turn; +}; + +void push_monster(lua_State *ls, monsters *mons) +{ + MonsterWrap *mw = clua_new_userdata< MonsterWrap >(ls, MONS_METATABLE); + mw->turn = you.num_turns; + mw->mons = mons; +} + +#define MDEF(name) \ + static int l_mons_##name(lua_State *ls, monsters *mons, \ + const char *attr) \ + +#define MDEFN(name, closure) \ + static int l_mons_##name(lua_State *ls, monsters *mons, const char *attrs) \ + { \ + lua_pushlightuserdata(ls, mons); \ + lua_pushcclosure(ls, l_mons_do_dismiss, 1); \ + return (1); \ + } + +MDEF(name) +{ + PLUARET(string, mons_type_name(mons->type, DESC_PLAIN).c_str()); +} + +MDEF(x) +{ + PLUARET(number, int(mons->pos().x) - int(you.pos().x)); +} + +MDEF(y) +{ + PLUARET(number, int(mons->pos().y) - int(you.pos().y)); +} + +MDEF(hd) +{ + PLUARET(number, mons->hit_dice); +} + +static const char *_monuse_names[] = +{ + "nothing", "open_doors", "starting_equipment", "weapons_armour", + "magic_items" +}; + +static const char *_monuse_to_str(mon_itemuse_type utyp) +{ + COMPILE_CHECK(ARRAYSZ(_monuse_names) == NUM_MONUSE, c1); + return _monuse_names[utyp]; +} + +MDEF(muse) +{ + if (const monsterentry *me = mons->find_monsterentry()) + { + PLUARET(string, _monuse_to_str(me->gmon_use)); + } + return (0); +} + +static const char *_moneat_names[] = +{ + "nothing", "items", "corpses", "food" +}; + +static const char *_moneat_to_str(mon_itemeat_type etyp) +{ + COMPILE_CHECK(ARRAYSZ(_moneat_names) == NUM_MONEAT, c1); + return _moneat_names[etyp]; +} + +MDEF(meat) +{ + if (const monsterentry *me = mons->find_monsterentry()) + { + PLUARET(string, _moneat_to_str(me->gmon_eat)); + } + return (0); +} + +static int l_mons_do_dismiss(lua_State *ls) +{ + // dismiss is only callable from dlua, not from managed VMs (i.e. + // end-user scripts cannot dismiss monsters). + ASSERT_DLUA; + monsters *mons = + util_get_userdata(ls, lua_upvalueindex(1)); + if (mons->alive()) + { + mons->flags |= MF_HARD_RESET; + monster_die(mons, KILL_DISMISSED, NON_MONSTER); + } + return (0); +} + +MDEFN(dismiss, do_dismiss) + +MDEF(experience) +{ + ASSERT_DLUA; + PLUARET(number, exper_value(mons)); +} + +struct MonsAccessor +{ + const char *attribute; + int (*accessor)(lua_State *ls, monsters *mons, const char *attr); +}; + +static MonsAccessor mons_attrs[] = +{ + { "name", l_mons_name }, + { "x" , l_mons_x }, + { "y" , l_mons_y }, + { "hd" , l_mons_hd }, + { "muse", l_mons_muse }, + { "meat", l_mons_meat }, + { "dismiss", l_mons_dismiss }, + { "experience", l_mons_experience }, +}; + +static int monster_get(lua_State *ls) +{ + MonsterWrap *mw = clua_get_userdata< MonsterWrap >(ls, MONS_METATABLE); + if (!mw || mw->turn != you.num_turns || !mw->mons) + return (0); + + const char *attr = luaL_checkstring(ls, 2); + if (!attr) + return (0); + + for (unsigned i = 0; i < sizeof(mons_attrs) / sizeof(mons_attrs[0]); ++i) + { + if (!strcmp(attr, mons_attrs[i].attribute)) + return (mons_attrs[i].accessor(ls, mw->mons, attr)); + } + + return (0); +} + +static const char *_monster_behaviour_names[] = { + "sleep", + "wander", + "seek", + "flee", + "cornered", + "panic", + "lurk" +}; + +static beh_type behaviour_by_name(const std::string &name) { + ASSERT(ARRAYSZ(_monster_behaviour_names) == NUM_BEHAVIOURS); + for (unsigned i = 0; i < ARRAYSZ(_monster_behaviour_names); ++i) + if (name == _monster_behaviour_names[i]) + return static_cast(i); + return NUM_BEHAVIOURS; +} + +static int monster_set(lua_State *ls) +{ + // Changing monster behaviour is for the dungeon builder only, + // never for user scripts. + ASSERT_DLUA; + + MonsterWrap *mw = clua_get_userdata< MonsterWrap >(ls, MONS_METATABLE); + if (!mw || !mw->mons) + return (0); + + const char *attr = luaL_checkstring(ls, 2); + if (!attr) + return (0); + + if (!strcmp(attr, "beh")) { + const beh_type beh = + lua_isnumber(ls, 3) ? + static_cast(luaL_checkint(ls, 3)) : + lua_isstring(ls, 3) ? behaviour_by_name(lua_tostring(ls, 3)) : + NUM_BEHAVIOURS; + if (beh != NUM_BEHAVIOURS) + mw->mons->behaviour = beh; + } + + return (0); +} + +static int mons_behaviour(lua_State *ls) { + if (lua_gettop(ls) < 1) + return (0); + + if (lua_isnumber(ls, 1)) { + lua_pushvalue(ls, 1); + return (1); + } + else if (lua_isstring(ls, 1)) { + const beh_type beh = behaviour_by_name(lua_tostring(ls, 1)); + if (beh != NUM_BEHAVIOURS) { + lua_pushnumber(ls, beh); + return (1); + } + } + return (0); +} + +static const struct luaL_reg mons_lib[] = +{ + { "behaviour", mons_behaviour }, + { NULL, NULL } +}; + +void cluaopen_monsters(lua_State *ls) +{ + luaL_newmetatable(ls, MONS_METATABLE); + lua_pushstring(ls, "__index"); + lua_pushcfunction(ls, monster_get); + lua_settable(ls, -3); + + lua_pushstring(ls, "__newindex"); + lua_pushcfunction(ls, monster_set); + lua_settable(ls, -3); + + // Pop the metatable off the stack. + lua_pop(ls, 1); + + luaL_openlib(ls, "mons", mons_lib, 0); +} diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj index 4bf1217c60..8b0c7412ab 100644 --- a/crawl-ref/source/makefile.obj +++ b/crawl-ref/source/makefile.obj @@ -53,6 +53,7 @@ l_file.o \ l_los.o \ l_mapgrd.o \ l_mapmrk.o \ +l_mons.o \ l_you.o \ los.o \ losparam.o \ -- cgit v1.2.3-54-g00ecf