diff --git a/fluidity/florbs.lua b/fluidity/florbs.lua new file mode 100644 index 0000000..1732641 --- /dev/null +++ b/fluidity/florbs.lua @@ -0,0 +1,162 @@ + +fluidity.florbs = {} + +local function get_itemdef_field(nodename, fieldname) + if not minetest.registered_items[nodename] then + return nil + end + return minetest.registered_items[nodename][fieldname] +end + +function fluidity.florbs.get_is_florb(stack) + return minetest.get_item_group(stack:get_name(), "florb") > 0 +end + +function fluidity.florbs.get_is_empty_florb(stack) + return minetest.get_item_group(stack:get_name(), "florb_blank") > 0 +end + +function fluidity.florbs.get_florb_contents(stack) + if not fluidity.florbs.get_is_florb(stack) then return nil end + local fcapacity = get_itemdef_field(stack:get_name(), "_florb_capacity") + local ffluid = get_itemdef_field(stack:get_name(), "_florb_source") + + local meta = stack:get_meta() + local contents = meta:get_int("contents") + if not contents then + contents = 0 + end + + return contents, ffluid, fcapacity +end + +local function update_florb(stack) + local def_desc = get_itemdef_field(stack:get_name(), "description") + local meta = stack:get_meta() + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack) + + meta:set_string("description", def_desc.."\nContains "..contents.."/"..capacity.." mB") + + return stack +end + +function fluidity.florbs.add_fluid(stack, source_name, amount) + if not fluidity.florbs.get_is_florb(stack) then return nil end + local source_node = fluidity.get_fluid_node(source_name) + local fluid = fluidity.fluid_name(source_node.description) + local internal = fluidity.fluid_short(fluid) + local florbname = stack:get_name() + + if minetest.get_item_group(florbname, "florb_blank") > 0 then + stack = ItemStack(florbname.."_"..internal) + end + + local meta = stack:get_meta() + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack) + + local remainder = 0 + + if contents + amount > capacity then + remainder = (contents + amount) - capacity + contents = capacity + else + contents = contents + amount + end + + meta:set_int("contents", contents) + stack = update_florb(stack) + + return stack, remainder +end + +function fluidity.florbs.take_fluid(stack, amount) + if not fluidity.florbs.get_is_florb(stack) then return nil end + + local meta = stack:get_meta() + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(stack) + local blank = get_itemdef_field(stack:get_name(), "_florb_blank") + + local leftover = 0 + if contents - amount < 0 then + leftover = (contents - amount) * -1 + contents = 0 + else + contents = contents - amount + end + + if contents == 0 then + stack = ItemStack(blank) + else + meta:set_int("contents", contents) + stack = update_florb(stack) + end + + return stack, leftover +end + +local function register_florbfluid(data) + local source_node = fluidity.get_fluid_node(data.source_name) + local fluid = fluidity.fluid_name(source_node.description) + local internal = fluidity.fluid_short(fluid) + + local stationary_name = source_node.tiles[1].name:gsub("_source_animated", "") + + -- Register base item + minetest.register_craftitem(data.mod_name..":"..data.florb_name.."_"..internal, { + description = data.florb_description.." ("..fluid..")", + inventory_image = stationary_name.."^[noalpha^"..data.textures[1].."^"..data.textures[2].."^[makealpha:255,0,0,", + _florb_capacity = data.capacity, + _florb_source = data.source_name, + _florb_blank = data.mod_name..":"..data.florb_name, + stack_max = 1, + groups = {florb = 1, not_in_creative_inventory = 1} + }) +end + +function fluidity.register_florb(data) + local mod_name = data.mod_name or minetest.get_current_modname() + local florb_name = data.florb_name or 'florb' + local florb_desc = data.florb_description or 'Florb' + local textures = data.textures or {"fluidity_florb.png", "fluidity_florb_mask.png"} + local capacity = data.capacity or 1000 + + -- Register base item + minetest.register_craftitem(mod_name..":"..florb_name, { + description = florb_desc.." (Empty)\nThis item holds percise amount of fluids.", + inventory_image = textures[1], + _florb_capacity = capacity, + _florb_source = nil, + stack_max = 1, + groups = {florb = 1, florb_blank = 1} + }) + + -- Register for all fluids + if data.fluids then + -- This tank only uses certain fluids + for _, v in pairs(data.fluids) do + register_florbfluid({ + mod_name = mod_name, + florb_name = florb_name, + florb_description = florb_desc, + textures = textures, + capacity = capacity, + source_name = v + }) + end + else + -- Get all fluids and buckets and cache them + for i, v in pairs(bucket.liquids) do + if (i:find("source") ~= nil) then + -- Add tank + register_florbfluid({ + mod_name = mod_name, + florb_name = florb_name, + florb_description = florb_desc, + textures = textures, + capacity = capacity, + source_name = v["source"] + }) + end + end + end +end diff --git a/fluidity/init.lua b/fluidity/init.lua index b8c816b..b1e776e 100644 --- a/fluidity/init.lua +++ b/fluidity/init.lua @@ -15,5 +15,8 @@ dofile(mpath.."/molten.lua") -- Tanks dofile(mpath.."/tanks.lua") +-- Florbs +dofile(mpath.."/florbs.lua") + -- Register everything dofile(mpath.."/register.lua") diff --git a/fluidity/register.lua b/fluidity/register.lua index 0719032..6fecb42 100644 --- a/fluidity/register.lua +++ b/fluidity/register.lua @@ -7,11 +7,18 @@ for _,v in pairs(metals) do fluidity.register_molten_metal(v) end --- Register tanks for all metals +-- Register tanks for all fluids fluidity.register_fluid_tank({ - mod_name = "fluidity", tank_name = "fluid_tank", tank_description = "Fluid Tank", capacity = 64, tiles = {"default_glass.png", "default_glass_detail.png"} }) + +-- Register florbs for all fluids +fluidity.register_florb({ + florb_name = "florb", + florb_description = "Florb", + capacity = 1000, + tiles = {"fluidity_florb.png", "fluidity_florb_mask.png"} +}) diff --git a/fluidity/textures/fluidity_florb.png b/fluidity/textures/fluidity_florb.png new file mode 100644 index 0000000..837042f Binary files /dev/null and b/fluidity/textures/fluidity_florb.png differ diff --git a/fluidity/textures/fluidity_florb_mask.png b/fluidity/textures/fluidity_florb_mask.png new file mode 100644 index 0000000..7aab3c4 Binary files /dev/null and b/fluidity/textures/fluidity_florb_mask.png differ diff --git a/metal_melter/caster.lua b/metal_melter/caster.lua index b1b222c..c75b743 100644 --- a/metal_melter/caster.lua +++ b/metal_melter/caster.lua @@ -112,7 +112,7 @@ local function allow_metadata_inventory_put (pos, listname, index, stack, player end if listname == "bucket_out" then - if stack:get_name() ~= "bucket:bucket_empty" then + if stack:get_name() ~= "bucket:bucket_empty" and not fluidity.florbs.get_is_florb(stack) then return 0 end @@ -270,42 +270,95 @@ local function caster_node_timer(pos, elapsed) end -- Handle input bucket, only allow a molten metal - local bucket_in = inv:get_stack("bucket_in", 1):get_name() - if bucket_in:find("bucket") and bucket_in ~= "bucket:bucket_empty" then - local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_in) - local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil - local empty_bucket = false + local bucket_in = inv:get_stack("bucket_in", 1) + local bucket_name = bucket_in:get_name() + if (bucket_name:find("bucket") and bucket_name ~= "bucket:bucket_empty") or (not fluidity.florbs.get_is_empty_florb(bucket_in) and fluidity.florbs.get_is_florb(bucket_in)) then + local is_florb = fluidity.florbs.get_is_florb(bucket_in) + if is_florb then + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_in) + local fluid_metal = fluidity.get_metal_for_fluid(fluid_name) + if fluid_metal and (fluid_name == metal or metal == "") then + local take = 1000 - if fluid_is_metal then - if metal ~= "" and metal == bucket_fluid then - if metal_count + 1000 <= metal_caster.max_metal then - metal_count = metal_count + 1000 + if metal_count + take > metal_melter.max_metal then + take = metal_melter.max_metal - metal_count + end + + -- Attempt to take 1000 millibuckets from the florb + local stack,res = fluidity.florbs.take_fluid(bucket_in, take) + if res > 0 then + take = take - res + end + + metal = fluid_name + metal_count = metal_count + take + inv:set_list("bucket_in", {stack}) + refresh = true + end + else + local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_name) + local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil + local empty_bucket = false + + if fluid_is_metal then + if metal ~= "" and metal == bucket_fluid then + if metal_count + 1000 <= metal_melter.max_metal then + metal_count = metal_count + 1000 + empty_bucket = true + end + elseif metal == "" then + metal_count = 1000 + metal = bucket_fluid empty_bucket = true end - elseif metal == "" then - metal_count = 1000 - metal = bucket_fluid - empty_bucket = true end - end - if empty_bucket then - inv:set_list("bucket_in", {"bucket:bucket_empty"}) - refresh = true + if empty_bucket then + inv:set_list("bucket_in", {"bucket:bucket_empty"}) + refresh = true + end end end -- Handle bucket output, only allow empty buckets in this slot - local bucket_out = inv:get_stack("bucket_out", 1):get_name() - if bucket_out == "bucket:bucket_empty" and metal ~= "" and inv:get_stack("bucket_out", 1):get_count() == 1 then - local bucket = fluidity.get_bucket_for_fluid(metal) - if metal_count >= 1000 then - metal_count = metal_count - 1000 - inv:set_list("bucket_out", {bucket}) - refresh = true + local bucket_out = inv:get_stack("bucket_out", 1) + bucket_name = bucket_out:get_name() + if (bucket_name == "bucket:bucket_empty" or fluidity.florbs.get_is_florb(bucket_out)) and metal ~= "" and bucket_out:get_count() == 1 then + local is_florb = fluidity.florbs.get_is_florb(bucket_out) + if is_florb then + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_out) + local fluid_metal = fluidity.get_metal_for_fluid(fluid_name) + if not fluid_name or fluid_name == metal then + local take = 1000 - if metal_count == 0 then - metal = "" + if metal_count < take then + take = metal_count + end + + -- Attempt to put 1000 millibuckets into the florb + local stack,res = fluidity.florbs.add_fluid(bucket_out, metal, take) + if res > 0 then + take = take - res + end + + metal_count = metal_count - take + inv:set_list("bucket_out", {stack}) + refresh = true + + if metal_count == 0 then + metal = "" + end + end + else + local bucket = fluidity.get_bucket_for_fluid(metal) + if metal_count >= 1000 then + metal_count = metal_count - 1000 + inv:set_list("bucket_out", {bucket}) + refresh = true + + if metal_count == 0 then + metal = "" + end end end end diff --git a/metal_melter/melter.lua b/metal_melter/melter.lua index 241bedf..ae428f9 100644 --- a/metal_melter/melter.lua +++ b/metal_melter/melter.lua @@ -127,7 +127,7 @@ local function allow_metadata_inventory_put (pos, listname, index, stack, player end if listname == "bucket_out" then - if stack:get_name() ~= "bucket:bucket_empty" then + if stack:get_name() ~= "bucket:bucket_empty" and not fluidity.florbs.get_is_florb(stack) then return 0 end @@ -209,42 +209,95 @@ local function melter_node_timer(pos, elapsed) end -- Handle input bucket, only allow a molten metal - local bucket_in = inv:get_stack("bucket_in", 1):get_name() - if bucket_in:find("bucket") and bucket_in ~= "bucket:bucket_empty" then - local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_in) - local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil - local empty_bucket = false + local bucket_in = inv:get_stack("bucket_in", 1) + local bucket_name = bucket_in:get_name() + if (bucket_name:find("bucket") and bucket_name ~= "bucket:bucket_empty") or (not fluidity.florbs.get_is_empty_florb(bucket_in) and fluidity.florbs.get_is_florb(bucket_in)) then + local is_florb = fluidity.florbs.get_is_florb(bucket_in) + if is_florb then + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_in) + local fluid_metal = fluidity.get_metal_for_fluid(fluid_name) + if fluid_metal and (fluid_name == metal or metal == "") then + local take = 1000 - if fluid_is_metal then - if metal ~= "" and metal == bucket_fluid then - if metal_count + 1000 <= metal_melter.max_metal then - metal_count = metal_count + 1000 + if metal_count + take > metal_melter.max_metal then + take = metal_melter.max_metal - metal_count + end + + -- Attempt to take 1000 millibuckets from the florb + local stack,res = fluidity.florbs.take_fluid(bucket_in, take) + if res > 0 then + take = take - res + end + + metal = fluid_name + metal_count = metal_count + take + inv:set_list("bucket_in", {stack}) + refresh = true + end + else + local bucket_fluid = fluidity.get_fluid_for_bucket(bucket_name) + local fluid_is_metal = fluidity.get_metal_for_fluid(bucket_fluid) ~= nil + local empty_bucket = false + + if fluid_is_metal then + if metal ~= "" and metal == bucket_fluid then + if metal_count + 1000 <= metal_melter.max_metal then + metal_count = metal_count + 1000 + empty_bucket = true + end + elseif metal == "" then + metal_count = 1000 + metal = bucket_fluid empty_bucket = true end - elseif metal == "" then - metal_count = 1000 - metal = bucket_fluid - empty_bucket = true end - end - if empty_bucket then - inv:set_list("bucket_in", {"bucket:bucket_empty"}) - refresh = true + if empty_bucket then + inv:set_list("bucket_in", {"bucket:bucket_empty"}) + refresh = true + end end end -- Handle bucket output, only allow empty buckets in this slot - local bucket_out = inv:get_stack("bucket_out", 1):get_name() - if bucket_out == "bucket:bucket_empty" and metal ~= "" and inv:get_stack("bucket_out", 1):get_count() == 1 then - local bucket = fluidity.get_bucket_for_fluid(metal) - if metal_count >= 1000 then - metal_count = metal_count - 1000 - inv:set_list("bucket_out", {bucket}) - refresh = true + local bucket_out = inv:get_stack("bucket_out", 1) + bucket_name = bucket_out:get_name() + if (bucket_name == "bucket:bucket_empty" or fluidity.florbs.get_is_florb(bucket_out)) and metal ~= "" and bucket_out:get_count() == 1 then + local is_florb = fluidity.florbs.get_is_florb(bucket_out) + if is_florb then + local contents, fluid_name, capacity = fluidity.florbs.get_florb_contents(bucket_out) + local fluid_metal = fluidity.get_metal_for_fluid(fluid_name) + if not fluid_name or fluid_name == metal then + local take = 1000 - if metal_count == 0 then - metal = "" + if metal_count < take then + take = metal_count + end + + -- Attempt to put 1000 millibuckets into the florb + local stack,res = fluidity.florbs.add_fluid(bucket_out, metal, take) + if res > 0 then + take = take - res + end + + metal_count = metal_count - take + inv:set_list("bucket_out", {stack}) + refresh = true + + if metal_count == 0 then + metal = "" + end + end + else + local bucket = fluidity.get_bucket_for_fluid(metal) + if metal_count >= 1000 then + metal_count = metal_count - 1000 + inv:set_list("bucket_out", {bucket}) + refresh = true + + if metal_count == 0 then + metal = "" + end end end end diff --git a/tinkering/nodesitems.lua b/tinkering/nodesitems.lua index 416eacb..8afff5c 100644 --- a/tinkering/nodesitems.lua +++ b/tinkering/nodesitems.lua @@ -53,3 +53,11 @@ minetest.register_craft({ {'group:tree'}, }, }) + +minetest.register_craft({ + output = 'fluidity:florb', + recipe = { + {'default:glass'}, + {'bucket:bucket_empty'}, + }, +})