Fix a number of crashes involving unknown nodes, also fix fishbuckets on_place (#3914)
Fixes: #3913 #3915 ~~You can reproduce the crash by placing a fish bucket on top snow above an unknown node. I also noticed that the code always uses pointed_thing.above so I fixed that and also added a function to mcl_utils to figure out where a node should be placed (either above or below). Looks like the rest of the code could also use improvement but at least it does not crash now.~~ Cora fixed a bunch of related crashes in Mineclona so I am replacing my commit and cherry picking all her commits here. https://codeberg.org/mineclonia/mineclonia/pulls/549 Here is the list of fixes from that PR: - Crash when placing snow layer on unknown nodes - Crash when snow layers on unknown nodes are flooded - Crash when placing fishbucket on snow on top of unknown nodes - Crash when placing chorus flower and stem on unknown - Crash when placing mob spawners on unknown - The fishbucket on place to actually replace buildable_to Co-authored-by: cora <coradelamouche@gmx.ch> Reviewed-on: https://git.minetest.land/MineClone2/MineClone2/pulls/3914 Reviewed-by: ancientmarinerdev <ancientmariner_dev@proton.me> Co-authored-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 <mrrar@noreply.git.minetest.land> Co-committed-by: 𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 <mrrar@noreply.git.minetest.land>hollow_logs_ref_recovery
parent
178b24886f
commit
a620d24ec8
|
@ -18,13 +18,21 @@ local function on_place_fish(itemstack, placer, pointed_thing)
|
||||||
return new_stack
|
return new_stack
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos = pointed_thing.above or pointed_thing.under
|
if pointed_thing.type ~= "node" then return end
|
||||||
if not pos then return end
|
|
||||||
local n = minetest.get_node_or_nil(pos)
|
local pos = pointed_thing.above
|
||||||
if n.name and minetest.registered_nodes[n.name].buildable_to or n.name == "mcl_portals:portal" then
|
local n = minetest.get_node(pointed_thing.above)
|
||||||
local fish = itemstack:get_name():gsub(fishbucket_prefix,"")
|
local def = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
||||||
if fish_names[fish] then
|
|
||||||
local o = minetest.add_entity(pos, "mobs_mc:" .. fish)
|
if ( def and def.buildable_to ) or n.name == "mcl_portals:portal" then
|
||||||
|
pos = pointed_thing.under
|
||||||
|
n = minetest.get_node(pointed_thing.under)
|
||||||
|
end
|
||||||
|
|
||||||
|
local fish = itemstack:get_definition()._mcl_buckets_fish
|
||||||
|
if fish_names[fish] then
|
||||||
|
local o = minetest.add_entity(pos, "mobs_mc:" .. fish)
|
||||||
|
if o and o:get_pos() then
|
||||||
local props = itemstack:get_meta():get_string("properties")
|
local props = itemstack:get_meta():get_string("properties")
|
||||||
if props ~= "" then
|
if props ~= "" then
|
||||||
o:set_properties(minetest.deserialize(props))
|
o:set_properties(minetest.deserialize(props))
|
||||||
|
@ -60,6 +68,7 @@ for techname, fishname in pairs(fish_names) do
|
||||||
stack_max = 1,
|
stack_max = 1,
|
||||||
groups = {bucket = 1, fish_bucket = 1},
|
groups = {bucket = 1, fish_bucket = 1},
|
||||||
liquids_pointable = false,
|
liquids_pointable = false,
|
||||||
|
_mcl_buckets_fish = techname,
|
||||||
on_place = on_place_fish,
|
on_place = on_place_fish,
|
||||||
on_secondary_use = on_place_fish,
|
on_secondary_use = on_place_fish,
|
||||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||||
|
|
|
@ -1581,7 +1581,7 @@ end
|
||||||
-- MUST NOT be called if there is a snow cover node above pos.
|
-- MUST NOT be called if there is a snow cover node above pos.
|
||||||
function mcl_core.clear_snow_dirt(pos, node)
|
function mcl_core.clear_snow_dirt(pos, node)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
if def._mcl_snowless then
|
if def and def._mcl_snowless then
|
||||||
minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2})
|
minetest.swap_node(pos, {name = def._mcl_snowless, param2=node.param2})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1602,7 +1602,7 @@ function mcl_core.on_snowable_construct(pos)
|
||||||
-- Make snowed if needed
|
-- Make snowed if needed
|
||||||
if minetest.get_item_group(anode.name, "snow_cover") == 1 then
|
if minetest.get_item_group(anode.name, "snow_cover") == 1 then
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
if def._mcl_snowed then
|
if def and def._mcl_snowed then
|
||||||
minetest.swap_node(pos, {name = def._mcl_snowed, param2=node.param2})
|
minetest.swap_node(pos, {name = def._mcl_snowed, param2=node.param2})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1623,7 +1623,7 @@ function mcl_core.on_snow_construct(pos)
|
||||||
local npos = {x=pos.x, y=pos.y-1, z=pos.z}
|
local npos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||||
local node = minetest.get_node(npos)
|
local node = minetest.get_node(npos)
|
||||||
local def = minetest.registered_nodes[node.name]
|
local def = minetest.registered_nodes[node.name]
|
||||||
if def._mcl_snowed then
|
if def and def._mcl_snowed then
|
||||||
minetest.swap_node(npos, {name = def._mcl_snowed, param2=node.param2})
|
minetest.swap_node(npos, {name = def._mcl_snowed, param2=node.param2})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1038,7 +1038,7 @@ for i=1,8 do
|
||||||
|
|
||||||
-- Get position where snow would be placed
|
-- Get position where snow would be placed
|
||||||
local target
|
local target
|
||||||
if minetest.registered_nodes[unode.name].buildable_to then
|
if def and def.buildable_to then
|
||||||
target = under
|
target = under
|
||||||
else
|
else
|
||||||
target = above
|
target = above
|
||||||
|
|
|
@ -155,7 +155,8 @@ minetest.register_node("mcl_end:chorus_flower", {
|
||||||
1) On top of end stone or chorus plant
|
1) On top of end stone or chorus plant
|
||||||
2) On top of air and horizontally adjacent to exactly 1 chorus plant ]]
|
2) On top of air and horizontally adjacent to exactly 1 chorus plant ]]
|
||||||
local pos
|
local pos
|
||||||
if minetest.registered_nodes[node_under.name].buildable_to then
|
local def = minetest.registered_nodes[node_under.name]
|
||||||
|
if def and def.buildable_to then
|
||||||
pos = pointed_thing.under
|
pos = pointed_thing.under
|
||||||
else
|
else
|
||||||
pos = pointed_thing.above
|
pos = pointed_thing.above
|
||||||
|
@ -283,7 +284,8 @@ minetest.register_node("mcl_end:chorus_plant", {
|
||||||
condition is met:
|
condition is met:
|
||||||
- placed on end stone or any chorus node ]]
|
- placed on end stone or any chorus node ]]
|
||||||
local pos_place, node_check
|
local pos_place, node_check
|
||||||
if minetest.registered_nodes[node_under.name].buildable_to then
|
local def = minetest.registered_nodes[node_under.name]
|
||||||
|
if def and def.buildable_to then
|
||||||
pos_place = pointed_thing.under
|
pos_place = pointed_thing.under
|
||||||
node_check = node_above
|
node_check = node_above
|
||||||
else
|
else
|
||||||
|
|
|
@ -301,7 +301,8 @@ minetest.register_node("mcl_mobspawners:spawner", {
|
||||||
local new_itemstack, success = minetest.item_place(itemstack, placer, pointed_thing)
|
local new_itemstack, success = minetest.item_place(itemstack, placer, pointed_thing)
|
||||||
if success then
|
if success then
|
||||||
local placepos
|
local placepos
|
||||||
if minetest.registered_nodes[node_under.name].buildable_to then
|
local def = minetest.registered_nodes[node_under.name]
|
||||||
|
if def and def.buildable_to then
|
||||||
placepos = pointed_thing.under
|
placepos = pointed_thing.under
|
||||||
else
|
else
|
||||||
placepos = pointed_thing.above
|
placepos = pointed_thing.above
|
||||||
|
|
Loading…
Reference in New Issue