merge fluid_lib and fix translation
|
@ -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`!
|
||||
|
|
|
@ -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)
|
|
@ -0,0 +1,3 @@
|
|||
default
|
||||
fluid_lib
|
||||
node_io?
|
|
@ -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"}},
|
||||
})
|
||||
|
|
@ -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/
|
|
@ -0,0 +1,6 @@
|
|||
# textdomain:bucket
|
||||
|
||||
Empty Bucket=空桶
|
||||
Water Bucket=水桶
|
||||
River Water Bucket=河水桶
|
||||
Lava Bucket=岩浆桶
|
|
@ -0,0 +1,6 @@
|
|||
# textdomain:bucket
|
||||
|
||||
Empty Bucket=
|
||||
Water Bucket=
|
||||
River Water Bucket=
|
||||
Lava Bucket=
|
|
@ -0,0 +1,3 @@
|
|||
name = bucket
|
||||
depends = default,fluid_lib
|
||||
optional_depends = node_io
|
After Width: | Height: | Size: 205 B |
After Width: | Height: | Size: 221 B |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 221 B |
After Width: | Height: | Size: 221 B |
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
node_io?
|
|
@ -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")
|
|
@ -0,0 +1,2 @@
|
|||
name = fluid_lib
|
||||
optional_depends = node_io
|
|
@ -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
|
|
@ -0,0 +1,2 @@
|
|||
fluid_lib
|
||||
bucket
|
|
@ -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")
|
|
@ -0,0 +1,3 @@
|
|||
name = fluid_tanks
|
||||
description = API for fluid storage.
|
||||
depends = fluid_lib,bucket
|
|
@ -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"},
|
||||
}
|
||||
})
|
|
@ -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
|
|
@ -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"},
|
||||
}
|
||||
})
|
|
@ -0,0 +1,2 @@
|
|||
fluid_lib
|
||||
node_io?
|
|
@ -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")
|
|
@ -0,0 +1,3 @@
|
|||
name = fluid_transfer
|
||||
depends = fluid_lib
|
||||
optional_depends = node_io
|
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
})
|
|
@ -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,
|
||||
})
|
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 5.1 KiB |
After Width: | Height: | Size: 619 B |
|
@ -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)
|
||||
|
|
|
@ -155,4 +155,11 @@ minetest.register_craft({
|
|||
cooktime = 3,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "default:lava_source",
|
||||
recipe = "default:stone",
|
||||
cooktime = 60,
|
||||
})
|
||||
|
||||
-- Pipeworks
|
||||
|
|
|
@ -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=消耗材料
|
||||
|
|
|
@ -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=消耗材料
|
||||
|
|
|
@ -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)
|
||||
|
|