mcl_bucket code refactoring + fix extra_check noot working

This commit is contained in:
AFCMS 2021-07-14 11:29:15 +02:00
parent b0127fc1c3
commit ca277b6769
3 changed files with 149 additions and 51 deletions

View file

@ -15,7 +15,33 @@ Accept folowing params:
* longdesc: long explanatory description (for help) * longdesc: long explanatory description (for help)
* usagehelp: short usage explanation (for help) * usagehelp: short usage explanation (for help)
* tt_help: very short tooltip help * tt_help: very short tooltip help
* extra_check(pos, placer): (optional) function(pos) which can returns false to avoid placing the liquid. Placer is object/player who is placing the liquid, can be nil. * extra_check(pos, placer): (optional) function(pos)
* groups: optional list of item groups * groups: optional list of item groups
This function can be called from any mod (which depends on this one)
**Usage exemple:**
```lua
mcl_buckets.register_liquid({
itemname = "dummy:bucket_dummy",
source_place = "dummy:dummy_source",
source_take = {"dummy:dummy_source"},
inventory_image = "bucket_dummy.png",
name = S("Dummy liquid Bucket"),
longdesc = S("This bucket is filled with a dummy liquid."),
usagehelp = S("Place it to empty the bucket and create a dummy liquid source."),
tt_help = S("Places a dummy liquid source"),
extra_check = function(pos, placer)
--pos = pos where the liquid should be placed
--placer people who tried to place the bucket (can be nil)
--no liquid node will be placed
--the bucket will not be emptied
--return false, false
--liquid node will be placed
--the bucket will be emptied
return true, true
end,
groups = { dummy_group = 123 },
})
```

View file

@ -56,6 +56,7 @@ local function place_liquid(pos, itemstring)
sound_place(itemstring, pos) sound_place(itemstring, pos)
minetest.add_node(pos, {name=itemstring, param2=fullness}) minetest.add_node(pos, {name=itemstring, param2=fullness})
end end
local function give_bucket(new_bucket, itemstack, user) local function give_bucket(new_bucket, itemstack, user)
local inv = user:get_inventory() local inv = user:get_inventory()
if minetest.is_creative_enabled(user:get_player_name()) then if minetest.is_creative_enabled(user:get_player_name()) then
@ -81,6 +82,7 @@ local pointable_sources = {}
local function bucket_raycast(user) local function bucket_raycast(user)
--local pos = user:get_pos() --local pos = user:get_pos()
local pos = mcl_util.get_object_center(user) local pos = mcl_util.get_object_center(user)
--local pos = vector.add(user:get_pos(), user:get_bone_position("Head_Control"))
pos.y = pos.y + user:get_properties().eye_height pos.y = pos.y + user:get_properties().eye_height
local look_dir = user:get_look_dir() local look_dir = user:get_look_dir()
look_dir = vector.multiply(look_dir, 4) look_dir = vector.multiply(look_dir, 4)
@ -98,6 +100,53 @@ local function bucket_raycast(user)
return nil return nil
end end
local function get_node_place(source_place, place_pos)
local node_place
if type(source_place) == "function" then
node_place = source_place(place_pos)
else
node_place = source_place
end
return node_place
end
local function get_extra_check(check, pos, user)
local result
local take_bucket
if check then
result, take_bucket = check(pos, user)
if result == nil then result = true end
if take_bucket == nil then take_bucket = true end
else
result = true
take_bucket = true
end
return result, take_bucket
end
local function get_bucket_drop(itemstack, user, take_bucket)
-- Handle bucket item and inventory stuff
if take_bucket and not minetest.is_creative_enabled(user:get_player_name()) then
-- Add empty bucket and put it into inventory, if possible.
-- Drop empty bucket otherwise.
local new_bucket = ItemStack("mcl_buckets:bucket_empty")
if itemstack:get_count() == 1 then
return new_bucket
else
local inv = user:get_inventory()
if inv:room_for_item("main", new_bucket) then
inv:add_item("main", new_bucket)
else
add_item(user:get_pos(), new_bucket)
end
itemstack:take_item()
return itemstack
end
else
return itemstack
end
end
function mcl_buckets.register_liquid(def) function mcl_buckets.register_liquid(def)
for _,source in ipairs(def.source_take) do for _,source in ipairs(def.source_take) do
mcl_buckets.liquids[source] = { mcl_buckets.liquids[source] = {
@ -135,23 +184,75 @@ function mcl_buckets.register_liquid(def)
return new_stack return new_stack
end end
local node = minetest.get_node(pointed_thing.under) local undernode = get_node(pointed_thing.under)
local place_pos = pointed_thing.under local abovenode = get_node(pointed_thing.above)
local nn = node.name local nn = undernode.name
local buildable1 = minetest.registered_nodes[undernode.name] and minetest.registered_nodes[undernode.name].buildable_to
local buildable2 = minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to
if not buildable1 and not buildable2 then return itemstack end --if both nodes aren't buildable_to, skip
local node_place if buildable1 then
if type(def.source_place) == "function" then local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.under, user)
node_place = def.source_place(place_pos) if result then
else local node_place = get_node_place(def.source_place, pointed_thing.under)
node_place = def.source_place local pns = user:get_player_name()
-- Check protection
if minetest.is_protected(pointed_thing.under, pns) then
minetest.record_protection_violation(pointed_thing.under, pns)
return itemstack
end end
-- Place liquid
place_liquid(pointed_thing.under, node_place)
-- Update doc mod
if mod_doc and doc.entry_exists("nodes", node_place) then
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
end
end
return get_bucket_drop(itemstack, user, take_bucket)
elseif buildable2 then
local result, take_bucket = get_extra_check(def.extra_check, pointed_thing.above, user)
if result then
local node_place = get_node_place(def.source_place, pointed_thing.above)
local pns = user:get_player_name()
-- Check protection
if minetest.is_protected(pointed_thing.above, pns) then
minetest.record_protection_violation(pointed_thing.above, pns)
return itemstack
end
-- Place liquid
place_liquid(pointed_thing.above, node_place)
-- Update doc mod
if mod_doc and doc.entry_exists("nodes", node_place) then
doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place)
end
end
return get_bucket_drop(itemstack, user, take_bucket)
else
return itemstack
end
-- Check if pointing to a buildable node -- Check if pointing to a buildable node
--local item = itemstack:get_name() --local item = itemstack:get_name()
if def.extra_check and def.extra_check(place_pos, user) == false then --[[
-- Fail placement of liquid if buildable_to_1 then
elseif minetest.registered_nodes[nn] and minetest.registered_nodes[nn].buildable_to then if can_place(pos) then
-- buildable; replace the node Place
end
else if buildable_to_2 then
if can_place2() then
Place
end
end
]]
--[[
if result then -- Fail placement of liquid if result is false
local pns = user:get_player_name() local pns = user:get_player_name()
if minetest.is_protected(place_pos, pns) then if minetest.is_protected(place_pos, pns) then
minetest.record_protection_violation(place_pos, pns) minetest.record_protection_violation(place_pos, pns)
@ -200,28 +301,17 @@ function mcl_buckets.register_liquid(def)
end end
else else
return return
end end]]
end, end,
_on_dispense = function(stack, pos, droppos, dropnode, dropdir) _on_dispense = function(stack, pos, droppos, dropnode, dropdir)
local iname = stack:get_name() local iname = stack:get_name()
local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal" local buildable = minetest.registered_nodes[dropnode.name].buildable_to or dropnode.name == "mcl_portals:portal"
if not buildable then return stack end if not buildable then return stack end
local result, take_bucket = get_extra_check(def.extra_check, droppos, nil)
local result
if def.extra_check then
result = def.extra_check(droppos, nil)
if result == nil then result = true end
else
result = true
end
if result then -- Fail placement of liquid if result is false if result then -- Fail placement of liquid if result is false
local node_place place_liquid(droppos, get_node_place(def.source_place, droppos))
if type(def.source_place) == "function" then
node_place = def.source_place(droppos)
else
node_place = def.source_place
end end
place_liquid(droppos, node_place) if take_bucket then
stack:set_name("mcl_buckets:bucket_empty") stack:set_name("mcl_buckets:bucket_empty")
end end
return stack return stack

