summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/clua.cc21
-rw-r--r--crawl-ref/source/clua.h4
-rw-r--r--crawl-ref/source/luadgn.cc18
-rw-r--r--crawl-ref/source/mapdef.cc33
-rw-r--r--crawl-ref/source/mapdef.h24
-rw-r--r--crawl-ref/source/mapmark.cc11
-rw-r--r--crawl-ref/source/mapmark.h1
-rw-r--r--crawl-ref/source/util/levcomp.lpp17
-rw-r--r--crawl-ref/source/util/levcomp.ypp50
9 files changed, 127 insertions, 52 deletions
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index 9fa1a79a9a..7fb7a310a7 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -131,10 +131,15 @@ void CLua::setregistry(const char *name)
lua_settable(state(), LUA_REGISTRYINDEX);
}
+void CLua::_getregistry(lua_State *ls, const char *name)
+{
+ lua_pushstring(ls, name);
+ lua_gettable(ls, LUA_REGISTRYINDEX);
+}
+
void CLua::getregistry(const char *name)
{
- lua_pushstring(state(), name);
- lua_gettable(state(), LUA_REGISTRYINDEX);
+ _getregistry(state(), name);
}
void CLua::save(const char *file)
@@ -639,6 +644,18 @@ void CLua::init_lua()
lua_pushboolean(_state, managed_vm);
setregistry("lua_vm_is_managed");
+
+ lua_pushlightuserdata(_state, this);
+ setregistry("__clua");
+}
+
+CLua &CLua::get_vm(lua_State *ls)
+{
+ _getregistry(ls, "__clua");
+ CLua *vm = util_get_userdata<CLua>(ls, -1);
+ if (!vm)
+ end(1, false, "Failed to find CLua for lua state %p", ls);
+ return (*vm);
}
bool CLua::is_managed_vm(lua_State *ls)
diff --git a/crawl-ref/source/clua.h b/crawl-ref/source/clua.h
index ae465aa3a0..e6ae4ecde7 100644
--- a/crawl-ref/source/clua.h
+++ b/crawl-ref/source/clua.h
@@ -93,6 +93,8 @@ public:
CLua(bool managed = true);
~CLua();
+ static CLua &get_vm(lua_State *);
+
lua_State *state();
operator lua_State * ()
@@ -170,6 +172,8 @@ private:
void load_chooks();
void init_throttle();
+ static void _getregistry(lua_State *, const char *name);
+
void vfnreturns(const char *par, va_list va);
bool proc_returns(const char *par) const;
diff --git a/crawl-ref/source/luadgn.cc b/crawl-ref/source/luadgn.cc
index 8ad3fc37ac..ca773b84d8 100644
--- a/crawl-ref/source/luadgn.cc
+++ b/crawl-ref/source/luadgn.cc
@@ -764,6 +764,23 @@ static int dgn_item(lua_State *ls)
return (0);
}
+static int dgn_lua_marker(lua_State *ls)
+{
+ MAP(ls, 1, map);
+ if (lua_gettop(ls) != 3 || !lua_isstring(ls, 2) || !lua_isfunction(ls, 3))
+ luaL_error(ls, "Expected marker key and marker function.");
+
+ 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);
+}
+
static int dgn_marker(lua_State *ls)
{
MAP(ls, 1, map);
@@ -2106,6 +2123,7 @@ static const struct luaL_reg dgn_lib[] =
{ "mons", dgn_mons },
{ "item", dgn_item },
{ "marker", dgn_marker },
+ { "lua_marker", dgn_lua_marker },
{ "kfeat", dgn_kfeat },
{ "kitem", dgn_kitem },
{ "kmons", dgn_kmons },
diff --git a/crawl-ref/source/mapdef.cc b/crawl-ref/source/mapdef.cc
index 0f9cb1f838..3eaea9b11f 100644
--- a/crawl-ref/source/mapdef.cc
+++ b/crawl-ref/source/mapdef.cc
@@ -63,11 +63,11 @@ static int find_weight(std::string &s, int defweight = TAG_UNFOUND)
return (weight == TAG_UNFOUND? defweight : weight);
}
-static std::string split_key_item(const std::string &s,
+std::string mapdef_split_key_item(const std::string &s,
std::string *key,
int *separator,
std::string *arg,
- int key_max_len = 1)
+ int key_max_len)
{
std::string::size_type
norm = s.find("=", 1),
@@ -383,7 +383,7 @@ std::string map_lines::add_feature_marker(const std::string &s)
{
std::string key, arg;
int sep = 0;
- std::string err = split_key_item(s, &key, &sep, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &arg);
if (!err.empty())
return (err);
@@ -391,6 +391,13 @@ std::string map_lines::add_feature_marker(const std::string &s)
return ("");
}
+std::string map_lines::add_lua_marker(const std::string &key,
+ const lua_datum &function)
+{
+ transforms.push_back(new map_marker_spec(key[0], function));
+ return ("");
+}
+
void map_lines::apply_markers(const coord_def &c)
{
for (int i = 0, size = markers.size(); i < size; ++i)
@@ -546,7 +553,7 @@ std::string map_lines::add_colour(const std::string &sub)
std::string key;
std::string substitute;
- std::string err = split_key_item(sub, &key, &sep, &substitute);
+ std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute);
if (!err.empty())
return (err);
@@ -570,7 +577,7 @@ std::string map_lines::add_subst(const std::string &sub)
std::string key;
std::string substitute;
- std::string err = split_key_item(sub, &key, &sep, &substitute);
+ std::string err = mapdef_split_key_item(sub, &key, &sep, &substitute);
if (!err.empty())
return (err);
@@ -589,7 +596,7 @@ std::string map_lines::parse_nsubst_spec(const std::string &s,
{
std::string key, arg;
int sep;
- std::string err = split_key_item(s, &key, &sep, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &arg);
if (!err.empty())
return err;
const int keyval = key == "*"? -1 : atoi(key.c_str());
@@ -612,7 +619,7 @@ std::string map_lines::add_nsubst(const std::string &s)
int sep;
std::string key, arg;
- std::string err = split_key_item(s, &key, &sep, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &sep, &arg);
if (!err.empty())
return (err);
@@ -1769,7 +1776,7 @@ std::string map_def::add_key_field(
int separator = 0;
std::string key, arg;
- std::string err = split_key_item(s, &key, &separator, &arg);
+ std::string err = mapdef_split_key_item(s, &key, &separator, &arg);
if (!err.empty())
return (err);
@@ -2810,8 +2817,7 @@ std::string map_marker_spec::apply_transform(map_lines &map)
{
try
{
- map_marker *mark =
- map_marker::parse_marker(marker);
+ map_marker *mark = create_marker();
if (!mark)
return make_stringf("Unable to parse marker from %s",
marker.c_str());
@@ -2826,6 +2832,13 @@ std::string map_marker_spec::apply_transform(map_lines &map)
return ("");
}
+map_marker *map_marker_spec::create_marker()
+{
+ return lua_fn.get()
+ ? new map_lua_marker(*lua_fn.get())
+ : map_marker::parse_marker(marker);
+}
+
map_transformer::transform_type map_marker_spec::type() const
{
return (TT_MARKER);
diff --git a/crawl-ref/source/mapdef.h b/crawl-ref/source/mapdef.h
index 775f2e82b2..83098d2b5a 100644
--- a/crawl-ref/source/mapdef.h
+++ b/crawl-ref/source/mapdef.h
@@ -15,6 +15,7 @@
#include <string>
#include <vector>
#include <cstdio>
+#include <memory>
#include "luadgn.h"
#include "enum.h"
@@ -202,15 +203,25 @@ class shuffle_spec : public map_transformer
class map_marker_spec : public map_transformer
{
- public:
+public:
int key;
std::string marker;
+ // Special handling for Lua markers:
+ std::auto_ptr<lua_datum> lua_fn;
+
map_marker_spec(int _key, const std::string &mark)
- : key(_key), marker(mark) { }
+ : key(_key), marker(mark), lua_fn() { }
+
+ map_marker_spec(int _key, const lua_datum &fn)
+ : key(_key), marker(), lua_fn(new lua_datum(fn)) { }
+
std::string apply_transform(map_lines &map);
transform_type type() const;
std::string describe() const;
+
+private:
+ map_marker *create_marker();
};
class map_def;
@@ -266,6 +277,8 @@ public:
void add_marker(map_marker *marker);
std::string add_feature_marker(const std::string &desc);
+ std::string add_lua_marker(const std::string &key,
+ const lua_datum &fn);
void apply_markers(const coord_def &pos);
void apply_colours(const coord_def &pos);
@@ -742,6 +755,13 @@ private:
std::string escape_string(std::string in, const std::string &toesc,
const std::string &escapewith);
+
+std::string mapdef_split_key_item(const std::string &s,
+ std::string *key,
+ int *separator,
+ std::string *arg,
+ int key_max_len = 1);
+
const char *map_section_name(int msect);
#endif
diff --git a/crawl-ref/source/mapmark.cc b/crawl-ref/source/mapmark.cc
index 7fadb6330e..ecbed091e3 100644
--- a/crawl-ref/source/mapmark.cc
+++ b/crawl-ref/source/mapmark.cc
@@ -165,6 +165,17 @@ map_lua_marker::map_lua_marker()
{
}
+map_lua_marker::map_lua_marker(const lua_datum &fn)
+ : map_marker(MAT_LUA_MARKER, coord_def())
+{
+ lua_stack_cleaner clean(dlua);
+ fn.push();
+ if (!dlua.callfn("dgn_run_map", 1, 1))
+ mprf(MSGCH_ERROR, "lua_marker exec error: %s", dlua.error.c_str());
+ else
+ check_register_table();
+}
+
map_lua_marker::map_lua_marker(const std::string &s, const std::string &,
bool mapdef_marker)
: map_marker(MAT_LUA_MARKER, coord_def()), initialised(false)
diff --git a/crawl-ref/source/mapmark.h b/crawl-ref/source/mapmark.h
index 07d89331be..eb7eb22ba4 100644
--- a/crawl-ref/source/mapmark.h
+++ b/crawl-ref/source/mapmark.h
@@ -98,6 +98,7 @@ class map_lua_marker : public map_marker, public dgn_event_listener
{
public:
map_lua_marker();
+ map_lua_marker(const lua_datum &function);
map_lua_marker(const std::string &s, const std::string &ctx,
bool mapdef_marker = true);
~map_lua_marker();
diff --git a/crawl-ref/source/util/levcomp.lpp b/crawl-ref/source/util/levcomp.lpp
index 42297b5016..590cd59122 100644
--- a/crawl-ref/source/util/levcomp.lpp
+++ b/crawl-ref/source/util/levcomp.lpp
@@ -122,7 +122,6 @@ static void cattext(bool trim_right = false, int strip_trailing = 0)
%s MNAME
%s KEYWORDS
%x ITEM_LIST
-%x TOEOL
%option yylineno
%option never-interactive
@@ -213,19 +212,9 @@ SPACE [\ \t\r]
cattext();
}
-<ARGUMENT>{SPACE}*$ { BEGIN(INITIAL); str_check(); return STRING; }
-
-<TOEOL>.*\\[ \t\r]*$ {
- settext(true, 1);
- return STRING;
- }
+<ARGUMENT>{NSPACE} cattext();
-<TOEOL>.+$ {
- BEGIN(INITIAL);
- settext(true);
- return STRING;
- }
-<TOEOL>\r?\n ;
+<ARGUMENT>{SPACE}*$ { BEGIN(INITIAL); str_check(); return STRING; }
^[ \t]*#.* ;
@@ -259,7 +248,7 @@ FLOORCOL: { CBEGIN(ARGUMENT); return FLOORCOL; }
ROCKCOL: { CBEGIN(ARGUMENT); return ROCKCOL; }
MONS: { CBEGIN(MNAME); return MONS; }
ITEM: { CBEGIN(ITEM_LIST); return ITEM; }
-MARKER: { CBEGIN(TOEOL); return MARKER; }
+MARKER: { CBEGIN(ARGUMENT); return MARKER; }
SHUFFLE: { CBEGIN(ITEM_LIST); return SHUFFLE; }
KFEAT: { CBEGIN(ARGUMENT); return KFEAT; }
diff --git a/crawl-ref/source/util/levcomp.ypp b/crawl-ref/source/util/levcomp.ypp
index fc75c4a53b..f2bb2b17b6 100644
--- a/crawl-ref/source/util/levcomp.ypp
+++ b/crawl-ref/source/util/levcomp.ypp
@@ -17,8 +17,6 @@ int yylex();
extern int yylineno;
-static bool start_marker_segment = false;
-
void yyerror(const char *e)
{
if (strstr(e, lc_desfile.c_str()) == e)
@@ -319,32 +317,36 @@ bflags : BFLAGS STRING
}
;
-marker : MARKER
- {
- lc_map.main.add(yylineno, "marker(");
- start_marker_segment = true;
- }
- marker_spec
+marker : MARKER STRING
{
- lc_map.main.add(yylineno, ")");
- }
- ;
+ std::string key, arg;
+ int sep(0);
-marker_spec : mspec_segments
+ const std::string err =
+ mapdef_split_key_item($2, &key, &sep, &arg);
-mspec_segments : /* nothing */
- | mspec_segments mspec_segment
- ;
+ if (!err.empty())
+ yyerror(err.c_str());
-mspec_segment : STRING
- {
- lc_map.main.add(
- yylineno,
- make_stringf(
- "%s\"%s\"",
- start_marker_segment? "" : " .. ",
- quote_lua_string($1).c_str()));
- start_marker_segment = false;
+ // Special treatment for Lua markers.
+ if (arg.find("lua:") == 0)
+ {
+ arg = arg.substr(4);
+ lc_map.main.add(
+ yylineno,
+ make_stringf("lua_marker(\"%s\", function () "
+ " return %s "
+ "end)",
+ quote_lua_string(key).c_str(),
+ arg.c_str()));
+ }
+ else
+ {
+ lc_map.main.add(
+ yylineno,
+ make_stringf("marker(\"%s\")",
+ quote_lua_string($2).c_str()));
+ }
}
;