mirror of
https://github.com/minetest/minetest.git
synced 2024-11-27 18:13:46 +01:00
Falling sand and gravel
This commit is contained in:
parent
cc03718d3c
commit
1220b642eb
@ -98,8 +98,9 @@ end
|
|||||||
--
|
--
|
||||||
-- EnvRef is basically ServerEnvironment and ServerMap combined.
|
-- EnvRef is basically ServerEnvironment and ServerMap combined.
|
||||||
-- EnvRef methods:
|
-- EnvRef methods:
|
||||||
-- - add_node(pos, content); pos={x=num, y=num, z=num}
|
-- - add_node(pos, node)
|
||||||
-- TODO: content -> MapNode as described below
|
-- - remove_node(pos)
|
||||||
|
-- - get_node(pos)
|
||||||
--
|
--
|
||||||
-- ObjectRef is basically ServerActiveObject.
|
-- ObjectRef is basically ServerActiveObject.
|
||||||
-- ObjectRef methods:
|
-- ObjectRef methods:
|
||||||
@ -117,28 +118,11 @@ end
|
|||||||
-- MapNode representation:
|
-- MapNode representation:
|
||||||
-- {name="name", param1=num, param2=num}
|
-- {name="name", param1=num, param2=num}
|
||||||
--
|
--
|
||||||
|
-- Position representation:
|
||||||
|
-- {x=num, y=num, z=num}
|
||||||
|
--
|
||||||
|
|
||||||
print("omg lol")
|
-- print("minetest dump: "..dump(minetest))
|
||||||
print("minetest dump: "..dump(minetest))
|
|
||||||
|
|
||||||
-- Global environment step function
|
|
||||||
function on_step(dtime)
|
|
||||||
-- print("on_step")
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_globalstep(on_step)
|
|
||||||
|
|
||||||
function on_placenode(p, node)
|
|
||||||
print("on_placenode")
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_placenode(on_placenode)
|
|
||||||
|
|
||||||
function on_dignode(p, node)
|
|
||||||
print("on_dignode")
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_dignode(on_dignode)
|
|
||||||
|
|
||||||
minetest.register_tool("WPick", {
|
minetest.register_tool("WPick", {
|
||||||
image = "tool_woodpick.png",
|
image = "tool_woodpick.png",
|
||||||
@ -626,10 +610,43 @@ minetest.register_craft({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Some common functions
|
||||||
|
--
|
||||||
|
|
||||||
|
function nodeupdate_single(p)
|
||||||
|
n = minetest.env:get_node(p)
|
||||||
|
if n.name == "sand" or n.name == "gravel" then
|
||||||
|
p_bottom = {x=p.x, y=p.y-1, z=p.z}
|
||||||
|
n_bottom = minetest.env:get_node(p_bottom)
|
||||||
|
if n_bottom.name == "air" then
|
||||||
|
minetest.env:remove_node(p)
|
||||||
|
minetest.env:add_luaentity(p, "falling_"..n.name)
|
||||||
|
nodeupdate(p)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function nodeupdate(p)
|
||||||
|
for x = -1,1 do
|
||||||
|
for y = -1,1 do
|
||||||
|
for z = -1,1 do
|
||||||
|
p2 = {x=p.x+x, y=p.y+y, z=p.z+z}
|
||||||
|
nodeupdate_single(p2)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
--
|
||||||
|
-- TNT (not functional)
|
||||||
|
--
|
||||||
|
|
||||||
local TNT = {
|
local TNT = {
|
||||||
|
-- Static definition
|
||||||
-- Maybe handle gravity and collision this way? dunno
|
-- Maybe handle gravity and collision this way? dunno
|
||||||
physical = true,
|
-- physical = true,
|
||||||
weight = 5,
|
-- weight = 5,
|
||||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||||
visual = "cube",
|
visual = "cube",
|
||||||
textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
|
textures = {"tnt_top.png","tnt_bottom.png","tnt_side.png","tnt_side.png","tnt_side.png","tnt_side.png"},
|
||||||
@ -638,7 +655,8 @@ local TNT = {
|
|||||||
-- Initial value for our timer
|
-- Initial value for our timer
|
||||||
timer = 0,
|
timer = 0,
|
||||||
-- List names of state variables, for serializing object state
|
-- List names of state variables, for serializing object state
|
||||||
state_variables = {"timer"},
|
-- (NOTE: not implemented and implementation will not be like this)
|
||||||
|
-- state_variables = {"timer"},
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Called periodically
|
-- Called periodically
|
||||||
@ -665,9 +683,106 @@ print("TNT dump: "..dump(TNT))
|
|||||||
print("Registering TNT");
|
print("Registering TNT");
|
||||||
minetest.register_entity("TNT", TNT)
|
minetest.register_entity("TNT", TNT)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Falling stuff
|
||||||
|
--
|
||||||
|
|
||||||
|
function register_falling_node(nodename, texture)
|
||||||
|
minetest.register_entity("falling_"..nodename, {
|
||||||
|
-- Static definition
|
||||||
|
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||||
|
visual = "cube",
|
||||||
|
textures = {texture,texture,texture,texture,texture,texture},
|
||||||
|
-- State
|
||||||
|
fallspeed = 0,
|
||||||
|
-- Methods
|
||||||
|
on_step = function(self, dtime)
|
||||||
|
-- Apply gravity manually
|
||||||
|
self.fallspeed = self.fallspeed + dtime * 5
|
||||||
|
fp = self.object:getpos()
|
||||||
|
fp.y = fp.y - self.fallspeed * dtime
|
||||||
|
self.object:moveto(fp, true)
|
||||||
|
-- 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=nodename})
|
||||||
|
self.object:remove()
|
||||||
|
else
|
||||||
|
-- Do nothing
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
register_falling_node("sand", "sand.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 environment step function
|
||||||
|
function on_step(dtime)
|
||||||
|
-- print("on_step")
|
||||||
|
end
|
||||||
|
minetest.register_globalstep(on_step)
|
||||||
|
|
||||||
|
function on_placenode(p, node)
|
||||||
|
print("on_placenode")
|
||||||
|
nodeupdate(p)
|
||||||
|
end
|
||||||
|
minetest.register_on_placenode(on_placenode)
|
||||||
|
|
||||||
|
function on_dignode(p, node)
|
||||||
|
print("on_dignode")
|
||||||
|
nodeupdate(p)
|
||||||
|
end
|
||||||
|
minetest.register_on_dignode(on_dignode)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Done, print some random stuff
|
||||||
|
--
|
||||||
|
|
||||||
print("minetest.registered_entities:")
|
print("minetest.registered_entities:")
|
||||||
dump2(minetest.registered_entities)
|
dump2(minetest.registered_entities)
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Some random pre-implementation planning and drafting
|
||||||
|
--
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
function TNT:on_rightclick(clicker)
|
function TNT:on_rightclick(clicker)
|
||||||
print("TNT:on_rightclick()")
|
print("TNT:on_rightclick()")
|
||||||
@ -677,7 +792,7 @@ function TNT:on_rightclick(clicker)
|
|||||||
pos = self.object:getpos()
|
pos = self.object:getpos()
|
||||||
print("TNT:on_rightclick(): object position: "..dump(pos))
|
print("TNT:on_rightclick(): object position: "..dump(pos))
|
||||||
pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
|
pos = {x=pos.x+0.5+1, y=pos.y+0.5, z=pos.z+0.5}
|
||||||
--minetest.env:add_node(pos, 0)
|
--minetest.env:add_node(pos, {name="stone")
|
||||||
end
|
end
|
||||||
--]]
|
--]]
|
||||||
|
|
||||||
|
@ -47,7 +47,9 @@ bool script_load(lua_State *L, const char *path)
|
|||||||
int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, 0);
|
int ret = luaL_loadfile(L, path) || lua_pcall(L, 0, 0, 0);
|
||||||
if(ret){
|
if(ret){
|
||||||
errorstream<<"Failed to load and run script from "<<path<<":"<<std::endl;
|
errorstream<<"Failed to load and run script from "<<path<<":"<<std::endl;
|
||||||
|
errorstream<<"[LUA] "<<std::endl;
|
||||||
errorstream<<"[LUA] "<<lua_tostring(L, -1)<<std::endl;
|
errorstream<<"[LUA] "<<lua_tostring(L, -1)<<std::endl;
|
||||||
|
errorstream<<"[LUA] "<<std::endl;
|
||||||
lua_pop(L, 1); // Pop error message from stack
|
lua_pop(L, 1); // Pop error message from stack
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -126,18 +126,16 @@ public:
|
|||||||
static v3f readFloatPos(lua_State *L, int index)
|
static v3f readFloatPos(lua_State *L, int index)
|
||||||
{
|
{
|
||||||
v3f pos;
|
v3f pos;
|
||||||
lua_pushvalue(L, index); // Push pos
|
luaL_checktype(L, index, LUA_TTABLE);
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
lua_getfield(L, index, "x");
|
||||||
lua_getfield(L, -1, "x");
|
|
||||||
pos.X = lua_tonumber(L, -1);
|
pos.X = lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_getfield(L, -1, "y");
|
lua_getfield(L, index, "y");
|
||||||
pos.Y = lua_tonumber(L, -1);
|
pos.Y = lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_getfield(L, -1, "z");
|
lua_getfield(L, index, "z");
|
||||||
pos.Z = lua_tonumber(L, -1);
|
pos.Z = lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
lua_pop(L, 1); // Pop pos
|
|
||||||
pos *= BS; // Scale to internal format
|
pos *= BS; // Scale to internal format
|
||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
@ -153,6 +151,18 @@ static void pushpos(lua_State *L, v3s16 p)
|
|||||||
lua_setfield(L, -2, "z");
|
lua_setfield(L, -2, "z");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static v3s16 readpos(lua_State *L, int index)
|
||||||
|
{
|
||||||
|
v3s16 p;
|
||||||
|
lua_getfield(L, index, "x");
|
||||||
|
p.X = lua_tonumber(L, -1);
|
||||||
|
lua_getfield(L, index, "y");
|
||||||
|
p.Y = lua_tonumber(L, -1);
|
||||||
|
lua_getfield(L, index, "z");
|
||||||
|
p.Z = lua_tonumber(L, -1);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
|
static void pushnode(lua_State *L, const MapNode &n, INodeDefManager *ndef)
|
||||||
{
|
{
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
@ -169,11 +179,19 @@ static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
|
|||||||
lua_getfield(L, index, "name");
|
lua_getfield(L, index, "name");
|
||||||
const char *name = lua_tostring(L, -1);
|
const char *name = lua_tostring(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
u8 param1;
|
||||||
lua_getfield(L, index, "param1");
|
lua_getfield(L, index, "param1");
|
||||||
u8 param1 = lua_tonumber(L, -1);
|
if(lua_isnil(L, -1))
|
||||||
|
param1 = 0;
|
||||||
|
else
|
||||||
|
param1 = lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
u8 param2;
|
||||||
lua_getfield(L, index, "param2");
|
lua_getfield(L, index, "param2");
|
||||||
u8 param2 = lua_tonumber(L, -1);
|
if(lua_isnil(L, -1))
|
||||||
|
param2 = 0;
|
||||||
|
else
|
||||||
|
param2 = lua_tonumber(L, -1);
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
return MapNode(ndef, name, param1, param2);
|
return MapNode(ndef, name, param1, param2);
|
||||||
}
|
}
|
||||||
@ -551,9 +569,8 @@ private:
|
|||||||
|
|
||||||
// Exported functions
|
// Exported functions
|
||||||
|
|
||||||
// EnvRef:add_node(pos, content)
|
// EnvRef:add_node(pos, node)
|
||||||
// pos = {x=num, y=num, z=num}
|
// pos = {x=num, y=num, z=num}
|
||||||
// content = number
|
|
||||||
static int l_add_node(lua_State *L)
|
static int l_add_node(lua_State *L)
|
||||||
{
|
{
|
||||||
infostream<<"EnvRef::l_add_node()"<<std::endl;
|
infostream<<"EnvRef::l_add_node()"<<std::endl;
|
||||||
@ -561,26 +578,61 @@ private:
|
|||||||
ServerEnvironment *env = o->m_env;
|
ServerEnvironment *env = o->m_env;
|
||||||
if(env == NULL) return 0;
|
if(env == NULL) return 0;
|
||||||
// pos
|
// pos
|
||||||
v3s16 pos;
|
v3s16 pos = readpos(L, 2);
|
||||||
lua_pushvalue(L, 2); // Push pos
|
|
||||||
luaL_checktype(L, -1, LUA_TTABLE);
|
|
||||||
lua_getfield(L, -1, "x");
|
|
||||||
pos.X = lua_tonumber(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_getfield(L, -1, "y");
|
|
||||||
pos.Y = lua_tonumber(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_getfield(L, -1, "z");
|
|
||||||
pos.Z = lua_tonumber(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_pop(L, 1); // Pop pos
|
|
||||||
// content
|
// content
|
||||||
u16 content = 0;
|
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
||||||
lua_pushvalue(L, 3); // Push content
|
|
||||||
content = lua_tonumber(L, -1);
|
|
||||||
lua_pop(L, 1); // Pop content
|
|
||||||
// Do it
|
// Do it
|
||||||
env->getMap().addNodeWithEvent(pos, MapNode(content));
|
env->getMap().addNodeWithEvent(pos, n);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvRef:remove_node(pos)
|
||||||
|
// pos = {x=num, y=num, z=num}
|
||||||
|
static int l_remove_node(lua_State *L)
|
||||||
|
{
|
||||||
|
infostream<<"EnvRef::l_remove_node()"<<std::endl;
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
// pos
|
||||||
|
v3s16 pos = readpos(L, 2);
|
||||||
|
// Do it
|
||||||
|
env->getMap().removeNodeWithEvent(pos);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvRef:get_node(pos)
|
||||||
|
// pos = {x=num, y=num, z=num}
|
||||||
|
static int l_get_node(lua_State *L)
|
||||||
|
{
|
||||||
|
infostream<<"EnvRef::l_get_node()"<<std::endl;
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
// pos
|
||||||
|
v3s16 pos = readpos(L, 2);
|
||||||
|
// Do it
|
||||||
|
MapNode n = env->getMap().getNodeNoEx(pos);
|
||||||
|
// Return node
|
||||||
|
pushnode(L, n, env->getGameDef()->ndef());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// EnvRef:add_luaentity(pos, entityname)
|
||||||
|
// pos = {x=num, y=num, z=num}
|
||||||
|
static int l_add_luaentity(lua_State *L)
|
||||||
|
{
|
||||||
|
infostream<<"EnvRef::l_add_luaentity()"<<std::endl;
|
||||||
|
EnvRef *o = checkobject(L, 1);
|
||||||
|
ServerEnvironment *env = o->m_env;
|
||||||
|
if(env == NULL) return 0;
|
||||||
|
// pos
|
||||||
|
v3f pos = readFloatPos(L, 2);
|
||||||
|
// content
|
||||||
|
const char *name = lua_tostring(L, 3);
|
||||||
|
// Do it
|
||||||
|
ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
|
||||||
|
env->addActiveObject(obj);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -650,6 +702,9 @@ public:
|
|||||||
const char EnvRef::className[] = "EnvRef";
|
const char EnvRef::className[] = "EnvRef";
|
||||||
const luaL_reg EnvRef::methods[] = {
|
const luaL_reg EnvRef::methods[] = {
|
||||||
method(EnvRef, add_node),
|
method(EnvRef, add_node),
|
||||||
|
method(EnvRef, remove_node),
|
||||||
|
method(EnvRef, get_node),
|
||||||
|
method(EnvRef, add_luaentity),
|
||||||
{0,0}
|
{0,0}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1281,6 +1336,8 @@ void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
|
|||||||
// State: object is at top of stack
|
// State: object is at top of stack
|
||||||
// Get step function
|
// Get step function
|
||||||
lua_getfield(L, -1, "on_step");
|
lua_getfield(L, -1, "on_step");
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
return;
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
lua_pushnumber(L, dtime); // dtime
|
lua_pushnumber(L, dtime); // dtime
|
||||||
@ -1304,6 +1361,8 @@ void scriptapi_luaentity_punch(lua_State *L, u16 id,
|
|||||||
// State: object is at top of stack
|
// State: object is at top of stack
|
||||||
// Get function
|
// Get function
|
||||||
lua_getfield(L, -1, "on_punch");
|
lua_getfield(L, -1, "on_punch");
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
return;
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
objectref_get_or_create(L, puncher); // Clicker reference
|
objectref_get_or_create(L, puncher); // Clicker reference
|
||||||
@ -1327,6 +1386,8 @@ void scriptapi_luaentity_rightclick(lua_State *L, u16 id,
|
|||||||
// State: object is at top of stack
|
// State: object is at top of stack
|
||||||
// Get function
|
// Get function
|
||||||
lua_getfield(L, -1, "on_rightclick");
|
lua_getfield(L, -1, "on_rightclick");
|
||||||
|
if(lua_isnil(L, -1))
|
||||||
|
return;
|
||||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||||
lua_pushvalue(L, object); // self
|
lua_pushvalue(L, object); // self
|
||||||
objectref_get_or_create(L, clicker); // Clicker reference
|
objectref_get_or_create(L, clicker); // Clicker reference
|
||||||
|
Loading…
Reference in New Issue
Block a user