From 117f09ac9a3c744801cdf462193a8d36232bfbfc Mon Sep 17 00:00:00 2001 From: Evert Prants Date: Mon, 1 Apr 2019 13:17:59 +0300 Subject: [PATCH] casting table now takes fluid --- metal_melter/caster.lua | 9 +- multifurnace/casting_table.lua | 157 ++++++++++++++++++++++++++++++++- 2 files changed, 159 insertions(+), 7 deletions(-) diff --git a/metal_melter/caster.lua b/metal_melter/caster.lua index b44dcc7..01a940b 100644 --- a/metal_melter/caster.lua +++ b/metal_melter/caster.lua @@ -150,7 +150,7 @@ local function in_table(t, n) end -- Get the corresponding cast for an item -local function get_cast_for(item) +function metal_caster.get_cast_for(item) local cast = nil local typename = nil @@ -174,8 +174,7 @@ local function get_cast_for(item) return typename, cast end - -local function find_castable(metal_name, cast_name) +function metal_caster.find_castable(metal_name, cast_name) local cast = metal_caster.casts[cast_name] if not cast then return nil end @@ -339,7 +338,7 @@ local function caster_node_timer(pos, elapsed) if castname ~= nil then -- Cast metal using a cast local cast = metal_caster.casts[castname] - local result_name = find_castable(metal_type, castname) + local result_name = metal_caster.find_castable(metal_type, castname) if result_name ~= nil then local result_cost = cast.cost * metal_caster.spec.ingot local coolant_cost = result_cost / 4 @@ -365,7 +364,7 @@ local function caster_node_timer(pos, elapsed) local result_cost = metal_caster.spec.cast local coolant_cost = result_cost / 4 if metal.amount >= result_cost and coolant.amount >= coolant_cost then - local mtype, ctype = get_cast_for(caststack) + local mtype, ctype = metal_caster.get_cast_for(caststack) if mtype and ctype then local cmod = metal_caster.casts[ctype].mod_name or "metal_melter" local stack = ItemStack(cmod..":"..ctype.."_cast") diff --git a/multifurnace/casting_table.lua b/multifurnace/casting_table.lua index d939e25..a0e61e7 100644 --- a/multifurnace/casting_table.lua +++ b/multifurnace/casting_table.lua @@ -1,4 +1,11 @@ +local function update_timer (pos) + local t = minetest.get_node_timer(pos) + if not t:is_started() then + t:start(1.0) + end +end + local function create_item_entity(istack, cast, tpos) local vpos = vector.add(tpos, {x=0,y=0.5,z=0}) local e = minetest.add_entity(vpos, "multifurnace:table_item") @@ -69,6 +76,71 @@ local function set_item_entities(inv, pos) end end +local function cast_amount (ctype) + if not metal_caster.casts[ctype] then return nil end + return metal_caster.spec.ingot * (metal_caster.casts[ctype].cost or 1) +end + +local function on_timer(pos, elapsed) + local refresh = false + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + + local cast = inv:get_stack("cast", 1) + local item = inv:get_stack("item", 1) + + if cast:is_empty() or not item:is_empty() then return false end + + local liquid = meta:get_string("liquid") + local liqc = meta:get_int("liquid_amount") + local liqt = meta:get_int("liquid_total") + + -- TODO: cast creation + local ctype = metal_caster.get_cast_for_name(cast:get_name()) + local amount = cast_amount(ctype) + + if not ctype then + meta:set_int("liquid_total", metal_caster.spec.ingot) + elseif liqt ~= amount then + meta:set_int("liquid_total", amount) + end + + if liquid == "" or not ctype then return false end + + local liqt = fluidity.get_metal_for_fluid(liquid) + + if not amount then return false end + + local result = metal_caster.find_castable(liqt, ctype) + if not result then return false end + + local solidify = meta:get_int("solidify") + + if liqc >= amount then + if solidify < 3 then + refresh = true + meta:set_int("solidify", solidify + 1) + else + liquid = "" + liqc = 0 + item = ItemStack(result) + refresh = false + + -- Set result + + meta:set_string("liquid", liquid) + meta:set_int("liquid_amount", liqc) + meta:set_int("solidify", 0) + + inv:set_stack("item", 1, item) + + set_item_entities(inv, pos) + end + end + + return refresh +end + minetest.register_node("multifurnace:casting_table", { description = "Casting Table", drawtype = "nodebox", @@ -106,6 +178,7 @@ minetest.register_node("multifurnace:casting_table", { if inv:get_stack("cast", 1):is_empty() and cast then inv:set_stack("cast", 1, itemstack:take_item(1)) set_item_entities(inv, pos) + update_timer(pos) --elseif inv:get_stack("item", 1):is_empty() and not cast then -- inv:set_stack("item", 1, itemstack:take_item(1)) -- set_item_entities(inv, pos) @@ -123,7 +196,13 @@ minetest.register_node("multifurnace:casting_table", { to_give = inv:get_stack("item", 1) inv:set_list("item", {}) elseif not inv:get_stack("cast", 1):is_empty() then - -- TODO: check for liquid + local liq = meta:get_int("liquid_amount") + if liq > 0 then + meta:set_int("liquid_amount", 0) + meta:set_string("liquid", "") + meta:set_int("solidify", 0) + end + to_give = inv:get_stack("cast", 1) inv:set_list("cast", {}) end @@ -146,6 +225,68 @@ minetest.register_node("multifurnace:casting_table", { local inv = meta:get_inventory() return inv:get_stack("item", 1):is_empty() and inv:get_stack("cast", 1):is_empty() end, + on_timer = on_timer, + node_io_can_put_liquid = function (pos, node, side) + return true + end, + node_io_can_take_liquid = function (pos, node, side) + return false + end, + node_io_accepts_millibuckets = function(pos, node, side) return true end, + node_io_put_liquid = function(pos, node, side, putter, liquid, millibuckets) + local meta = minetest.get_meta(pos) + local liq = meta:get_string("liquid") + local liqc = meta:get_int("liquid_amount") + local liqt = meta:get_int("liquid_total") + local add = millibuckets + + local leftovers = 0 + + if (liq ~= liquid and liq ~= "") or liqt == 0 then return millibuckets end + if liqc == liqt then return millibuckets end + if liqc + millibuckets > liqt then + leftovers = liqc + millibuckets - liqt + add = liqt - liqc + end + + meta:set_string("liquid", liquid) + meta:set_int("liquid_amount", liqc + add) + update_timer(pos) + + return leftovers + end, + node_io_room_for_liquid = function(pos, node, side, liquid, millibuckets) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + local liq = meta:get_string("liquid") + local liqc = meta:get_int("liquid_amount") + local liqt = meta:get_int("liquid_total") + local add = millibuckets + + -- Don't allow adding fluid when there's an item or there's something solidifying + if not inv:get_stack("item", 1):is_empty() or meta:get_int("solidify") > 0 then return 0 end + + if (liq ~= liquid and liq ~= "") or liqt == 0 then return 0 end + if liqc == liqt then return 0 end + if liqc + millibuckets > liqt then + add = liqt - liqc + end + + return add + end, + node_io_get_liquid_size = function (pos, node, side) + return 1 + end, + node_io_get_liquid_name = function(pos, node, side, index) + local meta = minetest.get_meta(pos) + return meta:get_string("liquid") + end, + node_io_get_liquid_stack = function(pos, node, side, index) + local meta = minetest.get_meta(pos) + + return ItemStack(meta:get_string("liquid") .. " " .. + meta:get_int("liquid_amount")) + end, }) minetest.register_entity("multifurnace:table_item", { @@ -156,7 +297,7 @@ minetest.register_entity("multifurnace:table_item", { visual_size = {x = 0.45, y = 0.45, z = 0.5}, textures = {}, pointable = false, - static_save = true, + static_save = false, }, item = "air", cast = false, @@ -171,3 +312,15 @@ minetest.register_entity("multifurnace:table_item", { self.cast = is == true end }) + +minetest.register_lbm({ + label = "Draw Casting Table entities", + name = "multifurnace:casting_table_load", + nodenames = {"multifurnace:casting_table"}, + run_at_every_load = true, + action = function (pos, node) + local meta = minetest.get_meta(pos) + local inv = meta:get_inventory() + set_item_entities(inv, pos) + end +})