Skip to content
Snippets Groups Projects
Commit 1220b642 authored by Perttu Ahola's avatar Perttu Ahola
Browse files

Falling sand and gravel

parent cc03718d
Branches
Tags
No related merge requests found
......@@ -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 @@ class StackUnroller
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 @@ class EnvRef
// 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 @@ class EnvRef
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
MapNode n = readnode(L, 3, env->getGameDef()->ndef());
// Do it
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
u16 content = 0;
lua_pushvalue(L, 3); // Push content
content = lua_tonumber(L, -1);
lua_pop(L, 1); // Pop content
const char *name = lua_tostring(L, 3);
// Do it
env->getMap().addNodeWithEvent(pos, MapNode(content));
ServerActiveObject *obj = new LuaEntitySAO(env, pos, name, "");
env->addActiveObject(obj);
return 0;
}
......@@ -650,6 +702,9 @@ class EnvRef
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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment