mirror of
https://github.com/minetest/minetest.git
synced 2024-12-25 15:42:24 +01:00
Lua interface for ActiveBlockModifier
This commit is contained in:
parent
8924588511
commit
34bd1b3032
@ -1296,36 +1296,6 @@ end
|
|||||||
register_falling_node("sand", "sand.png")
|
register_falling_node("sand", "sand.png")
|
||||||
register_falling_node("gravel", "gravel.png")
|
register_falling_node("gravel", "gravel.png")
|
||||||
|
|
||||||
--[[
|
|
||||||
minetest.register_entity("falling_sand", {
|
|
||||||
-- Definition
|
|
||||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
|
||||||
visual = "cube",
|
|
||||||
textures = {"sand.png","sand.png","sand.png","sand.png","sand.png","sand.png"},
|
|
||||||
-- State
|
|
||||||
fallspeed = 0,
|
|
||||||
-- Methods
|
|
||||||
on_step = function(self, dtime)
|
|
||||||
-- Apply gravity
|
|
||||||
self.fallspeed = self.fallspeed + dtime * 5
|
|
||||||
fp = self.object:getpos()
|
|
||||||
fp.y = fp.y - self.fallspeed * dtime
|
|
||||||
self.object:moveto(fp)
|
|
||||||
-- Turn to actual sand when collides to ground or just move
|
|
||||||
bcp = {x=fp.x, y=fp.y-0.5, z=fp.z} -- Position of bottom center point
|
|
||||||
bcn = minetest.env:get_node(bcp)
|
|
||||||
if bcn.name ~= "air" then
|
|
||||||
-- Turn to a sand node
|
|
||||||
np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
|
|
||||||
minetest.env:add_node(np, {name="sand"})
|
|
||||||
self.object:remove()
|
|
||||||
else
|
|
||||||
-- Do nothing
|
|
||||||
end
|
|
||||||
end
|
|
||||||
})
|
|
||||||
--]]
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Global callbacks
|
-- Global callbacks
|
||||||
--
|
--
|
||||||
@ -1389,6 +1359,17 @@ minetest.register_on_chat_message(function(name, message)
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
minetest.register_abm({
|
||||||
|
nodenames = {"TNT"},
|
||||||
|
interval = 10.0,
|
||||||
|
chance = 1,
|
||||||
|
action = function(pos, node, active_object_count, active_object_count_wider)
|
||||||
|
print("TNT ABM action")
|
||||||
|
pos.y = pos.y + 1
|
||||||
|
minetest.env:add_node(pos, {name="papyrus"})
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Done, print some random stuff
|
-- Done, print some random stuff
|
||||||
--
|
--
|
||||||
|
@ -498,6 +498,105 @@ static int l_register_entity(lua_State *L)
|
|||||||
return 0; /* number of results */
|
return 0; /* number of results */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class LuaABM : public ActiveBlockModifier
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
lua_State *m_lua;
|
||||||
|
int m_id;
|
||||||
|
|
||||||
|
std::set<std::string> m_trigger_contents;
|
||||||
|
float m_trigger_interval;
|
||||||
|
u32 m_trigger_chance;
|
||||||
|
public:
|
||||||
|
LuaABM(lua_State *L, int id,
|
||||||
|
const std::set<std::string> &trigger_contents,
|
||||||
|
float trigger_interval, u32 trigger_chance):
|
||||||
|
m_lua(L),
|
||||||
|
m_id(id),
|
||||||
|
m_trigger_contents(trigger_contents),
|
||||||
|
m_trigger_interval(trigger_interval),
|
||||||
|
m_trigger_chance(trigger_chance)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
virtual std::set<std::string> getTriggerContents()
|
||||||
|
{
|
||||||
|
return m_trigger_contents;
|
||||||
|
}
|
||||||
|
virtual float getTriggerInterval()
|
||||||
|
{
|
||||||
|
return m_trigger_interval;
|
||||||
|
}
|
||||||
|
virtual u32 getTriggerChance()
|
||||||
|
{
|
||||||
|
return m_trigger_chance;
|
||||||
|
}
|
||||||
|
virtual void trigger(ServerEnvironment *env, v3s16 p, MapNode n,
|
||||||
|
u32 active_object_count, u32 active_object_count_wider)
|
||||||
|
{
|
||||||
|
lua_State *L = m_lua;
|
||||||
|
|
||||||
|
realitycheck(L);
|
||||||
|
assert(lua_checkstack(L, 20));
|
||||||
|
StackUnroller stack_unroller(L);
|
||||||
|
|
||||||
|
// Get minetest.registered_abms
|
||||||
|
lua_getglobal(L, "minetest");
|
||||||
|
lua_getfield(L, -1, "registered_abms");
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
int registered_abms = lua_gettop(L);
|
||||||
|
|
||||||
|
// Get minetest.registered_abms[m_id]
|
||||||
|
lua_pushnumber(L, m_id);
|
||||||
|
lua_gettable(L, registered_abms);
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
assert(0);
|
||||||
|
|
||||||
|
// Call action
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
lua_getfield(L, -1, "action");
|
||||||
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
|
pushpos(L, p);
|
||||||
|
pushnode(L, n, env->getGameDef()->ndef());
|
||||||
|
lua_pushnumber(L, active_object_count);
|
||||||
|
lua_pushnumber(L, active_object_count_wider);
|
||||||
|
if(lua_pcall(L, 4, 0, 0))
|
||||||
|
script_error(L, "error: %s\n", lua_tostring(L, -1));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// register_abm({...})
|
||||||
|
static int l_register_abm(lua_State *L)
|
||||||
|
{
|
||||||
|
infostream<<"register_abm"<<std::endl;
|
||||||
|
luaL_checktype(L, 1, LUA_TTABLE);
|
||||||
|
|
||||||
|
// Get minetest.registered_abms
|
||||||
|
lua_getglobal(L, "minetest");
|
||||||
|
lua_getfield(L, -1, "registered_abms");
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
int registered_abms = lua_gettop(L);
|
||||||
|
|
||||||
|
int id = 1;
|
||||||
|
// Find free id
|
||||||
|
for(;;){
|
||||||
|
lua_pushnumber(L, id);
|
||||||
|
lua_gettable(L, registered_abms);
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
break;
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
infostream<<"register_abm: id="<<id<<std::endl;
|
||||||
|
|
||||||
|
// registered_abms[id] = spec
|
||||||
|
lua_pushnumber(L, id);
|
||||||
|
lua_pushvalue(L, 1);
|
||||||
|
lua_settable(L, registered_abms);
|
||||||
|
|
||||||
|
return 0; /* number of results */
|
||||||
|
}
|
||||||
|
|
||||||
// register_tool(name, {lots of stuff})
|
// register_tool(name, {lots of stuff})
|
||||||
static int l_register_tool(lua_State *L)
|
static int l_register_tool(lua_State *L)
|
||||||
{
|
{
|
||||||
@ -894,6 +993,7 @@ static const struct luaL_Reg minetest_f [] = {
|
|||||||
{"register_tool", l_register_tool},
|
{"register_tool", l_register_tool},
|
||||||
{"register_node", l_register_node},
|
{"register_node", l_register_node},
|
||||||
{"register_craft", l_register_craft},
|
{"register_craft", l_register_craft},
|
||||||
|
{"register_abm", l_register_abm},
|
||||||
{"setting_get", l_setting_get},
|
{"setting_get", l_setting_get},
|
||||||
{"setting_getbool", l_setting_getbool},
|
{"setting_getbool", l_setting_getbool},
|
||||||
{"chat_send_all", l_chat_send_all},
|
{"chat_send_all", l_chat_send_all},
|
||||||
@ -1420,6 +1520,8 @@ void scriptapi_export(lua_State *L, Server *server)
|
|||||||
lua_setfield(L, -2, "registered_nodes");
|
lua_setfield(L, -2, "registered_nodes");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, -2, "registered_entities");
|
lua_setfield(L, -2, "registered_entities");
|
||||||
|
lua_newtable(L);
|
||||||
|
lua_setfield(L, -2, "registered_abms");
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
lua_setfield(L, -2, "object_refs");
|
lua_setfield(L, -2, "object_refs");
|
||||||
@ -1458,6 +1560,58 @@ void scriptapi_add_environment(lua_State *L, ServerEnvironment *env)
|
|||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
lua_pushvalue(L, envref);
|
lua_pushvalue(L, envref);
|
||||||
lua_setfield(L, -2, "env");
|
lua_setfield(L, -2, "env");
|
||||||
|
|
||||||
|
// Store environment as light userdata in registry
|
||||||
|
lua_pushlightuserdata(L, env);
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, "minetest_env");
|
||||||
|
|
||||||
|
/* Add ActiveBlockModifiers to environment */
|
||||||
|
|
||||||
|
// Get minetest.registered_abms
|
||||||
|
lua_getglobal(L, "minetest");
|
||||||
|
lua_getfield(L, -1, "registered_abms");
|
||||||
|
luaL_checktype(L, -1, LUA_TTABLE);
|
||||||
|
int registered_abms = lua_gettop(L);
|
||||||
|
|
||||||
|
if(lua_istable(L, registered_abms)){
|
||||||
|
int table = lua_gettop(L);
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, table) != 0){
|
||||||
|
// key at index -2 and value at index -1
|
||||||
|
int id = lua_tonumber(L, -2);
|
||||||
|
int current_abm = lua_gettop(L);
|
||||||
|
|
||||||
|
std::set<std::string> trigger_contents;
|
||||||
|
lua_getfield(L, current_abm, "nodenames");
|
||||||
|
if(lua_istable(L, -1)){
|
||||||
|
int table = lua_gettop(L);
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, table) != 0){
|
||||||
|
// key at index -2 and value at index -1
|
||||||
|
luaL_checktype(L, -1, LUA_TSTRING);
|
||||||
|
trigger_contents.insert(lua_tostring(L, -1));
|
||||||
|
// removes value, keeps key for next iteration
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
float trigger_interval = 10.0;
|
||||||
|
getfloatfield(L, current_abm, "interval", trigger_interval);
|
||||||
|
|
||||||
|
int trigger_chance = 50;
|
||||||
|
getintfield(L, current_abm, "chance", trigger_chance);
|
||||||
|
|
||||||
|
LuaABM *abm = new LuaABM(L, id, trigger_contents,
|
||||||
|
trigger_interval, trigger_chance);
|
||||||
|
|
||||||
|
env->addActiveBlockModifier(abm);
|
||||||
|
|
||||||
|
// removes value, keeps key for next iteration
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
Reference in New Issue
Block a user