From fd8182c74cec2cee1e4e56be3d7fa5c22210adfe Mon Sep 17 00:00:00 2001 From: Phaethon H Date: Sun, 24 Oct 2021 15:37:43 -0700 Subject: [PATCH] Wire in documentation aliases for the filled cauldrons. Delete commented out code. Change names of variables to be more clear of purpose. Slightly cleaner logic getting bucket from cauldron. Play sounds when bucket takes from cauldron. Guard against entirety of bucket placing water source if cauldron filled successfully (avoid empty if branch). Adjust cauldron collision box to make it possible to jump/fall inside. Minimally functioning state: water cauldron extinguish entity on fire. Fix interaction of bottles with water sources and cauldrons: * take and give 1/3 level from/to cauldrons (creative mode and survival mode inventory changse). * take from mcl_core:water_source Removed utils.lua (contents were moved into register.lua). --- mods/ITEMS/mcl_buckets/init.lua | 94 ++++++------ mods/ITEMS/mcl_buckets/register.lua | 44 ++---- mods/ITEMS/mcl_cauldrons/API.md | 32 +---- mods/ITEMS/mcl_cauldrons/api.lua | 199 ++++---------------------- mods/ITEMS/mcl_cauldrons/init.lua | 1 - mods/ITEMS/mcl_cauldrons/register.lua | 63 ++++---- mods/ITEMS/mcl_cauldrons/utils.lua | 65 --------- mods/ITEMS/mcl_potions/init.lua | 108 ++++++-------- 8 files changed, 157 insertions(+), 449 deletions(-) delete mode 100644 mods/ITEMS/mcl_cauldrons/utils.lua diff --git a/mods/ITEMS/mcl_buckets/init.lua b/mods/ITEMS/mcl_buckets/init.lua index 56dd59ff9..648b9ef3c 100644 --- a/mods/ITEMS/mcl_buckets/init.lua +++ b/mods/ITEMS/mcl_buckets/init.lua @@ -90,47 +90,52 @@ function mcl_buckets.register_liquid(def) else node_place = def.source_place end - -- Check if pointing to a buildable node - --local item = itemstack:get_name() - local mcl_into_cauldron = def._mcl_into_cauldron + local handle_fill_cauldron = def._mcl_get_bucket_from_cauldron + local skip_build = false - if mcl_into_cauldron then - local new_bucketname = mcl_into_cauldron(place_pos, user) + if handle_fill_cauldron then + local new_bucketname = handle_fill_cauldron(place_pos, user) if not new_bucketname then - mcl_into_cauldron = nil + -- revoke cauldron codepath. + -- fall back to placing node normally. + handle_fill_cauldron = nil + else + skip_build = true end end - if def.extra_check and def.extra_check(place_pos, user) == true and nodedef and nodedef.buildable_to then - -- buildable; replace the node - local pns = user:get_player_name() - if minetest.is_protected(place_pos, pns) then - minetest.record_protection_violation(place_pos, pns) - return itemstack - end - place_liquid(place_pos, node_place) - if mod_doc and doc.entry_exists("nodes", node_place) then - doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) - end - elseif mcl_into_cauldron then - -- already handled; skip default case, to inventory handling. - else - -- not buildable to; place the liquid above - -- check if the node above can be replaced - local abovenode = minetest.get_node(pointed_thing.above) - if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then - local pn = user:get_player_name() - if minetest.is_protected(pointed_thing.above, pn) then - minetest.record_protection_violation(pointed_thing.above, pn) + -- Check if pointing to a buildable node + --local item = itemstack:get_name() + if not skip_build then + if def.extra_check and def.extra_check(place_pos, user) == true and nodedef and nodedef.buildable_to then + -- buildable; replace the node + local pns = user:get_player_name() + if minetest.is_protected(place_pos, pns) then + minetest.record_protection_violation(place_pos, pns) return itemstack end - place_liquid(pointed_thing.above, node_place) + place_liquid(place_pos, node_place) if mod_doc and doc.entry_exists("nodes", node_place) then doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) end else - -- do not remove the bucket with the liquid - return + -- not buildable to; place the liquid above + -- check if the node above can be replaced + local abovenode = minetest.get_node(pointed_thing.above) + if minetest.registered_nodes[abovenode.name] and minetest.registered_nodes[abovenode.name].buildable_to then + local pn = user:get_player_name() + if minetest.is_protected(pointed_thing.above, pn) then + minetest.record_protection_violation(pointed_thing.above, pn) + return itemstack + end + place_liquid(pointed_thing.above, node_place) + if mod_doc and doc.entry_exists("nodes", node_place) then + doc.mark_entry_as_revealed(user:get_player_name(), "nodes", node_place) + end + else + -- do not remove the bucket with the liquid + return + end end end @@ -237,29 +242,22 @@ minetest.register_craftitem("mcl_buckets:bucket_empty", { end elseif cauldron_stuff then - -- Cauldron ---[[ - elseif minetest.get_item_group(nn, "cauldron") then - new_bucket = mcl_cauldrons.take_cauldron(pointed_thing.under, new_bucket, user) ---]] + -- Cauldron local newnode - newnode = mcl_cauldrons.drain_levels(node, mcl_cauldrons.BUCKETFUL, "cauldron_water") - if node ~= newnode then - -- take water. - minetest.set_node(pointed_thing.under, newnode) - if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack({name = "mcl_buckets:bucket_water"}) - end - sound_take("mcl_core:water_source", pointed_thing.under) - else - newnode = mcl_cauldrons.drain_levels(node, mcl_cauldrons.BUCKETFUL, "cauldron_river_water") + local CAULDRON_TO_BUCKET = { + ["cauldron_water"]={bucket="mcl_buckets:bucket_water", sound="mcl_core:water_source"}, + ["cauldron_river_water"]={bucket="mcl_buckets:bucket_river_water", sound="mcl_core:river_water_source"}, + } + for cauldron_specifier, bucket_spec in pairs(CAULDRON_TO_BUCKET) do + newnode = mcl_cauldrons.drain_levels(node, mcl_cauldrons.BUCKETFUL, cauldron_specifier) if node ~= newnode then - -- take river water. + -- substance was taken out. minetest.set_node(pointed_thing.under, newnode) + sound_take(bucket_spec.sound, pointed_thing.under) if not minetest.is_creative_enabled(user:get_player_name()) then - new_bucket = ItemStack({name = "mcl_buckets:bucket_river_water"}) + new_bucket = ItemStack({name = bucket_spec.bucket}) end - sound_take("mcl_core:river_water_source", pointed_thing.under) + break end end end diff --git a/mods/ITEMS/mcl_buckets/register.lua b/mods/ITEMS/mcl_buckets/register.lua index 7c42fe4b4..e69785ba5 100644 --- a/mods/ITEMS/mcl_buckets/register.lua +++ b/mods/ITEMS/mcl_buckets/register.lua @@ -63,27 +63,15 @@ if mod_mcl_core then return false end local nn = minetest.get_node(pos).name - -- Pour water into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then ---[[ - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3" then - mcl_cauldrons.set_cauldron_level(pos, "water", 3) - end - sound_place("mcl_core:water_source", pos) - return false ---]] -- Evaporate water if used in Nether (except on cauldron) - else - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) + return false end end, groups = { water_bucket = 1 }, - _mcl_into_cauldron = function (pos, placer) + _mcl_get_bucket_from_cauldron = function(pos, placer) local node = minetest.get_node(pos) if not mcl_cauldrons.is_cauldron(node) then return nil @@ -129,27 +117,15 @@ if mod_mclx_core then return false end local nn = minetest.get_node(pos).name - -- Pour into cauldron - if minetest.get_item_group(nn, "cauldron") ~= 0 then ---[[ - -- Put water into cauldron - if nn ~= "mcl_cauldrons:cauldron_3r" then - mcl_cauldrons.set_cauldron(pos, "river_water", 3) - end - sound_place("mcl_core:water_source", pos) + -- Evaporate water if used in Nether (except on cauldron) + local dim = mcl_worlds.pos_to_dimension(pos) + if dim == "nether" then + minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) return false ---]] - else - -- Evaporate water if used in Nether (except on cauldron) - local dim = mcl_worlds.pos_to_dimension(pos) - if dim == "nether" then - minetest.sound_play("fire_extinguish_flame", {pos = pos, gain = 0.25, max_hear_distance = 16}, true) - return false - end end end, groups = { water_bucket = 1 }, - _mcl_into_cauldron = function (pos, placer) + _mcl_get_bucket_from_cauldron = function(pos, placer) local node = minetest.get_node(pos) if not mcl_cauldrons.is_cauldron(node) then return nil diff --git a/mods/ITEMS/mcl_cauldrons/API.md b/mods/ITEMS/mcl_cauldrons/API.md index 381d43d06..768815dcb 100644 --- a/mods/ITEMS/mcl_cauldrons/API.md +++ b/mods/ITEMS/mcl_cauldrons/API.md @@ -1,33 +1,7 @@ -# mcl_cauldrons +# `mcl_cauldrons` This mod add an API to add cauldrons to mcl. -## mcl_cauldrons.is_cauldron(name) -return true if name is cauldron, false overwise. - -## mcl_cauldrons.get_cauldron_string(type, level) -return itemstring of cauldron with and -e.g: `mcl_cauldrons.get_cauldron_string("water", 1) --return itemstring of a water cauldron with 1 level of water` - -## mcl_cauldrons.take_cauldron(pos, itemstack, user, sounds) -empty cauldron at `pos` -return `bucket` field of the cauldron def if user is player, itemstack overwise. -* pos: position of the cauldron -* itemstack: will be return if `bucket` field isn't defined in cauldron def or user is nil or not player. -* user: player who takes cauldron -* sounds: sounds table. If not nil, dug sound will be played. - -## mcl_cauldrons.register_cauldron_type(def) -def can have these fields: -* name: name of the liquid e.g: "water" -* bucket: string of the bucket item. can be nil. e.g: "mcl_buckets:bucket_water" -* desc: description of the item. %s will be replaced by the level. e.g: "Water Cauldron %s/3 full" -* texture: texture of the flowing liquid e.g: "mcl_core_water_flowing.png" - -## `mcl_cauldrons.registered_cauldrons` -Table containing cauldron definitions, indexed by name. - - Node definitions ---------------- @@ -44,8 +18,10 @@ Extensions to the base node definition descriptor (as passed to `minetest.regist * `.mcl_on_drain(node, amount)`: returns node { name, param1, param2 } -### `mcl_cauldrons.register_cauldron_node(nodename, cauldron_def)` +### `mcl_cauldrons.registered_cauldrons` +Table containing cauldron definitions, indexed by name. +### `mcl_cauldrons.register_cauldron_node(nodename, cauldron_def)` Cauldron interactions diff --git a/mods/ITEMS/mcl_cauldrons/api.lua b/mods/ITEMS/mcl_cauldrons/api.lua index 5d6dcab86..79f24160a 100644 --- a/mods/ITEMS/mcl_cauldrons/api.lua +++ b/mods/ITEMS/mcl_cauldrons/api.lua @@ -1,186 +1,27 @@ local has_doc = minetest.get_modpath(minetest.get_current_modname()) ---[[ -local function survival_give(inv, original_item, itemstack) - if inv:room_for_item("main", itemstack) then - inv:add_item("main", itemstack) - return original_item:take_item() - else - minetest.add_item(user:get_pos(), itemstack) - return original_item - end -end - -local function creative_give(inv, original_item, itemstack) - if not inv:contains_item("main", itemstack) then - inv:add_item("main", itemstack) - return original_item - end -end - -local function give_item(user, original_item, itemstack) - local inv = user:get_inventory() - if inv then - if minetest.is_creative_enabled(user:get_player_name()) then - creative_give(inv, original_item, itemstack) - else - survival_give(inv, original_item, itemstack) - end - end - return itemstack -end - ---]] mcl_cauldrons.registered_cauldrons = {} ---[[ - -function mcl_cauldrons.register_cauldron_type(def) - for water_level = 1,3 do - local id = "mcl_cauldrons:cauldron_"..def.name.."_"..water_level - mcl_cauldrons.registered_cauldrons[id] = def - minetest.register_node(id, { - description = string.format(def.desc, water_level), - _doc_items_create_entry = false, - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - drawtype = "nodebox", - paramtype = "light", - is_ground_content = false, - groups = {pickaxey=1, not_in_creative_inventory=1, cauldron=(1+water_level), cauldron_filled=water_level, comparator_signal=water_level}, - node_box = mcl_cauldrons.cauldron_nodeboxes[water_level], - collision_box = mcl_cauldrons.cauldron_nodeboxes[0], - selection_box = { type = "regular" }, - tiles = { - "("..def.texture.."^[verticalframe:16:0"..")^mcl_cauldrons_cauldron_top.png", - "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png", - "mcl_cauldrons_cauldron_side.png" - }, - sounds = mcl_sounds.node_sound_metal_defaults(), - drop = "mcl_cauldrons:cauldron", - _mcl_hardness = 2, - _mcl_blast_resistance = 2, - }) - -- Add entry aliases for the Help - if has_doc then - doc.add_entry_alias("nodes", "mcl_cauldrons:cauldron", "nodes", id) - end - end -end - -function mcl_cauldrons.is_cauldron(name) - return minetest.get_item_group(name, "cauldron") ~= 0 -end - -------------------------------------- ---Functions to get/set cauldron level -------------------------------------- -function mcl_cauldrons.get_cauldron_level(pos) - local nn = minetest.get_node(pos) - return minetest.get_item_group(nn.name, "cauldron") -end - -function mcl_cauldrons.set_cauldron_level(pos, type, level) - return minetest.set_node(pos, {name = mcl_cauldrons.get_cauldron_string(type, level)}) -end - -function mcl_cauldrons.add_cauldron_level(pos, type, number) - local current = mcl_cauldrons.get_cauldron_level(pos) - local number = current + number - if number > 4 then number = 4 end - if number < 1 then number = 1 end - mcl_cauldrons.set_cauldron_level(pos, type, number) - return number, not current == number -end - -function mcl_cauldrons.get_cauldron_string(type, level) - if mcl_cauldrons.registered_cauldrons["mcl_cauldrons:cauldron_"..type.."_"..level] then - return "mcl_cauldrons:cauldron_"..type.."_"..level - elseif level == 0 then - return "mcl_cauldrons:cauldron" - else - minetest.log("warning", "[mcl_cauldrons] trying to get string from invalid cauldron params") - return "air" - end -end - ----------------------------- ---Functions to take cauldron ----------------------------- -function mcl_cauldrons.take_cauldron(pos, itemstack, user, sounds) - local nn = minetest.get_node(pos) - if mcl_cauldrons.registered_cauldrons[nn.name] and mcl_cauldrons.registered_cauldrons[nn.name].bucket then - if user and not minetest.is_creative_enabled(user:get_player_name()) then - minetest.set_node(pos, {name="mcl_cauldrons:cauldron"}) - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - return give_item(user, original, ItemStack(mcl_cauldrons.registered_cauldrons[nn.name].bucket)) - else - minetest.set_node(pos, {name="mcl_cauldrons:cauldron"}) - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - return itemstack - end - else - minetest.set_node(pos, {name="mcl_cauldrons:cauldron"}) - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - return itemstack - end -end - -function mcl_cauldrons.take_small_cauldron(pos, itemstack, user, sounds) - local nn = minetest.get_node(pos) - if mcl_cauldrons.registered_cauldrons[nn.name] and mcl_cauldrons.registered_cauldrons[nn.name].bottle then - if user and not minetest.is_creative_enabled(user:get_player_name()) then - local number, changed = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1) - if changed then - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - local item_name = mcl_cauldrons.registered_cauldrons[nn.name].bottle - local inv = placer:get_inventory() - minetest.sound_play("mcl_potions_bottle_fill", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - if minetest.is_creative_enabled(placer:get_player_name()) then - -- Don't replace empty bottle in creative for convenience reasons - if not inv:contains_item("main", item_name) then - inv:add_item("main", item_name) - end - elseif itemstack:get_count() == 1 then - return item_name - else - return give_item(user, ItemStack(mcl_cauldrons.registered_cauldrons[nn.name].bucket)) - end - end - else - local number = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1) - if number ~= 0 then - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - end - return itemstack - end - else - local number = mcl_cauldrons.add_cauldron_level(pos, mcl_cauldrons.registered_cauldrons[nn.name].name, -1) - if number ~= 0 then - if sounds then minetest.sound_play(sounds.dug, {gain=1.0, pos = pos, pitch = 1 + math.random(-10, 10)*0.005}, true) end - end - return itemstack - end -end - ---]] - - - - - - ----------------------------------------- +-- symbolic constants. mcl_cauldrons.BUCKETFUL = 3 mcl_cauldrons.BOTTLEFUL = 1 +-- Find cauldron from registered cauldrons -> string, table +-- `substance` == nil for any cauldron content (incl. empty), "" = only empty. +-- `fill_level` == nil for any/first fill level satisfying `substance`. +-- e.g. find_cauldron("cauldron_water", 2) -> "mcl_cauldrons:cauldron_water_2" +-- Returns 2 values: node_name:string, node_definition:table; +-- if nothing else matches, returns empty cauldron ("mcl_cauldrons:cauldron"). function mcl_cauldrons.find_cauldron (substance, fill_level) if (substance == "") then fill_level = 0 end for nodename, nodedef in pairs(mcl_cauldrons.registered_cauldrons) do + -- matched on substance: 'any', or exact match from .groups. local substantial = (substance == nil) or (nodedef.groups[substance] and (nodedef.groups[substance] > 0)) + -- matched on fill_level: 'any', or exact match from .groups. local filling = (fill_level == nil) or (nodedef.groups.cauldron_filled == fill_level) if substantial and filling then return nodename, nodedef @@ -191,14 +32,19 @@ function mcl_cauldrons.find_cauldron (substance, fill_level) return nodename, mcl_cauldrons.registered_cauldrons[nodename] end +-- Test: node describes a cauldron -> boolean function mcl_cauldrons.is_cauldron (node) - return (minetest.get_item_group(node.name, "cauldron")) + return (minetest.get_item_group(node.name, "cauldron") > 0) end +-- Test: cauldron node contains specified substance -> boolean function mcl_cauldrons.has_substance (node, substance) return (minetest.get_item_group(node.name, substance) > 0) end +-- Get maximum number of levels available for cauldron node -> number +-- Optionally specify `substance` (mainly to determine a change in cauldron substance, e.g. filling a full one with bucket of something else) +-- substance == nil to ignore substance criteria function mcl_cauldrons.get_maximum (node, substance) local nodename if substance == nil then @@ -209,6 +55,8 @@ function mcl_cauldrons.get_maximum (node, substance) return minetest.get_item_group(nodename, "cauldron_maximum") end +-- Get current level of cauldron -> number +-- Optionally specify `substance`, substance==nil to indicate current content. function mcl_cauldrons.get_level (node, substance) if substance and (minetest.get_item_group(node.name, substance) == 0) then return 0 @@ -216,6 +64,8 @@ function mcl_cauldrons.get_level (node, substance) return minetest.get_item_group(node.name, "cauldron_filled") end +-- Test: cauldron is empty -> boolean +-- (i.e. fill level is 0, or contents is empty) function mcl_cauldrons.is_empty (node) if not mcl_cauldrons.is_cauldron(node) then error("not a cauldron", node.name) @@ -226,18 +76,26 @@ function mcl_cauldrons.is_empty (node) return false end +-- Test: cauldron is full -> boolean +-- (i.e. current fill level matches maximum level. function mcl_cauldrons.is_full (node) local maximum = mcl_cauldrons.get_maximum(node) local current = mcl_cauldrons.get_level(node) return (current >= maximum) end +-- Set fill level, bypassing game rules -> table +-- Optionally indicate substance (to change cauldron content); nil to preserve. +-- returns a node table as accepted by minetest.set_node() function mcl_cauldrons.set_level (node, fill_level, substance) local nodename, nodedef = mcl_cauldrons.find_cauldron(substance, fill_level) local newnode = { name = nodename, param1 = node.param1, param2 = node.param2 } return newnode end +-- Change content of cauldron by number of levels with indicated substance -> table +-- Subject to game rules (delegated to node definition's on_fill callback) +-- returns a node table as accepted by minetest.set_node() function mcl_cauldrons.fill_levels (node, change_levels, substance) local nodedef = mcl_cauldrons.registered_cauldrons[node.name] local callback = nodedef.mcl_on_fill @@ -253,6 +111,7 @@ function mcl_cauldrons.fill_levels (node, change_levels, substance) return newnode end +-- drain counterpart to fill_levels() function mcl_cauldrons.drain_levels (node, change_levels, substance) local nodedef = mcl_cauldrons.registered_cauldrons[node.name] local callback = nodedef.mcl_on_drain @@ -269,6 +128,8 @@ function mcl_cauldrons.drain_levels (node, change_levels, substance) end +-- Wrapper to register cauldron-specific nodes. +-- additional bookkeeping specific to mcl_cauldrons. function mcl_cauldrons.register_cauldron_node (nodename, nodedef, doc_alias) mcl_cauldrons.registered_cauldrons[nodename] = nodedef minetest.register_node(nodename, nodedef) diff --git a/mods/ITEMS/mcl_cauldrons/init.lua b/mods/ITEMS/mcl_cauldrons/init.lua index 75258bfcf..0d073b0cc 100644 --- a/mods/ITEMS/mcl_cauldrons/init.lua +++ b/mods/ITEMS/mcl_cauldrons/init.lua @@ -4,6 +4,5 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) mcl_cauldrons = {} -- Cauldron mod, adds cauldrons. -dofile(modpath.."/utils.lua") dofile(modpath.."/api.lua") dofile(modpath.."/register.lua") diff --git a/mods/ITEMS/mcl_cauldrons/register.lua b/mods/ITEMS/mcl_cauldrons/register.lua index 29a048a76..0c1198bfe 100644 --- a/mods/ITEMS/mcl_cauldrons/register.lua +++ b/mods/ITEMS/mcl_cauldrons/register.lua @@ -33,12 +33,18 @@ local create_cauldron_nodebox = function(water_level) } end +-- Generate nodeboxes for cauldrons, (0=empty, 1=1/3 filled, 2=2/3 filled, 3=full) mcl_cauldrons.cauldron_nodeboxes = {} for w=0,3 do mcl_cauldrons.cauldron_nodeboxes[w] = create_cauldron_nodebox(w) end +-- The normal Lua means of inheritance uses setmetatable. +-- For node definitions, minetest.register_node() breaks/overwrite the metatable for its own use. +-- This function copies in the "old" keys/values, to lets them be overwritten by another (newer) table. +-- Care should be exercised updating/modifying the return value, as nested tables are copied by reference (viz. followup code might end up modifying nested tables in the *parent* defintion). +-- This workaround happens to work as declarative objects do not change after instantiation. local function merge_tables (a,b) local result = {} for k,v in pairs(a) do result[k]=v end @@ -71,7 +77,7 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron", { _mcl_hardness = 2, _mcl_blast_resistance = 2, - mcl_on_fill = function (node, change_levels, substance) + mcl_on_fill = function(node, change_levels, substance) -- base rules for cauldrons. if change_levels <= 0 then -- no change. @@ -97,7 +103,7 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron", { local newnode = mcl_cauldrons.set_level(node, new_level, substance) return newnode end, - mcl_on_drain = function (node, change_levels, substance) + mcl_on_drain = function(node, change_levels, substance) -- base rules for cauldrons. if change_levels <= 0 then -- no change. @@ -128,15 +134,6 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron", { end, }) ---[[ -mcl_cauldrons.register_cauldron_type({ - name = "water", - bucket = "mcl_buckets:bucket_water", - bottle = "mcl_potions:water", - desc = S("Cauldron (%s/3 Water)"), - texture = "default_water_source_animated.png" -}) ---]] -- water cauldron as extension of empty cauldron. mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_1", @@ -150,14 +147,14 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_1", cauldron_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[1], - collision_box = mcl_cauldrons.cauldron_nodeboxes[1], + collision_box = mcl_cauldrons.cauldron_nodeboxes[0], tiles = { "(default_water_source_animated.png^[verticalframe:16:0"..")^mcl_cauldrons_cauldron_top.png", "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png", "mcl_cauldrons_cauldron_side.png" }, drop = "mcl_cauldrons:cauldron", -})) +}), "mcl_cauldrons:cauldron") -- water cauldron 2/3 as extension of 1/3. mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_2", @@ -171,8 +168,7 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_2", cauldron_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[2], - collision_box = mcl_cauldrons.cauldron_nodeboxes[2], -})) +}), "mcl_cauldrons:cauldron") -- water cauldron 3/3 as extension of 1/3. mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_3", @@ -186,8 +182,7 @@ mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_water_3", cauldron_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[3], - collision_box = mcl_cauldrons.cauldron_nodeboxes[3], -})) +}), "mcl_cauldrons:cauldron") if minetest.get_modpath("mclx_core") then --register_filled_cauldron(1, S("Cauldron (1/3 River Water)"), true) @@ -205,14 +200,14 @@ if minetest.get_modpath("mclx_core") then cauldron_river_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[1], - collision_box = mcl_cauldrons.cauldron_nodeboxes[1], + collision_box = mcl_cauldrons.cauldron_nodeboxes[0], tiles = { "(default_river_water_source_animated.png^[verticalframe:16:0"..")^mcl_cauldrons_cauldron_top.png", "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png", "mcl_cauldrons_cauldron_side.png" }, drop = "mcl_cauldrons:cauldron", - })) + }), "mcl_cauldrons:cauldron") -- water cauldron 2/3 as extension of 1/3. mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_river_water_2", merge_tables(mcl_cauldrons.registered_cauldrons["mcl_cauldrons:cauldron_river_water_1"], { @@ -225,8 +220,7 @@ if minetest.get_modpath("mclx_core") then cauldron_river_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[2], - collision_box = mcl_cauldrons.cauldron_nodeboxes[2], - })) + }), "mcl_cauldrons:cauldron") -- water cauldron 3/3 as extension of 1/3. mcl_cauldrons.register_cauldron_node("mcl_cauldrons:cauldron_river_water_3", merge_tables(mcl_cauldrons.registered_cauldrons["mcl_cauldrons:cauldron_river_water_1"], { @@ -239,10 +233,11 @@ if minetest.get_modpath("mclx_core") then cauldron_river_water = 1, }, node_box = mcl_cauldrons.cauldron_nodeboxes[3], - collision_box = mcl_cauldrons.cauldron_nodeboxes[3], - })) + }), "mcl_cauldrons:cauldron") end + +-- Crafting recipe: Cauldron minetest.register_craft({ output = "mcl_cauldrons:cauldron", recipe = { @@ -258,25 +253,21 @@ minetest.register_abm({ interval = 0.5, chance = 1, action = function(pos, node) - for _, obj in pairs(minetest.get_objects_inside_radius(pos, 0.4)) do + local EXTINGUISHING_RADIUS = 0.4 + for _, obj in pairs(minetest.get_objects_inside_radius(pos, EXTINGUISHING_RADIUS)) do if mcl_burning.is_burning(obj) then - mcl_burning.extinguish(obj) - local new_group = minetest.get_item_group(node.name, "cauldron_filled") - 1 - minetest.swap_node(pos, {name = "mcl_cauldrons:cauldron" .. (new_group == 0 and "" or "_" .. new_group)}) - break + local newnode = mcl_cauldrons.drain_levels(node, 1, "cauldron_water") + if node ~= newnode then + -- extinguishing requires 1 level of water from cauldron. + minetest.swap_node(pos, newnode) + mcl_burning.extinguish(obj) + break + end end end end }) ---[[ -for i = 1, 3 do --Backward compatibility - minetest.register_alias("mcl_cauldrons:cauldron_"..i, "mcl_cauldrons:cauldron_water_"..i) -end -for i = 1, 3 do - minetest.register_alias("mcl_cauldrons:cauldron_"..i.."r", "mcl_cauldrons:cauldron_river_water_"..i) -end ---]] -- backwards compatibility local aliases = { diff --git a/mods/ITEMS/mcl_cauldrons/utils.lua b/mods/ITEMS/mcl_cauldrons/utils.lua deleted file mode 100644 index 313cb379c..000000000 --- a/mods/ITEMS/mcl_cauldrons/utils.lua +++ /dev/null @@ -1,65 +0,0 @@ -local S = minetest.get_translator(minetest.get_current_modname()) - --- Convenience function because the cauldron nodeboxes are very similar -local create_cauldron_nodebox = function(water_level) - local floor_y - if water_level == 0 then -- empty - floor_y = -0.1875 - elseif water_level == 1 then -- 1/3 filled - floor_y = 1/16 - elseif water_level == 2 then -- 2/3 filled - floor_y = 4/16 - elseif water_level == 3 then -- full - floor_y = 7/16 - end - return { - type = "fixed", - fixed = { - {-0.5, -0.1875, -0.5, -0.375, 0.5, 0.5}, -- Left wall - {0.375, -0.1875, -0.5, 0.5, 0.5, 0.5}, -- Right wall - {-0.375, -0.1875, 0.375, 0.375, 0.5, 0.5}, -- Back wall - {-0.375, -0.1875, -0.5, 0.375, 0.5, -0.375}, -- Front wall - {-0.5, -0.3125, -0.5, 0.5, floor_y, 0.5}, -- Floor - {-0.5, -0.5, -0.5, -0.375, -0.3125, -0.25}, -- Left front foot, part 1 - {-0.375, -0.5, -0.5, -0.25, -0.3125, -0.375}, -- Left front foot, part 2 - {-0.5, -0.5, 0.25, -0.375, -0.3125, 0.5}, -- Left back foot, part 1 - {-0.375, -0.5, 0.375, -0.25, -0.3125, 0.5}, -- Left back foot, part 2 - {0.375, -0.5, 0.25, 0.5, -0.3125, 0.5}, -- Right back foot, part 1 - {0.25, -0.5, 0.375, 0.375, -0.3125, 0.5}, -- Right back foot, part 2 - {0.375, -0.5, -0.5, 0.5, -0.3125, -0.25}, -- Right front foot, part 1 - {0.25, -0.5, -0.5, 0.375, -0.3125, -0.375}, -- Right front foot, part 2 - } - } -end - -mcl_cauldrons.cauldron_nodeboxes = {} -for w=0,3 do - mcl_cauldrons.cauldron_nodeboxes[w] = create_cauldron_nodebox(w) -end - --- Empty cauldron ---[[ -minetest.register_node("mcl_cauldrons:cauldron", { - description = S("Cauldron"), - _tt_help = S("Stores water"), - _doc_items_longdesc = S("Cauldrons are used to store water and slowly fill up under rain."), - _doc_items_usagehelp = S("Place a water pucket into the cauldron to fill it with water. Place an empty bucket on a full cauldron to retrieve the water. Place a water bottle into the cauldron to fill the cauldron to one third with water. Place a glass bottle in a cauldron with water to retrieve one third of the water."), - wield_image = "mcl_cauldrons_cauldron.png", - inventory_image = "mcl_cauldrons_cauldron.png", - use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false, - drawtype = "nodebox", - paramtype = "light", - is_ground_content = false, - groups = {pickaxey=1, deco_block=1, cauldron=1}, - node_box = mcl_cauldrons.cauldron_nodeboxes[0], - selection_box = { type = "regular" }, - tiles = { - "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_top.png", - "mcl_cauldrons_cauldron_inner.png^mcl_cauldrons_cauldron_bottom.png", - "mcl_cauldrons_cauldron_side.png" - }, - sounds = mcl_sounds.node_sound_metal_defaults(), - _mcl_hardness = 2, - _mcl_blast_resistance = 2, -}) ---]] diff --git a/mods/ITEMS/mcl_potions/init.lua b/mods/ITEMS/mcl_potions/init.lua index 650b6ea0f..495a484ec 100644 --- a/mods/ITEMS/mcl_potions/init.lua +++ b/mods/ITEMS/mcl_potions/init.lua @@ -41,6 +41,34 @@ minetest.register_craft({ }) +local function deposit_player_inventory (placer, itemstack, item_name) + local new_itemstack = ItemStack({name=item_name}) + local inv = placer:get_inventory() + if minetest.is_creative_enabled(placer:get_player_name()) then + -- creative mode: have at most one. + if not inv:contains_item("main", new_itemstack) then + inv:add_item("main", new_itemstack) + end + else + -- survival mode + if itemstack:get_count() <= 1 then + -- swap in place. + return new_itemstack + elseif inv:room_for_item("main", new_itemstack) then + -- add to inventory, take one. + itemstack:take_item() + inv:add_item("main", new_itemstack) + return itemstack + else + -- drop in place. + itemstack:take_item() + minetest.add_item(placer:get_pos(), item_name) + end + end + -- no change in inventory. + return itemstack +end + local function take_from_cauldron (pos, node, itemstack, placer) local sounds = mcl_sounds.node_sound_metal_defaults() -- TODO: should come from declarative object -- check cauldron limits. @@ -56,30 +84,15 @@ local function take_from_cauldron (pos, node, itemstack, placer) end end if new_bottlename then - -- byproduct of draining cauldron. - local new_bottle = ItemStack({name=new_bottlename}) - local inv = placer:get_inventory() - if minetest.is_creative_enabled(placer:get_player_name()) then - -- creative mode: get for free - if not inv:contains_item("main", new_bottle) then - inv:add_item("main", new_bottle) - end - else - -- survival mode - if inv:room_for_item("main", new_bottle) then - itemstack:take_item() - inv:add_item("main", new_bottle) - else - minetest.add_item(placer:get_pos(), new_bottle) - end - end - return true + return deposit_player_inventory(placer, itemstack, new_bottlename) end + -- no change in inventory. + return itemstack end local function give_to_cauldron (pos, node, itemstack, placer, substance) if substance == nil then - return false + return itemstack end local sounds = mcl_sounds.node_sound_metal_defaults() -- TODO: should come from declarative object -- check cauldron limits. @@ -88,8 +101,7 @@ local function give_to_cauldron (pos, node, itemstack, placer, substance) local level = mcl_cauldrons.get_level(node, substance) local fit = maximum - level if fit > 0 then - -- sufficiently low level, add. - -- overwrites old content (old contents are lost). + -- sufficiently low level, add; old contents are lost. local newnode = mcl_cauldrons.fill_levels(node, mcl_cauldrons.BOTTLEFUL, substance) if node ~= new_node then -- change happened @@ -99,25 +111,10 @@ local function give_to_cauldron (pos, node, itemstack, placer, substance) end end if new_bottlename then - -- byproduct of filling cauldron. - local new_bottle = ItemStack({name=new_bottlename}) - local inv = placer:get_inventory() - if minetest.is_creative_enabled(placer:get_player_name()) then - -- creative mode: get for free - if not inv:contains_item("main", new_bottle) then - inv:add_item("main", new_bottle) - end - else - -- survival mode - if inv:room_for_item("main", new_bottle) then - itemstack:take_item() - inv:add_item("main", new_bottle) - else - minetest.add_item(placer:get_pos(), new_bottle) - end - end - return true + return deposit_player_inventory(placer, itemstack, new_bottlename) end + -- no change in inventory. + return itemstack end @@ -155,16 +152,9 @@ minetest.register_craftitem("mcl_potions:glass_bottle", { get_water = true --from_liquid_source = true river_water = node.name == "mclx_core:river_water_source" + local new_bottlename = river_water and "mcl_potions:river_water" or "mcl_potions:water" + return deposit_player_inventory(placer, itemstack, new_bottlename) -- Or reduce water level of cauldron by 1 ---[[ - elseif mcl_cauldrons.is_cauldron(node.name) then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - mcl_cauldrons.take_small_cauldron(pointed_thing.under, itemstack, placer, {dug = "mcl_potions_bottle_fill"}) ---]] elseif from_cauldron then if mcl_cauldrons.get_level(node, "cauldron_water") > 0 then -- take bottle of water. @@ -174,7 +164,7 @@ minetest.register_craftitem("mcl_potions:glass_bottle", { return itemstack end - take_from_cauldron(pointed_thing.under, node, itemstack, placer) + return take_from_cauldron(pointed_thing.under, node, itemstack, placer) end end end @@ -223,24 +213,6 @@ minetest.register_craftitem("mcl_potions:water", { end end - --[[ - local cauldron = fill_cauldron(node.name, "mcl_core:water_source") - if cauldron then - local pname = placer:get_player_name() - if minetest.is_protected(pointed_thing.under, pname) then - minetest.record_protection_violation(pointed_thing.under, pname) - return itemstack - end - -- Increase water level of cauldron by 1 - minetest.set_node(pointed_thing.under, {name=cauldron}) - minetest.sound_play("mcl_potions_bottle_pour", {pos=pointed_thing.under, gain=0.5, max_hear_range=16}, true) - if minetest.is_creative_enabled(placer:get_player_name()) then - return itemstack - else - return "mcl_potions:glass_bottle" - end - end - --]] if mcl_cauldrons.is_cauldron(node) then -- apply water bottle to empty or water cauldron -- anything else, replace content. @@ -249,7 +221,7 @@ minetest.register_craftitem("mcl_potions:water", { minetest.record_protection_violation(pointed_thing.under, pname) return itemstack end - give_to_cauldron(pointed_thing.under, node, itemstack, placer, "cauldron_water") + return give_to_cauldron(pointed_thing.under, node, itemstack, placer, "cauldron_water") end end