summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/clua.cc
diff options
context:
space:
mode:
authorDarshan Shaligram <dshaligram@users.sourceforge.net>2009-10-30 15:46:55 +0530
committerDarshan Shaligram <dshaligram@users.sourceforge.net>2009-10-31 22:16:46 +0530
commitad11744e5d49d226fc9c77ed48c3dd8b97921350 (patch)
treec4334fd1e6b4b052ac93593f9021f12c9f10baac /crawl-ref/source/clua.cc
parent23f8631266eac1a7b4b4727b26a5fc088a6f0184 (diff)
downloadcrawl-ref-ad11744e5d49d226fc9c77ed48c3dd8b97921350.tar.gz
crawl-ref-ad11744e5d49d226fc9c77ed48c3dd8b97921350.zip
lmark.synchronized_markers(): apply one marker's effects to multiple points simultaneously.
synchronized_markers() takes a marker, and a list of method names to override, and returns a set of markers that fire simultaneously, to allow, say, fog machines that fire at random intervals, but always fire in unison. lm_mslav.lua has details. volcano.des has an example volcano entry vault that uses this. Allow fetching a list of Lua markers/marker positions by property value. Renamed dgn.find_marker_prop -> dgn.find_marker_position_by_prop. s/helper/listener/ for fog machine listeners.
Diffstat (limited to 'crawl-ref/source/clua.cc')
-rw-r--r--crawl-ref/source/clua.cc50
1 files changed, 45 insertions, 5 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index d9273b74c9..64fd63b768 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -12,6 +12,7 @@
#include "l_libs.h"
#include "files.h"
+#include "libutil.h"
#include "state.h"
#include "stuff.h"
@@ -275,7 +276,7 @@ bool CLua::runhook(const char *hook, const char *params, ...)
// Remember top of stack, for debugging porpoises
int stack_top = lua_gettop(ls);
- lua_getglobal(ls, hook);
+ pushglobal(hook);
if (!lua_istable(ls, -1))
{
lua_pop(ls, 1);
@@ -475,7 +476,7 @@ bool CLua::callbooleanfn(bool def, const char *fn, const char *params, ...)
int stacktop = lua_gettop(ls);
- lua_getglobal(ls, fn);
+ pushglobal(fn);
if (!lua_isfunction(ls, -1))
{
lua_pop(ls, 1);
@@ -497,6 +498,46 @@ bool CLua::proc_returns(const char *par) const
return (strchr(par, '>') != NULL);
}
+// Identical to lua_getglobal for simple names, but will look up
+// "a.b.c" names in tables, so you can pushglobal("dgn.point") and get
+// _G['dgn']['point'], as expected.
+//
+// Guarantees to push exactly one value onto the stack.
+//
+void CLua::pushglobal(const std::string &name)
+{
+ std::vector<std::string> pieces = split_string(".", name);
+ lua_State *ls(state());
+
+ if (pieces.empty())
+ lua_pushnil(ls);
+
+ for (unsigned i = 0, size = pieces.size(); i < size; ++i)
+ {
+ if (!i)
+ lua_getglobal(ls, pieces[i].c_str());
+ else
+ {
+ if (lua_istable(ls, -1))
+ {
+ lua_pushstring(ls, pieces[i].c_str());
+ lua_gettable(ls, -2);
+ // Swap the value we just found with the table itself.
+ lua_insert(ls, -2);
+ // And remove the table.
+ lua_pop(ls, 1);
+ }
+ else
+ {
+ // We expected a table here, but got something else. Fail.
+ lua_pop(ls, 1);
+ lua_pushnil(ls);
+ break;
+ }
+ }
+ }
+}
+
bool CLua::callfn(const char *fn, const char *params, ...)
{
error.clear();
@@ -504,7 +545,7 @@ bool CLua::callfn(const char *fn, const char *params, ...)
if (!ls)
return (false);
- lua_getglobal(ls, fn);
+ pushglobal(fn);
if (!lua_isfunction(ls, -1))
{
lua_pop(ls, 1);
@@ -536,7 +577,7 @@ bool CLua::callfn(const char *fn, int nargs, int nret)
// If a function is not provided on the stack, get the named function.
if (fn)
{
- lua_getglobal(ls, fn);
+ pushglobal(fn);
if (!lua_isfunction(ls, -1))
{
lua_settop(ls, -nargs - 2);
@@ -1139,4 +1180,3 @@ bool lua_datum::is_udata() const
{
LUA_CHECK_TYPE(lua_isuserdata);
}
-