mirror of
https://github.com/minetest/minetest.git
synced 2024-11-23 16: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 methods:
|
||||
-- - add_node(pos, content); pos={x=num, y=num, z=num}
|
||||
-- TODO: content -> MapNode as described below
|
||||
-- - add_node(pos, node)
|
||||
-- - remove_node(pos)
|
||||
-- - get_node(pos)
|
||||
--
|
||||
-- ObjectRef is basically ServerActiveObject.
|
||||
-- ObjectRef methods:
|
||||
@ -117,28 +118,11 @@ end
|
||||
-- MapNode representation:
|
||||
-- {name="name", param1=num, param2=num}
|
||||
--
|
||||
-- Position representation:
|
||||
-- {x=num, y=num, z=num}
|
||||
--
|
||||
|
||||
print("omg lol")
|
||||
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)
|
||||
-- print("minetest dump: "..dump(minetest))
|
||||
|
||||
minetest.register_tool("WPick", {
|
||||
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 = {
|
||||
-- Static definition
|
||||
-- Maybe handle gravity and collision this way? dunno
|
||||
physical = true,
|
||||
weight = 5,
|
||||
-- physical = true,
|
||||
-- weight = 5,
|
||||
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
|
||||
visual = "cube",
|
||||
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
|
||||
timer = 0,
|
||||
-- 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
|
||||
@ -665,9 +683,106 @@ print("TNT dump: "..dump(TNT))
|
||||
print("Registering 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:")
|
||||
dump2(minetest.registered_entities)
|
||||
|
||||
--
|
||||
-- Some random pre-implementation planning and drafting
|
||||
--
|
||||
|
||||
--[[
|
||||
function TNT:on_rightclick(clicker)
|
||||
print("TNT:on_rightclick()")
|
||||
@ -677,7 +792,7 @@ function TNT:on_rightclick(clicker)
|
||||
pos = self.object:getpos()
|
||||
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}
|
||||
--minetest.env:add_node(pos, 0)
|
||||
--minetest.env:add_node(pos, {name="stone")
|
||||
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);
|
||||
if(ret){
|
||||
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] "<<std::endl;
|
||||
lua_pop(L, 1); // Pop error message from stack
|
||||
return false;
|
||||
}
|
||||
|
@ -126,18 +126,16 @@ public:
|
||||
static v3f readFloatPos(lua_State *L, int index)
|
||||
{
|
||||
v3f pos;
|
||||
lua_pushvalue(L, index); // Push pos
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
lua_getfield(L, -1, "x");
|
||||
luaL_checktype(L, index, LUA_TTABLE);
|
||||
lua_getfield(L, index, "x");
|
||||
pos.X = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "y");
|
||||
lua_getfield(L, index, "y");
|
||||
pos.Y = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "z");
|
||||
lua_getfield(L, index, "z");
|
||||
pos.Z = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
lua_pop(L, 1); // Pop pos
|
||||
pos *= BS; // Scale to internal format
|
||||
return pos;
|
||||
}
|
||||
@ -153,6 +151,18 @@ static void pushpos(lua_State *L, v3s16 p)
|
||||
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)
|
||||
{
|
||||
lua_newtable(L);
|
||||
@ -169,11 +179,19 @@ static MapNode readnode(lua_State *L, int index, INodeDefManager *ndef)
|
||||
lua_getfield(L, index, "name");
|
||||
const char *name = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
u8 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);
|
||||
u8 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);
|
||||
return MapNode(ndef, name, param1, param2);
|
||||
}
|
||||
@ -551,9 +569,8 @@ private:
|
||||
|
||||
// Exported functions
|
||||
|
||||
// EnvRef:add_node(pos, content)
|
||||
// EnvRef:add_node(pos, node)
|
||||
// pos = {x=num, y=num, z=num}
|
||||
// content = number
|
||||
static int l_add_node(lua_State *L)
|
||||
{
|
||||
infostream<<"EnvRef::l_add_node()"<<std::endl;
|
||||
@ -561,26 +578,61 @@ private:
|
||||
ServerEnvironment *env = o->m_env;
|
||||
if(env == NULL) return 0;
|
||||
// pos
|
||||
v3s16 pos;
|
||||
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
|
||||
v3s16 pos = readpos(L, 2);
|
||||
// content
|
||||
u16 content = 0;
|
||||
lua_pushvalue(L, 3); // Push content
|
||||
content = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1); // Pop content
|
||||
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -650,6 +702,9 @@ public:
|
||||
const char EnvRef::className[] = "EnvRef";
|
||||
const luaL_reg EnvRef::methods[] = {
|
||||
method(EnvRef, add_node),
|
||||
method(EnvRef, remove_node),
|
||||
method(EnvRef, get_node),
|
||||
method(EnvRef, add_luaentity),
|
||||
{0,0}
|
||||
};
|
||||
|
||||
@ -1281,6 +1336,8 @@ void scriptapi_luaentity_step(lua_State *L, u16 id, float dtime)
|
||||
// State: object is at top of stack
|
||||
// Get step function
|
||||
lua_getfield(L, -1, "on_step");
|
||||
if(lua_isnil(L, -1))
|
||||
return;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, object); // self
|
||||
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
|
||||
// Get function
|
||||
lua_getfield(L, -1, "on_punch");
|
||||
if(lua_isnil(L, -1))
|
||||
return;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, object); // self
|
||||
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
|
||||
// Get function
|
||||
lua_getfield(L, -1, "on_rightclick");
|
||||
if(lua_isnil(L, -1))
|
||||
return;
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
lua_pushvalue(L, object); // self
|
||||
objectref_get_or_create(L, clicker); // Clicker reference
|
||||
|
Loading…
Reference in New Issue
Block a user