Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move falling to builtin #270

Merged
merged 4 commits into from Nov 1, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions builtin/builtin.lua
Expand Up @@ -22,4 +22,5 @@ dofile(minetest.get_modpath("__builtin").."/auth.lua")
dofile(minetest.get_modpath("__builtin").."/chatcommands.lua")
dofile(minetest.get_modpath("__builtin").."/static_spawn.lua")
dofile(minetest.get_modpath("__builtin").."/detached_inventory.lua")
dofile(minetest.get_modpath("__builtin").."/falling.lua")

136 changes: 136 additions & 0 deletions builtin/falling.lua
@@ -0,0 +1,136 @@
-- Minetest: builtin/item.lua

--
-- Falling stuff
--

minetest.register_entity("__builtin:falling_node", {
initial_properties = {
physical = true,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "wielditem",
textures = {},
visual_size = {x=0.667, y=0.667},
},

nodename = "",

set_node = function(self, nodename)
self.nodename = nodename
local stack = ItemStack(nodename)
local itemtable = stack:to_table()
local itemname = nil
if itemtable then
itemname = stack:to_table().name
end
local item_texture = nil
local item_type = ""
if minetest.registered_items[itemname] then
item_texture = minetest.registered_items[itemname].inventory_image
item_type = minetest.registered_items[itemname].type
end
prop = {
is_visible = true,
textures = {nodename},
}
self.object:set_properties(prop)
end,

get_staticdata = function(self)
return self.nodename
end,

on_activate = function(self, staticdata)
self.nodename = staticdata
self.object:set_armor_groups({immortal=1})
--self.object:setacceleration({x=0, y=-10, z=0})
self:set_node(self.nodename)
end,

on_step = function(self, dtime)
-- Set gravity
self.object:setacceleration({x=0, y=-10, z=0})
-- Turn to actual sand when collides to ground or just move
local pos = self.object:getpos()
local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
local bcn = minetest.env:get_node(bcp)
-- Note: walkable is in the node definition, not in item groups
if minetest.registered_nodes[bcn.name] and
minetest.registered_nodes[bcn.name].walkable then
local np = {x=bcp.x, y=bcp.y+1, z=bcp.z}
-- Check what's here
local n2 = minetest.env:get_node(np)
-- If it's not air or liquid, remove node and replace it with
-- it's drops
if n2.name ~= "air" and (not minetest.registered_nodes[n2.name] or
minetest.registered_nodes[n2.name].liquidtype == "none") then
local drops = minetest.get_node_drops(n2.name, "")
minetest.env:remove_node(np)
-- Add dropped items
local _, dropped_item
for _, dropped_item in ipairs(drops) do
minetest.env:add_item(np, dropped_item)
end
-- Run script hook
local _, callback
for _, callback in ipairs(minetest.registered_on_dignodes) do
callback(np, n2, nil)
end
end
-- Create node and remove entity
minetest.env:add_node(np, {name=self.nodename})
self.object:remove()
else
-- Do nothing
end
end
})

function spawn_falling_node(p, nodename)
obj = minetest.env:add_entity(p, "__builtin:falling_node")
obj:get_luaentity():set_node(nodename)
end

--
-- Some common functions
--

function nodeupdate_single(p)
n = minetest.env:get_node(p)
if minetest.get_node_group(n.name, "falling_node") ~= 0 then
p_bottom = {x=p.x, y=p.y-1, z=p.z}
n_bottom = minetest.env:get_node(p_bottom)
-- Note: walkable is in the node definition, not in item groups
if minetest.registered_nodes[n_bottom.name] and
not minetest.registered_nodes[n_bottom.name].walkable then
minetest.env:remove_node(p)
spawn_falling_node(p, 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

--
-- Global callbacks
--

function on_placenode(p, node)
nodeupdate(p)
end
minetest.register_on_placenode(on_placenode)

function on_dignode(p, node)
nodeupdate(p)
end
minetest.register_on_dignode(on_dignode)
1 change: 1 addition & 0 deletions doc/lua_api.txt
Expand Up @@ -456,6 +456,7 @@ Special groups
- disable_jump: Player (and possibly other things) cannot jump from node
- fall_damage_add_percent: damage speed = speed * (1 + value/100)
- bouncy: value is bounce speed in percent
- falling_node: if there is no walkable block under the node it will fall

Known damage and digging time defining groups
----------------------------------------------
Expand Down
79 changes: 13 additions & 66 deletions games/minimal/mods/default/init.lua
Expand Up @@ -769,15 +769,15 @@ minetest.register_node("default:sand", {
description = "Sand",
tiles ={"default_sand.png"},
is_ground_content = true,
groups = {crumbly=3},
groups = {crumbly=3, falling_node=1},
sounds = default.node_sound_sand_defaults(),
})

minetest.register_node("default:gravel", {
description = "Gravel",
tiles ={"default_gravel.png"},
is_ground_content = true,
groups = {crumbly=2},
groups = {crumbly=2, falling_node=1},
sounds = default.node_sound_dirt_defaults({
footstep = {name="default_gravel_footstep", gain=0.45},
}),
Expand Down Expand Up @@ -1586,73 +1586,22 @@ minetest.register_alias("mapgen_stone_with_coal", "default:stone_with_coal")
minetest.register_alias("mapgen_stone_with_iron", "default:stone_with_iron")
minetest.register_alias("mapgen_mese", "default:mese")

--
-- Some common functions
--

default.falling_node_names = {}

function nodeupdate_single(p)
n = minetest.env:get_node(p)
if default.falling_node_names[n.name] ~= nil 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_entity(p, "default: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
-- Support old code
function default.spawn_falling_node(p, nodename)
spawn_falling_node(p, nodename)
end

--
-- Falling stuff
--

-- Horrible crap to support old code
-- Don't use this and never do what this does, it's completely wrong!
-- (More specifically, the client and the C++ code doesn't get the group)
function default.register_falling_node(nodename, texture)
default.falling_node_names[nodename] = true
-- Override naming conventions for stuff like :default:falling_default:sand
minetest.register_entity(":default:falling_"..nodename, {
-- Static definition
physical = true,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "cube",
textures = {texture,texture,texture,texture,texture,texture},
-- State
-- Methods
on_step = function(self, dtime)
-- Set gravity
self.object:setacceleration({x=0, y=-10, z=0})
-- Turn to actual sand when collides to ground or just move
local pos = self.object:getpos()
local bcp = {x=pos.x, y=pos.y-0.7, z=pos.z} -- Position of bottom center point
local bcn = minetest.env:get_node(bcp)
if bcn.name ~= "air" then
-- Turn to a sand node
local 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
})
minetest.log("error", debug.traceback())
minetest.log('error', "WARNING: default.register_falling_node is deprecated")
if minetest.registered_nodes[nodename] then
minetest.registered_nodes[nodename].groups.falling_node = 1
end
end

default.register_falling_node("default:sand", "default_sand.png")
default.register_falling_node("default:gravel", "default_gravel.png")

--
-- Global callbacks
--
Expand All @@ -1665,13 +1614,11 @@ 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)

Expand Down