summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/l_dgnmon.cc
diff options
context:
space:
mode:
authorRobert Vollmert <rvollmert@gmx.net>2009-10-20 00:40:33 +0200
committerRobert Vollmert <rvollmert@gmx.net>2009-10-20 00:44:30 +0200
commit378834da4d947a1a06c90ff3c20705b976714109 (patch)
tree30b18b1323dad6ded5ba020581a738ae411ebbaa /crawl-ref/source/l_dgnmon.cc
parenta4f9da4c2defdeedba6e172d8c8538f4b1aefe78 (diff)
downloadcrawl-ref-378834da4d947a1a06c90ff3c20705b976714109.tar.gz
crawl-ref-378834da4d947a1a06c90ff3c20705b976714109.zip
Split some parts of lua library "dgn" out.
Specifically, item and monster-related functions to l_dgnit.cc and l_dgnmon.cc.
Diffstat (limited to 'crawl-ref/source/l_dgnmon.cc')
-rw-r--r--crawl-ref/source/l_dgnmon.cc267
1 files changed, 267 insertions, 0 deletions
diff --git a/crawl-ref/source/l_dgnmon.cc b/crawl-ref/source/l_dgnmon.cc
new file mode 100644
index 0000000000..a464a4fb50
--- /dev/null
+++ b/crawl-ref/source/l_dgnmon.cc
@@ -0,0 +1,267 @@
+/*
+ * 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;
+ else
+ set_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);
+ else
+ lua_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);
+ else
+ lua_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 }
+};