summaryrefslogtreecommitdiff
path: root/src/scriptapi.cpp
diff options
context:
space:
mode:
authordarkrose <lisa@ltmnet.com>2012-07-17 23:00:04 +1000
committerPerttu Ahola <celeron55@gmail.com>2012-07-23 08:18:37 +0300
commitcd6becd442a50a6e2f7129108e1c2c495f885764 (patch)
tree9f013b53ff4ec7d4df6ee26769e397f3defee268 /src/scriptapi.cpp
parent829f262c7954c4eb82eff3931d065fce8bc7809e (diff)
downloadminetest-cd6becd442a50a6e2f7129108e1c2c495f885764.tar.gz
minetest-cd6becd442a50a6e2f7129108e1c2c495f885764.tar.bz2
minetest-cd6becd442a50a6e2f7129108e1c2c495f885764.zip
Implement node timers
Diffstat (limited to 'src/scriptapi.cpp')
-rw-r--r--src/scriptapi.cpp219
1 files changed, 206 insertions, 13 deletions
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 6cb701689..12d2a8247 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -3119,6 +3119,162 @@ const luaL_reg LuaPerlinNoise::methods[] = {
};
/*
+ NodeTimerRef
+*/
+
+class NodeTimerRef
+{
+private:
+ v3s16 m_p;
+ ServerEnvironment *m_env;
+
+ static const char className[];
+ static const luaL_reg methods[];
+
+ static int gc_object(lua_State *L) {
+ NodeTimerRef *o = *(NodeTimerRef **)(lua_touserdata(L, 1));
+ delete o;
+ return 0;
+ }
+
+ static NodeTimerRef *checkobject(lua_State *L, int narg)
+ {
+ luaL_checktype(L, narg, LUA_TUSERDATA);
+ void *ud = luaL_checkudata(L, narg, className);
+ if(!ud) luaL_typerror(L, narg, className);
+ return *(NodeTimerRef**)ud; // unbox pointer
+ }
+
+ static int l_set(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ f32 t = luaL_checknumber(L,2);
+ f32 e = luaL_checknumber(L,3);
+ env->getMap().setNodeTimer(o->m_p,NodeTimer(t,e));
+ return 0;
+ }
+
+ static int l_start(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ f32 t = luaL_checknumber(L,2);
+ env->getMap().setNodeTimer(o->m_p,NodeTimer(t,0));
+ return 0;
+ }
+
+ static int l_stop(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ env->getMap().removeNodeTimer(o->m_p);
+ return 0;
+ }
+
+ static int l_is_started(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+
+ NodeTimer t = env->getMap().getNodeTimer(o->m_p);
+ lua_pushboolean(L,(t.timeout != 0));
+ return 1;
+ }
+
+ static int l_get_timeout(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+
+ NodeTimer t = env->getMap().getNodeTimer(o->m_p);
+ lua_pushnumber(L,t.timeout);
+ return 1;
+ }
+
+ static int l_get_elapsed(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+
+ NodeTimer t = env->getMap().getNodeTimer(o->m_p);
+ lua_pushnumber(L,t.elapsed);
+ return 1;
+ }
+
+public:
+ NodeTimerRef(v3s16 p, ServerEnvironment *env):
+ m_p(p),
+ m_env(env)
+ {
+ }
+
+ ~NodeTimerRef()
+ {
+ }
+
+ // Creates an NodeTimerRef and leaves it on top of stack
+ // Not callable from Lua; all references are created on the C side.
+ static void create(lua_State *L, v3s16 p, ServerEnvironment *env)
+ {
+ NodeTimerRef *o = new NodeTimerRef(p, env);
+ *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
+ luaL_getmetatable(L, className);
+ lua_setmetatable(L, -2);
+ }
+
+ static void set_null(lua_State *L)
+ {
+ NodeTimerRef *o = checkobject(L, -1);
+ o->m_env = NULL;
+ }
+
+ static void Register(lua_State *L)
+ {
+ lua_newtable(L);
+ int methodtable = lua_gettop(L);
+ luaL_newmetatable(L, className);
+ int metatable = lua_gettop(L);
+
+ lua_pushliteral(L, "__metatable");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable); // hide metatable from Lua getmetatable()
+
+ lua_pushliteral(L, "__index");
+ lua_pushvalue(L, methodtable);
+ lua_settable(L, metatable);
+
+ lua_pushliteral(L, "__gc");
+ lua_pushcfunction(L, gc_object);
+ lua_settable(L, metatable);
+
+ lua_pop(L, 1); // drop metatable
+
+ luaL_openlib(L, 0, methods, 0); // fill methodtable
+ lua_pop(L, 1); // drop methodtable
+
+ // Cannot be created from Lua
+ //lua_register(L, className, create_object);
+ }
+};
+const char NodeTimerRef::className[] = "NodeTimerRef";
+const luaL_reg NodeTimerRef::methods[] = {
+ method(NodeTimerRef, start),
+ method(NodeTimerRef, set),
+ method(NodeTimerRef, stop),
+ method(NodeTimerRef, is_started),
+ method(NodeTimerRef, get_timeout),
+ method(NodeTimerRef, get_elapsed),
+ {0,0}
+};
+
+/*
EnvRef
*/
@@ -3351,6 +3507,31 @@ private:
return 1;
}
+ // EnvRef:get_meta(pos)
+ static int l_get_meta(lua_State *L)
+ {
+ //infostream<<"EnvRef::l_get_meta()"<<std::endl;
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ // Do it
+ v3s16 p = read_v3s16(L, 2);
+ NodeMetaRef::create(L, p, env);
+ return 1;
+ }
+
+ // EnvRef:get_node_timer(pos)
+ static int l_get_node_timer(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ // Do it
+ v3s16 p = read_v3s16(L, 2);
+ NodeTimerRef::create(L, p, env);
+ return 1;
+ }
+
// EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
// pos = {x=num, y=num, z=num}
static int l_add_entity(lua_State *L)
@@ -3431,19 +3612,6 @@ private:
return 0;
}
- // EnvRef:get_meta(pos)
- static int l_get_meta(lua_State *L)
- {
- //infostream<<"EnvRef::l_get_meta()"<<std::endl;
- EnvRef *o = checkobject(L, 1);
- ServerEnvironment *env = o->m_env;
- if(env == NULL) return 0;
- // Do it
- v3s16 p = read_v3s16(L, 2);
- NodeMetaRef::create(L, p, env);
- return 1;
- }
-
// EnvRef:get_player_by_name(name)
static int l_get_player_by_name(lua_State *L)
{
@@ -3713,6 +3881,7 @@ const luaL_reg EnvRef::methods[] = {
method(EnvRef, add_rat),
method(EnvRef, add_firefly),
method(EnvRef, get_meta),
+ method(EnvRef, get_node_timer),
method(EnvRef, get_player_by_name),
method(EnvRef, get_objects_inside_radius),
method(EnvRef, set_timeofday),
@@ -4729,6 +4898,7 @@ void scriptapi_export(lua_State *L, Server *server)
LuaItemStack::Register(L);
InvRef::Register(L);
NodeMetaRef::Register(L);
+ NodeTimerRef::Register(L);
ObjectRef::Register(L);
EnvRef::Register(L);
LuaPseudoRandom::Register(L);
@@ -5482,6 +5652,29 @@ void scriptapi_node_after_destruct(lua_State *L, v3s16 p, MapNode node)
script_error(L, "error: %s", lua_tostring(L, -1));
}
+bool scriptapi_node_on_timer(lua_State *L, v3s16 p, MapNode node, f32 dtime)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ StackUnroller stack_unroller(L);
+
+ INodeDefManager *ndef = get_server(L)->ndef();
+
+ // Push callback function on stack
+ if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_timer"))
+ return false;
+
+ // Call function
+ push_v3s16(L, p);
+ lua_pushnumber(L,dtime);
+ if(lua_pcall(L, 2, 1, 0))
+ script_error(L, "error: %s", lua_tostring(L, -1));
+ if(lua_isboolean(L,-1) && lua_toboolean(L,-1) == true)
+ return true;
+
+ return false;
+}
+
void scriptapi_node_on_receive_fields(lua_State *L, v3s16 p,
const std::string &formname,
const std::map<std::string, std::string> &fields,