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>
This commit is contained in:
parent
178b24886f
commit
a620d24ec8
@ -18,13 +18,21 @@ local function on_place_fish(itemstack, placer, pointed_thing)
|
||||
return new_stack
|
||||
end
|
||||
|
||||
local pos = pointed_thing.above or pointed_thing.under
|
||||
if not pos then return end
|
||||
local n = minetest.get_node_or_nil(pos)
|
||||
if n.name and minetest.registered_nodes[n.name].buildable_to or n.name == "mcl_portals:portal" then
|
||||
local fish = itemstack:get_name():gsub(fishbucket_prefix,"")
|
||||
if fish_names[fish] then
|
||||
local o = minetest.add_entity(pos, "mobs_mc:" .. fish)
|
||||
if pointed_thing.type ~= "node" then return end
|
||||
|
||||
local pos = pointed_thing.above
|
||||
local n = minetest.get_node(pointed_thing.above)
|
||||
local def = minetest.registered_nodes[minetest.get_node(pointed_thing.under).name]
|
||||
|
||||
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")
|
||||
if props ~= "" then
|
||||
o:set_properties(minetest.deserialize(props))
|
||||
@ -60,6 +68,7 @@ for techname, fishname in pairs(fish_names) do
|
||||
stack_max = 1,
|
||||
groups = {bucket = 1, fish_bucket = 1},
|
||||
liquids_pointable = false,
|
||||
_mcl_buckets_fish = techname,
|
||||
on_place = on_place_fish,
|
||||
on_secondary_use = on_place_fish,
|
||||
_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.
|
||||
function mcl_core.clear_snow_dirt(pos, node)
|
||||
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})
|
||||
end
|
||||
end
|
||||
@ -1602,7 +1602,7 @@ function mcl_core.on_snowable_construct(pos)
|
||||
-- Make snowed if needed
|
||||
if minetest.get_item_group(anode.name, "snow_cover") == 1 then
|
||||
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})
|
||||
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 node = minetest.get_node(npos)
|
||||
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})
|
||||
end
|
||||
end
|
||||
|
@ -1038,7 +1038,7 @@ for i=1,8 do
|
||||
|
||||
-- Get position where snow would be placed
|
||||
local target
|
||||
if minetest.registered_nodes[unode.name].buildable_to then
|
||||
if def and def.buildable_to then
|
||||
target = under
|
||||
else
|
||||
target = above
|
||||
|
@ -155,7 +155,8 @@ minetest.register_node("mcl_end:chorus_flower", {
|
||||
1) On top of end stone or chorus plant
|
||||
2) On top of air and horizontally adjacent to exactly 1 chorus plant ]]
|
||||
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
|
||||
else
|
||||
pos = pointed_thing.above
|
||||
@ -283,7 +284,8 @@ minetest.register_node("mcl_end:chorus_plant", {
|
||||
condition is met:
|
||||
- placed on end stone or any chorus node ]]
|
||||
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
|
||||
node_check = node_above
|
||||
else
|
||||
|
@ -301,7 +301,8 @@ minetest.register_node("mcl_mobspawners:spawner", {
|
||||
local new_itemstack, success = minetest.item_place(itemstack, placer, pointed_thing)
|
||||
if success then
|
||||
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
|
||||
else
|
||||
placepos = pointed_thing.above
|
||||
|
Loading…
Reference in New Issue
Block a user