summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc2
-rw-r--r--crawl-ref/source/ctest.cc2
-rw-r--r--crawl-ref/source/describe.h2
-rw-r--r--crawl-ref/source/dgnevent.h2
-rw-r--r--crawl-ref/source/dlua.cc916
-rw-r--r--crawl-ref/source/dlua.h (renamed from crawl-ref/source/luadgn.h)13
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/initfile.cc2
-rw-r--r--crawl-ref/source/l_dgn.cc (renamed from crawl-ref/source/luadgn.cc)2088
-rw-r--r--crawl-ref/source/l_los.cc4
-rw-r--r--crawl-ref/source/l_los.h16
-rw-r--r--crawl-ref/source/makefile.obj3
-rw-r--r--crawl-ref/source/mapdef.h2
-rw-r--r--crawl-ref/source/mapmark.cc2
-rw-r--r--crawl-ref/source/mapmark.h2
-rw-r--r--crawl-ref/source/maps.h1
-rw-r--r--crawl-ref/source/util/levcomp.ypp2
17 files changed, 1533 insertions, 1528 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 6d576bb76d..443da14ec2 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -56,6 +56,7 @@
#include "debug.h"
#include "delay.h"
#include "describe.h"
+#include "dlua.h"
#include "directn.h"
#include "dungeon.h"
#include "effects.h"
@@ -72,7 +73,6 @@
#include "items.h"
#include "lev-pand.h"
#include "los.h"
-#include "luadgn.h"
#include "macro.h"
#include "makeitem.h"
#include "mapmark.h"
diff --git a/crawl-ref/source/ctest.cc b/crawl-ref/source/ctest.cc
index daca476c7d..054cebfc2e 100644
--- a/crawl-ref/source/ctest.cc
+++ b/crawl-ref/source/ctest.cc
@@ -17,8 +17,8 @@
#if DEBUG_DIAGNOSTICS
#include "clua.h"
+#include "dlua.h"
#include "files.h"
-#include "luadgn.h"
#include "maps.h"
#include "state.h"
#include "stuff.h"
diff --git a/crawl-ref/source/describe.h b/crawl-ref/source/describe.h
index 327cf2a483..9e71c2a337 100644
--- a/crawl-ref/source/describe.h
+++ b/crawl-ref/source/describe.h
@@ -63,7 +63,7 @@ void get_feature_desc(const coord_def &gc, describe_info &inf);
// last updated 24 Dec 2008 {mpc}
/* ***********************************************************************
- * called from: luadgn
+ * called from: l_dgn
* *********************************************************************** */
void set_feature_desc_long(const std::string &raw_name,
const std::string &desc);
diff --git a/crawl-ref/source/dgnevent.h b/crawl-ref/source/dgnevent.h
index 0607469b37..c9eea419b1 100644
--- a/crawl-ref/source/dgnevent.h
+++ b/crawl-ref/source/dgnevent.h
@@ -10,7 +10,7 @@
#include "externs.h"
#include <list>
-// Keep event names in luadgn.cc in sync.
+// Keep event names in l_dgn.cc in sync.
enum dgn_event_type
{
DET_NONE = 0x0000,
diff --git a/crawl-ref/source/dlua.cc b/crawl-ref/source/dlua.cc
new file mode 100644
index 0000000000..7d26c87d24
--- /dev/null
+++ b/crawl-ref/source/dlua.cc
@@ -0,0 +1,916 @@
+/*
+ * File: luadgn.cc
+ * Summary: Dungeon-builder Lua interface.
+ * Created by: dshaligram on Sat Jun 23 20:02:09 2007 UTC
+ */
+
+#include "AppHdr.h"
+
+#include <sstream>
+#include <algorithm>
+#include <memory>
+#include <cmath>
+
+#include "branch.h"
+#include "chardump.h"
+#include "clua.h"
+#include "cloud.h"
+#include "describe.h"
+#include "directn.h"
+#include "dlua.h"
+#include "dungeon.h"
+#include "files.h"
+#include "hiscores.h"
+#include "initfile.h"
+#include "items.h"
+#include "l_los.h"
+#include "los.h"
+#include "mapdef.h"
+#include "mapmark.h"
+#include "maps.h"
+#include "message.h"
+#include "misc.h"
+#include "mon-util.h"
+#include "monplace.h"
+#include "monstuff.h"
+#include "place.h"
+#include "spells3.h"
+#include "spl-util.h"
+#include "state.h"
+#include "stuff.h"
+#include "tags.h"
+#include "terrain.h"
+#include "view.h"
+
+#ifdef UNIX
+#include <sys/time.h>
+#include <time.h>
+#endif
+
+template <typename list, typename lpush>
+static int dlua_gentable(lua_State *ls, const list &strings, lpush push)
+{
+ lua_newtable(ls);
+ for (int i = 0, size = strings.size(); i < size; ++i)
+ {
+ push(ls, strings[i]);
+ lua_rawseti(ls, -2, i + 1);
+ }
+ return (1);
+}
+
+inline static void dlua_pushcxxstring(lua_State *ls, const std::string &s)
+{
+ lua_pushstring(ls, s.c_str());
+}
+
+int dlua_stringtable(lua_State *ls, const std::vector<std::string> &s)
+{
+ return dlua_gentable(ls, s, dlua_pushcxxstring);
+}
+
+static int dlua_compiled_chunk_writer(lua_State *ls, const void *p,
+ size_t sz, void *ud)
+{
+ std::ostringstream &out = *static_cast<std::ostringstream*>(ud);
+ out.write((const char *) p, sz);
+ return (0);
+}
+
+///////////////////////////////////////////////////////////////////////////
+// dlua_chunk
+
+dlua_chunk::dlua_chunk(const std::string &_context)
+ : file(), chunk(), compiled(), context(_context), first(-1),
+ last(-1), error()
+{
+ clear();
+}
+
+// Initialises a chunk from the function on the top of stack.
+// This function must not be a closure, i.e. must not have any upvalues.
+dlua_chunk::dlua_chunk(lua_State *ls)
+ : file(), chunk(), compiled(), context(), first(-1), last(-1), error()
+{
+ clear();
+
+ lua_stack_cleaner cln(ls);
+ std::ostringstream out;
+ const int err = lua_dump(ls, dlua_compiled_chunk_writer, &out);
+ if (err)
+ {
+ const char *e = lua_tostring(ls, -1);
+ error = e? e : "Unknown error compiling chunk";
+ }
+ compiled = out.str();
+}
+
+dlua_chunk dlua_chunk::precompiled(const std::string &chunk)
+{
+ dlua_chunk dchunk;
+ dchunk.compiled = chunk;
+ return (dchunk);
+}
+
+void dlua_chunk::write(writer& outf) const
+{
+ if (empty())
+ {
+ marshallByte(outf, CT_EMPTY);
+ return;
+ }
+
+ if (!compiled.empty())
+ {
+ marshallByte(outf, CT_COMPILED);
+ marshallString4(outf, compiled);
+ }
+ else
+ {
+ marshallByte(outf, CT_SOURCE);
+ marshallString4(outf, chunk);
+ }
+
+ marshallString4(outf, file);
+ marshallLong(outf, first);
+}
+
+void dlua_chunk::read(reader& inf)
+{
+ clear();
+ chunk_t type = static_cast<chunk_t>(unmarshallByte(inf));
+ switch (type)
+ {
+ case CT_EMPTY:
+ return;
+ case CT_SOURCE:
+ unmarshallString4(inf, chunk);
+ break;
+ case CT_COMPILED:
+ unmarshallString4(inf, compiled);
+ break;
+ }
+ unmarshallString4(inf, file);
+ first = unmarshallLong(inf);
+}
+
+void dlua_chunk::clear()
+{
+ file.clear();
+ chunk.clear();
+ first = last = -1;
+ error.clear();
+ compiled.clear();
+}
+
+void dlua_chunk::set_file(const std::string &s)
+{
+ file = s;
+}
+
+void dlua_chunk::add(int line, const std::string &s)
+{
+ if (first == -1)
+ first = line;
+
+ if (line != last && last != -1)
+ while (last++ < line)
+ chunk += '\n';
+
+ chunk += " ";
+ chunk += s;
+ last = line;
+}
+
+void dlua_chunk::set_chunk(const std::string &s)
+{
+ chunk = s;
+}
+
+int dlua_chunk::check_op(CLua &interp, int err)
+{
+ error = interp.error;
+ return (err);
+}
+
+int dlua_chunk::load(CLua &interp)
+{
+ if (!compiled.empty())
+ return check_op( interp,
+ interp.loadbuffer(compiled.c_str(), compiled.length(),
+ context.c_str()) );
+
+ if (empty())
+ {
+ chunk.clear();
+ return (-1000);
+ }
+
+ int err = check_op( interp,
+ interp.loadstring(chunk.c_str(), context.c_str()) );
+ if (err)
+ return (err);
+ std::ostringstream out;
+ err = lua_dump(interp, dlua_compiled_chunk_writer, &out);
+ if (err)
+ {
+ const char *e = lua_tostring(interp, -1);
+ error = e? e : "Unknown error compiling chunk";
+ lua_pop(interp, 2);
+ }
+ compiled = out.str();
+ chunk.clear();
+ return (err);
+}
+
+int dlua_chunk::run(CLua &interp)
+{
+ int err = load(interp);
+ if (err)
+ return (err);
+ // callfn returns true on success, but we want to return 0 on success.
+ return (check_op(interp, !interp.callfn(NULL, 0, 0)));
+}
+
+int dlua_chunk::load_call(CLua &interp, const char *fn)
+{
+ int err = load(interp);
+ if (err == -1000)
+ return (0);
+ if (err)
+ return (err);
+
+ return check_op(interp, !interp.callfn(fn, fn? 1 : 0, 0));
+}
+
+std::string dlua_chunk::orig_error() const
+{
+ rewrite_chunk_errors(error);
+ return (error);
+}
+
+bool dlua_chunk::empty() const
+{
+ return compiled.empty() && trimmed_string(chunk).empty();
+}
+
+bool dlua_chunk::rewrite_chunk_errors(std::string &s) const
+{
+ const std::string contextm = "[string \"" + context + "\"]:";
+ std::string::size_type dlwhere = s.find(contextm);
+
+ if (dlwhere == std::string::npos)
+ return (false);
+
+ if (!dlwhere)
+ {
+ s = rewrite_chunk_prefix(s);
+ return (true);
+ }
+
+ // Our chunk is mentioned, go back through and rewrite lines.
+ std::vector<std::string> lines = split_string("\n", s);
+ std::string newmsg = lines[0];
+ bool wrote_prefix = false;
+ for (int i = 2, size = lines.size() - 1; i < size; ++i)
+ {
+ const std::string &st = lines[i];
+ if (st.find(context) != std::string::npos)
+ {
+ if (!wrote_prefix)
+ {
+ newmsg = get_chunk_prefix(st) + ": " + newmsg;
+ wrote_prefix = true;
+ }
+ else
+ newmsg += "\n" + rewrite_chunk_prefix(st);
+ }
+ }
+ s = newmsg;
+ return (true);
+}
+
+std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line,
+ bool skip_body) const
+{
+ std::string s = line;
+ const std::string contextm = "[string \"" + context + "\"]:";
+ const std::string::size_type ps = s.find(contextm);
+ if (ps == std::string::npos)
+ return (s);
+
+ const std::string::size_type lns = ps + contextm.length();
+ std::string::size_type pe = s.find(':', ps + contextm.length());
+ if (pe != std::string::npos)
+ {
+ const std::string line_num = s.substr(lns, pe - lns);
+ const int lnum = atoi(line_num.c_str());
+ const std::string newlnum = make_stringf("%d", lnum + first - 1);
+ s = s.substr(0, lns) + newlnum + s.substr(pe);
+ pe = lns + newlnum.length();
+ }
+
+ return s.substr(0, ps) + (file.empty()? context : file) + ":"
+ + (skip_body? s.substr(lns, pe - lns)
+ : s.substr(lns));
+}
+
+std::string dlua_chunk::get_chunk_prefix(const std::string &sorig) const
+{
+ return rewrite_chunk_prefix(sorig, true);
+}
+
+LUAFN(_crawl_args)
+{
+ return dlua_stringtable(ls, SysEnv.cmd_args);
+}
+
+LUAFN(_crawl_milestone)
+{
+#ifdef DGL_MILESTONES
+ mark_milestone(luaL_checkstring(ls, 1),
+ luaL_checkstring(ls, 2));
+#endif
+ return (0);
+}
+
+LUAFN(_crawl_redraw_view)
+{
+ viewwindow(true, false);
+ return (0);
+}
+
+#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 const struct luaL_reg crawl_lib[] =
+{
+ { "args", _crawl_args },
+ { "mark_milestone", _crawl_milestone },
+ { "redraw_view", _crawl_redraw_view },
+#ifdef UNIX
+ { "millis", _crawl_millis },
+#endif
+ { NULL, NULL }
+};
+
+static int file_marshall(lua_State *ls)
+{
+ if (lua_gettop(ls) != 2)
+ luaL_error(ls, "Need two arguments: tag header and value");
+ writer &th(*static_cast<writer*>( lua_touserdata(ls, 1) ));
+ if (lua_isnumber(ls, 2))
+ marshallLong(th, luaL_checklong(ls, 2));
+ else if (lua_isboolean(ls, 2))
+ marshallByte(th, lua_toboolean(ls, 2));
+ else if (lua_isstring(ls, 2))
+ marshallString(th, lua_tostring(ls, 2));
+ else if (lua_isfunction(ls, 2))
+ {
+ dlua_chunk chunk(ls);
+ marshallString(th, chunk.compiled_chunk());
+ }
+ return (0);
+}
+
+static int file_unmarshall_boolean(lua_State *ls)
+{
+ if (lua_gettop(ls) != 1)
+ luaL_error(ls, "Need reader as one argument");
+ reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
+ lua_pushboolean(ls, unmarshallByte(th));
+ return (1);
+}
+
+static int file_unmarshall_number(lua_State *ls)
+{
+ if (lua_gettop(ls) != 1)
+ luaL_error(ls, "Need reader as one argument");
+ reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
+ lua_pushnumber(ls, unmarshallLong(th));
+ return (1);
+}
+
+static int file_unmarshall_string(lua_State *ls)
+{
+ if (lua_gettop(ls) != 1)
+ luaL_error(ls, "Need reader as one argument");
+ reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
+ lua_pushstring(ls, unmarshallString(th).c_str());
+ return (1);
+}
+
+static int file_unmarshall_fn(lua_State *ls)
+{
+ if (lua_gettop(ls) != 1)
+ luaL_error(ls, "Need reader as one argument");
+ reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
+ const std::string s(unmarshallString(th, LUA_CHUNK_MAX_SIZE));
+ dlua_chunk chunk = dlua_chunk::precompiled(s);
+ if (chunk.load(dlua))
+ lua_pushnil(ls);
+ return (1);
+}
+
+enum lua_persist_type
+{
+ LPT_NONE,
+ LPT_NUMBER,
+ LPT_STRING,
+ LPT_FUNCTION,
+ LPT_NIL,
+ LPT_BOOLEAN
+};
+
+static int file_marshall_meta(lua_State *ls)
+{
+ if (lua_gettop(ls) != 2)
+ luaL_error(ls, "Need two arguments: tag header and value");
+
+ writer &th(*static_cast<writer*>( lua_touserdata(ls, 1) ));
+
+ lua_persist_type ptype = LPT_NONE;
+ if (lua_isnumber(ls, 2))
+ ptype = LPT_NUMBER;
+ else if (lua_isboolean(ls, 2))
+ ptype = LPT_BOOLEAN;
+ else if (lua_isstring(ls, 2))
+ ptype = LPT_STRING;
+ else if (lua_isfunction(ls, 2))
+ ptype = LPT_FUNCTION;
+ else if (lua_isnil(ls, 2))
+ ptype = LPT_NIL;
+ else
+ luaL_error(ls,
+ make_stringf("Cannot marshall %s",
+ lua_typename(ls, lua_type(ls, 2))).c_str());
+ marshallByte(th, ptype);
+ if (ptype != LPT_NIL)
+ file_marshall(ls);
+ return (0);
+}
+
+static int file_unmarshall_meta(lua_State *ls)
+{
+ reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
+ const lua_persist_type ptype =
+ static_cast<lua_persist_type>(unmarshallByte(th));
+ switch (ptype)
+ {
+ case LPT_BOOLEAN:
+ return file_unmarshall_boolean(ls);
+ case LPT_NUMBER:
+ return file_unmarshall_number(ls);
+ case LPT_STRING:
+ return file_unmarshall_string(ls);
+ case LPT_FUNCTION:
+ return file_unmarshall_fn(ls);
+ case LPT_NIL:
+ lua_pushnil(ls);
+ return (1);
+ default:
+ luaL_error(ls, "Unexpected type signature.");
+ }
+ // Never get here.
+ return (0);
+}
+
+static const struct luaL_reg file_lib[] =
+{
+ { "marshall", file_marshall },
+ { "marshall_meta", file_marshall_meta },
+ { "unmarshall_meta", file_unmarshall_meta },
+ { "unmarshall_number", file_unmarshall_number },
+ { "unmarshall_string", file_unmarshall_string },
+ { "unmarshall_fn", file_unmarshall_fn },
+ { NULL, NULL }
+};
+
+LUARET1(you_can_hear_pos, boolean,
+ player_can_hear(coord_def(luaL_checkint(ls,1), luaL_checkint(ls, 2))))
+LUARET1(you_x_pos, number, you.pos().x)
+LUARET1(you_y_pos, number, you.pos().y)
+LUARET2(you_pos, number, you.pos().x, you.pos().y)
+
+// see_cell should not be exposed to user scripts. The game should
+// never disclose grid coordinates to the player. Therefore we load it
+// only into the core Lua interpreter (dlua), never into the user
+// script interpreter (clua).
+LUARET1(you_see_cell, boolean,
+ see_cell(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))
+LUARET1(you_see_cell_no_trans, boolean,
+ see_cell_no_trans(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))
+
+LUAFN(you_moveto)
+{
+ const coord_def place(luaL_checkint(ls, 1), luaL_checkint(ls, 2));
+ ASSERT(map_bounds(place));
+ you.moveto(place);
+ return (0);
+}
+
+LUAFN(you_random_teleport)
+{
+ you_teleport_now(false, false);
+ return (0);
+}
+
+LUAFN(you_losight)
+{
+ calc_show_los();
+ return (0);
+}
+
+static const struct luaL_reg you_lib[] =
+{
+ { "hear_pos", you_can_hear_pos },
+ { "x_pos", you_x_pos },
+ { "y_pos", you_y_pos },
+ { "pos", you_pos },
+ { "moveto", you_moveto },
+ { "see_cell", you_see_cell },
+ { "see_cell_no_trans", you_see_cell_no_trans },
+ { "random_teleport", you_random_teleport },
+ { "losight", you_losight },
+ { NULL, NULL }
+};
+
+static int dgnevent_type(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ PLUARET(number, dev->type);
+}
+
+static int dgnevent_place(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ lua_pushnumber(ls, dev->place.x);
+ lua_pushnumber(ls, dev->place.y);
+ return (2);
+}
+
+static int dgnevent_dest(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ lua_pushnumber(ls, dev->dest.x);
+ lua_pushnumber(ls, dev->dest.y);
+ return (2);
+}
+
+static int dgnevent_ticks(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ PLUARET(number, dev->elapsed_ticks);
+}
+
+static int dgnevent_arg1(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ PLUARET(number, dev->arg1);
+}
+
+static int dgnevent_arg2(lua_State *ls)
+{
+ DEVENT(ls, 1, dev);
+ PLUARET(number, dev->arg2);
+}
+
+static const struct luaL_reg dgnevent_lib[] =
+{
+ { "type", dgnevent_type },
+ { "pos", dgnevent_place },
+ { "dest", dgnevent_dest },
+ { "ticks", dgnevent_ticks },
+ { "arg1", dgnevent_arg1 },
+ { "arg2", dgnevent_arg2 },
+ { NULL, NULL }
+};
+
+void luaopen_setmeta(lua_State *ls,
+ const char *global,
+ const luaL_reg *lua_lib,
+ const char *meta)
+{
+ luaL_newmetatable(ls, meta);
+ lua_setglobal(ls, global);
+
+ luaL_openlib(ls, global, lua_lib, 0);
+
+ // Do <global>.__index = <global>
+ lua_pushstring(ls, "__index");
+ lua_pushvalue(ls, -2);
+ lua_settable(ls, -3);
+}
+
+static void luaopen_dgnevent(lua_State *ls)
+{
+ luaopen_setmeta(ls, "dgnevent", dgnevent_lib, DEVENT_METATABLE);
+}
+
+static int mapmarker_pos(lua_State *ls)
+{
+ MAPMARKER(ls, 1, mark);
+ lua_pushnumber(ls, mark->pos.x);
+ lua_pushnumber(ls, mark->pos.y);
+ return (2);
+}
+
+static int mapmarker_move(lua_State *ls)
+{
+ MAPMARKER(ls, 1, mark);
+ const coord_def dest( luaL_checkint(ls, 2), luaL_checkint(ls, 3) );
+ env.markers.move_marker(mark, dest);
+ return (0);
+}
+
+static const struct luaL_reg mapmarker_lib[] =
+{
+ { "pos", mapmarker_pos },
+ { "move", mapmarker_move },
+ { NULL, NULL }
+};
+
+static void luaopen_mapmarker(lua_State *ls)
+{
+ luaopen_setmeta(ls, "mapmarker", mapmarker_lib, MAPMARK_METATABLE);
+}
+
+
+// Return the integer stored in the table (on the stack) with the key name.
+// If the key doesn't exist or the value is the wrong type, return defval.
+static int _table_int(lua_State *ls, int idx, const char *name, int defval)
+{
+ lua_pushstring(ls, name);
+ lua_gettable(ls, idx < 0 ? idx - 1 : idx);
+ bool nil = lua_isnil(ls, idx);
+ bool valid = lua_isnumber(ls, idx);
+ if (!nil && !valid)
+ luaL_error(ls, "'%s' in table, but not an int.", name);
+ int ret = (!nil && valid ? lua_tonumber(ls, idx) : defval);
+ lua_pop(ls, 1);
+ return (ret);
+}
+
+// Return the character stored in the table (on the stack) with the key name.
+// If the key doesn't exist or the value is the wrong type, return defval.
+static char _table_char(lua_State *ls, int idx, const char *name, char defval)
+{
+ lua_pushstring(ls, name);
+ lua_gettable(ls, idx < 0 ? idx - 1 : idx);
+ bool nil = lua_isnil(ls, idx);
+ bool valid = lua_isstring(ls, idx);
+ if (!nil && !valid)
+ luaL_error(ls, "'%s' in table, but not a string.", name);
+
+ char ret = defval;
+ if (!nil && valid)
+ {
+ const char *str = lua_tostring(ls, idx);
+ if (str[0] && !str[1])
+ ret = str[0];
+ else
+ luaL_error(ls, "'%s' has more than one character.", name);
+ }
+ lua_pop(ls, 1);
+ return (ret);
+}
+
+// Return the string stored in the table (on the stack) with the key name.
+// If the key doesn't exist or the value is the wrong type, return defval.
+static const char* _table_str(lua_State *ls, int idx, const char *name, const char *defval)
+{
+ lua_pushstring(ls, name);
+ lua_gettable(ls, idx < 0 ? idx - 1 : idx);
+ bool nil = lua_isnil(ls, idx);
+ bool valid = lua_isstring(ls, idx);
+ if (!nil && !valid)
+ luaL_error(ls, "'%s' in table, but not a string.", name);
+ const char *ret = (!nil && valid ? lua_tostring(ls, idx) : defval);
+ lua_pop(ls, 1);
+ return (ret);
+}
+
+// Return the boolean stored in the table (on the stack) with the key name.
+// If the key doesn't exist or the value is the wrong type, return defval.
+static bool _table_bool(lua_State *ls, int idx, const char *name, bool defval)
+{
+ lua_pushstring(ls, name);
+ lua_gettable(ls, idx < 0 ? idx - 1 : idx);
+ bool nil = lua_isnil(ls, idx);
+ bool valid = lua_isboolean(ls, idx);
+ if (!nil && !valid)
+ luaL_error(ls, "'%s' in table, but not a bool.", name);
+ bool ret = (!nil && valid ? lua_toboolean(ls, idx) : defval);
+ lua_pop(ls, 1);
+ return (ret);
+}
+
+#define BF_INT(ls, val, def) int val = _table_int(ls, -1, #val, def);
+#define BF_CHAR(ls, val, def) char val = _table_char(ls, -1, #val, def);
+#define BF_STR(ls, val, def) const char *val = _table_str(ls, -1, #val, def);
+#define BF_BOOL(ls, val, def) bool val = _table_bool(ls, -1, #val, def);
+
+static void bf_octa_room(lua_State *ls, map_lines &lines)
+{
+ int default_oblique = std::min(lines.width(), lines.height()) / 2 - 1;
+ BF_INT(ls, oblique, default_oblique);
+ BF_CHAR(ls, outside, 'x');
+ BF_CHAR(ls, inside, '.');
+ BF_STR(ls, replace, ".");
+
+ coord_def tl, br;
+ if (!lines.find_bounds(replace, tl, br))
+ return;
+
+ for (rectangle_iterator ri(tl, br); ri; ++ri)
+ {
+ const coord_def mc = *ri;
+ char glyph = lines(mc);
+ if (replace[0] && !strchr(replace, glyph))
+ continue;
+
+ int ob = 0;
+ ob += std::max(oblique + tl.x - mc.x, 0);
+ ob += std::max(oblique + mc.x - br.x, 0);
+
+ bool is_inside = (mc.y >= tl.y + ob && mc.y <= br.y - ob);
+ lines(mc) = is_inside ? inside : outside;
+ }
+}
+
+static void bf_smear(lua_State *ls, map_lines &lines)
+{
+ BF_INT(ls, iterations, 1);
+ BF_CHAR(ls, smear, 'x');
+ BF_STR(ls, onto, ".");
+ BF_BOOL(ls, boxy, false);
+
+ const int max_test_per_iteration = 10;
+ int sanity = 0;
+ int max_sanity = iterations * max_test_per_iteration;
+
+ for (int i = 0; i < iterations; i++)
+ {
+ bool diagonals, straights;
+ coord_def mc;
+
+ do
+ {
+ do
+ {
+ sanity++;
+ mc.x = random_range(1, lines.width() - 2);
+ mc.y = random_range(1, lines.height() - 2);
+ }
+ while (onto[0] && !strchr(onto, lines(mc)));
+
+ // Prevent too many iterations.
+ if (sanity > max_sanity)
+ return;
+
+ // Is there a "smear" feature along the diagonal from mc?
+ diagonals = lines(coord_def(mc.x+1, mc.y+1)) == smear ||
+ lines(coord_def(mc.x-1, mc.y+1)) == smear ||
+ lines(coord_def(mc.x-1, mc.y-1)) == smear ||
+ lines(coord_def(mc.x+1, mc.y-1)) == smear;
+
+ // Is there a "smear" feature up, down, left, or right from mc?
+ straights = lines(coord_def(mc.x+1, mc.y)) == smear ||
+ lines(coord_def(mc.x-1, mc.y)) == smear ||
+ lines(coord_def(mc.x, mc.y+1)) == smear ||
+ lines(coord_def(mc.x, mc.y-1)) == smear;
+ }
+ while (!straights && (boxy || !diagonals));
+
+ lines(mc) = smear;
+ }
+}
+
+static void bf_extend(lua_State *ls, map_lines &lines)
+{
+ BF_INT(ls, height, 1);
+ BF_INT(ls, width, 1);
+ BF_CHAR(ls, fill, 'x');
+
+ lines.extend(width, height, fill);
+}
+
+typedef void (*bf_func)(lua_State *ls, map_lines &lines);
+struct bf_entry
+{
+ const char* name;
+ bf_func func;
+};
+
+// Create a separate list of builder funcs so that we can automatically
+// generate a list of closures for them, rather than individually
+// and explicitly exposing them to the dgn namespace.
+static struct bf_entry bf_map[] =
+{
+ { "map_octa_room", &bf_octa_room },
+ { "map_smear", &bf_smear },
+ { "map_extend", &bf_extend }
+};
+
+static int dgn_call_builder_func(lua_State *ls)
+{
+ // This function gets called for all the builder functions that
+ // operate on map_lines.
+
+ MAP(ls, 1, map);
+ if (!lua_istable(ls, 2) && !lua_isfunction(ls, 2))
+ return luaL_argerror(ls, 2, "Expected table");
+
+ bf_func *func = (bf_func *)lua_topointer(ls, lua_upvalueindex(1));
+ if (!func)
+ return luaL_error(ls, "Expected C function in closure upval");
+
+ // Put the table on top.
+ lua_settop(ls, 2);
+
+ // Call the builder func itself.
+ (*func)(ls, map->map);
+
+ return (0);
+}
+
+static void _register_builder_funcs(lua_State *ls)
+{
+ lua_getglobal(ls, "dgn");
+
+ const size_t num_entries = sizeof(bf_map) / sizeof(bf_entry);
+ for (size_t i = 0; i < num_entries; i++)
+ {
+ // Push a closure with the C function into the dgn table.
+ lua_pushlightuserdata(ls, &bf_map[i].func);
+ lua_pushcclosure(ls, &dgn_call_builder_func, 1);
+ lua_setfield(ls, -2, bf_map[i].name);
+ }
+
+ lua_pop(ls, 1);
+}
+
+void init_dungeon_lua()
+{
+ lua_stack_cleaner clean(dlua);
+
+ luaL_openlib(dlua, "dgn", dgn_lib, 0);
+ // Add additional function to the Crawl module.
+ luaL_openlib(dlua, "crawl", crawl_lib, 0);
+ luaL_openlib(dlua, "file", file_lib, 0);
+ luaL_openlib(dlua, "you", you_lib, 0);
+ luaL_openlib(dlua, "los", los_lib, 0);
+
+ dlua.execfile("clua/dungeon.lua", true, true);
+ dlua.execfile("clua/luamark.lua", true, true);
+
+ lua_getglobal(dlua, "dgn_run_map");
+ luaopen_debug(dlua);
+ luaL_newmetatable(dlua, MAP_METATABLE);
+
+ luaopen_dgnevent(dlua);
+ luaopen_mapmarker(dlua);
+ luaopen_ray(dlua);
+
+ _register_builder_funcs(dlua);
+
+ register_mapdef_tables(dlua);
+}
+
+// Can be called from within a debugger to look at the current Lua
+// call stack. (Borrowed from ToME 3)
+void print_dlua_stack(void)
+{
+ struct lua_Debug dbg;
+ int i = 0;
+ lua_State *L = dlua.state();
+
+ fprintf(stderr, EOL);
+ while (lua_getstack(L, i++, &dbg) == 1)
+ {
+ lua_getinfo(L, "lnuS", &dbg);
+
+ char* file = strrchr(dbg.short_src, '/');
+ if (file == NULL)
+ file = dbg.short_src;
+ else
+ file++;
+
+ fprintf(stderr, "%s, function %s, line %d" EOL, file,
+ dbg.name, dbg.currentline);
+ }
+
+ fprintf(stderr, EOL);
+}
diff --git a/crawl-ref/source/luadgn.h b/crawl-ref/source/dlua.h
index 571fdf05db..f0acccb384 100644
--- a/crawl-ref/source/luadgn.h
+++ b/crawl-ref/source/dlua.h
@@ -1,5 +1,5 @@
/*
- * File: luadgn.h
+ * File: dlua.h
* Summary: Dungeon-builder Lua interface.
* Created by: dshaligram on Sat Jun 23 20:02:09 2007 UTC
*/
@@ -112,6 +112,17 @@ void luaopen_setmeta(lua_State *ls,
#define COORDS(c, p1, p2) \
GETCOORD(c, p1, p2, in_bounds)
+#define MAP(ls, n, var) \
+map_def *var = *(map_def **) luaL_checkudata(ls, n, MAP_METATABLE)
+#define DEVENT(ls, n, var) \
+dgn_event *var = *(dgn_event **) luaL_checkudata(ls, n, DEVENT_METATABLE)
+#define MAPMARKER(ls, n, var) \
+map_marker *var = *(map_marker **) luaL_checkudata(ls, n, MAPMARK_METATABLE)
+
+extern const struct luaL_reg dgn_lib[];
+extern const struct luaL_reg los_lib[];
+
+void register_mapdef_tables(lua_State *ls);
//////////////////////////////////////////////////////////////////////////
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index de5b3fb266..e040da7450 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -462,7 +462,7 @@ struct delay_queue_item
// Identifies a level. Should never include virtual methods or
// dynamically allocated memory (see code to push level_id onto Lua
-// stack in luadgn.cc)
+// stack in l_dgn.cc)
class level_id
{
public:
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 6c9072505a..c3719a3671 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -15,7 +15,7 @@
#include "chardump.h"
#include "clua.h"
-#include "luadgn.h"
+#include "dlua.h"
#include "delay.h"
#include "directn.h"
#include "kills.h"
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/l_dgn.cc
index b34853f3c0..a6e05cf589 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/l_dgn.cc
@@ -1,348 +1,93 @@
-/*
- * File: luadgn.cc
- * Summary: Dungeon-builder Lua interface.
- * Created by: dshaligram on Sat Jun 23 20:02:09 2007 UTC
- */
-
#include "AppHdr.h"
-#include <sstream>
-#include <algorithm>
-#include <memory>
+#include "dlua.h"
+
#include <cmath>
#include "branch.h"
#include "chardump.h"
-#include "clua.h"
#include "cloud.h"
-#include "describe.h"
-#include "directn.h"
-#include "dungeon.h"
-#include "files.h"
-#include "hiscores.h"
#include "initfile.h"
#include "items.h"
-#include "l_los.h"
-#include "los.h"
-#include "luadgn.h"
-#include "mapdef.h"
#include "mapmark.h"
#include "maps.h"
#include "message.h"
-#include "misc.h"
#include "mon-util.h"
#include "monplace.h"
#include "monstuff.h"
#include "place.h"
-#include "spells3.h"
#include "spl-util.h"
-#include "state.h"
-#include "stuff.h"
-#include "tags.h"
-#include "terrain.h"
#include "view.h"
-#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);
-}
-
-template <typename list, typename lpush>
-static int dlua_gentable(lua_State *ls, const list &strings, lpush push)
-{
- lua_newtable(ls);
- for (int i = 0, size = strings.size(); i < size; ++i)
- {
- push(ls, strings[i]);
- lua_rawseti(ls, -2, i + 1);
- }
- return (1);
-}
-
-inline static void dlua_pushcxxstring(lua_State *ls, const std::string &s)
-{
- lua_pushstring(ls, s.c_str());
-}
-
-int dlua_stringtable(lua_State *ls, const std::vector<std::string> &s)
-{
- return dlua_gentable(ls, s, dlua_pushcxxstring);
-}
-
-static int dlua_compiled_chunk_writer(lua_State *ls, const void *p,
- size_t sz, void *ud)
-{
- std::ostringstream &out = *static_cast<std::ostringstream*>(ud);
- out.write((const char *) p, sz);
- return (0);
-}
-
-///////////////////////////////////////////////////////////////////////////
-// dlua_chunk
-
-dlua_chunk::dlua_chunk(const std::string &_context)
- : file(), chunk(), compiled(), context(_context), first(-1),
- last(-1), error()
-{
- clear();
-}
-
-// Initialises a chunk from the function on the top of stack.
-// This function must not be a closure, i.e. must not have any upvalues.
-dlua_chunk::dlua_chunk(lua_State *ls)
- : file(), chunk(), compiled(), context(), first(-1), last(-1), error()
-{
- clear();
-
- lua_stack_cleaner cln(ls);
- std::ostringstream out;
- const int err = lua_dump(ls, dlua_compiled_chunk_writer, &out);
- if (err)
- {
- const char *e = lua_tostring(ls, -1);
- error = e? e : "Unknown error compiling chunk";
- }
- compiled = out.str();
-}
-
-dlua_chunk dlua_chunk::precompiled(const std::string &chunk)
-{
- dlua_chunk dchunk;
- dchunk.compiled = chunk;
- return (dchunk);
-}
-
-void dlua_chunk::write(writer& outf) const
+static mons_list _lua_get_mlist(lua_State *ls, int ndx)
{
- if (empty())
- {
- marshallByte(outf, CT_EMPTY);
- return;
- }
-
- if (!compiled.empty())
+ if (lua_isstring(ls, ndx))
{
- marshallByte(outf, CT_COMPILED);
- marshallString4(outf, compiled);
+ 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
{
- marshallByte(outf, CT_SOURCE);
- marshallString4(outf, chunk);
- }
-
- marshallString4(outf, file);
- marshallLong(outf, first);
-}
+ mons_list **mlist =
+ clua_get_userdata<mons_list*>(ls, MONSLIST_METATABLE, ndx);
+ if (mlist)
+ return (**mlist);
-void dlua_chunk::read(reader& inf)
-{
- clear();
- chunk_t type = static_cast<chunk_t>(unmarshallByte(inf));
- switch (type)
- {
- case CT_EMPTY:
- return;
- case CT_SOURCE:
- unmarshallString4(inf, chunk);
- break;
- case CT_COMPILED:
- unmarshallString4(inf, compiled);
- break;
+ luaL_argerror(ls, ndx, "Expected monster list object or string");
+ return mons_list();
}
- unmarshallString4(inf, file);
- first = unmarshallLong(inf);
}
-void dlua_chunk::clear()
-{
- file.clear();
- chunk.clear();
- first = last = -1;
- error.clear();
- compiled.clear();
-}
-
-void dlua_chunk::set_file(const std::string &s)
-{
- file = s;
-}
-
-void dlua_chunk::add(int line, const std::string &s)
-{
- if (first == -1)
- first = line;
-
- if (line != last && last != -1)
- while (last++ < line)
- chunk += '\n';
-
- chunk += " ";
- chunk += s;
- last = line;
-}
-
-void dlua_chunk::set_chunk(const std::string &s)
-{
- chunk = s;
-}
-
-int dlua_chunk::check_op(CLua &interp, int err)
-{
- error = interp.error;
- return (err);
-}
-
-int dlua_chunk::load(CLua &interp)
+static item_list _lua_get_ilist(lua_State *ls, int ndx)
{
- if (!compiled.empty())
- return check_op( interp,
- interp.loadbuffer(compiled.c_str(), compiled.length(),
- context.c_str()) );
-
- if (empty())
+ if (lua_isstring(ls, ndx))
{
- chunk.clear();
- return (-1000);
- }
+ const char *spec = lua_tostring(ls, ndx);
- int err = check_op( interp,
- interp.loadstring(chunk.c_str(), context.c_str()) );
- if (err)
- return (err);
- std::ostringstream out;
- err = lua_dump(interp, dlua_compiled_chunk_writer, &out);
- if (err)
- {
- const char *e = lua_tostring(interp, -1);
- error = e? e : "Unknown error compiling chunk";
- lua_pop(interp, 2);
+ item_list ilist;
+ const std::string err = ilist.add_item(spec);
+ if (!err.empty())
+ luaL_error(ls, err.c_str());
+
+ return (ilist);
}
- compiled = out.str();
- chunk.clear();
- return (err);
-}
-
-int dlua_chunk::run(CLua &interp)
-{
- int err = load(interp);
- if (err)
- return (err);
- // callfn returns true on success, but we want to return 0 on success.
- return (check_op(interp, !interp.callfn(NULL, 0, 0)));
-}
-
-int dlua_chunk::load_call(CLua &interp, const char *fn)
-{
- int err = load(interp);
- if (err == -1000)
- return (0);
- if (err)
- return (err);
-
- return check_op(interp, !interp.callfn(fn, fn? 1 : 0, 0));
-}
-
-std::string dlua_chunk::orig_error() const
-{
- rewrite_chunk_errors(error);
- return (error);
-}
-
-bool dlua_chunk::empty() const
-{
- return compiled.empty() && trimmed_string(chunk).empty();
-}
-
-bool dlua_chunk::rewrite_chunk_errors(std::string &s) const
-{
- const std::string contextm = "[string \"" + context + "\"]:";
- std::string::size_type dlwhere = s.find(contextm);
-
- if (dlwhere == std::string::npos)
- return (false);
-
- if (!dlwhere)
+ else
{
- s = rewrite_chunk_prefix(s);
- return (true);
- }
+ item_list **ilist =
+ clua_get_userdata<item_list*>(ls, ITEMLIST_METATABLE, ndx);
+ if (ilist)
+ return (**ilist);
- // Our chunk is mentioned, go back through and rewrite lines.
- std::vector<std::string> lines = split_string("\n", s);
- std::string newmsg = lines[0];
- bool wrote_prefix = false;
- for (int i = 2, size = lines.size() - 1; i < size; ++i)
- {
- const std::string &st = lines[i];
- if (st.find(context) != std::string::npos)
- {
- if (!wrote_prefix)
- {
- newmsg = get_chunk_prefix(st) + ": " + newmsg;
- wrote_prefix = true;
- }
- else
- newmsg += "\n" + rewrite_chunk_prefix(st);
- }
+ luaL_argerror(ls, ndx, "Expected item list object or string");
+ return item_list();
}
- s = newmsg;
- return (true);
}
-std::string dlua_chunk::rewrite_chunk_prefix(const std::string &line,
- bool skip_body) const
+void register_mapdef_tables(lua_State *ls)
{
- std::string s = line;
- const std::string contextm = "[string \"" + context + "\"]:";
- const std::string::size_type ps = s.find(contextm);
- if (ps == std::string::npos)
- return (s);
-
- const std::string::size_type lns = ps + contextm.length();
- std::string::size_type pe = s.find(':', ps + contextm.length());
- if (pe != std::string::npos)
- {
- const std::string line_num = s.substr(lns, pe - lns);
- const int lnum = atoi(line_num.c_str());
- const std::string newlnum = make_stringf("%d", lnum + first - 1);
- s = s.substr(0, lns) + newlnum + s.substr(pe);
- pe = lns + newlnum.length();
- }
-
- return s.substr(0, ps) + (file.empty()? context : file) + ":"
- + (skip_body? s.substr(lns, pe - lns)
- : s.substr(lns));
+ clua_register_metatable(ls, MONSLIST_METATABLE, NULL,
+ lua_object_gc<mons_list>);
+ clua_register_metatable(ls, ITEMLIST_METATABLE, NULL,
+ lua_object_gc<item_list>);
}
-std::string dlua_chunk::get_chunk_prefix(const std::string &sorig) const
+template <class T>
+static void _push_object_type(lua_State *ls, const char *meta, const T &data)
{
- return rewrite_chunk_prefix(sorig, true);
+ T **ptr = clua_new_userdata<T*>(ls, meta);
+ *ptr = new T(data);
}
///////////////////////////////////////////////////////////////////////////
// Lua dungeon bindings (in the dgn table).
-#define MAP(ls, n, var) \
- map_def *var = *(map_def **) luaL_checkudata(ls, n, MAP_METATABLE)
-#define DEVENT(ls, n, var) \
- dgn_event *var = *(dgn_event **) luaL_checkudata(ls, n, DEVENT_METATABLE)
-#define MAPMARKER(ls, n, var) \
- map_marker *var = *(map_marker **) luaL_checkudata(ls, n, MAPMARK_METATABLE)
-
static dungeon_feature_type _get_lua_feature(lua_State *ls, int idx)
{
dungeon_feature_type feat = (dungeon_feature_type)0;
@@ -352,7 +97,7 @@ static dungeon_feature_type _get_lua_feature(lua_State *ls, int 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;
}
@@ -370,7 +115,7 @@ static inline bool _lua_boolean(lua_State *ls, int ndx, bool defval)
}
#define FEAT(f, pos) \
- dungeon_feature_type f = _check_lua_feature(ls, pos)
+dungeon_feature_type f = _check_lua_feature(ls, pos)
void dgn_reset_default_depth()
{
@@ -425,13 +170,13 @@ static int dgn_depth_proc(lua_State *ls, depth_ranges &dr, int s)
{
PLUARET(string, dgn_depth_list_string(dr).c_str());
}
-
+
if (lua_isnil(ls, s))
{
dr.clear();
return (0);
}
-
+
dr.clear();
dgn_add_depths(dr, ls, s, lua_gettop(ls));
return (0);
@@ -530,7 +275,7 @@ static int dgn_tags(lua_State *ls)
static int dgn_tags_remove(lua_State *ls)
{
MAP(ls, 1, map);
-
+
const int top = lua_gettop(ls);
for (int i = 2; i <= top; ++i)
{
@@ -538,19 +283,19 @@ static int dgn_tags_remove(lua_State *ls)
const std::string::size_type pos = map->tags.find(axee);
if (pos != std::string::npos)
map->tags =
- map->tags.substr(0, pos)
- + map->tags.substr(pos + axee.length());
+ map->tags.substr(0, pos)
+ + map->tags.substr(pos + axee.length());
}
PLUARET(string, map->tags.c_str());
}
static const std::string level_flag_names[] =
- {"no_tele_control", "not_mappable", "no_magic_map", ""};
+{"no_tele_control", "not_mappable", "no_magic_map", ""};
static int dgn_lflags(lua_State *ls)
{
MAP(ls, 1, map);
-
+
try
{
map->level_flags = map_flags::parse(level_flag_names,
@@ -560,14 +305,14 @@ static int dgn_lflags(lua_State *ls)
{
luaL_argerror(ls, 2, error.c_str());
}
-
+
return (0);
}
static int dgn_change_level_flags(lua_State *ls)
{
map_flags flags;
-
+
try {
flags = map_flags::parse(level_flag_names,
luaL_checkstring(ls, 1));
@@ -578,24 +323,24 @@ static int dgn_change_level_flags(lua_State *ls)
lua_pushboolean(ls, false);
return (1);
}
-
+
bool silent = lua_toboolean(ls, 2);
-
+
bool changed1 = set_level_flags(flags.flags_set, silent);
bool changed2 = unset_level_flags(flags.flags_unset, silent);
-
+
lua_pushboolean(ls, changed1 || changed2);
-
+
return (1);
}
static const std::string branch_flag_names[] =
- {"no_tele_control", "not_mappable", "no_magic_map", ""};
+{"no_tele_control", "not_mappable", "no_magic_map", ""};
static int dgn_bflags(lua_State *ls)
{
MAP(ls, 1, map);
-
+
try {
map->branch_flags = map_flags::parse(branch_flag_names,
luaL_checkstring(ls, 2));
@@ -604,14 +349,14 @@ static int dgn_bflags(lua_State *ls)
{
luaL_argerror(ls, 2, error.c_str());
}
-
+
return (0);
}
static int dgn_change_branch_flags(lua_State *ls)
{
map_flags flags;
-
+
try {
flags = map_flags::parse(branch_flag_names,
luaL_checkstring(ls, 1));
@@ -622,14 +367,14 @@ static int dgn_change_branch_flags(lua_State *ls)
lua_pushboolean(ls, false);
return (1);
}
-
+
bool silent = lua_toboolean(ls, 2);
-
+
bool changed1 = set_branch_flags(flags.flags_set, silent);
bool changed2 = unset_branch_flags(flags.flags_unset, silent);
-
+
lua_pushboolean(ls, changed1 || changed2);
-
+
return (1);
}
@@ -643,9 +388,9 @@ static int dgn_set_random_mon_list(lua_State *ls)
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)
{
@@ -660,10 +405,10 @@ static int dgn_set_random_mon_list(lua_State *ls)
else if (nargs == 2)
{
map_def **_map =
- clua_get_userdata<map_def*>(ls, MAP_METATABLE, 1);
+ clua_get_userdata<map_def*>(ls, MAP_METATABLE, 1);
map = *_map;
}
-
+
if (map)
{
if (map->orient != MAP_ENCOMPASS || map->place.is_valid()
@@ -673,36 +418,36 @@ static int dgn_set_random_mon_list(lua_State *ls)
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)
@@ -710,7 +455,7 @@ static int dgn_set_random_mon_list(lua_State *ls)
num_lords++;
continue;
}
-
+
std::string name;
if (mon.place.is_valid())
{
@@ -739,42 +484,42 @@ static int dgn_set_random_mon_list(lua_State *ls)
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.",
+ "being discarded.",
name.c_str());
-
+
if (mon.band)
mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : band request for "
- "%s being ignored.",
+ "%s being ignored.",
name.c_str());
-
+
if (mon.colour != BLACK)
mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : colour for "
- "%s being ignored.",
+ "%s being ignored.",
name.c_str());
-
+
if (mon.items.size() > 0)
mprf(MSGCH_ERROR, "dgn.set_random_mon_list() : items for "
- "%s being ignored.",
+ "%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);
}
@@ -789,7 +534,7 @@ static int dgn_chance(lua_State *ls)
luaL_argerror(ls, 2,
make_stringf("Chance must be in the range [0,%d]",
CHANCE_ROLL).c_str());
-
+
map->chance_priority = chance_priority;
map->chance = chance;
}
@@ -833,13 +578,13 @@ static int dgn_orient(lua_State *ls)
}
static int dgn_map_add_transform(
- lua_State *ls,
- std::string (map_lines::*add)(const std::string &s))
+ lua_State *ls,
+ std::string (map_lines::*add)(const std::string &s))
{
MAP(ls, 1, map);
if (lua_gettop(ls) == 1)
luaL_error(ls, "Expected args, got none.");
-
+
for (int i = 2, size = lua_gettop(ls); i <= size; ++i)
{
if (lua_isnil(ls, i))
@@ -853,7 +598,7 @@ static int dgn_map_add_transform(
luaL_error(ls, err.c_str());
}
}
-
+
return (0);
}
@@ -889,31 +634,31 @@ static int dgn_map(lua_State *ls)
MAP(ls, 1, map);
if (lua_gettop(ls) == 1)
return dlua_stringtable(ls, map->map.get_lines());
-
+
if (lua_isnil(ls, 2))
{
map->map.clear();
return (0);
}
-
+
// map(<map>, x, y) = glyph at (x,y), subject to map being
// resolved and normalised.
if (lua_gettop(ls) == 3 && lua_isnumber(ls, 2) && lua_isnumber(ls, 3))
{
const int gly = map->map.glyph(luaL_checkint(ls, 2),
- luaL_checkint(ls, 3));
+ luaL_checkint(ls, 3));
char buf[2] = "";
buf[0] = gly;
lua_pushstring(ls, buf);
return (1);
}
-
+
if (lua_isstring(ls, 2))
{
map->map.add_line(luaL_checkstring(ls, 2));
return (0);
}
-
+
std::vector<std::string> &lines = map->map.get_lines();
int which_line = luaL_checkint(ls, 2);
if (which_line < 0)
@@ -930,7 +675,7 @@ static int dgn_map(lua_State *ls)
}
PLUARET(string, lines[which_line].c_str());
}
-
+
if (lua_isnil(ls, 3))
{
if (which_line >= 0 && which_line < (int) lines.size())
@@ -940,18 +685,18 @@ static int dgn_map(lua_State *ls)
}
return (0);
}
-
+
const std::string newline = luaL_checkstring(ls, 3);
if (which_line < 0)
luaL_error(ls,
make_stringf("Index %d out of range", which_line).c_str());
-
+
if (which_line < (int) lines.size())
{
lines[which_line] = newline;
return (0);
}
-
+
lines.reserve(which_line + 1);
lines.resize(which_line + 1, "");
lines[which_line] = newline;
@@ -963,13 +708,13 @@ static int dgn_mons(lua_State *ls)
MAP(ls, 1, map);
if (lua_gettop(ls) == 1)
return (0);
-
+
if (lua_isnil(ls, 2))
{
map->mons.clear();
return (0);
}
-
+
if (lua_isstring(ls, 2))
{
std::string err = map->mons.add_mons(luaL_checkstring(ls, 2));
@@ -977,7 +722,7 @@ static int dgn_mons(lua_State *ls)
luaL_error(ls, err.c_str());
return (0);
}
-
+
const int index = luaL_checkint(ls, 2);
std::string err = map->mons.set_mons(index, luaL_checkstring(ls, 3));
if (!err.empty())
@@ -990,13 +735,13 @@ static int dgn_item(lua_State *ls)
MAP(ls, 1, map);
if (lua_gettop(ls) == 1)
return (0);
-
+
if (lua_isnil(ls, 2))
{
map->items.clear();
return (0);
}
-
+
if (lua_isstring(ls, 2))
{
std::string err = map->items.add_item(luaL_checkstring(ls, 2));
@@ -1004,7 +749,7 @@ static int dgn_item(lua_State *ls)
luaL_error(ls, err.c_str());
return (0);
}
-
+
const int index = luaL_checkint(ls, 2);
std::string err = map->items.set_item(index, luaL_checkstring(ls, 3));
if (!err.empty())
@@ -1020,15 +765,15 @@ static int dgn_lua_marker(lua_State *ls)
{
luaL_error(ls, "Expected marker key and marker function/table.");
}
-
+
CLua &lvm(CLua::get_vm(ls));
std::string key = lua_tostring(ls, 2);
lua_datum function(lvm, 3, false);
-
+
const std::string err = map->map.add_lua_marker(key, function);
if (!err.empty())
luaL_error(ls, err.c_str());
-
+
return (0);
}
@@ -1042,7 +787,7 @@ static int dgn_marker(lua_State *ls)
map->map.clear_markers();
return (0);
}
-
+
if (lua_isstring(ls, 2))
{
std::string err = map->map.add_feature_marker(luaL_checkstring(ls, 2));
@@ -1112,7 +857,7 @@ static int dgn_welcome(lua_State *ls)
static int dgn_grid(lua_State *ls)
{
GETCOORD(c, 1, 2, map_bounds);
-
+
if (!lua_isnone(ls, 3))
{
const dungeon_feature_type feat = _get_lua_feature(ls, 3);
@@ -1133,8 +878,8 @@ static int dgn_max_bounds(lua_State *ls)
}
typedef
-flood_find<map_def::map_feature_finder, map_def::map_bounds_check>
-map_flood_finder;
+ flood_find<map_def::map_feature_finder, map_def::map_bounds_check>
+ map_flood_finder;
static int dgn_map_pathfind(lua_State *ls, int minargs,
bool (map_flood_finder::*f)(const coord_def &))
@@ -1143,21 +888,21 @@ static int dgn_map_pathfind(lua_State *ls, int minargs,
const int nargs = lua_gettop(ls);
if (nargs < minargs)
return luaL_error
- (ls,
- make_stringf("Not enough points to test connectedness "
- "(need at least %d)", minargs / 2).c_str());
-
+ (ls,
+ make_stringf("Not enough points to test connectedness "
+ "(need at least %d)", minargs / 2).c_str());
+
map_def::map_feature_finder feat_finder(*map);
map_def::map_bounds_check bounds_checker(*map);
map_flood_finder finder(feat_finder, bounds_checker);
-
+
for (int i = 4; i < nargs; i += 2)
{
const coord_def c(luaL_checkint(ls, i),
luaL_checkint(ls, i + 1));
finder.add_point(c);
}
-
+
const coord_def pos(luaL_checkint(ls, 2), luaL_checkint(ls, 3));
PLUARET(boolean, (finder.*f)(pos));
}
@@ -1199,7 +944,7 @@ static int dgn_gly_points(lua_State *ls)
{
MAP(ls, 1, map);
std::vector<coord_def> cs = map->find_glyph(*luaL_checkstring(ls, 2));
-
+
for (int i = 0, size = cs.size(); i < size; ++i)
dlua_push_coord(ls, cs[i]);
return (cs.size() * 2);
@@ -1226,16 +971,16 @@ static int dgn_load_des_file(lua_State *ls)
static int dgn_lfloorcol(lua_State *ls)
{
MAP(ls, 1, map);
-
+
if (!lua_isnone(ls, 2))
{
const char *s = luaL_checkstring(ls, 2);
int colour = str_to_colour(s);
-
+
if (colour < 0 || colour == BLACK)
{
std::string error;
-
+
if (colour == BLACK)
{
error = "Can't set floor to black.";
@@ -1246,9 +991,9 @@ static int dgn_lfloorcol(lua_State *ls)
error += s;
error += "'";
}
-
+
luaL_argerror(ls, 2, error.c_str());
-
+
return (0);
}
map->floor_colour = (unsigned char) colour;
@@ -1259,16 +1004,16 @@ static int dgn_lfloorcol(lua_State *ls)
static int dgn_lrockcol(lua_State *ls)
{
MAP(ls, 1, map);
-
+
if (!lua_isnone(ls, 2))
{
const char *s = luaL_checkstring(ls, 2);
int colour = str_to_colour(s);
-
+
if (colour < 0 || colour == BLACK)
{
std::string error;
-
+
if (colour == BLACK)
{
error = "Can't set rock to black.";
@@ -1279,12 +1024,12 @@ static int dgn_lrockcol(lua_State *ls)
error += s;
error += "'";
}
-
+
luaL_argerror(ls, 2, error.c_str());
-
+
return (0);
}
-
+
map->rock_colour = (unsigned char) colour;
}
PLUARET(string, colour_to_str(map->rock_colour).c_str());
@@ -1308,7 +1053,7 @@ static int _lua_colour(lua_State *ls, int ndx,
else if (const char *s = luaL_checkstring(ls, ndx))
{
const int colour = str_to_colour(s);
-
+
if (colour < 0 || colour == forbidden_colour)
{
std::string error;
@@ -1327,9 +1072,9 @@ static int dgn_change_floor_colour(lua_State *ls)
{
const int colour = _lua_colour(ls, 1, BLACK);
const bool update_now = _lua_boolean(ls, 2, false);
-
+
env.floor_colour = (unsigned char) colour;
-
+
if (crawl_state.need_save && update_now)
viewwindow(true, false);
return (0);
@@ -1339,9 +1084,9 @@ static int dgn_change_rock_colour(lua_State *ls)
{
const int colour = _lua_colour(ls, 1, BLACK);
const bool update_now = _lua_boolean(ls, 2, false);
-
+
env.rock_colour = (unsigned char) colour;
-
+
if (crawl_state.need_save && update_now)
viewwindow(true, false);
return (0);
@@ -1357,50 +1102,50 @@ static int dgn_colour_at(lua_State *ls)
const char *dngn_feature_names[] =
{
- "unseen", "closed_door", "detected_secret_door", "secret_door",
- "wax_wall", "metal_wall", "green_crystal_wall", "rock_wall", "stone_wall",
- "permarock_wall",
- "clear_rock_wall", "clear_stone_wall", "clear_permarock_wall", "trees",
- "open_sea", "orcish_idol", "", "", "", "", "",
- "granite_statue", "statue_reserved_1", "statue_reserved_2",
- "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "", "", "", "", "", "", "lava",
- "deep_water", "", "", "shallow_water", "water_stuck", "floor",
- "floor_special", "floor_reserved", "exit_hell", "enter_hell",
- "open_door", "", "", "trap_mechanical", "trap_magical", "trap_natural",
- "undiscovered_trap", "", "enter_shop", "enter_labyrinth",
- "stone_stairs_down_i", "stone_stairs_down_ii",
- "stone_stairs_down_iii", "escape_hatch_down", "stone_stairs_up_i",
- "stone_stairs_up_ii", "stone_stairs_up_iii", "escape_hatch_up", "",
- "", "enter_dis", "enter_gehenna", "enter_cocytus",
- "enter_tartarus", "enter_abyss", "exit_abyss", "stone_arch",
- "enter_pandemonium", "exit_pandemonium", "transit_pandemonium",
- "", "", "", "builder_special_wall", "builder_special_floor", "",
- "", "", "enter_orcish_mines", "enter_hive", "enter_lair",
- "enter_slime_pits", "enter_vaults", "enter_crypt",
- "enter_hall_of_blades", "enter_zot", "enter_temple",
- "enter_snake_pit", "enter_elven_halls", "enter_tomb",
- "enter_swamp", "enter_shoals", "enter_reserved_2",
- "enter_reserved_3", "enter_reserved_4", "", "", "",
- "return_from_orcish_mines", "return_from_hive",
- "return_from_lair", "return_from_slime_pits",
- "return_from_vaults", "return_from_crypt",
- "return_from_hall_of_blades", "return_from_zot",
- "return_from_temple", "return_from_snake_pit",
- "return_from_elven_halls", "return_from_tomb",
- "return_from_swamp", "return_from_shoals", "return_reserved_2",
- "return_reserved_3", "return_reserved_4", "", "", "", "", "", "",
- "", "", "", "", "", "", "", "enter_portal_vault", "exit_portal_vault",
- "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
- "", "", "altar_zin", "altar_shining_one", "altar_kikubaaqudgha",
- "altar_yredelemnul", "altar_xom", "altar_vehumet",
- "altar_okawaru", "altar_makhleb", "altar_sif_muna", "altar_trog",
- "altar_nemelex_xobeh", "altar_elyvilon", "altar_lugonu",
- "altar_beogh", "altar_jiyva", "altar_feawn", "", "", "", "",
- "fountain_blue", "fountain_sparkling", "fountain_blood",
- "dry_fountain_blue", "dry_fountain_sparkling", "dry_fountain_blood",
- "permadry_fountain", "abandoned_shop"
+"unseen", "closed_door", "detected_secret_door", "secret_door",
+"wax_wall", "metal_wall", "green_crystal_wall", "rock_wall", "stone_wall",
+"permarock_wall",
+"clear_rock_wall", "clear_stone_wall", "clear_permarock_wall", "trees",
+"open_sea", "orcish_idol", "", "", "", "", "",
+"granite_statue", "statue_reserved_1", "statue_reserved_2",
+"", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "lava",
+"deep_water", "", "", "shallow_water", "water_stuck", "floor",
+"floor_special", "floor_reserved", "exit_hell", "enter_hell",
+"open_door", "", "", "trap_mechanical", "trap_magical", "trap_natural",
+"undiscovered_trap", "", "enter_shop", "enter_labyrinth",
+"stone_stairs_down_i", "stone_stairs_down_ii",
+"stone_stairs_down_iii", "escape_hatch_down", "stone_stairs_up_i",
+"stone_stairs_up_ii", "stone_stairs_up_iii", "escape_hatch_up", "",
+"", "enter_dis", "enter_gehenna", "enter_cocytus",
+"enter_tartarus", "enter_abyss", "exit_abyss", "stone_arch",
+"enter_pandemonium", "exit_pandemonium", "transit_pandemonium",
+"", "", "", "builder_special_wall", "builder_special_floor", "",
+"", "", "enter_orcish_mines", "enter_hive", "enter_lair",
+"enter_slime_pits", "enter_vaults", "enter_crypt",
+"enter_hall_of_blades", "enter_zot", "enter_temple",
+"enter_snake_pit", "enter_elven_halls", "enter_tomb",
+"enter_swamp", "enter_shoals", "enter_reserved_2",
+"enter_reserved_3", "enter_reserved_4", "", "", "",
+"return_from_orcish_mines", "return_from_hive",
+"return_from_lair", "return_from_slime_pits",
+"return_from_vaults", "return_from_crypt",
+"return_from_hall_of_blades", "return_from_zot",
+"return_from_temple", "return_from_snake_pit",
+"return_from_elven_halls", "return_from_tomb",
+"return_from_swamp", "return_from_shoals", "return_reserved_2",
+"return_reserved_3", "return_reserved_4", "", "", "", "", "", "",
+"", "", "", "", "", "", "", "enter_portal_vault", "exit_portal_vault",
+"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
+"", "", "altar_zin", "altar_shining_one", "altar_kikubaaqudgha",
+"altar_yredelemnul", "altar_xom", "altar_vehumet",
+"altar_okawaru", "altar_makhleb", "altar_sif_muna", "altar_trog",
+"altar_nemelex_xobeh", "altar_elyvilon", "altar_lugonu",
+"altar_beogh", "altar_jiyva", "altar_feawn", "", "", "", "",
+"fountain_blue", "fountain_sparkling", "fountain_blood",
+"dry_fountain_blue", "dry_fountain_sparkling", "dry_fountain_blood",
+"permadry_fountain", "abandoned_shop"
};
dungeon_feature_type dungeon_feature_by_name(const std::string &name)
@@ -1408,36 +1153,36 @@ dungeon_feature_type dungeon_feature_by_name(const std::string &name)
COMPILE_CHECK(ARRAYSZ(dngn_feature_names) == NUM_REAL_FEATURES, c1);
if (name.empty())
return (DNGN_UNSEEN);
-
+
for (unsigned i = 0; i < ARRAYSZ(dngn_feature_names); ++i)
if (dngn_feature_names[i] == name)
return static_cast<dungeon_feature_type>(i);
-
+
return (DNGN_UNSEEN);
}
std::vector<std::string> dungeon_feature_matches(const std::string &name)
{
std::vector<std::string> matches;
-
+
COMPILE_CHECK(ARRAYSZ(dngn_feature_names) == NUM_REAL_FEATURES, c1);
if (name.empty())
return (matches);
-
+
for (unsigned i = 0; i < ARRAYSZ(dngn_feature_names); ++i)
if (strstr(dngn_feature_names[i], name.c_str()))
matches.push_back(dngn_feature_names[i]);
-
+
return (matches);
}
const char *dungeon_feature_name(dungeon_feature_type rfeat)
{
const unsigned feat = rfeat;
-
+
if (feat >= ARRAYSZ(dngn_feature_names))
return (NULL);
-
+
return dngn_feature_names[feat];
}
@@ -1456,10 +1201,10 @@ static int dgn_feature_name(lua_State *ls)
static const char *dgn_event_type_names[] =
{
- "none", "turn", "mons_move", "player_move", "leave_level",
- "entering_level", "entered_level", "player_los", "player_climb",
- "monster_dies", "item_pickup", "item_moved", "feat_change",
- "wall_hit"
+"none", "turn", "mons_move", "player_move", "leave_level",
+"entering_level", "entered_level", "player_los", "player_climb",
+"monster_dies", "item_pickup", "item_moved", "feat_change",
+"wall_hit"
};
static dgn_event_type dgn_event_type_by_name(const std::string &name)
@@ -1474,11 +1219,11 @@ static const char *dgn_event_type_name(unsigned evmask)
{
if (evmask == 0)
return (dgn_event_type_names[0]);
-
+
for (unsigned i = 1; i < ARRAYSZ(dgn_event_type_names); ++i)
if (evmask & (1 << (i - 1)))
return (dgn_event_type_names[i]);
-
+
return (dgn_event_type_names[0]);
}
@@ -1516,7 +1261,7 @@ static int dgn_register_listener(lua_State *ls)
pos.x = luaL_checkint(ls, 3);
pos.y = luaL_checkint(ls, 4);
}
-
+
dungeon_events.register_listener(mask, listener, pos);
return (0);
}
@@ -1548,28 +1293,28 @@ static int dgn_num_matching_markers(lua_State *ls)
const char* key = luaL_checkstring(ls, 1);
const char* val_ptr = lua_tostring(ls, 2);
const char* val;
-
+
if (val_ptr == NULL)
val = "";
else
val = val_ptr;
-
+
std::vector<map_marker*> markers = env.markers.get_all(key, val);
-
+
PLUARET(number, markers.size());
}
static int dgn_feature_desc(lua_State *ls)
{
const dungeon_feature_type feat =
- static_cast<dungeon_feature_type>(luaL_checkint(ls, 1));
+ static_cast<dungeon_feature_type>(luaL_checkint(ls, 1));
const description_level_type dtype =
- lua_isnumber(ls, 2)?
- static_cast<description_level_type>(luaL_checkint(ls, 2)) :
- description_type_by_name(lua_tostring(ls, 2));
+ lua_isnumber(ls, 2)?
+ static_cast<description_level_type>(luaL_checkint(ls, 2)) :
+ description_type_by_name(lua_tostring(ls, 2));
const bool need_stop = lua_isboolean(ls, 3)? lua_toboolean(ls, 3) : false;
const std::string s =
- feature_description(feat, NUM_TRAPS, false, dtype, need_stop);
+ feature_description(feat, NUM_TRAPS, false, dtype, need_stop);
lua_pushstring(ls, s.c_str());
return (1);
}
@@ -1577,14 +1322,14 @@ static int dgn_feature_desc(lua_State *ls)
static int dgn_feature_desc_at(lua_State *ls)
{
const description_level_type dtype =
- lua_isnumber(ls, 3)?
- static_cast<description_level_type>(luaL_checkint(ls, 3)) :
- description_type_by_name(lua_tostring(ls, 3));
+ lua_isnumber(ls, 3)?
+ static_cast<description_level_type>(luaL_checkint(ls, 3)) :
+ description_type_by_name(lua_tostring(ls, 3));
const bool need_stop = lua_isboolean(ls, 4)? lua_toboolean(ls, 4) : false;
const std::string s =
- feature_description(coord_def(luaL_checkint(ls, 1),
- luaL_checkint(ls, 2)),
- false, dtype, need_stop);
+ feature_description(coord_def(luaL_checkint(ls, 1),
+ luaL_checkint(ls, 2)),
+ false, dtype, need_stop);
lua_pushstring(ls, s.c_str());
return (1);
}
@@ -1593,15 +1338,15 @@ static int dgn_set_feature_desc_short(lua_State *ls)
{
const std::string base_name = luaL_checkstring(ls, 1);
const std::string desc = luaL_checkstring(ls, 2);
-
+
if (base_name.empty())
{
luaL_argerror(ls, 1, "Base name can't be empty");
return (0);
}
-
+
set_feature_desc_short(base_name, desc);
-
+
return (0);
}
@@ -1609,15 +1354,15 @@ static int dgn_set_feature_desc_long(lua_State *ls)
{
const std::string raw_name = luaL_checkstring(ls, 1);
const std::string desc = luaL_checkstring(ls, 2);
-
+
if (raw_name.empty())
{
luaL_argerror(ls, 1, "Raw name can't be empty");
return (0);
}
-
+
set_feature_desc_long(raw_name, desc);
-
+
return (0);
}
@@ -1629,50 +1374,50 @@ static int dgn_terrain_changed(lua_State *ls)
else if (lua_isstring(ls, 3))
type = dungeon_feature_by_name(lua_tostring(ls, 3));
const bool affect_player =
- lua_isboolean(ls, 4)? lua_toboolean(ls, 4) : true;
+ lua_isboolean(ls, 4)? lua_toboolean(ls, 4) : true;
const bool preserve_features =
- lua_isboolean(ls, 5)? lua_toboolean(ls, 5) : true;
+ lua_isboolean(ls, 5)? lua_toboolean(ls, 5) : true;
const bool preserve_items =
- lua_isboolean(ls, 6)? lua_toboolean(ls, 6) : true;
+ lua_isboolean(ls, 6)? lua_toboolean(ls, 6) : true;
dungeon_terrain_changed( coord_def( luaL_checkint(ls, 1),
- luaL_checkint(ls, 2) ),
- type, affect_player,
- preserve_features, preserve_items );
+ luaL_checkint(ls, 2) ),
+ type, affect_player,
+ preserve_features, preserve_items );
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);
else
lua_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);
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);
@@ -1691,31 +1436,31 @@ static int dgn_items_at(lua_State *ls)
static int lua_dgn_set_lt_callback(lua_State *ls)
{
const char *level_type = luaL_checkstring(ls, 1);
-
+
if (level_type == NULL || strlen(level_type) == 0)
return (0);
-
+
const char *callback_name = luaL_checkstring(ls, 2);
-
+
if (callback_name == NULL || strlen(callback_name) == 0)
return (0);
-
+
dgn_set_lt_callback(level_type, callback_name);
-
+
return (0);
}
static int dgn_fixup_stairs(lua_State *ls)
{
const dungeon_feature_type up_feat =
- dungeon_feature_by_name(luaL_checkstring(ls, 1));
-
+ dungeon_feature_by_name(luaL_checkstring(ls, 1));
+
const dungeon_feature_type down_feat =
- dungeon_feature_by_name(luaL_checkstring(ls, 2));
-
+ dungeon_feature_by_name(luaL_checkstring(ls, 2));
+
if (up_feat == DNGN_UNSEEN && down_feat == DNGN_UNSEEN)
return(0);
-
+
for (int y = 0; y < GYM; ++y)
{
for (int x = 0; x < GXM; ++x)
@@ -1724,24 +1469,24 @@ static int dgn_fixup_stairs(lua_State *ls)
if (feat_is_stone_stair(feat) || feat_is_escape_hatch(feat))
{
dungeon_feature_type new_feat = DNGN_UNSEEN;
-
+
if (feat_stair_direction(feat) == CMD_GO_DOWNSTAIRS)
new_feat = down_feat;
else
new_feat = up_feat;
-
+
if (new_feat != DNGN_UNSEEN)
{
grd[x][y] = new_feat;
env.markers.add(
- new map_feature_marker(
- coord_def(x, y),
- new_feat));
+ new map_feature_marker(
+ coord_def(x, y),
+ new_feat));
}
}
}
}
-
+
return (0);
}
@@ -1753,9 +1498,9 @@ static unsigned int _get_tile_idx(lua_State *ls, int arg)
luaL_argerror(ls, arg, "Expected string for tile name");
return 0;
}
-
+
const char *tile_name = luaL_checkstring(ls, arg);
-
+
unsigned int idx;
if (!tile_dngn_index(tile_name, idx))
{
@@ -1765,7 +1510,7 @@ static unsigned int _get_tile_idx(lua_State *ls, int arg)
luaL_argerror(ls, arg, error.c_str());
return 0;
}
-
+
return idx;
}
#endif
@@ -1773,20 +1518,20 @@ static unsigned int _get_tile_idx(lua_State *ls, int arg)
static int dgn_floor_halo(lua_State *ls)
{
std::string error = "";
-
+
const char *s1 = luaL_checkstring(ls, 1);
const dungeon_feature_type target = dungeon_feature_by_name(s1);
-
+
if (target == DNGN_UNSEEN)
{
error += "No such dungeon feature as '";
error += s1;
error += "'. ";
}
-
+
const char *s2 = luaL_checkstring(ls, 2);
short colour = str_to_colour(s2);
-
+
if (colour == -1)
{
error += "No such colour as '";
@@ -1795,37 +1540,37 @@ static int dgn_floor_halo(lua_State *ls)
}
else if (colour == BLACK)
error += "Can't set floor colour to black.";
-
+
if (!error.empty())
{
luaL_argerror(ls, 2, error.c_str());
return(0);
}
-
+
for (int y = 0; y < GYM; ++y)
for (int x = 0; x < GXM; ++x)
{
const dungeon_feature_type feat = grd[x][y];
if (feat == target)
{
-
+
for (int i = -1; i <= 1; i++)
- for (int j = -1; j <= 1; j++)
- {
- if (!map_bounds(x+i, y+j))
- continue;
-
- const dungeon_feature_type feat2 = grd[x+i][y+j];
-
- if (feat2 == DNGN_FLOOR
- || feat2 == DNGN_UNDISCOVERED_TRAP)
- {
- env.grid_colours[x+i][y+j] = colour;
- }
- }
+ for (int j = -1; j <= 1; j++)
+ {
+ if (!map_bounds(x+i, y+j))
+ continue;
+
+ const dungeon_feature_type feat2 = grd[x+i][y+j];
+
+ if (feat2 == DNGN_FLOOR
+ || feat2 == DNGN_UNDISCOVERED_TRAP)
+ {
+ env.grid_colours[x+i][y+j] = colour;
+ }
+ }
}
}
-
+
#ifdef USE_TILE
unsigned int tile = _get_tile_idx(ls, 3);
if (!tile)
@@ -1840,10 +1585,10 @@ static int dgn_floor_halo(lua_State *ls)
luaL_argerror(ls, 3, error.c_str());
return (0);
}
-
+
tile_floor_halo(target, tile);
#endif
-
+
return (0);
}
@@ -1854,12 +1599,12 @@ static int dgn_random_walk(lua_State *ls)
const int x = luaL_checkint(ls, 1);
const int y = luaL_checkint(ls, 2);
const int dist = luaL_checkint(ls, 3);
-
+
// Fourth param being true means that we can move past
// statues.
const dungeon_feature_type minmove =
- lua_isnil(ls, 4) ? DNGN_MINMOVE : DNGN_ORCISH_IDOL;
-
+ lua_isnil(ls, 4) ? DNGN_MINMOVE : DNGN_ORCISH_IDOL;
+
if (!in_bounds(x, y))
{
char buf[80];
@@ -1872,13 +1617,13 @@ static int dgn_random_walk(lua_State *ls)
luaL_argerror(ls, 3, "Distance must be positive.");
return (0);
}
-
+
float dist_left = dist;
// Allow movement to all 8 adjacent squares if distance is 1
// (needed since diagonal moves are distance sqrt(2))
if (dist == 1)
dist_left = (float)SQRT_2;
-
+
int moves_left = dist;
coord_def pos(x, y);
while (dist_left >= 1.0 && moves_left-- > 0)
@@ -1889,7 +1634,7 @@ static int dgn_random_walk(lua_State *ls)
{
const coord_def new_pos = pos + Compass[j];
const float move_dist = (j % 2 == 0) ? 1.0 : SQRT_2;
-
+
if (in_bounds(new_pos) && grd(new_pos) >= minmove
&& move_dist <= dist_left)
{
@@ -1897,35 +1642,35 @@ static int dgn_random_walk(lua_State *ls)
dir = j;
}
}
-
+
if (okay_dirs == 0)
break;
-
+
if (one_chance_in(++okay_dirs))
continue;
-
+
pos += Compass[dir];
dist_left -= (dir % 2 == 0) ? 1.0 : SQRT_2;
}
-
+
dlua_push_coord(ls, pos);
-
+
return (2);
}
static cloud_type dgn_cloud_name_to_type(std::string name)
{
lowercase(name);
-
+
if (name == "random")
return (CLOUD_RANDOM);
else if (name == "debugging")
return (CLOUD_DEBUGGING);
-
+
for (int i = CLOUD_NONE; i < CLOUD_RANDOM; i++)
if (cloud_name(static_cast<cloud_type>(i)) == name)
return static_cast<cloud_type>(i);
-
+
return (CLOUD_NONE);
}
@@ -1933,9 +1678,9 @@ static kill_category dgn_kill_name_to_category(std::string name)
{
if (name.empty())
return KC_OTHER;
-
+
lowercase(name);
-
+
if (name == "you")
return KC_YOU;
else if (name == "friendly")
@@ -1955,7 +1700,7 @@ static int make_a_lua_cloud(coord_def where, int garbage, int spread_rate,
killer_type killer)
{
UNUSED( garbage );
-
+
const int pow = random_range(lua_cloud_pow_min,
lua_cloud_pow_max,
lua_cloud_pow_rolls);
@@ -1971,14 +1716,14 @@ static int dgn_apply_area_cloud(lua_State *ls)
lua_cloud_pow_max = luaL_checkint(ls, 4);
lua_cloud_pow_rolls = luaL_checkint(ls, 5);
const int size = luaL_checkint(ls, 6);
-
+
const cloud_type ctype = dgn_cloud_name_to_type(luaL_checkstring(ls, 7));
const char* kname = lua_isstring(ls, 8) ? luaL_checkstring(ls, 8)
- : "";
+ : "";
const kill_category kc = dgn_kill_name_to_category(kname);
-
+
const int spread_rate = lua_isnumber(ls, 9) ? luaL_checkint(ls, 9) : -1;
-
+
if (!in_bounds(x, y))
{
char buf[80];
@@ -1986,37 +1731,37 @@ static int dgn_apply_area_cloud(lua_State *ls)
luaL_argerror(ls, 1, buf);
return (0);
}
-
+
if (lua_cloud_pow_min < 0)
{
luaL_argerror(ls, 4, "pow_min must be non-negative");
return (0);
}
-
+
if (lua_cloud_pow_max < lua_cloud_pow_min)
{
luaL_argerror(ls, 5, "pow_max must not be less than pow_min");
return (0);
}
-
+
if (lua_cloud_pow_max == 0)
{
luaL_argerror(ls, 5, "pow_max must be positive");
return (0);
}
-
+
if (lua_cloud_pow_rolls <= 0)
{
luaL_argerror(ls, 6, "pow_rolls must be positive");
return (0);
}
-
+
if (size < 1)
{
luaL_argerror(ls, 4, "size must be positive.");
return (0);
}
-
+
if (ctype == CLOUD_NONE)
{
std::string error = "Invalid cloud type '";
@@ -2025,7 +1770,7 @@ static int dgn_apply_area_cloud(lua_State *ls)
luaL_argerror(ls, 7, error.c_str());
return (0);
}
-
+
if (kc == KC_NCATEGORIES)
{
std::string error = "Invalid kill category '";
@@ -2034,18 +1779,18 @@ static int dgn_apply_area_cloud(lua_State *ls)
luaL_argerror(ls, 8, error.c_str());
return (0);
}
-
+
if (spread_rate < -1 || spread_rate > 100)
{
luaL_argerror(ls, 9, "spread_rate must be between -1 and 100,"
"inclusive");
return (0);
}
-
+
apply_area_cloud(make_a_lua_cloud, coord_def(x, y), 0, size,
ctype, kc, cloud_struct::whose_to_killer(kc),
spread_rate);
-
+
return (0);
}
@@ -2060,10 +1805,10 @@ static void _clamp_to_bounds(int &x, int &y, bool edge_ok = false)
static int dgn_grd_table(lua_State *ls)
{
MAP(ls, 1, map);
-
+
map_def **mapref = clua_new_userdata<map_def *>(ls, GRD_METATABLE);
*mapref = map;
-
+
return (1);
}
@@ -2090,18 +1835,18 @@ static int dgn_fill_area(lua_State *ls)
int x2 = luaL_checkint(ls, 3);
int y2 = luaL_checkint(ls, 4);
dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
+
_clamp_to_bounds(x1, y1);
_clamp_to_bounds(x2, y2);
if (x2 < x1)
std::swap(x1, x2);
if (y2 < y1)
std::swap(y1, y2);
-
+
for (int y = y1; y <= y2; y++)
for (int x = x1; x <= x2; x++)
grd[x][y] = feat;
-
+
return 0;
}
@@ -2113,7 +1858,7 @@ static int dgn_replace_area(lua_State *ls)
int y2 = luaL_checkint(ls, 4);
dungeon_feature_type search = _check_lua_feature(ls, 5);
dungeon_feature_type replace = _check_lua_feature(ls, 6);
-
+
// gracefully handle out of bound areas by truncating them.
_clamp_to_bounds(x1, y1);
_clamp_to_bounds(x2, y2);
@@ -2121,12 +1866,12 @@ static int dgn_replace_area(lua_State *ls)
std::swap(x1, x2);
if (y2 < y1)
std::swap(y1, y2);
-
+
for (int y = y1; y <= y2; y++)
for (int x = x1; x <= x2; x++)
if (grd[x][y] == search)
grd[x][y] = replace;
-
+
return 0;
}
@@ -2138,15 +1883,15 @@ static int dgn_octa_room(lua_State *ls)
int y2 = luaL_checkint(ls, 4);
int oblique = luaL_checkint(ls, 5);
dungeon_feature_type fill = _check_lua_feature(ls, 6);
-
+
spec_room sr;
sr.tl.x = x1;
sr.br.x = x2;
sr.tl.y = y1;
sr.br.y = y2;
-
+
octa_room(sr, oblique, fill);
-
+
return 0;
}
@@ -2159,7 +1904,7 @@ static int dgn_make_pillars(lua_State *ls)
int big_radius = luaL_checkint(ls, 5);
int pillar_radius = luaL_checkint(ls, 6);
dungeon_feature_type fill = _check_lua_feature(ls, 8);
-
+
// [enne] The underscore is for DJGPP's brain damage.
const float _PI = 3.14159265f;
for (int n = 0; n < num; n++)
@@ -2167,16 +1912,16 @@ static int dgn_make_pillars(lua_State *ls)
float angle = n * 2 * _PI / (float)num;
int x = (int)std::floor(std::cos(angle) * big_radius * scale_x + 0.5f);
int y = (int)std::floor(std::sin(angle) * big_radius + 0.5f);
-
+
lua_pushvalue(ls, 7);
lua_pushnumber(ls, center_x + x);
lua_pushnumber(ls, center_y + y);
lua_pushnumber(ls, pillar_radius);
lua_pushnumber(ls, fill);
-
+
lua_call(ls, 4, 0);
}
-
+
return 0;
}
@@ -2186,11 +1931,11 @@ static int dgn_make_square(lua_State *ls)
int center_y = luaL_checkint(ls, 2);
int radius = std::abs(luaL_checkint(ls, 3));
dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
+
for (int x = -radius; x <= radius; x++)
for (int y = -radius; y <= radius; y++)
grd[center_x + x][center_y + y] = fill;
-
+
return 0;
}
@@ -2200,12 +1945,12 @@ static int dgn_make_rounded_square(lua_State *ls)
int center_y = luaL_checkint(ls, 2);
int radius = std::abs(luaL_checkint(ls, 3));
dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
+
for (int x = -radius; x <= radius; x++)
for (int y = -radius; y <= radius; y++)
if (std::abs(x) != radius || std::abs(y) != radius)
grd[center_x + x][center_y + y] = fill;
-
+
return 0;
}
@@ -2215,12 +1960,12 @@ static int dgn_make_circle(lua_State *ls)
int center_y = luaL_checkint(ls, 2);
int radius = std::abs(luaL_checkint(ls, 3));
dungeon_feature_type fill = _check_lua_feature(ls, 4);
-
+
for (int x = -radius; x <= radius; x++)
for (int y = -radius; y <= radius; y++)
if (x * x + y * y < radius * radius)
grd[center_x + x][center_y + y] = fill;
-
+
return 0;
}
@@ -2228,7 +1973,7 @@ static int dgn_in_bounds(lua_State *ls)
{
int x = luaL_checkint(ls, 1);
int y = luaL_checkint(ls, 2);
-
+
lua_pushboolean(ls, in_bounds(x, y));
return 1;
}
@@ -2241,7 +1986,7 @@ static int dgn_replace_first(lua_State *ls)
int dy = luaL_checkint(ls, 4);
dungeon_feature_type search = _check_lua_feature(ls, 5);
dungeon_feature_type replace = _check_lua_feature(ls, 6);
-
+
_clamp_to_bounds(x, y);
bool found = false;
while (in_bounds(x, y))
@@ -2252,11 +1997,11 @@ static int dgn_replace_first(lua_State *ls)
found = true;
break;
}
-
+
x += dx;
y += dy;
}
-
+
lua_pushboolean(ls, found);
return 1;
}
@@ -2265,7 +2010,7 @@ static int dgn_replace_random(lua_State *ls)
{
dungeon_feature_type search = _check_lua_feature(ls, 1);
dungeon_feature_type replace = _check_lua_feature(ls, 2);
-
+
int x, y;
do
{
@@ -2273,9 +2018,9 @@ static int dgn_replace_random(lua_State *ls)
y = random2(GYM);
}
while (grd[x][y] != search);
-
+
grd[x][y] = replace;
-
+
return 0;
}
@@ -2284,7 +2029,7 @@ static int dgn_spotty_level(lua_State *ls)
bool seeded = lua_toboolean(ls, 1);
int iterations = luaL_checkint(ls, 2);
bool boxy = lua_toboolean(ls, 3);
-
+
spotty_level(seeded, iterations, boxy);
return 0;
}
@@ -2294,17 +2039,17 @@ static int dgn_smear_feature(lua_State *ls)
int iterations = luaL_checkint(ls, 1);
bool boxy = lua_toboolean(ls, 2);
dungeon_feature_type feat = _check_lua_feature(ls, 3);
-
+
int x1 = luaL_checkint(ls, 4);
int y1 = luaL_checkint(ls, 5);
int x2 = luaL_checkint(ls, 6);
int y2 = luaL_checkint(ls, 7);
-
+
_clamp_to_bounds(x1, y1, true);
_clamp_to_bounds(x2, y2, true);
-
+
smear_feature(iterations, boxy, feat, x1, y1, x2, y2);
-
+
return 0;
}
@@ -2315,7 +2060,7 @@ static int dgn_count_feature_in_box(lua_State *ls)
int x2 = luaL_checkint(ls, 3);
int y2 = luaL_checkint(ls, 4);
dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
+
lua_pushnumber(ls, count_feature_in_box(x1, y1, x2, y2, feat));
return 1;
}
@@ -2327,7 +2072,7 @@ static int dgn_count_antifeature_in_box(lua_State *ls)
int x2 = luaL_checkint(ls, 3);
int y2 = luaL_checkint(ls, 4);
dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
+
lua_pushnumber(ls, count_antifeature_in_box(x1, y1, x2, y2, feat));
return 1;
}
@@ -2337,7 +2082,7 @@ static int dgn_count_neighbours(lua_State *ls)
int x = luaL_checkint(ls, 1);
int y = luaL_checkint(ls, 2);
dungeon_feature_type feat = _check_lua_feature(ls, 3);
-
+
lua_pushnumber(ls, count_neighbours(x, y, feat));
return 1;
}
@@ -2351,13 +2096,13 @@ static int dgn_join_the_dots(lua_State *ls)
// TODO enne - push map masks to lua?
unsigned map_mask = MMT_VAULT;
bool early_exit = lua_toboolean(ls, 5);
-
+
coord_def from(from_x, from_y);
coord_def to(to_x, to_y);
-
+
bool ret = join_the_dots(from, to, map_mask, early_exit);
lua_pushboolean(ls, ret);
-
+
return 1;
}
@@ -2367,11 +2112,11 @@ static int dgn_fill_disconnected_zones(lua_State *ls)
int from_y = luaL_checkint(ls, 2);
int to_x = luaL_checkint(ls, 3);
int to_y = luaL_checkint(ls, 4);
-
+
dungeon_feature_type feat = _check_lua_feature(ls, 5);
-
+
process_disconnected_zones(from_x, from_y, to_x, to_y, true, feat);
-
+
return 0;
}
@@ -2402,7 +2147,7 @@ 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;
@@ -2413,7 +2158,7 @@ static int dgn_register_lua_marker(lua_State *ls)
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)
{
@@ -2449,11 +2194,11 @@ 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;
-
+ lua_isnumber(ls, 4) ? lua_tointeger(ls, 4) : you.your_level;
+
dgn_place_multiple_items(ilist, c, level);
link_items();
return (0);
@@ -2469,28 +2214,28 @@ static bool _lua_map_place_valid(const map_def &map,
mprf(MSGCH_DIAGNOSTICS, "lua_map_place_invalid: (%d,%d) (%d,%d)",
c.x, c.y, size.x, size.y);
#endif
-
+
lua_stack_cleaner clean(_dgn_map_safe_bounds_fn->lua);
-
+
// Push the Lua function onto the stack.
_dgn_map_safe_bounds_fn->push();
-
+
lua_State *ls = _dgn_map_safe_bounds_fn->lua;
-
+
// Push map, pos.x, pos.y, size.x, size.y
clua_push_map(ls, const_cast<map_def*>(&map));
clua_push_coord(ls, c);
clua_push_coord(ls, size);
-
+
const int err = lua_pcall(ls, 5, 1, 0);
-
+
// Lua error invalidates place.
if (err)
{
mprf(MSGCH_ERROR, "Lua error: %s", lua_tostring(ls, -1));
return (true);
}
-
+
return (lua_toboolean(ls, -1));
}
@@ -2499,30 +2244,30 @@ LUAFN(dgn_with_map_bounds_fn)
CLua &vm(CLua::get_vm(ls));
if (lua_gettop(ls) != 2 || !lua_isfunction(ls, 1) || !lua_isfunction(ls, 2))
luaL_error(ls, "Expected map-bounds check fn and action fn.");
-
+
_dgn_map_safe_bounds_fn.reset(new lua_datum(vm, 1, false));
-
+
int err = 0;
{
unwind_var<map_place_check_t> mpc(map_place_valid,
_lua_map_place_valid);
-
+
// All set, call our friend, the second function.
ASSERT(lua_isfunction(ls, -1));
-
+
// Copy the function since pcall will pop it off.
lua_pushvalue(ls, -1);
-
+
// Use pcall to catch the error here, else unwind_var won't
// happen when lua_call does its longjmp.
err = lua_pcall(ls, 0, 1, 0);
-
+
_dgn_map_safe_bounds_fn.reset(NULL);
}
-
+
if (err)
lua_error(ls);
-
+
return (1);
}
@@ -2535,20 +2280,20 @@ LUAFN(dgn_with_map_anchors)
int err = 0;
{
unwind_var<point_vector> uanchor(map_anchor_points);
-
+
map_anchor_points.clear();
-
+
int i;
for (i = 1; i < top; i += 2)
{
if (lua_isnumber(ls, i) && lua_isnumber(ls, i + 1))
map_anchor_points.push_back(
- coord_def( lua_tointeger(ls, i),
- lua_tointeger(ls, i + 1) ) );
+ coord_def( lua_tointeger(ls, i),
+ lua_tointeger(ls, i + 1) ) );
}
-
+
ASSERT(lua_isfunction(ls, -1));
-
+
lua_pushvalue(ls, -1);
err = lua_pcall(ls, 0, 1, 0);
}
@@ -2558,17 +2303,17 @@ LUAFN(dgn_with_map_anchors)
}
#define BRANCH(br, pos) \
- const char *branch_name = luaL_checkstring(ls, pos); \
- branch_type req_branch_type = str_to_branch(branch_name); \
- if (req_branch_type == NUM_BRANCHES) \
- luaL_error(ls, "Expected branch name"); \
- Branch &br = branches[req_branch_type]
+const char *branch_name = luaL_checkstring(ls, pos); \
+branch_type req_branch_type = str_to_branch(branch_name); \
+if (req_branch_type == NUM_BRANCHES) \
+luaL_error(ls, "Expected branch name"); \
+Branch &br = branches[req_branch_type]
#define BRANCHFN(name, type, expr) \
- LUAFN(dgn_br_##name) { \
- BRANCH(br, 1); \
- PLUARET(type, expr); \
- }
+LUAFN(dgn_br_##name) { \
+BRANCH(br, 1); \
+PLUARET(type, expr); \
+}
BRANCHFN(floorcol, number, br.floor_colour)
BRANCHFN(rockcol, number, br.rock_colour)
@@ -2579,21 +2324,21 @@ BRANCHFN(parent_branch, string,
: branches[br.parent_branch].abbrevname)
#define LEVEL(lev, br, pos) \
- const char *level_name = luaL_checkstring(ls, pos); \
- level_area_type lev = str_to_level_area_type(level_name); \
- if (lev == NUM_LEVEL_AREA_TYPES) \
- luaL_error(ls, "Expected level name"); \
- const char *branch_name = luaL_checkstring(ls, pos); \
- branch_type br = str_to_branch(branch_name); \
- if (lev == LEVEL_DUNGEON && br == NUM_BRANCHES) \
- luaL_error(ls, "Expected branch name");
+const char *level_name = luaL_checkstring(ls, pos); \
+level_area_type lev = str_to_level_area_type(level_name); \
+if (lev == NUM_LEVEL_AREA_TYPES) \
+luaL_error(ls, "Expected level name"); \
+const char *branch_name = luaL_checkstring(ls, pos); \
+branch_type br = str_to_branch(branch_name); \
+if (lev == LEVEL_DUNGEON && br == NUM_BRANCHES) \
+luaL_error(ls, "Expected branch name");
static void push_level_id(lua_State *ls, const level_id &lid)
{
// We're skipping the constructor; naughty, but level_id has no
// virtual methods and no dynamically allocated memory.
level_id *nlev =
- static_cast<level_id*>(lua_newuserdata(ls, sizeof(level_id)));
+ static_cast<level_id*>(lua_newuserdata(ls, sizeof(level_id)));
*nlev = lid;
}
@@ -2616,7 +2361,7 @@ static level_id _lua_level_id(lua_State *ls, int ndx)
const level_id *lid = static_cast<level_id*>(lua_touserdata(ls, ndx));
return (*lid);
}
-
+
luaL_argerror(ls, ndx, "Expected level_id");
// Never gets here.
return level_id();
@@ -2646,15 +2391,15 @@ LUAFN(dgn_set_level_type_name)
luaL_error(ls, "Can only set level type name on portal vaults");
return(0);
}
-
+
if (!lua_isstring(ls, 1))
{
luaL_argerror(ls, 1, "Expected string for level type name");
return(0);
}
-
+
you.level_type_name = luaL_checkstring(ls, 1);
-
+
return(0);
}
@@ -2663,19 +2408,19 @@ LUAFN(dgn_set_level_type_name_abbrev)
if (you.level_type != LEVEL_PORTAL_VAULT)
{
luaL_error(ls, "Can only set level type name abbreviation on "
- "portal vaults");
+ "portal vaults");
return(0);
}
-
+
if (!lua_isstring(ls, 1))
{
luaL_argerror(ls, 1, "Expected string for level type name "
- "abbreviation");
+ "abbreviation");
return(0);
}
-
+
you.level_type_name_abbrev = luaL_checkstring(ls, 1);
-
+
return(0);
}
@@ -2686,15 +2431,15 @@ LUAFN(dgn_set_level_type_origin)
luaL_error(ls, "Can only set level type origin on portal vaults");
return(0);
}
-
+
if (!lua_isstring(ls, 1))
{
luaL_argerror(ls, 1, "Expected string for level type origin");
return(0);
}
-
+
you.level_type_origin = luaL_checkstring(ls, 1);
-
+
return(0);
}
@@ -2761,7 +2506,7 @@ LUAFN(_dgn_find_marker_prop)
{
const char *prop = luaL_checkstring(ls, 1);
const std::string value(
- lua_gettop(ls) >= 2 ? luaL_checkstring(ls, 2) : "");
+ lua_gettop(ls) >= 2 ? luaL_checkstring(ls, 2) : "");
const coord_def place = find_marker_prop(prop, value);
if (map_bounds(place))
clua_push_coord(ls, place);
@@ -2778,17 +2523,17 @@ extern int lua_special_room_level;
LUAFN(dgn_get_special_room_info)
{
- if (!lua_special_room_spec.created || !in_bounds(lua_special_room_spec.tl)
- || lua_special_room_level == -1)
- {
- return (0);
- }
-
- lua_pushnumber(ls, lua_special_room_level);
- dlua_push_coord(ls, lua_special_room_spec.tl);
- dlua_push_coord(ls, lua_special_room_spec.br);
-
- return (5);
+ if (!lua_special_room_spec.created || !in_bounds(lua_special_room_spec.tl)
+ || lua_special_room_level == -1)
+ {
+ return (0);
+ }
+
+ lua_pushnumber(ls, lua_special_room_level);
+ dlua_push_coord(ls, lua_special_room_spec.tl);
+ dlua_push_coord(ls, lua_special_room_spec.br);
+
+ return (5);
}
LUAFN(_dgn_resolve_map)
@@ -2798,16 +2543,16 @@ LUAFN(_dgn_resolve_map)
lua_pushnil(ls);
return (1);
}
-
+
MAP(ls, 1, map);
const bool check_collisions = _lua_boolean(ls, 2, true);
-
+
// Save the vault_placement into Temp_Vaults because the map_def
// will need to be alive through to the end of dungeon gen.
Temp_Vaults.push_back(vault_placement());
-
+
vault_placement &place(Temp_Vaults[Temp_Vaults.size() - 1]);
-
+
if (vault_main(place, map, check_collisions) != MAP_NONE)
{
clua_push_map(ls, &place.map);
@@ -2825,36 +2570,36 @@ LUAFN(_dgn_reuse_map)
{
if (!lua_isuserdata(ls, 1))
luaL_argerror(ls, 1, "Expected vault_placement");
-
+
vault_placement &vp(
- *static_cast<vault_placement*>(lua_touserdata(ls, 1)));
-
+ *static_cast<vault_placement*>(lua_touserdata(ls, 1)));
+
COORDS(place, 2, 3);
-
+
const bool flip_horiz = _lua_boolean(ls, 4, false);
const bool flip_vert = _lua_boolean(ls, 5, false);
-
+
// 1 for clockwise, -1 for anticlockwise, 0 for no rotation.
const int rotate_dir = lua_isnone(ls, 6) ? 0 : luaL_checkint(ls, 6);
-
+
const bool register_place = _lua_boolean(ls, 7, true);
const bool register_vault = register_place && _lua_boolean(ls, 8, false);
-
+
if (flip_horiz)
vp.map.hmirror();
if (flip_vert)
vp.map.vmirror();
if (rotate_dir)
vp.map.rotate(rotate_dir == 1);
-
+
vp.size = vp.map.map.size();
-
+
// draw_at changes vault_placement.
vp.draw_at(place);
-
+
if (register_place)
dgn_register_place(vp, register_vault);
-
+
return (0);
}
@@ -2862,10 +2607,10 @@ LUAFN(dgn_lev_floortile)
{
#ifdef USE_TILE
LEVEL(lev, br, 1);
-
+
tile_flavour flv;
tile_default_flv(lev, br, flv);
-
+
const char *tile_name = tile_dngn_name(flv.floor);
PLUARET(string, tile_name);
#else
@@ -2877,10 +2622,10 @@ LUAFN(dgn_lev_rocktile)
{
#ifdef USE_TILE
LEVEL(lev, br, 1);
-
+
tile_flavour flv;
tile_default_flv(lev, br, flv);
-
+
const char *tile_name = tile_dngn_name(flv.wall);
PLUARET(string, tile_name);
#else
@@ -2891,11 +2636,11 @@ LUAFN(dgn_lev_rocktile)
LUAFN(dgn_lrocktile)
{
MAP(ls, 1, map);
-
+
#ifdef USE_TILE
unsigned short tile = _get_tile_idx(ls, 2);
map->rock_tile = tile;
-
+
const char *tile_name = tile_dngn_name(tile);
PLUARET(string, tile_name);
#else
@@ -2907,11 +2652,11 @@ LUAFN(dgn_lrocktile)
LUAFN(dgn_lfloortile)
{
MAP(ls, 1, map);
-
+
#ifdef USE_TILE
unsigned short tile = _get_tile_idx(ls, 2);
map->floor_tile = tile;
-
+
const char *tile_name = tile_dngn_name(tile);
PLUARET(string, tile_name);
#else
@@ -2926,7 +2671,7 @@ LUAFN(dgn_change_rock_tile)
unsigned short tile = _get_tile_idx(ls, 1);
if (tile)
env.tile_default.wall = tile;
-
+
const char *tile_name = tile_dngn_name(tile);
PLUARET(string, tile_name);
#else
@@ -2940,7 +2685,7 @@ LUAFN(dgn_change_floor_tile)
unsigned short tile = _get_tile_idx(ls, 1);
if (tile)
env.tile_default.floor = tile;
-
+
const char *tile_name = tile_dngn_name(tile);
PLUARET(string, tile_name);
#else
@@ -2991,809 +2736,158 @@ LUAFN(dgn_dismiss_monsters)
LUAWRAP(_dgn_reset_level, dgn_reset_level())
-static const struct luaL_reg dgn_lib[] =
-{
- { "dbg_goto_place", dgn_dbg_goto_place },
- { "dbg_flush_map_memory", dgn_dbg_flush_map_memory },
- { "dbg_generate_level", dgn_dbg_generate_level },
- { "dbg_dump_map", dgn_dbg_dump_map },
- { "dbg_test_explore", dgn_dbg_test_explore },
-
- { "reset_level", _dgn_reset_level },
- { "dismiss_monsters", dgn_dismiss_monsters },
-
- { "default_depth", dgn_default_depth },
- { "name", dgn_name },
- { "depth", dgn_depth },
- { "place", dgn_place },
- { "tags", dgn_tags },
- { "tags_remove", dgn_tags_remove },
- { "lflags", dgn_lflags },
- { "bflags", dgn_bflags },
- { "chance", dgn_chance },
- { "weight", dgn_weight },
- { "welcome", dgn_welcome },
- { "orient", dgn_orient },
- { "shuffle", dgn_shuffle },
- { "subst", dgn_subst },
- { "nsubst", dgn_nsubst },
- { "colour", dgn_colour },
- { "lfloorcol", dgn_lfloorcol},
- { "lrockcol", dgn_lrockcol},
- { "normalise", dgn_normalise },
- { "map", dgn_map },
- { "mons", dgn_mons },
- { "item", dgn_item },
- { "marker", dgn_marker },
- { "lua_marker", dgn_lua_marker },
- { "kfeat", dgn_kfeat },
- { "kitem", dgn_kitem },
- { "kmons", dgn_kmons },
- { "kmask", dgn_kmask },
- { "mapsize", dgn_map_size },
-
- { "grid", dgn_grid },
- { "is_wall", _dgn_is_wall },
- { "max_bounds", dgn_max_bounds },
- { "colour_at", dgn_colour_at },
-
- { "terrain_changed", dgn_terrain_changed },
- { "points_connected", dgn_points_connected },
- { "any_point_connected", dgn_any_point_connected },
- { "has_exit_from", dgn_has_exit_from },
- { "gly_point", dgn_gly_point },
- { "gly_points", dgn_gly_points },
- { "original_map", dgn_original_map },
- { "load_des_file", dgn_load_des_file },
- { "feature_number", dgn_feature_number },
- { "feature_name", dgn_feature_name },
- { "dgn_event_type", dgn_dgn_event },
- { "register_listener", dgn_register_listener },
- { "remove_listener", dgn_remove_listener },
- { "remove_marker", dgn_remove_marker },
- { "num_matching_markers", dgn_num_matching_markers },
- { "feature_desc", dgn_feature_desc },
- { "feature_desc_at", dgn_feature_desc_at },
- { "set_feature_desc_short", dgn_set_feature_desc_short },
- { "set_feature_desc_long", dgn_set_feature_desc_long },
- { "item_from_index", dgn_item_from_index },
- { "mons_from_index", dgn_mons_from_index },
- { "mons_at", dgn_mons_at },
- { "items_at", dgn_items_at },
- { "change_level_flags", dgn_change_level_flags },
- { "change_branch_flags", dgn_change_branch_flags },
- { "set_random_mon_list", dgn_set_random_mon_list },
- { "get_floor_colour", dgn_get_floor_colour },
- { "get_rock_colour", dgn_get_rock_colour },
- { "change_floor_colour", dgn_change_floor_colour },
- { "change_rock_colour", dgn_change_rock_colour },
- { "set_lt_callback", lua_dgn_set_lt_callback },
- { "fixup_stairs", dgn_fixup_stairs },
- { "floor_halo", dgn_floor_halo },
- { "random_walk", dgn_random_walk },
- { "apply_area_cloud", dgn_apply_area_cloud },
-
- // building routines
- { "grd_table", dgn_grd_table },
- { "width", dgn_width },
- { "height", dgn_height },
- { "fill_area", dgn_fill_area },
- { "replace_area", dgn_replace_area },
- { "octa_room", dgn_octa_room },
- { "make_pillars", dgn_make_pillars },
- { "make_square", dgn_make_square },
- { "make_rounded_square", dgn_make_rounded_square },
- { "make_circle", dgn_make_circle },
- { "in_bounds", dgn_in_bounds },
- { "replace_first", dgn_replace_first },
- { "replace_random", dgn_replace_random },
- { "spotty_level", dgn_spotty_level },
- { "smear_feature", dgn_smear_feature },
- { "count_feature_in_box", dgn_count_feature_in_box },
- { "count_antifeature_in_box", dgn_count_antifeature_in_box },
- { "count_neighbours", dgn_count_neighbours },
- { "join_the_dots", dgn_join_the_dots },
- { "fill_disconnected_zones", dgn_fill_disconnected_zones },
-
- { "is_opaque", _dgn_is_opaque },
- { "is_passable", _dgn_is_passable },
-
- { "register_feature_marker", dgn_register_feature_marker },
- { "register_lua_marker", dgn_register_lua_marker },
-
- { "create_monster", dgn_create_monster },
- { "create_item", dgn_create_item },
-
- { "monster_spec", _dgn_monster_spec },
- { "item_spec", _dgn_item_spec },
-
- { "max_monsters", _dgn_max_monsters },
-
- { "with_map_bounds_fn", dgn_with_map_bounds_fn },
- { "with_map_anchors", dgn_with_map_anchors },
-
- { "br_floorcol", dgn_br_floorcol },
- { "br_rockcol", dgn_br_rockcol },
- { "br_has_shops", dgn_br_has_shops },
- { "br_has_uniques", dgn_br_has_uniques },
- { "br_parent_branch", dgn_br_parent_branch },
-
- { "level_id", dgn_level_id },
- { "level_name", dgn_level_name },
- { "set_level_type_name", dgn_set_level_type_name },
- { "set_level_type_name_abbrev", dgn_set_level_type_name_abbrev },
- { "set_level_type_origin", dgn_set_level_type_origin },
- { "map_by_tag", dgn_map_by_tag },
- { "map_in_depth", dgn_map_in_depth },
- { "map_by_place", dgn_map_by_place },
- { "place_map", _dgn_place_map },
- { "reuse_map", _dgn_reuse_map },
- { "resolve_map", _dgn_resolve_map },
- { "in_vault", _dgn_in_vault },
-
- { "find_marker_prop", _dgn_find_marker_prop },
-
- { "get_special_room_info", dgn_get_special_room_info },
-
- { "lrocktile", dgn_lrocktile },
- { "lfloortile", dgn_lfloortile },
- { "rtile", dgn_rtile },
- { "ftile", dgn_ftile },
- { "change_rock_tile", dgn_change_rock_tile },
- { "change_floor_tile", dgn_change_floor_tile },
- { "lev_floortile", dgn_lev_floortile },
- { "lev_rocktile", dgn_lev_rocktile },
-
- { NULL, NULL }
-};
-
-LUAFN(_crawl_args)
-{
- return dlua_stringtable(ls, SysEnv.cmd_args);
-}
-
-LUAFN(_crawl_milestone)
-{
-#ifdef DGL_MILESTONES
- mark_milestone(luaL_checkstring(ls, 1),
- luaL_checkstring(ls, 2));
-#endif
- return (0);
-}
-
-LUAFN(_crawl_redraw_view)
-{
- viewwindow(true, false);
- return (0);
-}
-
-#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 const struct luaL_reg crawl_lib[] =
-{
- { "args", _crawl_args },
- { "mark_milestone", _crawl_milestone },
- { "redraw_view", _crawl_redraw_view },
-#ifdef UNIX
- { "millis", _crawl_millis },
-#endif
- { NULL, NULL }
+const struct luaL_reg dgn_lib[] =
+{
+{ "dbg_goto_place", dgn_dbg_goto_place },
+{ "dbg_flush_map_memory", dgn_dbg_flush_map_memory },
+{ "dbg_generate_level", dgn_dbg_generate_level },
+{ "dbg_dump_map", dgn_dbg_dump_map },
+{ "dbg_test_explore", dgn_dbg_test_explore },
+
+{ "reset_level", _dgn_reset_level },
+{ "dismiss_monsters", dgn_dismiss_monsters },
+
+{ "default_depth", dgn_default_depth },
+{ "name", dgn_name },
+{ "depth", dgn_depth },
+{ "place", dgn_place },
+{ "tags", dgn_tags },
+{ "tags_remove", dgn_tags_remove },
+{ "lflags", dgn_lflags },
+{ "bflags", dgn_bflags },
+{ "chance", dgn_chance },
+{ "weight", dgn_weight },
+{ "welcome", dgn_welcome },
+{ "orient", dgn_orient },
+{ "shuffle", dgn_shuffle },
+{ "subst", dgn_subst },
+{ "nsubst", dgn_nsubst },
+{ "colour", dgn_colour },
+{ "lfloorcol", dgn_lfloorcol},
+{ "lrockcol", dgn_lrockcol},
+{ "normalise", dgn_normalise },
+{ "map", dgn_map },
+{ "mons", dgn_mons },
+{ "item", dgn_item },
+{ "marker", dgn_marker },
+{ "lua_marker", dgn_lua_marker },
+{ "kfeat", dgn_kfeat },
+{ "kitem", dgn_kitem },
+{ "kmons", dgn_kmons },
+{ "kmask", dgn_kmask },
+{ "mapsize", dgn_map_size },
+
+{ "grid", dgn_grid },
+{ "is_wall", _dgn_is_wall },
+{ "max_bounds", dgn_max_bounds },
+{ "colour_at", dgn_colour_at },
+
+{ "terrain_changed", dgn_terrain_changed },
+{ "points_connected", dgn_points_connected },
+{ "any_point_connected", dgn_any_point_connected },
+{ "has_exit_from", dgn_has_exit_from },
+{ "gly_point", dgn_gly_point },
+{ "gly_points", dgn_gly_points },
+{ "original_map", dgn_original_map },
+{ "load_des_file", dgn_load_des_file },
+{ "feature_number", dgn_feature_number },
+{ "feature_name", dgn_feature_name },
+{ "dgn_event_type", dgn_dgn_event },
+{ "register_listener", dgn_register_listener },
+{ "remove_listener", dgn_remove_listener },
+{ "remove_marker", dgn_remove_marker },
+{ "num_matching_markers", dgn_num_matching_markers },
+{ "feature_desc", dgn_feature_desc },
+{ "feature_desc_at", dgn_feature_desc_at },
+{ "set_feature_desc_short", dgn_set_feature_desc_short },
+{ "set_feature_desc_long", dgn_set_feature_desc_long },
+{ "item_from_index", dgn_item_from_index },
+{ "mons_from_index", dgn_mons_from_index },
+{ "mons_at", dgn_mons_at },
+{ "items_at", dgn_items_at },
+{ "change_level_flags", dgn_change_level_flags },
+{ "change_branch_flags", dgn_change_branch_flags },
+{ "set_random_mon_list", dgn_set_random_mon_list },
+{ "get_floor_colour", dgn_get_floor_colour },
+{ "get_rock_colour", dgn_get_rock_colour },
+{ "change_floor_colour", dgn_change_floor_colour },
+{ "change_rock_colour", dgn_change_rock_colour },
+{ "set_lt_callback", lua_dgn_set_lt_callback },
+{ "fixup_stairs", dgn_fixup_stairs },
+{ "floor_halo", dgn_floor_halo },
+{ "random_walk", dgn_random_walk },
+{ "apply_area_cloud", dgn_apply_area_cloud },
+
+// building routines
+{ "grd_table", dgn_grd_table },
+{ "width", dgn_width },
+{ "height", dgn_height },
+{ "fill_area", dgn_fill_area },
+{ "replace_area", dgn_replace_area },
+{ "octa_room", dgn_octa_room },
+{ "make_pillars", dgn_make_pillars },
+{ "make_square", dgn_make_square },
+{ "make_rounded_square", dgn_make_rounded_square },
+{ "make_circle", dgn_make_circle },
+{ "in_bounds", dgn_in_bounds },
+{ "replace_first", dgn_replace_first },
+{ "replace_random", dgn_replace_random },
+{ "spotty_level", dgn_spotty_level },
+{ "smear_feature", dgn_smear_feature },
+{ "count_feature_in_box", dgn_count_feature_in_box },
+{ "count_antifeature_in_box", dgn_count_antifeature_in_box },
+{ "count_neighbours", dgn_count_neighbours },
+{ "join_the_dots", dgn_join_the_dots },
+{ "fill_disconnected_zones", dgn_fill_disconnected_zones },
+
+{ "is_opaque", _dgn_is_opaque },
+{ "is_passable", _dgn_is_passable },
+
+{ "register_feature_marker", dgn_register_feature_marker },
+{ "register_lua_marker", dgn_register_lua_marker },
+
+{ "create_monster", dgn_create_monster },
+{ "create_item", dgn_create_item },
+
+{ "monster_spec", _dgn_monster_spec },
+{ "item_spec", _dgn_item_spec },
+
+{ "max_monsters", _dgn_max_monsters },
+
+{ "with_map_bounds_fn", dgn_with_map_bounds_fn },
+{ "with_map_anchors", dgn_with_map_anchors },
+
+{ "br_floorcol", dgn_br_floorcol },
+{ "br_rockcol", dgn_br_rockcol },
+{ "br_has_shops", dgn_br_has_shops },
+{ "br_has_uniques", dgn_br_has_uniques },
+{ "br_parent_branch", dgn_br_parent_branch },
+
+{ "level_id", dgn_level_id },
+{ "level_name", dgn_level_name },
+{ "set_level_type_name", dgn_set_level_type_name },
+{ "set_level_type_name_abbrev", dgn_set_level_type_name_abbrev },
+{ "set_level_type_origin", dgn_set_level_type_origin },
+{ "map_by_tag", dgn_map_by_tag },
+{ "map_in_depth", dgn_map_in_depth },
+{ "map_by_place", dgn_map_by_place },
+{ "place_map", _dgn_place_map },
+{ "reuse_map", _dgn_reuse_map },
+{ "resolve_map", _dgn_resolve_map },
+{ "in_vault", _dgn_in_vault },
+
+{ "find_marker_prop", _dgn_find_marker_prop },
+
+{ "get_special_room_info", dgn_get_special_room_info },
+
+{ "lrocktile", dgn_lrocktile },
+{ "lfloortile", dgn_lfloortile },
+{ "rtile", dgn_rtile },
+{ "ftile", dgn_ftile },
+{ "change_rock_tile", dgn_change_rock_tile },
+{ "change_floor_tile", dgn_change_floor_tile },
+{ "lev_floortile", dgn_lev_floortile },
+{ "lev_rocktile", dgn_lev_rocktile },
+
+{ NULL, NULL }
};
-
-static int file_marshall(lua_State *ls)
-{
- if (lua_gettop(ls) != 2)
- luaL_error(ls, "Need two arguments: tag header and value");
- writer &th(*static_cast<writer*>( lua_touserdata(ls, 1) ));
- if (lua_isnumber(ls, 2))
- marshallLong(th, luaL_checklong(ls, 2));
- else if (lua_isboolean(ls, 2))
- marshallByte(th, lua_toboolean(ls, 2));
- else if (lua_isstring(ls, 2))
- marshallString(th, lua_tostring(ls, 2));
- else if (lua_isfunction(ls, 2))
- {
- dlua_chunk chunk(ls);
- marshallString(th, chunk.compiled_chunk());
- }
- return (0);
-}
-
-static int file_unmarshall_boolean(lua_State *ls)
-{
- if (lua_gettop(ls) != 1)
- luaL_error(ls, "Need reader as one argument");
- reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
- lua_pushboolean(ls, unmarshallByte(th));
- return (1);
-}
-
-static int file_unmarshall_number(lua_State *ls)
-{
- if (lua_gettop(ls) != 1)
- luaL_error(ls, "Need reader as one argument");
- reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
- lua_pushnumber(ls, unmarshallLong(th));
- return (1);
-}
-
-static int file_unmarshall_string(lua_State *ls)
-{
- if (lua_gettop(ls) != 1)
- luaL_error(ls, "Need reader as one argument");
- reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
- lua_pushstring(ls, unmarshallString(th).c_str());
- return (1);
-}
-
-static int file_unmarshall_fn(lua_State *ls)
-{
- if (lua_gettop(ls) != 1)
- luaL_error(ls, "Need reader as one argument");
- reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
- const std::string s(unmarshallString(th, LUA_CHUNK_MAX_SIZE));
- dlua_chunk chunk = dlua_chunk::precompiled(s);
- if (chunk.load(dlua))
- lua_pushnil(ls);
- return (1);
-}
-
-enum lua_persist_type
-{
- LPT_NONE,
- LPT_NUMBER,
- LPT_STRING,
- LPT_FUNCTION,
- LPT_NIL,
- LPT_BOOLEAN
-};
-
-static int file_marshall_meta(lua_State *ls)
-{
- if (lua_gettop(ls) != 2)
- luaL_error(ls, "Need two arguments: tag header and value");
-
- writer &th(*static_cast<writer*>( lua_touserdata(ls, 1) ));
-
- lua_persist_type ptype = LPT_NONE;
- if (lua_isnumber(ls, 2))
- ptype = LPT_NUMBER;
- else if (lua_isboolean(ls, 2))
- ptype = LPT_BOOLEAN;
- else if (lua_isstring(ls, 2))
- ptype = LPT_STRING;
- else if (lua_isfunction(ls, 2))
- ptype = LPT_FUNCTION;
- else if (lua_isnil(ls, 2))
- ptype = LPT_NIL;
- else
- luaL_error(ls,
- make_stringf("Cannot marshall %s",
- lua_typename(ls, lua_type(ls, 2))).c_str());
- marshallByte(th, ptype);
- if (ptype != LPT_NIL)
- file_marshall(ls);
- return (0);
-}
-
-static int file_unmarshall_meta(lua_State *ls)
-{
- reader &th(*static_cast<reader*>( lua_touserdata(ls, 1) ));
- const lua_persist_type ptype =
- static_cast<lua_persist_type>(unmarshallByte(th));
- switch (ptype)
- {
- case LPT_BOOLEAN:
- return file_unmarshall_boolean(ls);
- case LPT_NUMBER:
- return file_unmarshall_number(ls);
- case LPT_STRING:
- return file_unmarshall_string(ls);
- case LPT_FUNCTION:
- return file_unmarshall_fn(ls);
- case LPT_NIL:
- lua_pushnil(ls);
- return (1);
- default:
- luaL_error(ls, "Unexpected type signature.");
- }
- // Never get here.
- return (0);
-}
-
-static const struct luaL_reg file_lib[] =
-{
- { "marshall", file_marshall },
- { "marshall_meta", file_marshall_meta },
- { "unmarshall_meta", file_unmarshall_meta },
- { "unmarshall_number", file_unmarshall_number },
- { "unmarshall_string", file_unmarshall_string },
- { "unmarshall_fn", file_unmarshall_fn },
- { NULL, NULL }
-};
-
-LUARET1(you_can_hear_pos, boolean,
- player_can_hear(coord_def(luaL_checkint(ls,1), luaL_checkint(ls, 2))))
-LUARET1(you_x_pos, number, you.pos().x)
-LUARET1(you_y_pos, number, you.pos().y)
-LUARET2(you_pos, number, you.pos().x, you.pos().y)
-
-// see_cell should not be exposed to user scripts. The game should
-// never disclose grid coordinates to the player. Therefore we load it
-// only into the core Lua interpreter (dlua), never into the user
-// script interpreter (clua).
-LUARET1(you_see_cell, boolean,
- see_cell(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))
-LUARET1(you_see_cell_no_trans, boolean,
- see_cell_no_trans(luaL_checkint(ls, 1), luaL_checkint(ls, 2)))
-
-LUAFN(you_moveto)
-{
- const coord_def place(luaL_checkint(ls, 1), luaL_checkint(ls, 2));
- ASSERT(map_bounds(place));
- you.moveto(place);
- return (0);
-}
-
-LUAFN(you_random_teleport)
-{
- you_teleport_now(false, false);
- return (0);
-}
-
-LUAFN(you_losight)
-{
- calc_show_los();
- return (0);
-}
-
-static const struct luaL_reg you_lib[] =
-{
- { "hear_pos", you_can_hear_pos },
- { "x_pos", you_x_pos },
- { "y_pos", you_y_pos },
- { "pos", you_pos },
- { "moveto", you_moveto },
- { "see_cell", you_see_cell },
- { "see_cell_no_trans", you_see_cell_no_trans },
- { "random_teleport", you_random_teleport },
- { "losight", you_losight },
- { NULL, NULL }
-};
-
-static int dgnevent_type(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- PLUARET(number, dev->type);
-}
-
-static int dgnevent_place(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- lua_pushnumber(ls, dev->place.x);
- lua_pushnumber(ls, dev->place.y);
- return (2);
-}
-
-static int dgnevent_dest(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- lua_pushnumber(ls, dev->dest.x);
- lua_pushnumber(ls, dev->dest.y);
- return (2);
-}
-
-static int dgnevent_ticks(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- PLUARET(number, dev->elapsed_ticks);
-}
-
-static int dgnevent_arg1(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- PLUARET(number, dev->arg1);
-}
-
-static int dgnevent_arg2(lua_State *ls)
-{
- DEVENT(ls, 1, dev);
- PLUARET(number, dev->arg2);
-}
-
-static const struct luaL_reg dgnevent_lib[] =
-{
- { "type", dgnevent_type },
- { "pos", dgnevent_place },
- { "dest", dgnevent_dest },
- { "ticks", dgnevent_ticks },
- { "arg1", dgnevent_arg1 },
- { "arg2", dgnevent_arg2 },
- { NULL, NULL }
-};
-
-void luaopen_setmeta(lua_State *ls,
- const char *global,
- const luaL_reg *lua_lib,
- const char *meta)
-{
- luaL_newmetatable(ls, meta);
- lua_setglobal(ls, global);
-
- luaL_openlib(ls, global, lua_lib, 0);
-
- // Do <global>.__index = <global>
- lua_pushstring(ls, "__index");
- lua_pushvalue(ls, -2);
- lua_settable(ls, -3);
-}
-
-static void luaopen_dgnevent(lua_State *ls)
-{
- luaopen_setmeta(ls, "dgnevent", dgnevent_lib, DEVENT_METATABLE);
-}
-
-static int mapmarker_pos(lua_State *ls)
-{
- MAPMARKER(ls, 1, mark);
- lua_pushnumber(ls, mark->pos.x);
- lua_pushnumber(ls, mark->pos.y);
- return (2);
-}
-
-static int mapmarker_move(lua_State *ls)
-{
- MAPMARKER(ls, 1, mark);
- const coord_def dest( luaL_checkint(ls, 2), luaL_checkint(ls, 3) );
- env.markers.move_marker(mark, dest);
- return (0);
-}
-
-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();
- }
-}
-
-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>);
-}
-
-static const struct luaL_reg mapmarker_lib[] =
-{
- { "pos", mapmarker_pos },
- { "move", mapmarker_move },
- { NULL, NULL }
-};
-
-static void luaopen_mapmarker(lua_State *ls)
-{
- luaopen_setmeta(ls, "mapmarker", mapmarker_lib, MAPMARK_METATABLE);
-}
-
-
-// Return the integer stored in the table (on the stack) with the key name.
-// If the key doesn't exist or the value is the wrong type, return defval.
-static int _table_int(lua_State *ls, int idx, const char *name, int defval)
-{
- lua_pushstring(ls, name);
- lua_gettable(ls, idx < 0 ? idx - 1 : idx);
- bool nil = lua_isnil(ls, idx);
- bool valid = lua_isnumber(ls, idx);
- if (!nil && !valid)
- luaL_error(ls, "'%s' in table, but not an int.", name);
- int ret = (!nil && valid ? lua_tonumber(ls, idx) : defval);
- lua_pop(ls, 1);
- return (ret);
-}
-
-// Return the character stored in the table (on the stack) with the key name.
-// If the key doesn't exist or the value is the wrong type, return defval.
-static char _table_char(lua_State *ls, int idx, const char *name, char defval)
-{
- lua_pushstring(ls, name);
- lua_gettable(ls, idx < 0 ? idx - 1 : idx);
- bool nil = lua_isnil(ls, idx);
- bool valid = lua_isstring(ls, idx);
- if (!nil && !valid)
- luaL_error(ls, "'%s' in table, but not a string.", name);
-
- char ret = defval;
- if (!nil && valid)
- {
- const char *str = lua_tostring(ls, idx);
- if (str[0] && !str[1])
- ret = str[0];
- else
- luaL_error(ls, "'%s' has more than one character.", name);
- }
- lua_pop(ls, 1);
- return (ret);
-}
-
-// Return the string stored in the table (on the stack) with the key name.
-// If the key doesn't exist or the value is the wrong type, return defval.
-static const char* _table_str(lua_State *ls, int idx, const char *name, const char *defval)
-{
- lua_pushstring(ls, name);
- lua_gettable(ls, idx < 0 ? idx - 1 : idx);
- bool nil = lua_isnil(ls, idx);
- bool valid = lua_isstring(ls, idx);
- if (!nil && !valid)
- luaL_error(ls, "'%s' in table, but not a string.", name);
- const char *ret = (!nil && valid ? lua_tostring(ls, idx) : defval);
- lua_pop(ls, 1);
- return (ret);
-}
-
-// Return the boolean stored in the table (on the stack) with the key name.
-// If the key doesn't exist or the value is the wrong type, return defval.
-static bool _table_bool(lua_State *ls, int idx, const char *name, bool defval)
-{
- lua_pushstring(ls, name);
- lua_gettable(ls, idx < 0 ? idx - 1 : idx);
- bool nil = lua_isnil(ls, idx);
- bool valid = lua_isboolean(ls, idx);
- if (!nil && !valid)
- luaL_error(ls, "'%s' in table, but not a bool.", name);
- bool ret = (!nil && valid ? lua_toboolean(ls, idx) : defval);
- lua_pop(ls, 1);
- return (ret);
-}
-
-#define BF_INT(ls, val, def) int val = _table_int(ls, -1, #val, def);
-#define BF_CHAR(ls, val, def) char val = _table_char(ls, -1, #val, def);
-#define BF_STR(ls, val, def) const char *val = _table_str(ls, -1, #val, def);
-#define BF_BOOL(ls, val, def) bool val = _table_bool(ls, -1, #val, def);
-
-static void bf_octa_room(lua_State *ls, map_lines &lines)
-{
- int default_oblique = std::min(lines.width(), lines.height()) / 2 - 1;
- BF_INT(ls, oblique, default_oblique);
- BF_CHAR(ls, outside, 'x');
- BF_CHAR(ls, inside, '.');
- BF_STR(ls, replace, ".");
-
- coord_def tl, br;
- if (!lines.find_bounds(replace, tl, br))
- return;
-
- for (rectangle_iterator ri(tl, br); ri; ++ri)
- {
- const coord_def mc = *ri;
- char glyph = lines(mc);
- if (replace[0] && !strchr(replace, glyph))
- continue;
-
- int ob = 0;
- ob += std::max(oblique + tl.x - mc.x, 0);
- ob += std::max(oblique + mc.x - br.x, 0);
-
- bool is_inside = (mc.y >= tl.y + ob && mc.y <= br.y - ob);
- lines(mc) = is_inside ? inside : outside;
- }
-}
-
-static void bf_smear(lua_State *ls, map_lines &lines)
-{
- BF_INT(ls, iterations, 1);
- BF_CHAR(ls, smear, 'x');
- BF_STR(ls, onto, ".");
- BF_BOOL(ls, boxy, false);
-
- const int max_test_per_iteration = 10;
- int sanity = 0;
- int max_sanity = iterations * max_test_per_iteration;
-
- for (int i = 0; i < iterations; i++)
- {
- bool diagonals, straights;
- coord_def mc;
-
- do
- {
- do
- {
- sanity++;
- mc.x = random_range(1, lines.width() - 2);
- mc.y = random_range(1, lines.height() - 2);
- }
- while (onto[0] && !strchr(onto, lines(mc)));
-
- // Prevent too many iterations.
- if (sanity > max_sanity)
- return;
-
- // Is there a "smear" feature along the diagonal from mc?
- diagonals = lines(coord_def(mc.x+1, mc.y+1)) == smear ||
- lines(coord_def(mc.x-1, mc.y+1)) == smear ||
- lines(coord_def(mc.x-1, mc.y-1)) == smear ||
- lines(coord_def(mc.x+1, mc.y-1)) == smear;
-
- // Is there a "smear" feature up, down, left, or right from mc?
- straights = lines(coord_def(mc.x+1, mc.y)) == smear ||
- lines(coord_def(mc.x-1, mc.y)) == smear ||
- lines(coord_def(mc.x, mc.y+1)) == smear ||
- lines(coord_def(mc.x, mc.y-1)) == smear;
- }
- while (!straights && (boxy || !diagonals));
-
- lines(mc) = smear;
- }
-}
-
-static void bf_extend(lua_State *ls, map_lines &lines)
-{
- BF_INT(ls, height, 1);
- BF_INT(ls, width, 1);
- BF_CHAR(ls, fill, 'x');
-
- lines.extend(width, height, fill);
-}
-
-typedef void (*bf_func)(lua_State *ls, map_lines &lines);
-struct bf_entry
-{
- const char* name;
- bf_func func;
-};
-
-// Create a separate list of builder funcs so that we can automatically
-// generate a list of closures for them, rather than individually
-// and explicitly exposing them to the dgn namespace.
-static struct bf_entry bf_map[] =
-{
- { "map_octa_room", &bf_octa_room },
- { "map_smear", &bf_smear },
- { "map_extend", &bf_extend }
-};
-
-static int dgn_call_builder_func(lua_State *ls)
-{
- // This function gets called for all the builder functions that
- // operate on map_lines.
-
- MAP(ls, 1, map);
- if (!lua_istable(ls, 2) && !lua_isfunction(ls, 2))
- return luaL_argerror(ls, 2, "Expected table");
-
- bf_func *func = (bf_func *)lua_topointer(ls, lua_upvalueindex(1));
- if (!func)
- return luaL_error(ls, "Expected C function in closure upval");
-
- // Put the table on top.
- lua_settop(ls, 2);
-
- // Call the builder func itself.
- (*func)(ls, map->map);
-
- return (0);
-}
-
-static void _register_builder_funcs(lua_State *ls)
-{
- lua_getglobal(ls, "dgn");
-
- const size_t num_entries = sizeof(bf_map) / sizeof(bf_entry);
- for (size_t i = 0; i < num_entries; i++)
- {
- // Push a closure with the C function into the dgn table.
- lua_pushlightuserdata(ls, &bf_map[i].func);
- lua_pushcclosure(ls, &dgn_call_builder_func, 1);
- lua_setfield(ls, -2, bf_map[i].name);
- }
-
- lua_pop(ls, 1);
-}
-
-void init_dungeon_lua()
-{
- lua_stack_cleaner clean(dlua);
-
- luaL_openlib(dlua, "dgn", dgn_lib, 0);
- // Add additional function to the Crawl module.
- luaL_openlib(dlua, "crawl", crawl_lib, 0);
- luaL_openlib(dlua, "file", file_lib, 0);
- luaL_openlib(dlua, "you", you_lib, 0);
- luaL_openlib(dlua, "los", los_lib, 0);
-
- dlua.execfile("clua/dungeon.lua", true, true);
- dlua.execfile("clua/luamark.lua", true, true);
-
- lua_getglobal(dlua, "dgn_run_map");
- luaopen_debug(dlua);
- luaL_newmetatable(dlua, MAP_METATABLE);
-
- luaopen_dgnevent(dlua);
- luaopen_mapmarker(dlua);
- luaopen_ray(dlua);
-
- _register_builder_funcs(dlua);
-
- _register_mapdef_tables(dlua);
-}
-
-// Can be called from within a debugger to look at the current Lua
-// call stack. (Borrowed from ToME 3)
-void print_dlua_stack(void)
-{
- struct lua_Debug dbg;
- int i = 0;
- lua_State *L = dlua.state();
-
- fprintf(stderr, EOL);
- while (lua_getstack(L, i++, &dbg) == 1)
- {
- lua_getinfo(L, "lnuS", &dbg);
-
- char* file = strrchr(dbg.short_src, '/');
- if (file == NULL)
- file = dbg.short_src;
- else
- file++;
-
- fprintf(stderr, "%s, function %s, line %d" EOL, file,
- dbg.name, dbg.currentline);
- }
-
- fprintf(stderr, EOL);
-}
diff --git a/crawl-ref/source/l_los.cc b/crawl-ref/source/l_los.cc
index b6e3463b89..8ccd2ffa07 100644
--- a/crawl-ref/source/l_los.cc
+++ b/crawl-ref/source/l_los.cc
@@ -6,10 +6,8 @@
#include "AppHdr.h"
-#include "l_los.h"
-
#include "los.h"
-#include "luadgn.h"
+#include "dlua.h"
#include "ray.h"
#define RAY_METATABLE "dgn.ray"
diff --git a/crawl-ref/source/l_los.h b/crawl-ref/source/l_los.h
deleted file mode 100644
index c07bde12b2..0000000000
--- a/crawl-ref/source/l_los.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * File: l_los.h
- * Summary: Lua bindings for LOS.
- * Created by: Robert Vollmert
- */
-
-#ifndef L_LOS_H
-#define L_LOS_H
-
-#include "clua.h"
-
-extern const struct luaL_reg los_lib[];
-void luaopen_ray(lua_State *ls);
-
-#endif
-
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index 58f9390345..08e7497bf2 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -17,6 +17,7 @@ debug.o \
decks.o \
delay.o \
describe.o \
+dlua.o \
dgnevent.o \
directn.o \
dungeon.o \
@@ -37,10 +38,10 @@ itemprop.o \
items.o \
lev-pand.o \
libutil.o \
+l_dgn.o \
l_los.o \
los.o \
losparam.o \
-luadgn.o \
macro.o \
makeitem.o \
mapdef.o \
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 85c8484aef..257735a65e 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -15,10 +15,10 @@
#include <cstdio>
#include <memory>
+#include "dlua.h"
#include "enum.h"
#include "externs.h"
#include "fixary.h"
-#include "luadgn.h"
#include "makeitem.h"
#include "stuff.h"
#include "travel.h"
diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc
index 33599f1d28..ecef3cd297 100644
--- a/crawl-ref/source/mapmark.cc
+++ b/crawl-ref/source/mapmark.cc
@@ -12,8 +12,8 @@
#include "clua.h"
#include "directn.h"
+#include "dlua.h"
#include "libutil.h"
-#include "luadgn.h"
#include "stuff.h"
#include "tags.h"
diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h
index a26c35d4bd..e9560b950e 100644
--- a/crawl-ref/source/mapmark.h
+++ b/crawl-ref/source/mapmark.h
@@ -10,7 +10,7 @@
#include "dungeon.h"
#include "dgnevent.h"
#include "clua.h"
-#include "luadgn.h"
+#include "dlua.h"
#include <map>
#include <string>
#include <memory>
diff --git a/crawl-ref/source/maps.h b/crawl-ref/source/maps.h
index 484e3a0f01..afaac0695e 100644
--- a/crawl-ref/source/maps.h
+++ b/crawl-ref/source/maps.h
@@ -8,6 +8,7 @@
#ifndef MAPS_H
#define MAPS_H
+#include "dlua.h"
#include "fixvec.h"
#include "dungeon.h"
diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp
index 1aa82e25b1..566b54247d 100644
--- a/crawl-ref/source/util/levcomp.ypp
+++ b/crawl-ref/source/util/levcomp.ypp
@@ -5,8 +5,8 @@
#include "AppHdr.h"
#include "clua.h"
+#include "dlua.h"
#include "libutil.h"
-#include "luadgn.h"
#include "mapdef.h"
#include "maps.h"
#include "stuff.h"