summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--builtin/item.lua50
-rw-r--r--src/game.cpp7
2 files changed, 42 insertions, 15 deletions
diff --git a/builtin/item.lua b/builtin/item.lua
index 5cd28303a..08b8d1c58 100644
--- a/builtin/item.lua
+++ b/builtin/item.lua
@@ -125,50 +125,70 @@ function minetest.item_place_node(itemstack, placer, pointed_thing)
local item = itemstack:peek_item()
local def = itemstack:get_definition()
if def.type == "node" and pointed_thing.type == "node" then
- local pos = pointed_thing.above
- local oldnode = minetest.env:get_node(pos)
- local olddef = ItemStack({name=oldnode.name}):get_definition()
-
- if not olddef.buildable_to then
+ local under = pointed_thing.under
+ local oldnode_under = minetest.env:get_node(under)
+ local olddef_under = ItemStack({name=oldnode_under.name}):get_definition()
+ olddef_under = olddef_under or minetest.nodedef_default
+ local above = pointed_thing.above
+ local oldnode_above = minetest.env:get_node(above)
+ local olddef_above = ItemStack({name=oldnode_above.name}):get_definition()
+ olddef_above = olddef_above or minetest.nodedef_default
+
+ if not olddef_above.buildable_to and not olddef_under.buildable_to then
minetest.log("info", placer:get_player_name() .. " tried to place"
- .. " node in invalid position " .. minetest.pos_to_string(pos)
- .. ", replacing " .. oldnode.name)
+ .. " node in invalid position " .. minetest.pos_to_string(above)
+ .. ", replacing " .. oldnode_above.name)
return
end
+ -- Place above pointed node
+ local place_to = {x = above.x, y = above.y, z = above.z}
+
+ -- If node under is buildable_to, place into it instead (eg. snow)
+ if olddef_under.buildable_to then
+ minetest.log("info", "node under is buildable to")
+ place_to = {x = under.x, y = under.y, z = under.z}
+ end
+
minetest.log("action", placer:get_player_name() .. " places node "
- .. def.name .. " at " .. minetest.pos_to_string(pos))
+ .. def.name .. " at " .. minetest.pos_to_string(place_to))
local newnode = {name = def.name, param1 = 0, param2 = 0}
-- Calculate direction for wall mounted stuff like torches and signs
if def.paramtype2 == 'wallmounted' then
- local under = pointed_thing.under
- local above = pointed_thing.above
- local dir = {x = under.x - above.x, y = under.y - above.y, z = under.z - above.z}
+ local dir = {
+ x = under.x - above.x,
+ y = under.y - above.y,
+ z = under.z - above.z
+ }
newnode.param2 = minetest.dir_to_wallmounted(dir)
-- Calculate the direction for furnaces and chests and stuff
elseif def.paramtype2 == 'facedir' then
local placer_pos = placer:getpos()
if placer_pos then
- local dir = {x = pos.x - placer_pos.x, y = pos.y - placer_pos.y, z = pos.z - placer_pos.z}
+ local dir = {
+ x = above.x - placer_pos.x,
+ y = above.y - placer_pos.y,
+ z = above.z - placer_pos.z
+ }
newnode.param2 = minetest.dir_to_facedir(dir)
minetest.log("action", "facedir: " .. newnode.param2)
end
end
-- Add node and update
- minetest.env:add_node(pos, newnode)
+ minetest.env:add_node(place_to, newnode)
-- Run callback
if def.after_place_node then
- def.after_place_node(pos, placer)
+ def.after_place_node(place_to, placer)
end
-- Run script hook (deprecated)
local _, callback
for _, callback in ipairs(minetest.registered_on_placenodes) do
- callback(pos, newnode, placer)
+ callback(place_to, newnode, placer)
end
itemstack:take_item()
diff --git a/src/game.cpp b/src/game.cpp
index 19c4707de..7d93e3db2 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -2304,6 +2304,13 @@ void the_game(
<<playeritem.name<<" is "
<<def.node_placement_prediction<<std::endl;
v3s16 p = neighbourpos;
+ // Place inside node itself if buildable_to
+ try{
+ MapNode n_under = map.getNode(nodepos);
+ if(nodedef->get(n_under).buildable_to)
+ p = nodepos;
+ }catch(InvalidPositionException &e){}
+ // Find id of predicted node
content_t id;
bool found =
nodedef->getId(def.node_placement_prediction, id);