merge fluid_lib and fix translation

master
pevernow 2021-07-01 20:09:18 +08:00
parent 63fb4c3361
commit 759c74bcd2
40 changed files with 1924 additions and 14 deletions

View File

@ -3,7 +3,7 @@
An in-development mod for [Minetest](http://minetest.net) 0.5.0+ that adds molten metals, melting, casting and creating tools. This mod is inspired by the [Tinkers Construct](https://minecraft.curseforge.com/projects/tinkers-construct) mod for Minecraft, however it's much less-featured due to the current limitations of the Minetest API. None of the components used in this mod have been taken from TC - everything is my original creation.
**Depends on [fluid_lib](https://gitlab.icynet.eu/evert/fluid_lib)!**
**Included [fluid_lib](https://gitlab.icynet.eu/evert/fluid_lib).Don't install it again!**
## Installation
Just do `git clone https://gitlab.icynet.eu/evert/melterns.git` in your `minetest/mods` directory. You can also [download the repository](https://gitlab.icynet.eu/evert/melterns/archive/master.zip) but in that case you **must** change the folder name from `melterns-master` to `melterns`!

18
bucket/README.md Normal file
View File

@ -0,0 +1,18 @@
bucket
=========================
This is an addition to the Minetest Game `bucket` mod that implements the `fluid_lib` API seamlessly.
See license.txt for original license information.
Authors of source code
----------------------
Kahrl <kahrl@gmx.net> (LGPL 2.1)
celeron55, Perttu Ahola <celeron55@gmail.com> (LGPL 2.1)
Various Minetest developers and contributors (LGPL 2.1)
Modified by Evert "Diamond" Prants <evert@lunasqu.ee> (MIT)
Authors of media (textures)
---------------------------
ElementW (CC BY-SA 3.0)

3
bucket/depends.txt Normal file
View File

@ -0,0 +1,3 @@
default
fluid_lib
node_io?

339
bucket/init.lua Normal file
View File

@ -0,0 +1,339 @@
-- Minetest 0.4 mod: bucket
-- See README.md for licensing and other information.
local napi = minetest.get_modpath("node_io")
local S = minetest.get_translator("bucket")
minetest.register_alias("bucket", "bucket:bucket_empty")
minetest.register_alias("bucket_water", "bucket:bucket_water")
minetest.register_alias("bucket_lava", "bucket:bucket_lava")
minetest.register_craft({
output = 'bucket:bucket_empty 1',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'', 'default:steel_ingot', ''},
}
})
bucket = {}
bucket.liquids = {}
local function check_protection(pos, name, text)
if minetest.is_protected(pos, name) then
minetest.log("action", (name ~= "" and name or "A mod")
.. " tried to " .. text
.. " at protected position "
.. minetest.pos_to_string(pos)
.. " with a bucket")
minetest.record_protection_violation(pos, name)
return true
end
return false
end
-- Register a new liquid
-- source = name of the source node
-- flowing = name of the flowing node
-- itemname = name of the new bucket item (or nil if liquid is not takeable)
-- inventory_image = texture of the new bucket item (ignored if itemname == nil)
-- name = text description of the bucket item
-- groups = (optional) groups of the bucket item, for example {water_bucket = 1}
-- force_renew = (optional) bool. Force the liquid source to renew if it has a
-- source neighbour, even if defined as 'liquid_renewable = false'.
-- Needed to avoid creating holes in sloping rivers.
-- This function can be called from any mod (that depends on bucket).
function bucket.register_liquid(source, flowing, itemname, inventory_image, name,
groups, force_renew)
bucket.liquids[source] = {
source = source,
flowing = flowing,
itemname = itemname,
force_renew = force_renew,
}
bucket.liquids[flowing] = bucket.liquids[source]
if itemname ~= nil then
-- Create an image using a color
if inventory_image:match("^#") then
inventory_image = "bucket.png^(bucket_mask.png^[multiply:".. inventory_image ..")"
end
minetest.register_craftitem(itemname, {
description = name,
inventory_image = inventory_image,
stack_max = 1,
liquids_pointable = true,
groups = groups,
on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
local node = minetest.get_node_or_nil(pointed_thing.under)
local ndef = node and minetest.registered_nodes[node.name]
-- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and
not (user and user:is_player() and
user:get_player_control().sneak) then
return ndef.on_rightclick(
pointed_thing.under,
node, user,
itemstack)
end
local lpos
-- Check if pointing to a buildable node
if ndef and ndef.buildable_to then
-- buildable; replace the node
lpos = pointed_thing.under
else
-- not buildable to; place the liquid above
-- check if the node above can be replaced
lpos = pointed_thing.above
node = minetest.get_node_or_nil(lpos)
local above_ndef = node and minetest.registered_nodes[node.name]
if not above_ndef or not above_ndef.buildable_to then
-- do not remove the bucket with the liquid
return itemstack
end
end
if check_protection(lpos, user
and user:get_player_name()
or "", "place "..source) then
return
end
-- Fill any fluid buffers if present
local place = true
local ppos = pointed_thing.under
local node = minetest.get_node(ppos)
-- Node IO Support
local usedef = ndef
local defpref = "node_io_"
local lookat = "N"
if napi then
usedef = node_io
lookat = node_io.get_pointed_side(user, pointed_thing)
defpref = ""
end
if usedef[defpref..'can_put_liquid'] and usedef[defpref..'can_put_liquid'](ppos, node, lookat) then
if usedef[defpref..'room_for_liquid'](ppos, node, lookat, source, 1000) >= 1000 then
usedef[defpref..'put_liquid'](ppos, node, lookat, user, source, 1000)
if ndef.on_timer then
minetest.get_node_timer(ppos):start(ndef.node_timer_seconds or 1.0)
end
place = false
end
end
if place then
minetest.set_node(lpos, {name = source})
end
return ItemStack("bucket:bucket_empty")
end
})
end
end
function bucket.get_liquid_for_bucket(itemname)
local found = nil
for source, b in pairs(bucket.liquids) do
if b.itemname and b.itemname == itemname then
found = b.source
break
end
end
return found
end
minetest.register_craftitem("bucket:bucket_empty", {
description = S("Empty Bucket"),
inventory_image = "bucket.png",
stack_max = 99,
liquids_pointable = true,
groups = {bucket_empty = 1},
on_use = function(itemstack, user, pointed_thing)
if pointed_thing.type == "object" then
pointed_thing.ref:punch(user, 1.0, { full_punch_interval=1.0 }, nil)
return user:get_wielded_item()
elseif pointed_thing.type ~= "node" then
-- do nothing if it's neither object nor node
return
end
-- Check if pointing to a liquid source
local node = minetest.get_node(pointed_thing.under)
local liquiddef = bucket.liquids[node.name]
local item_count = user:get_wielded_item():get_count()
if liquiddef ~= nil
and liquiddef.itemname ~= nil
and node.name == liquiddef.source then
if check_protection(pointed_thing.under,
user:get_player_name(),
"take ".. node.name) then
return
end
-- default set to return filled bucket
local giving_back = liquiddef.itemname
-- check if holding more than 1 empty bucket
if item_count > 1 then
-- if space in inventory add filled bucked, otherwise drop as item
local inv = user:get_inventory()
if inv:room_for_item("main", {name=liquiddef.itemname}) then
inv:add_item("main", liquiddef.itemname)
else
local pos = user:getpos()
pos.y = math.floor(pos.y + 0.5)
minetest.add_item(pos, liquiddef.itemname)
end
-- set to return empty buckets minus 1
giving_back = "bucket:bucket_empty "..tostring(item_count-1)
end
-- force_renew requires a source neighbour
local source_neighbor = false
if liquiddef.force_renew then
source_neighbor =
minetest.find_node_near(pointed_thing.under, 1, liquiddef.source)
end
if not (source_neighbor and liquiddef.force_renew) then
minetest.add_node(pointed_thing.under, {name = "air"})
end
return ItemStack(giving_back)
else
-- non-liquid nodes will have their on_punch triggered
local node_def = minetest.registered_nodes[node.name]
if node_def then
node_def.on_punch(pointed_thing.under, node, user, pointed_thing)
end
return user:get_wielded_item()
end
end,
on_place = function(itemstack, user, pointed_thing)
-- Must be pointing to node
if pointed_thing.type ~= "node" then
return
end
local lpos = pointed_thing.under
local node = minetest.get_node_or_nil(lpos)
local ndef = node and minetest.registered_nodes[node.name]
-- Call on_rightclick if the pointed node defines it
if ndef and ndef.on_rightclick and
not (user and user:is_player() and
user:get_player_control().sneak) then
return ndef.on_rightclick(
lpos,
node, user,
itemstack)
end
if check_protection(lpos, user
and user:get_player_name()
or "", "take "..node.name) then
return
end
-- Node IO Support
local usedef = ndef
local defpref = "node_io_"
local lookat = "N"
if napi then
usedef = node_io
lookat = node_io.get_pointed_side(user, pointed_thing)
defpref = ""
end
-- Remove fluid from buffers if present
if usedef[defpref..'can_take_liquid'] and usedef[defpref..'can_take_liquid'](lpos, node, lookat) then
local bfc = usedef[defpref..'get_liquid_size'](lpos, node, lookat)
local buffers = {}
for i = 1, bfc do
buffers[i] = usedef[defpref..'get_liquid_name'](lpos, node, lookat, i)
end
if #buffers > 0 then
for id,fluid in pairs(buffers) do
if fluid ~= "" then
local took = usedef[defpref..'take_liquid'](lpos, node, lookat, user, fluid, 1000)
if took.millibuckets == 1000 and took.name == fluid then
if bucket.liquids[fluid] then
itemstack = ItemStack(bucket.liquids[fluid].itemname)
if ndef.on_timer then
minetest.get_node_timer(lpos):start(ndef.node_timer_seconds or 1.0)
end
break
end
end
end
end
end
end
return itemstack
end
})
bucket.register_liquid(
"default:water_source",
"default:water_flowing",
"bucket:bucket_water",
"bucket_water.png",
S("Water Bucket"),
{water_bucket = 1}
)
-- River water source is 'liquid_renewable = false' to avoid horizontal spread
-- of water sources in sloping rivers that can cause water to overflow
-- riverbanks and cause floods.
-- River water source is instead made renewable by the 'force renew' option
-- used here.
bucket.register_liquid(
"default:river_water_source",
"default:river_water_flowing",
"bucket:bucket_river_water",
"bucket_river_water.png",
S("River Water Bucket"),
{water_bucket = 1},
true
)
bucket.register_liquid(
"default:lava_source",
"default:lava_flowing",
"bucket:bucket_lava",
"bucket_lava.png",
S("Lava Bucket")
)
minetest.register_craft({
type = "fuel",
recipe = "bucket:bucket_lava",
burntime = 60,
replacements = {{"bucket:bucket_lava", "bucket:bucket_empty"}},
})

51
bucket/license.txt Normal file
View File

@ -0,0 +1,51 @@
License of source code
----------------------
GNU Lesser General Public License, version 2.1
Copyright (C) 2011-2016 Kahrl <kahrl@gmx.net>
Copyright (C) 2011-2016 celeron55, Perttu Ahola <celeron55@gmail.com>
Copyright (C) 2011-2016 Various Minetest developers and contributors
This program is free software; you can redistribute it and/or modify it under the terms
of the GNU Lesser General Public License as published by the Free Software Foundation;
either version 2.1 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details:
https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
Licenses of media (textures)
----------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Copyright (C) 2015-2016 ElementW
You are free to:
Share — copy and redistribute the material in any medium or format.
Adapt — remix, transform, and build upon the material for any purpose, even commercially.
The licensor cannot revoke these freedoms as long as you follow the license terms.
Under the following terms:
Attribution — You must give appropriate credit, provide a link to the license, and
indicate if changes were made. You may do so in any reasonable manner, but not in any way
that suggests the licensor endorses you or your use.
ShareAlike — If you remix, transform, or build upon the material, you must distribute
your contributions under the same license as the original.
No additional restrictions — You may not apply legal terms or technological measures that
legally restrict others from doing anything the license permits.
Notices:
You do not have to comply with the license for elements of the material in the public
domain or where your use is permitted by an applicable exception or limitation.
No warranties are given. The license may not give you all of the permissions necessary
for your intended use. For example, other rights such as publicity, privacy, or moral
rights may limit how you use the material.
For more details:
http://creativecommons.org/licenses/by-sa/3.0/

View File

@ -0,0 +1,6 @@
# textdomain:bucket
Empty Bucket=空桶
Water Bucket=水桶
River Water Bucket=河水桶
Lava Bucket=岩浆桶

View File

@ -0,0 +1,6 @@
# textdomain:bucket
Empty Bucket=
Water Bucket=
River Water Bucket=
Lava Bucket=

3
bucket/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = bucket
depends = default,fluid_lib
optional_depends = node_io

BIN
bucket/textures/bucket.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 205 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 B

157
fluid_lib/buffer.lua Normal file
View File

@ -0,0 +1,157 @@
-- Fluid buffer support functions.
local function node_data(pos)
local node = minetest.get_node(pos)
local nodedef = minetest.registered_nodes[node.name]
return node, nodedef
end
function fluid_lib.get_node_buffers(pos)
local node, nodedef = node_data(pos)
if not nodedef['fluid_buffers'] then
return nil
end
return nodedef['fluid_buffers']
end
function fluid_lib.get_buffer_data(pos, buffer)
local node, nodedef = node_data(pos)
local buffers = fluid_lib.get_node_buffers(pos)
if not buffers[buffer] then
return nil
end
local meta = minetest.get_meta(pos)
local fluid = meta:get_string(buffer .. "_fluid")
local amount = meta:get_int(buffer .. "_fluid_storage")
local capacity = buffers[buffer].capacity
local accepts = buffers[buffer].accepts
local drainable = buffers[buffer].drainable
if drainable == nil then
drainable = true
end
return {
fluid = fluid,
amount = amount,
accepts = accepts,
capacity = capacity,
drainable = drainable,
}
end
function fluid_lib.buffer_accepts_fluid(pos, buffer, fluid)
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
if not bfdata then return false end
if not bfdata.accepts then
return false
end
if bfdata.fluid ~= "" and bfdata.fluid ~= fluid then
return false
end
if bfdata.accepts == true or bfdata.accepts == fluid then
return true
end
if type(bfdata.accepts) ~= "table" then
bfdata.accepts = { bfdata.accepts }
end
for _,pf in pairs(bfdata.accepts) do
if pf == fluid then
return true
elseif pf:match("^group") and ele.helpers.get_item_group(fluid, pf:gsub("group:", "")) then
return true
end
end
return false
end
function fluid_lib.can_insert_into_buffer(pos, buffer, fluid, count)
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
if not bfdata then return 0 end
if not fluid_lib.buffer_accepts_fluid(pos, buffer, fluid) then return 0 end
local can_put = 0
if bfdata.amount + count > bfdata.capacity then
can_put = bfdata.capacity - bfdata.amount
else
can_put = count
end
return can_put
end
function fluid_lib.insert_into_buffer(pos, buffer, fluid, count)
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
if not bfdata then return count end
if bfdata.fluid ~= fluid and bfdata.fluid ~= "" then return count end
local can_put = fluid_lib.can_insert_into_buffer(pos, buffer, fluid, count)
if can_put == 0 then return count end
local meta = minetest.get_meta(pos)
meta:set_int(buffer .. "_fluid_storage", bfdata.amount + can_put)
meta:set_string(buffer .. "_fluid", fluid)
return 0
end
function fluid_lib.can_take_from_buffer(pos, buffer, count)
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
if not bfdata or not bfdata.drainable then return 0 end
local amount = bfdata.amount
local take_count = 0
if amount < count then
take_count = amount
else
take_count = count
end
return take_count
end
function fluid_lib.take_from_buffer(pos, buffer, count)
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
if not bfdata then return nil end
local fluid = bfdata.fluid
local amount = bfdata.amount
local take_count = fluid_lib.can_take_from_buffer(pos, buffer, count)
local new_storage = amount - take_count
if new_storage == 0 then
fluid = ""
end
local meta = minetest.get_meta(pos)
meta:set_int(buffer .. "_fluid_storage", new_storage)
meta:set_string(buffer .. "_fluid", fluid)
return bfdata.fluid, take_count
end
function fluid_lib.buffer_to_string(buffer)
if not buffer then return "" end
local amount = fluid_lib.comma_value(buffer.amount)
local capacity = fluid_lib.comma_value(buffer.capacity)
local description = "Empty"
if buffer.fluid ~= "" then
--description = fluid_lib.cleanse_node_description(buffer.fluid)
description = minetest.registered_nodes[buffer.fluid].description
end
return ("%s (%s / %s %s)"):format(description, amount, capacity, fluid_lib.unit)
end

1
fluid_lib/depends.txt Normal file
View File

@ -0,0 +1 @@
node_io?

53
fluid_lib/init.lua Normal file
View File

@ -0,0 +1,53 @@
-- Universal Fluid API implementation
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
fluid_lib = rawget(_G, "fluid_lib") or {}
fluid_lib.modpath = modpath
fluid_lib.unit = "mB"
fluid_lib.unit_description = "milli-bucket"
fluid_lib.fluid_name_cache = {}
fluid_lib.fluid_description_cache = {}
function fluid_lib.cleanse_node_name(node)
if fluid_lib.fluid_name_cache[node] then
return fluid_lib.fluid_name_cache[node]
end
local no_mod = node:gsub("^([%w_]+:)", "")
local no_source = no_mod:gsub("(_?source_?)", "")
fluid_lib.fluid_name_cache[node] = no_source
return no_source
end
function fluid_lib.cleanse_node_description(node)
if fluid_lib.fluid_description_cache[node] then
return fluid_lib.fluid_description_cache[node]
end
local ndef = minetest.registered_nodes[node]
if not ndef then return nil end
-- Remove translation string
local desc_no_translation = ndef.description
if string.match(desc_no_translation, "^\27") ~= nil then
desc_no_translation = desc_no_translation:match("[)]([%w%s]+)\27")
end
local no_source = desc_no_translation:gsub("(%s?Source%s?)", "")
fluid_lib.fluid_description_cache[node] = no_source
return no_source
end
function fluid_lib.comma_value(n) -- credit http://richard.warburton.it
local left,num,right = string.match(n,'^([^%d]*%d)(%d*)(.-)$')
return left..(num:reverse():gsub('(%d%d%d)','%1,'):reverse())..right
end
dofile(modpath.."/buffer.lua")
dofile(modpath.."/nodeio.lua")

View File

2
fluid_lib/mod.conf Normal file
View File

@ -0,0 +1,2 @@
name = fluid_lib
optional_depends = node_io

100
fluid_lib/nodeio.lua Normal file
View File

@ -0,0 +1,100 @@
-- Node IO System
local nodeiodef = {
node_io_can_put_liquid = function (pos, node, side)
return minetest.get_item_group(node.name, 'fluid_container') > 0
end,
node_io_can_take_liquid = function (pos, node, side)
return minetest.get_item_group(node.name, 'fluid_container') > 0
end,
-- if false, transfer node should only put and take in 1000 increments
-- inventory nodes that don't accept milibuckets should:
-- return zero in node_io_room_for_liquid() if non-1000 increment
-- return millibuckets parameter in node_io_put_liquid() if non-1000 increment
-- only return upto a 1000 increment in node_io_take_liquid()
-- transfer nodes that can put non-1000 increments should always check this or the inventory node might pretend to be full
node_io_accepts_millibuckets = function(pos, node, side) return true end,
node_io_put_liquid = function(pos, node, side, putter, liquid, millibuckets)
local buffers = fluid_lib.get_node_buffers(pos)
local leftovers = 0
for buffer,data in pairs(buffers) do
if millibuckets == 0 then break end
local didnt_fit = fluid_lib.insert_into_buffer(pos, buffer, liquid, millibuckets)
millibuckets = millibuckets - (millibuckets - didnt_fit)
leftovers = leftovers + didnt_fit
end
return leftovers
end,
-- returns millibuckets if inventory can hold entire amount, else returns amount the inventory can hold
-- use millibuckets=1 to check if not full, then call put_liquid() with actual amount to transfer
-- use millibuckets=1000 with room_for_liquid() and put_liquid() to only insert full buckets
node_io_room_for_liquid = function(pos, node, side, liquid, millibuckets)
local buffers = fluid_lib.get_node_buffers(pos)
local insertable = 0
for buffer,data in pairs(buffers) do
local insert = fluid_lib.can_insert_into_buffer(pos, buffer, liquid, millibuckets)
if insert > 0 then
insertable = insert
break
end
end
return insertable
end,
-- returns {name:string, millibuckets:int} with <= want_millibuckets or nil if inventory is empty or doesn't have want_liquid
-- want_liquid should be the name of a source liquid (in bucket.liquids of bucket mod)
node_io_take_liquid = function(pos, node, side, taker, want_liquid, want_millibuckets)
local buffers = fluid_lib.get_node_buffers(pos)
local took = 0
local name = ""
for buffer,data in pairs(buffers) do
local bfdata = fluid_lib.get_buffer_data(pos, buffer)
local storage = bfdata.amount
local fluid = bfdata.fluid
if (fluid == want_liquid or want_liquid == "") and storage >= want_millibuckets then
name, took = fluid_lib.take_from_buffer(pos, buffer, want_millibuckets)
if took > 0 then break end
end
end
return {name = name, millibuckets = took}
end,
node_io_get_liquid_size = function (pos, node, side)
-- this is always 1 unless inventory can hold multiple liquid types
local cnt = 0
local bfs = fluid_lib.get_node_buffers(pos)
for _ in pairs(bfs) do
cnt = cnt + 1
end
return cnt
end,
node_io_get_liquid_name = function(pos, node, side, index)
local cnt = {}
local bfs = fluid_lib.get_node_buffers(pos)
for buf in pairs(bfs) do
cnt[#cnt + 1] = buf
end
if not cnt[index] then return ItemStack(nil) end
local meta = minetest.get_meta(pos)
return meta:get_string(cnt[index] .. "_fluid")
end,
node_io_get_liquid_stack = function(pos, node, side, index)
local cnt = {}
local bfs = fluid_lib.get_node_buffers(pos)
for buf in pairs(bfs) do
cnt[#cnt + 1] = buf
end
if not cnt[index] then return ItemStack(nil) end
local meta = minetest.get_meta(pos)
return ItemStack(meta:get_string(cnt[index] .. "_fluid") .. " " ..
meta:get_int(cnt[index] .. "_fluid_storage"))
end,
}
function fluid_lib.register_node(nodename)
minetest.override_item(nodename, nodeiodef)
end

2
fluid_tanks/depends.txt Normal file
View File

@ -0,0 +1,2 @@
fluid_lib
bucket

216
fluid_tanks/init.lua Normal file
View File

@ -0,0 +1,216 @@
-- Fluid Tanks
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
fluid_tanks = {}
-- Preserve fluid count in the item stack dropped
local function preserve_metadata(pos, oldnode, oldmeta, drops)
local buffer = fluid_lib.get_buffer_data(pos, "buffer")
local meta = minetest.get_meta(pos)
if buffer.amount > 0 then
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
for i,stack in pairs(drops) do
local stack_meta = stack:get_meta()
stack_meta:set_int("fluid_storage", buffer.amount)
stack_meta:set_string("fluid", buffer.fluid)
stack_meta:set_string("description", ("%s\nContents: %s"):format(ndef.description,
fluid_lib.buffer_to_string(buffer)))
drops[i] = stack
end
end
return drops
end
-- Retrieve fluid count from itemstack when placed
local function after_place_node(pos, placer, itemstack, pointed_thing)
local item_meta = itemstack:get_meta()
local fluid_cnt = item_meta:get_int("fluid_storage")
local fluid = item_meta:get_string("fluid")
if fluid_cnt then
local meta = minetest.get_meta(pos)
meta:set_string("buffer_fluid", fluid)
meta:set_int("buffer_fluid_storage", fluid_cnt)
end
minetest.get_node_timer(pos):start(0.2)
return false
end
local function tank_on_timer(pos, elapsed)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local buffer = fluid_lib.get_buffer_data(pos, "buffer")
local percentile = buffer.amount / buffer.capacity
local node_name = node.name
local ndef = minetest.registered_nodes[node_name]
if buffer.amount == 0 and ndef['_base_node'] then
node_name = ndef['_base_node']
end
-- Select valid tank for current fluid
if buffer.amount > 0 and not ndef['_base_node'] and buffer.fluid ~= "" then
local fluid_name = fluid_lib.cleanse_node_name(buffer.fluid)
local new_node_name = node.name .. "_" .. fluid_name
local new_def = minetest.registered_nodes[new_node_name]
if new_def then
node_name = new_node_name
ndef = new_def
end
end
if buffer.amount == 0 and ndef['_base_node'] then
node_name = ndef['_base_node']
ndef = minetest.registered_nodes[node_name]
meta:set_string("buffer_fluid", "")
end
if node_name:match("^:") ~= nil then
node_name = node_name:sub(2)
ndef = minetest.registered_nodes[node_name]
end
-- Update infotext
meta:set_string("infotext", ("%s\nContents: %s"):format(ndef.description,
fluid_lib.buffer_to_string(buffer)))
local param2 = math.min(percentile * 63, 63)
-- Node changed, lets switch it
if node_name ~= node.name or param2 ~= node.param2 then
minetest.swap_node(pos, {name = node_name, param2 = param2, param1 = node.param1})
end
return false
end
local function create_tank_node(tankname, def, fluid_name)
local capacity = def.capacity or 16000
local tiles = def.tiles or {"default_glass.png", "default_glass_detail.png"}
local desc = def.description
local srcnode = def.srcnode or nil
local accepts = def.accepts or true
local groups = {cracky = 1, oddly_breakable_by_hand = 3, fluid_container = 1}
if srcnode then
groups["not_in_creative_inventory"] = 1
end
if minetest.registered_nodes[tankname] then
return
end
local special_tiles = {}
if fluid_name then
local fdef = minetest.registered_nodes[fluid_name]
if fdef and fdef.tiles then
special_tiles = fdef.tiles
end
end
minetest.register_node(tankname, {
description = desc,
drawtype = "glasslike_framed_optional",
paramtype = "light",
paramtype2 = "glasslikeliquidlevel",
is_ground_content = false,
sunlight_propagates = true,
special_tiles = special_tiles,
fluid_buffers = {
buffer = {
capacity = capacity,
accepts = accepts,
drainable = true,
}
},
on_construct = function ( pos )
local meta = minetest.get_meta(pos)
meta:set_string("infotext", "Empty "..desc)
end,
on_timer = tank_on_timer,
groups = groups,
tiles = tiles,
_base_node = srcnode,
node_timer_seconds = 0.2,
preserve_metadata = preserve_metadata,
after_place_node = after_place_node,
})
if tankname:match("^:") then
tankname = tankname:sub(2)
end
fluid_lib.register_node(tankname)
if srcnode then
if srcnode:match("^:") then
srcnode = srcnode:sub(2)
end
minetest.register_craft({
type = "shapeless",
output = srcnode,
recipe = { tankname },
})
end
end
function fluid_tanks.register_tank(tankname, def)
local accepts = def.accepts or true
if not accepts then return end
if not minetest.registered_nodes[tankname] then
create_tank_node(tankname, def)
end
if type(accepts) == "string" then
accepts = {accepts}
end
if type(accepts) == "table" then
local new_accepts = {}
for _,s in ipairs(accepts) do
if s:match("^group:") then
local grp = s:gsub("^(group:)", "")
for f in pairs(bucket.liquids) do
if minetest.get_item_group(f, grp) > 0 then
new_accepts[#new_accepts + 1] = f
end
end
else
if bucket.liquids[s] then
new_accepts[#new_accepts + 1] = s
end
end
end
accepts = new_accepts
end
if accepts == true then
accepts = {}
for _,i in pairs(bucket.liquids) do
accepts[#accepts + 1] = i.source
end
end
def.srcnode = tankname
for _, src in ipairs(accepts) do
local fluid = fluid_lib.cleanse_node_name(src)
create_tank_node(tankname .. "_" .. fluid, def, src)
end
end
dofile(modpath.."/register.lua")

3
fluid_tanks/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = fluid_tanks
description = API for fluid storage.
depends = fluid_lib,bucket

15
fluid_tanks/register.lua Normal file
View File

@ -0,0 +1,15 @@
fluid_tanks.register_tank("fluid_tanks:tank", {
description = "Fluid Tank",
capacity = 8000,
accepts = true,
})
minetest.register_craft({
output = "fluid_tanks:tank",
recipe = {
{"default:glass", "default:glass", "default:glass"},
{"default:glass", "default:steel_ingot", "default:glass"},
{"default:glass", "default:glass", "default:glass"},
}
})

111
fluid_transfer/api.lua Normal file
View File

@ -0,0 +1,111 @@
-- Nodes for transferring fluids
-- All units are in millibuckets (1 bucket)
-- This is the node that takes fluid from another node.
function fluid_lib.register_extractor_node(nodename, nodedef)
if not nodedef.groups then
nodedef.groups = {}
end
nodedef.groups["fluid_transport_source"] = 1
nodedef.paramtype2 = "facedir"
nodedef.legacy_facedir_simple = true
nodedef.on_timer = fluid_lib.transfer_timer_tick
nodedef.node_io_on_neighbor_update = function (pos, node, side)
local t = minetest.get_node_timer(pos)
if not t:is_started() then
t:start(1.0)
end
end
local orig_construct = nodedef.on_construct
nodedef.on_construct = function (pos)
local meta = minetest.get_meta(pos)
meta:set_int("fluid_store", 0)
meta:set_string("fluid", "")
fluid_lib.refresh_node(pos)
if orig_construct then
orig_construct(pos)
end
end
nodedef.on_punch = function (pos, node, puncher, pointed_thing)
minetest.get_node_timer(pos):start(1.0)
minetest.node_punch(pos, node, puncher, pointed_thing)
end
-- Default transfer capacity
if not nodedef.fluid_pump_capacity then
nodedef.fluid_pump_capacity = 1000
end
minetest.register_node(nodename, nodedef)
end
-- This is the node that allows for fluid transfer.
function fluid_lib.register_transfer_node(nodename, nodedef)
if not nodedef.groups then
nodedef.groups = {}
end
nodedef.groups["fluid_transport"] = 1
-- Duct node density
local cd = 1/7
if nodedef.duct_density then
cd = math.abs(nodedef.duct_density)
nodedef.duct_density = nil
end
-- Default values, including the nodebox
local defaults = {
drawtype = "nodebox",
node_box = {
type = "connected",
fixed = {
{-cd, -cd, -cd, cd, cd, cd}
},
connect_front = {
{-cd, -cd, -1/2, cd, cd, -cd}
},
connect_back = {
{-cd, -cd, cd, cd, cd, 1/2}
},
connect_top = {
{-cd, cd, -cd, cd, 1/2, cd}
},
connect_bottom = {
{-cd, -1/2, -cd, cd, -cd, cd}
},
connect_left = {
{-1/2, -cd, -cd, cd, cd, cd}
},
connect_right = {
{cd, -cd, -cd, 1/2, cd, cd}
},
},
paramtype = "light",
connect_sides = { "top", "bottom", "front", "left", "back", "right" },
is_ground_content = false,
connects_to = {
"group:fluid_transport",
"group:fluid_transport_source",
"group:fluid_container"
},
}
for k,v in pairs(defaults) do
if not nodedef[k] then
nodedef[k] = v
end
end
nodedef.on_construct = fluid_lib.refresh_node
nodedef.after_destruct = fluid_lib.refresh_node
minetest.register_node(nodename, nodedef)
end

View File

@ -0,0 +1,30 @@
-- Duct
minetest.register_craft({
output = "fluid_transfer:fluid_duct 8",
recipe = {
{"default:glass", "default:glass", "default:glass"},
{"", "", ""},
{"default:glass", "default:glass", "default:glass"},
}
})
-- Pump
minetest.register_craft({
output = "fluid_transfer:fluid_transfer_pump",
recipe = {
{"", "fluid_transfer:fluid_duct", ""},
{"default:glass", "default:mese_crystal", "default:glass"},
{"default:stone", "default:stone", "default:stone"},
}
})
-- Trash
minetest.register_craft({
output = "fluid_transfer:fluid_trash",
recipe = {
{"default:cobble", "default:cobble", "default:cobble"},
{"default:stone", "bucket:bucket_empty", "default:stone"},
{"default:stone", "fluid_transfer:fluid_duct", "default:stone"},
}
})

View File

@ -0,0 +1,2 @@
fluid_lib
node_io?

16
fluid_transfer/init.lua Normal file
View File

@ -0,0 +1,16 @@
-- Universal Fluid API implementation
-- Copyright (c) 2018 Evert "Diamond" Prants <evert@lunasqu.ee>
local modpath = minetest.get_modpath(minetest.get_current_modname())
-- Transfer network
dofile(modpath.."/network.lua")
-- API for ducts and pumps
dofile(modpath.."/api.lua")
-- Simple duct and pump
dofile(modpath.."/register.lua")
-- Crafting recipes
dofile(modpath.."/crafting.lua")

3
fluid_transfer/mod.conf Normal file
View File

@ -0,0 +1,3 @@
name = fluid_transfer
depends = fluid_lib
optional_depends = node_io

View File

@ -0,0 +1,185 @@
o Node
v 0.400000 0.400000 -0.370263
v 0.400000 0.400000 -0.497499
v -0.400000 0.400000 -0.497499
v -0.400000 0.400000 -0.370263
v 0.400000 -0.400000 -0.370263
v 0.400000 -0.400000 -0.497499
v -0.400000 -0.400000 -0.497499
v -0.400000 -0.400000 -0.370263
v 0.320000 0.320000 -0.243027
v 0.320000 0.320000 -0.370263
v -0.320000 0.320000 -0.370263
v -0.320000 0.320000 -0.243027
v 0.320000 -0.320000 -0.243027
v 0.320000 -0.320000 -0.370263
v -0.320000 -0.320000 -0.370263
v -0.320000 -0.320000 -0.243027
v 0.256000 0.256000 -0.115790
v 0.256000 0.256000 -0.243027
v -0.256000 0.256000 -0.243027
v -0.256000 0.256000 -0.115790
v 0.256000 -0.256000 -0.115790
v 0.256000 -0.256000 -0.243026
v -0.256000 -0.256000 -0.243026
v -0.256000 -0.256000 -0.115790
v 0.204800 0.204800 0.008210
v 0.204800 0.204800 -0.119027
v -0.204800 0.204800 -0.119027
v -0.204800 0.204800 0.008210
v 0.204800 -0.204800 0.008210
v 0.204800 -0.204800 -0.119026
v -0.204800 -0.204800 -0.119026
v -0.204800 -0.204800 0.008210
v 0.146894 0.146894 0.503596
v 0.146894 0.146894 -0.002413
v -0.146894 0.146894 -0.002413
v -0.146894 0.146894 0.503596
v 0.146894 -0.146894 0.503596
v 0.146894 -0.146894 -0.002413
v -0.146894 -0.146894 -0.002413
v -0.146894 -0.146894 0.503596
v 0.320665 0.320665 -0.497499
v -0.320665 0.320665 -0.497499
v 0.320664 -0.320665 -0.497499
v -0.320665 -0.320665 -0.497499
vt 0.712514 0.681510
vt 0.975774 0.681510
vt 0.975774 0.944770
vt 0.712514 0.944770
vt 0.712514 0.681510
vt 0.975774 0.681510
vt 0.975774 0.944770
vt 0.712514 0.944770
vt 0.975774 0.681510
vt 0.975774 0.944770
vt 0.712514 0.944770
vt 0.315390 0.302988
vt 0.315390 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.712514 0.681510
vt 0.975774 0.681510
vt 0.975774 0.944770
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.052130 0.302988
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.315390 0.039728
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.113358 0.155808
vt 0.139491 0.183677
vt 0.052150 0.175815
vt 0.070263 0.158170
vt 0.118317 0.113646
vt 0.075071 0.114371
vt 0.052211 0.096257
vt 0.139491 0.086694
vt 0.975306 0.069495
vt 0.371324 0.069495
vt 0.371324 0.276848
vt 0.975306 0.276848
vt 0.975306 0.069495
vt 0.975306 0.276848
vt 0.371324 0.276849
vt 0.371324 0.069495
vt 0.975125 0.070933
vt 0.975125 0.278286
vt 0.371143 0.278286
vt 0.371143 0.070933
vt 0.371143 0.070933
vt 0.371143 0.278286
vt 0.975125 0.278286
vt 0.975125 0.070933
vt 0.043937 0.339371
vt 0.658425 0.339371
vt 0.658425 0.953858
vt 0.043937 0.953858
vt 0.052130 0.302988
vt 0.315390 0.302988
vt 0.315390 0.302988
vt 0.052130 0.302988
vt 0.315390 0.039728
vt 0.052130 0.039728
vt 0.052130 0.039728
vt 0.315390 0.039728
vt 0.052130 0.302988
vt 0.315390 0.302988
vt 0.315390 0.302988
vt 0.052130 0.302988
vn 0.0000 1.0000 -0.0000
vn 0.0000 -1.0000 0.0000
vn 1.0000 -0.0000 -0.0000
vn 0.0000 0.0000 -1.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
s off
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/2 8/6/2 7/7/2 6/8/2
f 1/1/3 5/9/3 6/10/3 2/11/3
f 3/12/4 2/13/4 41/14/4 42/15/4
f 3/16/5 7/17/5 8/18/5 4/4/5
f 5/19/6 1/20/6 4/21/6 8/22/6
f 9/23/1 10/24/1 11/25/1 12/26/1
f 13/27/2 16/28/2 15/29/2 14/30/2
f 9/23/3 13/31/3 14/32/3 10/33/3
f 10/34/4 14/35/4 15/29/4 11/36/4
f 11/37/5 15/38/5 16/39/5 12/26/5
f 13/27/6 9/40/6 12/41/6 16/42/6
f 17/43/1 18/44/1 19/45/1 20/46/1
f 21/47/2 24/48/2 23/49/2 22/50/2
f 17/43/3 21/51/3 22/52/3 18/53/3
f 18/54/4 22/55/4 23/49/4 19/56/4
f 19/57/5 23/58/5 24/59/5 20/46/5
f 21/47/6 17/60/6 20/61/6 24/62/6
f 25/63/1 26/64/1 27/65/1 28/66/1
f 29/67/2 32/68/2 31/69/2 30/70/2
f 25/63/3 29/67/3 30/70/3 26/64/3
f 27/65/5 31/69/5 32/68/5 28/66/5
f 29/67/6 25/63/6 28/66/6 32/68/6
f 33/71/1 34/72/1 35/73/1 36/74/1
f 37/75/2 40/76/2 39/77/2 38/78/2
f 33/79/3 37/80/3 38/81/3 34/82/3
f 35/83/5 39/84/5 40/85/5 36/86/5
f 41/87/4 43/88/4 44/89/4 42/90/4
f 6/91/4 7/92/4 44/93/4 43/94/4
f 7/95/4 3/96/4 42/97/4 44/98/4
f 2/99/4 6/100/4 43/101/4 41/102/4

View File

@ -0,0 +1,260 @@
# Blender v2.79 (sub 6) OBJ File: ''
# www.blender.org
o Cube
v -0.316979 -0.500000 0.316979
v -0.376150 0.300000 0.376150
v -0.316979 -0.500000 -0.316979
v -0.376150 0.300000 -0.376150
v 0.316979 -0.500000 0.316979
v 0.376150 0.300000 0.376150
v 0.316979 -0.500000 -0.316979
v 0.376150 0.300000 -0.376150
v -0.449371 0.290267 0.449371
v -0.449371 0.290267 -0.449371
v 0.449371 0.290267 -0.449371
v 0.449371 0.290267 0.449371
v -0.449371 0.409733 0.449371
v -0.449371 0.409733 -0.449371
v 0.449371 0.409733 -0.449371
v 0.449371 0.409733 0.449371
v -0.211595 0.409445 0.026604
v -0.211595 0.475526 0.026604
v -0.211595 0.409445 -0.026604
v -0.211595 0.475526 -0.026604
v 0.211595 0.409445 0.026604
v 0.211595 0.475526 0.026604
v 0.211595 0.409445 -0.026604
v 0.211595 0.475526 -0.026604
v 0.288011 -0.211200 0.211200
v 0.288011 0.211200 0.211200
v 0.288011 -0.211200 -0.211200
v 0.288011 0.211200 -0.211200
v 0.500001 -0.211200 0.211200
v 0.500001 0.211200 0.211200
v 0.500001 -0.211200 -0.211200
v 0.500001 0.211200 -0.211200
v -0.288009 0.211200 0.211200
v -0.288009 -0.211200 0.211200
v -0.288009 0.211200 -0.211200
v -0.288009 -0.211200 -0.211200
v -0.499999 0.211200 0.211200
v -0.499999 -0.211200 0.211200
v -0.499999 0.211200 -0.211200
v -0.499999 -0.211200 -0.211200
v 0.211201 -0.211200 -0.288010
v 0.211201 0.211200 -0.288010
v -0.211199 -0.211200 -0.288010
v -0.211199 0.211200 -0.288010
v 0.211201 -0.211200 -0.500000
v 0.211201 0.211200 -0.500000
v -0.211199 -0.211200 -0.500000
v -0.211199 0.211200 -0.500000
v 0.211201 0.211200 0.288010
v 0.211201 -0.211200 0.288010
v -0.211199 0.211200 0.288010
v -0.211199 -0.211200 0.288010
v 0.211201 0.211200 0.500000
v 0.211201 -0.211200 0.500000
v -0.211199 0.211200 0.500000
v -0.211199 -0.211200 0.500000
vt 0.582082 0.566971
vt 0.603718 0.850456
vt 0.328633 0.850456
vt 0.350269 0.566971
vt 0.328633 0.283485
vt 0.603718 0.283485
vt 0.582082 0.566971
vt 0.625354 0.283485
vt 0.603718 0.000000
vt 0.878803 0.000000
vt 0.857167 0.283485
vt 0.350269 0.283485
vt 0.328633 0.000000
vt 0.603718 0.000000
vt 0.582082 0.283485
vt 0.603718 0.283485
vt 0.835530 0.283485
vt 0.835530 0.507945
vt 0.603718 0.507945
vt 0.301859 0.292285
vt 0.301859 0.025925
vt 0.328633 0.000000
vt 0.328633 0.318210
vt 0.026774 0.292285
vt 0.000000 0.318210
vt 0.000000 0.636419
vt 0.000000 0.318210
vt 0.328633 0.318210
vt 0.328633 0.636419
vt 0.922484 0.000000
vt 0.922484 0.318210
vt 0.878803 0.318210
vt 0.878803 0.000000
vt 0.845522 0.826155
vt 0.845522 0.507945
vt 0.889202 0.507945
vt 0.889202 0.826155
vt 0.801841 0.826155
vt 0.801841 0.507945
vt 0.845522 0.507945
vt 0.845522 0.826155
vt 0.758161 0.826155
vt 0.758161 0.507945
vt 0.801841 0.507945
vt 0.801841 0.826155
vt 0.026774 0.025925
vt 0.000000 0.000000
vt 0.308885 0.683210
vt 0.308885 0.659814
vt 0.328341 0.659814
vt 0.328341 0.683210
vt 0.705396 0.807056
vt 0.729557 0.807056
vt 0.729558 0.956891
vt 0.705396 0.956891
vt 0.328341 0.636419
vt 0.328341 0.659814
vt 0.308885 0.659814
vt 0.308885 0.636419
vt 0.681234 0.807056
vt 0.705396 0.807056
vt 0.705396 0.956891
vt 0.681234 0.956891
vt 0.986174 0.507945
vt 0.986174 0.657780
vt 0.966719 0.657780
vt 0.966719 0.507945
vt 0.328633 1.000000
vt 0.328633 0.850456
vt 0.406149 0.850456
vt 0.406149 1.000000
vt 0.913047 0.507934
vt 0.913047 0.358390
vt 0.990563 0.358390
vt 0.990563 0.507934
vt 0.154443 0.636419
vt 0.308885 0.636419
vt 0.308885 0.785975
vt 0.154443 0.785975
vt 0.922484 0.149544
vt 0.922484 0.000000
vt 1.000000 0.000000
vt 1.000000 0.149544
vt 0.232549 0.785975
vt 0.310065 0.785975
vt 0.310065 0.935530
vt 0.232549 0.935530
vt 0.966719 0.807056
vt 0.889202 0.807056
vt 0.889202 0.657501
vt 0.966719 0.657501
vt 0.000000 0.636419
vt 0.154443 0.636419
vt 0.154443 0.785975
vt 0.000000 0.785975
vt 0.966719 0.807056
vt 0.966719 0.956600
vt 0.889202 0.956600
vt 0.889202 0.807056
vt 0.913047 0.507945
vt 0.835531 0.507945
vt 0.835530 0.358390
vt 0.913047 0.358390
vt 0.155032 0.785975
vt 0.232549 0.785975
vt 0.232549 0.935530
vt 0.155032 0.935530
vt 0.483665 1.000000
vt 0.483665 0.850456
vt 0.561182 0.850456
vt 0.561182 1.000000
vt 0.758161 0.975699
vt 0.758161 0.826155
vt 0.835677 0.826155
vt 0.835677 0.975699
vt 0.603718 0.657501
vt 0.758161 0.657501
vt 0.758161 0.807056
vt 0.603718 0.807056
vt 0.483665 0.850456
vt 0.483665 1.000000
vt 0.406149 1.000000
vt 0.406149 0.850456
vt 0.077516 0.785975
vt 0.155032 0.785975
vt 0.155032 0.935530
vt 0.077516 0.935530
vt 0.889202 0.507945
vt 0.966719 0.507945
vt 0.966719 0.657501
vt 0.889202 0.657501
vt 0.758161 0.657501
vt 0.603718 0.657501
vt 0.603718 0.507945
vt 0.758161 0.507945
vt 0.922484 0.299088
vt 0.922484 0.149544
vt 1.000000 0.149544
vt 1.000000 0.299088
vt 0.077516 0.935530
vt 0.000000 0.935530
vt 0.000000 0.785975
vt 0.077516 0.785975
vt 0.681234 0.956612
vt 0.603718 0.956612
vt 0.603718 0.807056
vt 0.681234 0.807056
vn -0.9973 -0.0738 0.0000
vn 0.0000 -0.0738 -0.9973
vn 0.9973 -0.0738 0.0000
vn 0.0000 -0.0738 0.9973
vn 0.0000 -1.0000 0.0000
vn 0.0000 -0.9913 -0.1318
vn 0.1318 -0.9913 0.0000
vn 0.0000 1.0000 0.0000
vn -1.0000 0.0000 0.0000
vn 0.0000 0.0000 1.0000
vn 0.0000 0.0000 -1.0000
vn 1.0000 0.0000 0.0000
vn 0.0000 -0.9913 0.1318
vn -0.1318 -0.9913 0.0000
s off
f 1/1/1 2/2/1 4/3/1 3/4/1
f 3/4/2 4/5/2 8/6/2 7/7/2
f 7/8/3 8/9/3 6/10/3 5/11/3
f 5/12/4 6/13/4 2/14/4 1/15/4
f 3/16/5 7/17/5 5/18/5 1/19/5
f 2/20/6 6/21/6 12/22/6 9/23/6
f 4/24/7 2/20/7 9/23/7 10/25/7
f 13/26/8 16/27/8 15/28/8 14/29/8
f 10/30/9 9/31/9 13/32/9 14/33/9
f 9/34/10 12/35/10 16/36/10 13/37/10
f 11/38/11 10/39/11 14/40/11 15/41/11
f 12/42/12 11/43/12 15/44/12 16/45/12
f 8/46/13 4/24/13 10/25/13 11/47/13
f 6/21/14 8/46/14 11/47/14 12/22/14
f 17/48/9 18/49/9 20/50/9 19/51/9
f 19/52/11 20/53/11 24/54/11 23/55/11
f 23/56/12 24/57/12 22/58/12 21/59/12
f 21/60/10 22/61/10 18/62/10 17/63/10
f 24/64/8 20/65/8 18/66/8 22/67/8
f 35/68/11 36/69/11 40/70/11 39/71/11
f 27/72/11 28/73/11 32/74/11 31/75/11
f 31/76/12 32/77/12 30/78/12 29/79/12
f 29/80/10 30/81/10 26/82/10 25/83/10
f 27/84/5 31/85/5 29/86/5 25/87/5
f 32/88/8 28/89/8 26/90/8 30/91/8
f 39/92/9 40/93/9 38/94/9 37/95/9
f 37/96/10 38/97/10 34/98/10 33/99/10
f 35/100/8 39/101/8 37/102/8 33/103/8
f 40/104/5 36/105/5 34/106/5 38/107/5
f 51/108/9 52/109/9 56/110/9 55/111/9
f 43/112/9 44/113/9 48/114/9 47/115/9
f 47/116/11 48/117/11 46/118/11 45/119/11
f 45/120/12 46/121/12 42/122/12 41/123/12
f 43/124/5 47/125/5 45/126/5 41/127/5
f 48/128/8 44/129/8 42/130/8 46/131/8
f 55/132/10 56/133/10 54/134/10 53/135/10
f 53/136/12 54/137/12 50/138/12 49/139/12
f 51/140/8 55/141/8 53/142/8 49/143/8
f 56/144/5 52/145/5 50/146/5 54/147/5

253
fluid_transfer/network.lua Normal file
View File

@ -0,0 +1,253 @@
local node_io_present = minetest.get_modpath("node_io") ~= nil
-- Network graphs are built eminating from provider nodes.
-- TODO: Caching
---------------------
-- Graph Functions --
---------------------
local function flatten(map)
local list = {}
for key, value in pairs(map) do
list[#list + 1] = value
end
return list
end
local function get_node_property(meta, pos, prop)
local value = meta:get_int(prop)
if value == 0 or value == nil then
local nname = minetest.get_node(pos).name
local ndef = minetest.registered_nodes[nname]
value = ndef[prop]
end
if not value then return 0 end
return value
end
local function face_front(pos, fd)
local back = minetest.facedir_to_dir(fd)
local front = table.copy(back)
front.x = front.x * -1 + pos.x
front.y = front.y * -1 + pos.y
front.z = front.z * -1 + pos.z
return front
end
local function clear_networks_from_node(pos)
local meta = minetest.get_meta(pos)
meta:set_string("network_id", "")
end
local function add_node(nodes, pos, pnodeid)
local node_id = minetest.hash_node_position(pos)
if nodes[node_id] then
return false
end
nodes[node_id] = pos
return true
end
local function add_duct_node(nodes, pos, pnodeid, queue)
if add_node(nodes, pos, pnodeid) then
queue[#queue + 1] = pos
end
end
local function check_node(targets, all_nodes, pos, p_pos, pnodeid, queue)
local node = minetest.get_node(pos)
local meta = minetest.get_meta(pos)
local ndef = minetest.registered_nodes[node.name]
if not ndef then return end
if minetest.get_item_group(node.name, "fluid_transport") > 0 then
add_duct_node(all_nodes, pos, pnodeid, queue)
return
end
if not ndef['node_io_can_put_liquid'] or not ndef['node_io_can_put_liquid'](pos, node, "") then
return
end
add_node(targets, pos, pnodeid)
end
local function traverse_network(targets, all_nodes, pos, p_pos, pnodeid, queue)
local positions = {
{x=pos.x+1, y=pos.y, z=pos.z},
{x=pos.x-1, y=pos.y, z=pos.z},
{x=pos.x, y=pos.y+1, z=pos.z},
{x=pos.x, y=pos.y-1, z=pos.z},
{x=pos.x, y=pos.y, z=pos.z+1},
{x=pos.x, y=pos.y, z=pos.z-1}}
for _, cur_pos in pairs(positions) do
check_node(targets, all_nodes, cur_pos, p_pos, pnodeid, queue)
end
end
local function fluid_targets(p_pos, pos)
local provider = minetest.get_node(p_pos)
local pnodeid = minetest.pos_to_string(p_pos)
local targets = {}
local queue = {}
local all_nodes = {}
local node = minetest.get_node(pos)
local ndef = minetest.registered_nodes[node.name]
if ndef and minetest.get_item_group(node.name, "fluid_transport") > 0 then
add_duct_node(all_nodes, pos, pnodeid, queue)
elseif ndef and ndef['node_io_can_put_liquid'] and ndef['node_io_can_put_liquid'](pos, node, "") then
queue = {p_pos}
end
while next(queue) do
local to_visit = {}
for _, posi in ipairs(queue) do
traverse_network(targets, all_nodes, posi, p_pos, pnodeid, to_visit)
end
queue = to_visit
end
targets = flatten(targets)
all_nodes = flatten(all_nodes)
return targets
end
function fluid_lib.transfer_timer_tick(pos, elapsed)
local refresh = true
local node = minetest.get_node_or_nil(pos)
if not node then
return false
end
local meta = minetest.get_meta(pos)
local targets = {}
-- Only allow the node directly behind to be a start of a network
local tpos = vector.add(minetest.facedir_to_dir(node.param2), pos)
local tnode = minetest.get_node(tpos)
local ndef = minetest.registered_nodes[tnode.name]
if minetest.get_item_group(tnode.name, "fluid_transport") == 0 and
(not ndef or not ndef['node_io_can_put_liquid'] or not ndef['node_io_can_put_liquid'](tpos, tnode, "")) then
minetest.forceload_free_block(pos)
return
end
-- Retrieve network
targets = fluid_targets(pos, tpos)
-- No targets, don't proceed
if #targets == 0 then
return true
end
-- Begin transfer
local srcpos = face_front(pos, node.param2)
local srcnode = minetest.get_node(srcpos)
-- Make sure source node is not air
if not srcnode or srcnode.name == "air" then
return true
end
local srcdef = minetest.registered_nodes[srcnode.name]
-- Make sure source node is a registered fluid container
if not srcdef or not srcdef['node_io_can_take_liquid'] then
return false
end
local c = srcdef.node_io_can_take_liquid(srcpos, srcnode, "")
if not c then return false end
local srcmeta = minetest.get_meta(srcpos)
local fl_size = srcdef.node_io_get_liquid_size(srcpos, srcnode, "")
local buffers = {}
for i = 1, fl_size do
buffers[i] = srcdef.node_io_get_liquid_name(srcpos, srcnode, "", i)
end
if not #buffers then return true end
-- Limit the amount of fluid pumped per cycle
local pcapability = get_node_property(meta, pos, "fluid_pump_capacity")
local pumped = 0
-- Transfer some fluid here
for _,pos in pairs(targets) do
if not vector.equals(pos, srcpos) then
if pumped >= pcapability then break end
local destnode = minetest.get_node(pos)
local destdef = minetest.registered_nodes[destnode.name]
local pp = nil
if destdef and destdef['node_io_can_put_liquid'] then
if destdef.node_io_can_put_liquid(pos, destnode, "") then
pp = {}
local fl_size = destdef.node_io_get_liquid_size(pos, destnode, "")
for i = 1, fl_size do
pp[i] = destdef.node_io_get_liquid_name(pos, destnode, "", i)
end
if #pp == 0 then pp = nil end
end
end
local changed = false
if pp ~= nil then
for bindex,bfluid in pairs(pp) do
for aindex,afluid in pairs(buffers) do
if pumped >= pcapability then break end
if (afluid == bfluid or bfluid == "") then
local idef = destdef.node_io_room_for_liquid(pos, destnode, "", afluid, pcapability)
if idef > 0 then
local fluidcount = srcdef.node_io_get_liquid_stack(srcpos, srcnode, "", aindex):get_count()
local defc = math.min(fluidcount, idef)
local defi = srcdef.node_io_take_liquid(srcpos, srcnode, "", nil, afluid, defc)
if defi and defi.millibuckets > 0 then
local lo = destdef.node_io_put_liquid(pos, destnode, "", nil, afluid, defi.millibuckets)
pumped = pumped + (defi.millibuckets - lo)
changed = true
end
end
end
end
end
end
if changed then
minetest.get_node_timer(srcpos):start(1.0)
minetest.get_node_timer(pos):start(1.0)
end
end
end
return refresh
end
function fluid_lib.refresh_node(pos)
local t = minetest.get_node_timer(pos)
if t and not t:is_started() then
t:start(1.0)
end
if node_io_present then
node_io.update_neighbors(pos)
end
end
minetest.register_lbm({
label = "Fluid Transfer Tick",
name = "fluid_transfer:fluid_transfer_tick",
nodenames = {"group:fluid_transport_source", "group:fluid_pump"},
run_at_every_load = true,
action = fluid_lib.refresh_node,
})

View File

@ -0,0 +1,49 @@
fluid_lib.register_extractor_node("fluid_transfer:fluid_transfer_pump", {
description = "Fluid Transfer Pump\nPunch to start pumping",
tiles = {"fluid_transfer_pump.png"},
drawtype = "mesh",
mesh = "fluid_transfer_pump.obj",
groups = {oddly_breakable_by_hand = 1, cracky = 1},
paramtype = "light",
selection_box = {
type = "fixed",
fixed = {
{-0.4375, -0.4375, -0.5000, 0.4375, 0.4375, 0.000},
{-0.1875, -0.1875, 0.000, 0.1875, 0.1875, 0.5000}
}
}
})
fluid_lib.register_transfer_node("fluid_transfer:fluid_duct", {
description = "Fluid Duct",
tiles = {"fluid_transfer_duct.png"},
groups = {oddly_breakable_by_hand = 1, cracky = 1}
})
minetest.register_node("fluid_transfer:fluid_trash", {
description = "Fluid Trash Can",
drawtype = "mesh",
mesh = "fluid_transfer_trash.obj",
tiles = {"fluid_transfer_trash.png"},
groups = {oddly_breakable_by_hand = 1, cracky = 1, fluid_container = 1},
node_io_can_put_liquid = function (pos, node, side)
return true
end,
node_io_accepts_millibuckets = function(pos, node, side) return true end,
node_io_put_liquid = function(pos, node, side, putter, liquid, millibuckets)
return 0
end,
node_io_room_for_liquid = function(pos, node, side, liquid, millibuckets)
return millibuckets
end,
node_io_get_liquid_size = function (pos, node, side)
return 1
end,
node_io_get_liquid_name = function(pos, node, side, index)
return ""
end,
node_io_get_liquid_stack = function(pos, node, side, index)
return ItemStack(nil)
end,
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 B

View File

@ -19,7 +19,7 @@ metal_caster.casts = {
local metal_cache = {}
function metal_caster.get_metal_caster_formspec(water, metal)
local metal_formspec = "tooltip[6.68,0;0.8,2.45;No Molten Metal]"
local metal_formspec = "tooltip[6.68,0;0.8,2.45;"..S("No Molten Metal").."]"
if metal ~= nil then
metal_formspec = "tooltip[6.68,0;0.8,2.45;"..fluid_lib.buffer_to_string(metal).."]"
@ -32,6 +32,7 @@ function metal_caster.get_metal_caster_formspec(water, metal)
"list[context;cast;2.7,0.2;1,1;]"..
"image[2.7,1.35;1,1;gui_furnace_arrow_bg.png^[transformFY]"..
"list[context;output;2.7,2.5;1,1;]"..
"checkbox[2.7,3.5;auto;Auto;true]"..
"image[0.08,2.5;1,1;metal_melter_gui_bucket.png]"..
"list[context;coolant;0.08,2.5;1,1;]"..
metal_melter.fluid_bar(0.08, 0, water)..
@ -395,13 +396,13 @@ local function caster_node_timer(pos, elapsed)
meta:set_string("metal_fluid", metal.fluid)
meta:set_string("water_fluid", "default:water_source")
local infotext = "Metal Caster\n"
local infotext = S("Metal Caster").."\n"
infotext = infotext .. fluid_lib.buffer_to_string(coolant) .. "\n"
if metal and metal.fluid ~= "" then
infotext = infotext .. fluid_lib.buffer_to_string(metal)
else
infotext = infotext .. "No Molten Metal"
infotext = infotext .. S("No Molten Metal")
end
meta:set_string("infotext", infotext)
@ -421,12 +422,13 @@ local function on_construct(pos)
inv:set_size('coolant', 1)
inv:set_size('bucket_in', 1)
inv:set_size('bucket_out', 1)
meta:set_int("auto",1)
-- Water source block
meta:set_string('water_fluid', 'default:water_source')
-- Default infotext
meta:set_string("infotext", "Metal Caster Inactive")
meta:set_string("infotext", S("Metal Caster Inactive"))
end
-- Register a new cast
@ -435,7 +437,7 @@ function metal_caster.register_cast(name, data)
local castname = mod..":"..name.."_cast"
minetest.register_craftitem(castname, {
description = data.description.." Cast\n\nMaterial Cost: "..data.cost,
description = data.description.." "..S("Cast").."\n\n"..S("Material Cost")..": "..data.cost,
inventory_image = "caster_"..name.."_cast.png",
stack_max = 1,
groups = {tinker_cast=1}
@ -455,6 +457,13 @@ local function on_receive_fields(pos, formname, fields, sender)
end
local meta = minetest.get_meta(pos)
if fields["auto"]~=nil then
if fields["auto"]~=true then
meta:set_int("auto",1)
else
meta:set_int("auto",0)
end
end
if fields["dump"] then
meta:set_int('dump', 1)
minetest.get_node_timer(pos):start(1.0)

View File

@ -155,4 +155,11 @@ minetest.register_craft({
cooktime = 3,
})
minetest.register_craft({
type = "cooking",
output = "default:lava_source",
recipe = "default:stone",
cooktime = 60,
})
-- Pipeworks

View File

@ -1,13 +1,18 @@
# textdomain:metal_melter
Ingot=
Lump=肿块
Ingot=锭
Lump=矿石
Gem=宝石
Metal Caster=金属铸造机
Metal Caster=铸造台
Heatbrick=热砖
Heatbricks=加热砖
Heat Gravel=热砾石
Heat Exchanger Plate=热交换器板
Casting Table=铸造工作台
Heated Tank=加热水箱
Metal Melter=金属熔化器
Metal Melter=高炉
No Molten Metal=缺少液态金属
Metal Caster Inactive=铸造台(未运行)
Metal Melter Inactive=高炉(未运行)
Cast=模板
Material Cost=消耗材料

View File

@ -10,4 +10,9 @@ Heat Gravel=
Heat Exchanger Plate=
Casting Table=
Heated Tank=
Metal Melter=
Metal Melter=
No Molten Metal=
Metal Caster Inactive=
Metal Melter Inactive=
Cast=模板
Material Cost=消耗材料

View File

@ -302,13 +302,13 @@ local function melter_node_timer(pos, elapsed)
meta:set_string("metal_fluid", metal.fluid)
meta:set_string("lava_fluid", "default:lava_source")
local infotext = "Metal Melter\n"
local infotext = S("Metal Melter").."\n"
infotext = infotext .. fluid_lib.buffer_to_string(lava) .. "\n"
if metal and metal.fluid ~= "" then
infotext = fluid_lib.buffer_to_string(metal)
else
infotext = infotext .. "No Molten Metal"
infotext = infotext .. S("No Molten Metal")
end
if lava.amount > 144 then
@ -339,7 +339,7 @@ local function on_construct(pos)
meta:set_string('lava_fluid', 'default:lava_source')
-- Default infotext
meta:set_string("infotext", "Metal Melter Inactive")
meta:set_string("infotext", S("Metal Melter Inactive"))
end
local function can_dig(pos, player)