From a4dd435b4ea2fb8f77481adc6fe57cecfc94959a Mon Sep 17 00:00:00 2001 From: Evert Date: Fri, 6 Apr 2018 16:43:16 +0300 Subject: [PATCH] New API for tanks --- fluidity/florbs.lua | 2 +- fluidity/register.lua | 6 +- fluidity/tanks.lua | 196 +++++++++++++++++++++++++++--------- metal_melter/components.lua | 4 +- 4 files changed, 153 insertions(+), 55 deletions(-) diff --git a/fluidity/florbs.lua b/fluidity/florbs.lua index 5e6c59d..fcccea7 100644 --- a/fluidity/florbs.lua +++ b/fluidity/florbs.lua @@ -113,7 +113,7 @@ local function register_florbfluid(data) }) end -function fluidity.register_florb(data) +function fluidity.florbs.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' diff --git a/fluidity/register.lua b/fluidity/register.lua index 6fecb42..48ff91f 100644 --- a/fluidity/register.lua +++ b/fluidity/register.lua @@ -8,15 +8,15 @@ for _,v in pairs(metals) do end -- Register tanks for all fluids -fluidity.register_fluid_tank({ +fluidity.tanks.register_fluid_tank({ tank_name = "fluid_tank", tank_description = "Fluid Tank", - capacity = 64, + capacity = 64000, tiles = {"default_glass.png", "default_glass_detail.png"} }) -- Register florbs for all fluids -fluidity.register_florb({ +fluidity.florbs.register_florb({ florb_name = "florb", florb_description = "Florb", capacity = 1000, diff --git a/fluidity/tanks.lua b/fluidity/tanks.lua index 55bf42e..c4c0da1 100644 --- a/fluidity/tanks.lua +++ b/fluidity/tanks.lua @@ -1,8 +1,9 @@ -- Register tanks for each fluid fluidity.bucket_cache = {} +fluidity.tanks = {} --- Get fluid source block name for bucket item +-- Get fluid source block name for bucket item. function fluidity.get_fluid_for_bucket(itemname) for i,v in pairs(fluidity.bucket_cache) do if v == itemname then @@ -11,15 +12,17 @@ function fluidity.get_fluid_for_bucket(itemname) end end --- Get bucket item name for fluid source block +-- Get bucket item name for fluid source block. function fluidity.get_bucket_for_fluid(source) return fluidity.bucket_cache[source] end +-- Ensure that this fluid node exists. function fluidity.get_fluid_node(name) return minetest.registered_nodes[name] end +-- Get a nodedef field. local function get_nodedef_field(nodename, fieldname) if not minetest.registered_nodes[nodename] then return nil @@ -27,73 +30,168 @@ local function get_nodedef_field(nodename, fieldname) return minetest.registered_nodes[nodename][fieldname] end +-- Ensure that the node is a tank. +function fluidity.tanks.get_is_tank(node) + return minetest.get_item_group(node, "fluidity_tank") > 0 +end + +-- Ensure that the node is an empty tank. +function fluidity.tanks.get_is_empty_tank(node) + return minetest.get_item_group(node, "fluidity_tank_empty") > 0 +end + +-- Get tank data at position. +-- Returns fluid name, fluid level, capacity, base tank name and the mod it was added from. +-- Base tank name and mod name are used to construct different variants of this tank type. +function fluidity.tanks.get_tank_at(pos) + local meta = minetest.get_meta(pos) + local node = minetest.get_node(pos) + + if not fluidity.tanks.get_is_tank(node.name) then return nil end + + local ffluid = get_nodedef_field(node.name, "fluidity_fluid") + local fcapacity = get_nodedef_field(node.name, "_capacity") + local fbasetank = get_nodedef_field(node.name, "_dataname") + local fmod = get_nodedef_field(node.name, "_mod") + local fluidcount = meta:get_int("fluid") + + return ffluid, fluidcount, fcapacity, fbasetank, fmod +end + +-- Check to see if a fluid can go in the tank and pos. +function fluidity.tanks.can_fluid_go_in_tank(pos, fluid) + local fluid_name, count, capacity, base_tank, mod = fluidity.tanks.get_tank_at(pos) + if not fluid_name then return true end + if fluid_name ~= fluid then return false end + if count == capacity then return false end + + local source_node = fluidity.get_fluid_node(fluid) + local fluid_desc = fluidity.fluid_name(source_node.description) + local shorthand_name = fluidity.fluid_short(fluid_desc) + + if not minetest.registered_nodes[mod..":"..base_tank.."_"..shorthand_name] then return false end + + return true +end + +-- Fill the tank at pos with fluid. +-- Overfilling means it will return an integer as the second variable that shows the amount over the capacity. +function fluidity.tanks.fill_tank_at(pos, fluid, amount, overfill) + local fluid_name, count, capacity, base_tank, mod = fluidity.tanks.get_tank_at(pos) + if not fluid_name == fluid and fluid_name ~= nil then return nil end + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local node_name = mod..":"..base_tank + + local remainder = 0 + if count + amount > capacity then + if overfill then + remainder = (count + amount) - capacity + count = capacity + else + return nil + end + else + count = count + amount + end + + local source_node = fluidity.get_fluid_node(fluid) + local fluid_desc = fluidity.fluid_name(source_node.description) + local shorthand_name = fluidity.fluid_short(fluid_desc) + + node_name = mod..":"..base_tank.."_"..shorthand_name + if not minetest.registered_nodes[node_name] then return nil end + + meta:set_int("fluid", count) + meta:set_string("infotext", "Tank of "..fluid_desc.."("..count.."/"..capacity.." mB)") + + local param2 = math.min((count/capacity)*63, 63) + + minetest.swap_node(pos, {name=node_name,param1=node.param1,param2=param2}) + + return fluid, remainder +end + +-- Take some fluid from the tank at pos. +-- Underfill returns an integer as the second variable indicating level below zero. +function fluidity.tanks.take_from_tank_at(pos, amount, underfill) + local fluid_name, count, capacity, base_tank, mod = fluidity.tanks.get_tank_at(pos) + if not fluid_name then return nil end + local node = minetest.get_node(pos) + local meta = minetest.get_meta(pos) + local node_name = mod..":"..base_tank + local fluid = fluid_name + + local leftover = 0 + if count - amount < 0 then + if underfill then + leftover = (count - amount) * -1 + count = 0 + else + return nil + end + else + count = count - amount + end + + if count == 0 then + fluid = nil + end + + meta:set_int("fluid", count) + + if fluid then + local source_node = fluidity.get_fluid_node(fluid) + local fluid_desc = fluidity.fluid_name(source_node.description) + local shorthand_name = fluidity.fluid_short(fluid_desc) + + node_name = mod..":"..base_tank.."_"..shorthand_name + + meta:set_string("infotext", "Tank of "..fluid_desc.."("..count.."/"..capacity.." mB)") + else + meta:set_string("infotext", "Empty Tank") + end + + local param2 = math.min((count/capacity)*63, 63) + + minetest.swap_node(pos, {name=node_name,param1=node.param1,param2=param2}) + + return fluid_name, leftover +end + local function bucket_fill(pos, node, clicker, itemstack, pointed_thing) local stackname = itemstack:get_name() - local nodename = node.name local stack = "bucket:bucket_empty" - local meta = minetest.get_meta(pos) if not stackname:find("bucket") then return itemstack end - local tankfluid = get_nodedef_field(node.name, "fluidity_fluid") - local tankname = get_nodedef_field(node.name, "_dataname") - local tankcap = get_nodedef_field(node.name, "_capacity") - local tankmod = get_nodedef_field(node.name, "_mod") - - local fluidcount = meta:get_int("fluid") if stackname == "bucket:bucket_empty" then - if tankfluid == nil then + if fluidity.tanks.get_is_empty_tank(node.name) then return itemstack end - fluidcount = fluidcount - 1 - stack = fluidity.get_bucket_for_fluid(tankfluid) - - if fluidcount == 0 then - nodename = tankmod..":"..tankname - tankfluid = nil + local fluid = fluidity.tanks.take_from_tank_at(pos, 1000) + if not fluid then + return itemstack end + + stack = fluidity.get_bucket_for_fluid(fluid) else local srcnode = fluidity.get_fluid_for_bucket(stackname) - if (tankfluid ~= srcnode and tankfluid ~= nil) or (fluidcount >= tankcap) then + if not fluidity.tanks.can_fluid_go_in_tank(pos, srcnode) then return itemstack end - if tankfluid == nil then - local source_node = fluidity.get_fluid_node(srcnode) - local fluid_name = fluidity.fluid_name(source_node.description) - local shorthand_name = fluidity.fluid_short(fluid_name) + local fluid = fluidity.tanks.fill_tank_at(pos, srcnode, 1000) - nodename = tankmod..":"..tankname.."_"..shorthand_name - - if not minetest.registered_nodes[nodename] then - return itemstack - end - - tankfluid = srcnode + if fluid == nil then + return itemstack end - - fluidcount = fluidcount + 1 end - meta:set_int("fluid", fluidcount) - - if tankfluid then - local source_node = fluidity.get_fluid_node(tankfluid) - local fluid_name = fluidity.fluid_name(source_node.description) - - meta:set_string("infotext", "Tank of "..fluid_name.."("..fluidcount.."/"..tankcap..")") - else - meta:set_string("infotext", "Empty Tank") - end - - local param2 = (fluidcount/tankcap)*63 - - minetest.swap_node(pos, {name=nodename,param1=node.param1,param2=param2}) - return ItemStack(stack) end @@ -124,12 +222,12 @@ local function register_tankfluid(data) end -- Register a new tank -function fluidity.register_fluid_tank(data) +function fluidity.tanks.register_fluid_tank(data) local modname = data.mod_name or minetest.get_current_modname() local tankname = data.tank_name or 'fluid_tank' local tankdesc = data.tank_description or 'Fluid Tank' local tiles = data.tiles or {"default_glass.png", "default_glass_detail.png"} - local capacity = data.capacity or 64 + local capacity = data.capacity or 64000 minetest.register_node(modname..":"..tankname, { description = tankdesc, @@ -148,7 +246,7 @@ function fluidity.register_fluid_tank(data) _mod = modname, _dataname = tankname, _capacity = capacity, - groups = {cracky = 1, oddly_breakable_by_hand = 3, fluidity_tank = 1}, + groups = {cracky = 1, oddly_breakable_by_hand = 3, fluidity_tank = 1, fluid_tank_empty = 1}, tiles = tiles }) diff --git a/metal_melter/components.lua b/metal_melter/components.lua index f8ffbbb..8010c37 100644 --- a/metal_melter/components.lua +++ b/metal_melter/components.lua @@ -66,11 +66,11 @@ minetest.register_node('metal_melter:casting_table', { }) -fluidity.register_fluid_tank({ +fluidity.tanks.register_fluid_tank({ mod_name = "metal_melter", tank_name = "heated_tank", tank_description = "Heated Tank", - capacity = 8, + capacity = 8000, tiles = {"default_glass.png", "default_glass_detail.png"}, fluids = {"default:lava_source"} })