View file

@ -53,15 +53,6 @@ if mod_mcl_core then
usagehelp = S("Place it to empty the bucket and create a water source."), usagehelp = S("Place it to empty the bucket and create a water source."),
tt_help = S("Places a water source"), tt_help = S("Places a water source"),
extra_check = function(pos, placer) extra_check = function(pos, placer)
-- Check protection
local placer_name = ""
if placer then
placer_name = placer:get_player_name()
end
if placer and minetest.is_protected(pos, placer_name) then
minetest.record_protection_violation(pos, placer_name)
return false
end
local nn = minetest.get_node(pos).name local nn = minetest.get_node(pos).name
-- Pour water into cauldron -- Pour water into cauldron
if minetest.get_item_group(nn, "cauldron") ~= 0 then if minetest.get_item_group(nn, "cauldron") ~= 0 then
@ -70,13 +61,13 @@ if mod_mcl_core then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"}) minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3"})
end end
sound_place("mcl_core:water_source", pos) sound_place("mcl_core:water_source", pos)
return false return false, true
-- Evaporate water if used in Nether (except on cauldron) -- Evaporate water if used in Nether (except on cauldron)
else else
local dim = mcl_worlds.pos_to_dimension(pos) local dim = mcl_worlds.pos_to_dimension(pos)
if dim == "nether" then if dim == "nether" then
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
return false return false, true
end end
end end
end, end,
@ -96,15 +87,6 @@ if mod_mclx_core then
usagehelp = S("Place it to empty the bucket and create a river water source."), usagehelp = S("Place it to empty the bucket and create a river water source."),
tt_help = S("Places a river water source"), tt_help = S("Places a river water source"),
extra_check = function(pos, placer) extra_check = function(pos, placer)
-- Check protection
local placer_name = ""
if placer then
placer_name = placer:get_player_name()
end
if placer and minetest.is_protected(pos, placer_name) then
minetest.record_protection_violation(pos, placer_name)
return false
end
local nn = minetest.get_node(pos).name local nn = minetest.get_node(pos).name
-- Pour into cauldron -- Pour into cauldron
if minetest.get_item_group(nn, "cauldron") ~= 0 then if minetest.get_item_group(nn, "cauldron") ~= 0 then
@ -113,13 +95,13 @@ if mod_mclx_core then
minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"}) minetest.set_node(pos, {name="mcl_cauldrons:cauldron_3r"})
end end
sound_place("mcl_core:water_source", pos) sound_place("mcl_core:water_source", pos)
return false return false, true
else else
-- Evaporate water if used in Nether (except on cauldron) -- Evaporate water if used in Nether (except on cauldron)
local dim = mcl_worlds.pos_to_dimension(pos) local dim = mcl_worlds.pos_to_dimension(pos)
if dim == "nether" then if dim == "nether" then
minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true)
return false return false, true
end end
end end
end, end,