techage/basis/liquid_lib.lua

258 lines
8.3 KiB
Lua
Raw Normal View History

2020-02-02 18:47:58 +03:00
--[[
TechAge
=======
Copyright (C) 2019-2020 Joachim Stolberg
2020-10-19 20:09:17 +03:00
AGPL v3
2020-02-02 18:47:58 +03:00
See LICENSE.txt for more information
2022-01-03 23:40:31 +03:00
2020-02-02 18:47:58 +03:00
Liquid lib
]]--
local M = minetest.get_meta
local S = techage.S
local P2S = minetest.pos_to_string
local LQD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).liquid end
local BLOCKING_TIME = 0.3 -- 300ms
techage.liquid = {}
local LiquidDef = {}
2020-02-16 21:53:40 +03:00
local IsLiquid = {}
2020-02-02 18:47:58 +03:00
local ContainerDef = {}
local function help(x, y)
local tooltip = S("To add liquids punch\nthe tank\nwith a liquid container")
return "label["..x..","..y..";"..minetest.colorize("#000000", minetest.formspec_escape("[?]")).."]"..
"tooltip["..x..","..y..";0.5,0.5;"..tooltip..";#0C3D32;#FFFFFF]"
end
2021-12-31 19:25:37 +03:00
function techage.liquid.formspec(pos, nvm, title)
title = title or S("Liquid Tank")
2020-02-02 18:47:58 +03:00
local itemname = "techage:liquid"
if nvm.liquid and nvm.liquid.amount and nvm.liquid.amount > 0 and nvm.liquid.name then
itemname = nvm.liquid.name.." "..nvm.liquid.amount
end
local name = minetest.get_node(pos).name
if name == "techage:ta4_tank" then
local meta = M(pos)
local public = dump((meta:get_int("public") or 0) == 1)
local keep_assignment = dump((meta:get_int("keep_assignment") or 0) == 1)
2021-12-31 19:25:37 +03:00
return "size[8,3.5]"..
"box[0,-0.1;7.8,0.5;#c6e8ff]"..
"label[0.2,-0.1;"..minetest.colorize("#000000", title).."]"..
help(7.4, -0.1)..
techage.item_image(3.5, 1, itemname)..
"checkbox[0.1,2.5;public;"..S("Allow public access to the tank")..";"..public.."]"..
"checkbox[0.1,3;keep_assignment;"..S("keep assignment")..";"..keep_assignment.."]"
else
2021-12-31 19:25:37 +03:00
return "size[8,2]"..
"box[0,-0.1;7.8,0.5;#c6e8ff]"..
"label[0.2,-0.1;"..minetest.colorize("#000000", title).."]"..
help(7.4, -0.1)..
techage.item_image(3.5, 1, itemname)
end
2022-01-03 23:40:31 +03:00
end
2020-02-02 18:47:58 +03:00
function techage.liquid.is_empty(pos)
local nvm = techage.get_nvm(pos)
return not nvm.liquid or (nvm.liquid.amount or 0) <= 0
2020-02-02 18:47:58 +03:00
end
2020-02-10 23:20:54 +03:00
techage.liquid.recv_message = {
2020-02-02 18:47:58 +03:00
on_recv_message = function(pos, src, topic, payload)
if topic == "load" then
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
return techage.power.percent(LQD(pos).capa, nvm.liquid.amount), nvm.liquid.amount
2020-02-02 18:47:58 +03:00
elseif topic == "size" then
return LQD(pos).capa
else
return "unsupported"
end
end,
2022-01-03 23:40:31 +03:00
}
2020-02-02 18:47:58 +03:00
-- like: register_liquid("techage:ta3_barrel_oil", "techage:ta3_barrel_empty", 10, "techage:oil")
function techage.register_liquid(full_container, empty_container, container_size, inv_item)
LiquidDef[full_container] = {container = empty_container, size = container_size, inv_item = inv_item}
ContainerDef[empty_container] = ContainerDef[empty_container] or {}
ContainerDef[empty_container][inv_item] = full_container
2020-02-16 21:53:40 +03:00
IsLiquid[inv_item] = true
2020-02-02 18:47:58 +03:00
end
local function get_liquid_def(full_container)
return LiquidDef[full_container]
end
2022-01-03 23:40:31 +03:00
2020-02-02 18:47:58 +03:00
local function get_container_def(container_name)
return ContainerDef[container_name]
end
local function is_container_empty(container_name)
return ContainerDef[container_name]
end
local function get_full_container(empty_container, inv_item)
return ContainerDef[empty_container] and ContainerDef[empty_container][inv_item]
end
2020-02-18 00:46:29 +03:00
-- used by filler
2020-02-02 18:47:58 +03:00
local function fill_container(pos, inv, empty_container)
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
local full_container = get_full_container(empty_container, nvm.liquid.name)
if empty_container and full_container then
local ldef = get_liquid_def(full_container)
2022-01-03 23:40:31 +03:00
if ldef and nvm.liquid.amount - ldef.size >= 0 then
2020-02-02 18:47:58 +03:00
if inv:room_for_item("dst", {name = full_container}) then
inv:add_item("dst", {name = full_container})
nvm.liquid.amount = nvm.liquid.amount - ldef.size
if nvm.liquid.amount == 0 then
nvm.liquid.name = nil
end
return true
end
end
end
-- undo
inv:add_item("src", {name = empty_container})
return false
end
2020-02-18 00:46:29 +03:00
-- used by filler
2020-02-02 18:47:58 +03:00
local function empty_container(pos, inv, full_container)
local nvm = techage.get_nvm(pos)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
2020-02-10 23:20:54 +03:00
local ndef_lqd = LQD(pos)
local tank_size = (ndef_lqd and ndef_lqd.capa) or 0
2020-02-02 18:47:58 +03:00
local ldef = get_liquid_def(full_container)
if ldef and (not nvm.liquid.name or ldef.inv_item == nvm.liquid.name) then
2022-01-03 23:40:31 +03:00
if nvm.liquid.amount + ldef.size <= tank_size then
2020-02-02 18:47:58 +03:00
if inv:room_for_item("dst", {name = ldef.container}) then
inv:add_item("dst", {name = ldef.container})
nvm.liquid.amount = nvm.liquid.amount + ldef.size
nvm.liquid.name = ldef.inv_item
return true
end
end
end
-- undo
inv:add_item("src", {name = full_container})
return false
end
2020-02-18 00:46:29 +03:00
-- check if the wielded empty container can be replaced by a full
2020-02-02 18:47:58 +03:00
-- container and added to the players inventory
local function fill_on_punch(nvm, empty_container, item_count, puncher)
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
local full_container = get_full_container(empty_container, nvm.liquid.name)
if empty_container and full_container then
local item = {name = full_container}
local ldef = get_liquid_def(full_container)
2022-01-03 23:40:31 +03:00
if ldef and nvm.liquid.amount - ldef.size >= 0 then
2020-02-02 18:47:58 +03:00
if item_count > 1 then -- can't be simply replaced?
-- check for extra free space
local inv = puncher:get_inventory()
if inv:room_for_item("main", {name = full_container}) then
-- add full container and return
-- the empty once - 1
2022-01-03 23:40:31 +03:00
inv:add_item("main", {name = full_container})
2020-02-02 18:47:58 +03:00
item = {name = empty_container, count = item_count - 1}
else
return -- no free space
end
end
nvm.liquid.amount = nvm.liquid.amount - ldef.size
2022-01-03 23:40:31 +03:00
if nvm.liquid.amount == 0 then
nvm.liquid.name = nil
2020-02-02 18:47:58 +03:00
end
return item -- to be added to the players inv.
end
2020-02-16 21:53:40 +03:00
elseif nvm.liquid.name and not IsLiquid[nvm.liquid.name] then
if empty_container == "" then
local count = math.max(nvm.liquid.amount, 99)
local name = nvm.liquid.name
nvm.liquid.amount = nvm.liquid.amount - count
2022-01-03 23:40:31 +03:00
if nvm.liquid.amount == 0 then
nvm.liquid.name = nil
2020-02-16 21:53:40 +03:00
end
return {name = name, count = count}
end
2020-02-02 18:47:58 +03:00
end
end
local function legacy_items(full_container, item_count)
if full_container == "techage:hydrogen" then
return {container = "", size = item_count, inv_item = full_container}
elseif full_container == "techage:oil_source" then
return {container = "", size = item_count, inv_item = full_container}
end
2022-01-03 23:40:31 +03:00
end
2020-02-24 22:59:26 +03:00
-- check if the wielded full container can be emptied into the tank
2020-02-18 00:46:29 +03:00
local function empty_on_punch(pos, nvm, full_container, item_count)
2020-02-02 18:47:58 +03:00
nvm.liquid = nvm.liquid or {}
nvm.liquid.amount = nvm.liquid.amount or 0
local lqd_def = get_liquid_def(full_container) or legacy_items(full_container, item_count)
2020-02-10 23:20:54 +03:00
local ndef_lqd = LQD(pos)
2022-01-03 23:40:31 +03:00
if lqd_def and ndef_lqd then
2020-02-10 23:20:54 +03:00
local tank_size = ndef_lqd.capa or 0
if not nvm.liquid.name or lqd_def.inv_item == nvm.liquid.name then
2022-01-03 23:40:31 +03:00
if nvm.liquid.amount + lqd_def.size <= tank_size then
2020-02-10 23:20:54 +03:00
nvm.liquid.amount = nvm.liquid.amount + lqd_def.size
nvm.liquid.name = lqd_def.inv_item
return {name = lqd_def.container}
2020-02-02 18:47:58 +03:00
end
end
end
end
function techage.liquid.on_punch(pos, node, puncher, pointed_thing)
local public = M(pos):get_int("public") == 1
if not public and minetest.is_protected(pos, puncher:get_player_name()) then
2020-09-08 22:39:34 +03:00
return
end
2020-02-02 18:47:58 +03:00
local nvm = techage.get_nvm(pos)
local mem = techage.get_mem(pos)
mem.blocking_time = mem.blocking_time or 0
if mem.blocking_time > techage.SystemTime then
return
end
2022-01-03 23:40:31 +03:00
2020-02-02 18:47:58 +03:00
local wielded_item = puncher:get_wielded_item():get_name()
local item_count = puncher:get_wielded_item():get_count()
2022-01-03 23:40:31 +03:00
local new_item = fill_on_punch(nvm, wielded_item, item_count, puncher)
2020-02-18 00:46:29 +03:00
or empty_on_punch(pos, nvm, wielded_item, item_count)
2020-02-02 18:47:58 +03:00
if new_item then
puncher:set_wielded_item(new_item)
M(pos):set_string("formspec", techage.fuel.formspec(pos, nvm))
mem.blocking_time = techage.SystemTime + BLOCKING_TIME
return
end
end
2020-02-28 00:33:42 +03:00
function techage.liquid.get_liquid_amount(nvm)
if nvm.liquid and nvm.liquid.amount then
return nvm.liquid.amount
end
return 0
end
2020-02-02 18:47:58 +03:00
techage.liquid.get_liquid_def = get_liquid_def
techage.liquid.get_container_def = get_container_def
techage.liquid.is_container_empty = is_container_empty
techage.liquid.get_full_container = get_full_container
techage.liquid.fill_container = fill_container
techage.liquid.empty_container = empty_container
techage.liquid.fill_on_punch = fill_on_punch
techage.liquid.empty_on_punch = empty_on_punch