Add working reservoirs implementation
This commit is contained in:
parent
767d5bb97f
commit
2bf30a11b6
@ -17,3 +17,4 @@ dofile(path.."/crafter_auto.lua")
|
||||
dofile(path.."/crafting_supplier.lua")
|
||||
dofile(path.."/cobble_supplier.lua")
|
||||
dofile(path.."/synchronizer.lua")
|
||||
dofile(path.."/reservoir.lua")
|
||||
|
176
api/reservoir.lua
Normal file
176
api/reservoir.lua
Normal file
@ -0,0 +1,176 @@
|
||||
local S = logistica.TRANSLATOR
|
||||
local function L(str) return "logistica:"..str end
|
||||
|
||||
local META_LIQUID_LEVEL = "liquidLevel"
|
||||
local META_LIQUID_NAME = "liquidName"
|
||||
|
||||
local EMPTY_SUFFIX = "_empty"
|
||||
|
||||
local LIQUID_NONE = ""
|
||||
|
||||
local VAR_SMALL = "silverin"
|
||||
local VAR_LARGE = "obsidian"
|
||||
|
||||
local SMALL_MAX = 32
|
||||
local LARGE_MAX = 128
|
||||
|
||||
local variants = {VAR_SMALL}
|
||||
if logistica.settings.large_liquid_tank_enabled then table.insert(variants, VAR_LARGE) end
|
||||
|
||||
local variantSpecificDefs = {
|
||||
[VAR_SMALL] = {
|
||||
description = logistica.reservoir_get_description(0, SMALL_MAX, ""),
|
||||
tiles = {"logistica_reservoir_silverin.png"},
|
||||
sounds = logistica.node_sound_metallic(),
|
||||
logistica = {
|
||||
maxBuckets = SMALL_MAX,
|
||||
},
|
||||
},
|
||||
[VAR_LARGE] = {
|
||||
description = logistica.reservoir_get_description(0, LARGE_MAX, ""),
|
||||
tiles = {"logistica_reservoir_obsidian.png"},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
logistica = {
|
||||
maxBuckets = LARGE_MAX,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- general helper functions
|
||||
----------------------------------------------------------------
|
||||
|
||||
-- local function drop_item(pos, stack)
|
||||
-- minetest.add_item(pos, stack)
|
||||
-- end
|
||||
|
||||
local function give_item_to_player(pos, player, stack)
|
||||
local inv = player:get_inventory()
|
||||
local leftover = inv:add_item("main", stack)
|
||||
if leftover and not leftover:is_empty() then
|
||||
-- print("leftover not empty, size = " .. leftover:get_count())
|
||||
minetest.item_drop(leftover, player, player:get_pos())
|
||||
end
|
||||
end
|
||||
|
||||
----------------------------------------------------------------
|
||||
-- callbacks
|
||||
----------------------------------------------------------------
|
||||
|
||||
|
||||
local function after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
local nodeMeta = minetest.get_meta(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local stackMeta = itemstack:get_meta()
|
||||
local nodeDef = minetest.registered_nodes[node.name]
|
||||
if not nodeDef or not nodeDef.logistica then return end
|
||||
|
||||
local liquidLevel = stackMeta:get_int(META_LIQUID_LEVEL)
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
|
||||
nodeMeta:set_int(META_LIQUID_LEVEL, liquidLevel)
|
||||
node.param2 = logistica.reservoir_make_param2(liquidLevel, maxBuckets)
|
||||
minetest.swap_node(pos, node)
|
||||
nodeMeta:set_string("infotext", logistica.reservoir_get_description(liquidLevel, maxBuckets, liquidDesc))
|
||||
end
|
||||
|
||||
|
||||
local function preserve_metadata(pos, oldnode, oldmeta, drops)
|
||||
if not drops or not drops[1] then return end
|
||||
local nodeDef = minetest.registered_nodes[oldnode.name]
|
||||
if not nodeDef or not nodeDef.logistica then return end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local drop = drops[1]
|
||||
local dropMeta = drop:get_meta()
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
local liquidLevel = meta:get_int(META_LIQUID_LEVEL)
|
||||
|
||||
dropMeta:set_int(META_LIQUID_LEVEL, liquidLevel)
|
||||
dropMeta:set_string("description", logistica.reservoir_get_description(liquidLevel, maxBuckets, liquidDesc))
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, player, itemstack, pointed_thing, max)
|
||||
if not player or not player:is_player() or minetest.is_protected(pos, player:get_player_name()) then return end
|
||||
|
||||
local usedItem = logistica.reservoir_use_item_on(pos, itemstack, node)
|
||||
|
||||
if not usedItem then return end
|
||||
|
||||
if itemstack:get_count() == 1 then
|
||||
return usedItem
|
||||
else
|
||||
give_item_to_player(pos, player, usedItem)
|
||||
itemstack:take_item(1)
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- registration helpers
|
||||
--------------------------------
|
||||
|
||||
local commonDef = {
|
||||
drawtype = "glasslike_framed_optional",
|
||||
paramtype = "light",
|
||||
paramtype2 = "glasslikeliquidlevel",
|
||||
is_ground_content = false,
|
||||
sunlight_propagates = false,
|
||||
groups = {cracky = 3, level = 1},
|
||||
preserve_metadata = preserve_metadata,
|
||||
after_place_node = after_place_node,
|
||||
on_rightclick = on_rightclick,
|
||||
stack_max = 1,
|
||||
backface_culling = false,
|
||||
}
|
||||
|
||||
local function get_variant_def(variantName)
|
||||
if not variantSpecificDefs[variantName] then return nil end
|
||||
local vDef = variantSpecificDefs[variantName]
|
||||
local def = table.copy(commonDef)
|
||||
for k,v in pairs(vDef) do def[k] = v end
|
||||
return def
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- minetest registration
|
||||
--------------------------------
|
||||
|
||||
-- register empty tanks, always
|
||||
for _, variantName in ipairs(variants) do
|
||||
local def = table.copy(get_variant_def(variantName))
|
||||
local nodeName = L("reservoir_"..variantName..EMPTY_SUFFIX)
|
||||
def.drops = nodeName
|
||||
def.logistica.liquidName = LIQUID_NONE
|
||||
def.logistica.liquidDesc = LIQUID_NONE
|
||||
minetest.register_node(nodeName, def)
|
||||
end
|
||||
|
||||
--[[
|
||||
`liquidName`: the name used to register the reservoir, should have no spaces and all lowercase<br>
|
||||
`liquidDesc`: a human readable liquid description, e.g. "Water"<br>
|
||||
`bucketItemName` : the name of the bucket that holds the liquid<br>
|
||||
`liquidTexture` : a single texture to use for the liquid<br>
|
||||
`optLight` : optional, if nil assumed 0. How much a non-empty reservoir will glow
|
||||
`emptyBucketName` : optional, if nil, bucket:bucket_empty will be used - the "empty" container to use<br>
|
||||
]]
|
||||
function logistica.register_reservoir(liquidName, liquidDesc, bucketItemName, liquidTexture, optLight, optEmptyBucketName)
|
||||
local lname = string.lower(liquidName:gsub(" ", "_"))
|
||||
|
||||
for _, variantName in ipairs(variants) do
|
||||
local nodeName = L("reservoir_"..variantName.."_"..lname)
|
||||
local def = table.copy(get_variant_def(variantName))
|
||||
def.drops = nodeName
|
||||
def.special_tiles = {liquidTexture}
|
||||
def.logistica.liquidName = lname
|
||||
def.logistica.liquidDesc = liquidDesc
|
||||
def.groups.not_in_creative_inventory = 1
|
||||
def.light_source = optLight
|
||||
|
||||
minetest.register_node(nodeName, def)
|
||||
|
||||
logistica.reservoir_register_names(lname, bucketItemName, optEmptyBucketName)
|
||||
end
|
||||
end
|
@ -18,3 +18,4 @@ dofile(path.."/vaccuum_chest.lua")
|
||||
dofile(path.."/autocrafting_logic.lua")
|
||||
dofile(path.."/crafting_supplier.lua")
|
||||
dofile(path.."/synchronizer.lua")
|
||||
dofile(path.."/reservoir.lua")
|
||||
|
140
logic/reservoir.lua
Normal file
140
logic/reservoir.lua
Normal file
@ -0,0 +1,140 @@
|
||||
local S = logistica.TRANSLATOR
|
||||
|
||||
local BUCKET_TO_NAME = {}
|
||||
local NAME_TO_BUCKET = {}
|
||||
local NAME_TO_EMPTY_BUCKET = {}
|
||||
local EMPTY_BUCKET = "bucket:bucket_empty"
|
||||
local EMPTY_SUFFIX = "_empty"
|
||||
|
||||
local META_LIQUID_LEVEL = "liquidLevel"
|
||||
local LIQUID_NONE = ""
|
||||
local BUCKET_ANY = "BUCKET_ANY"
|
||||
|
||||
local strDescription = S("Reservoir")
|
||||
local strEmpty = S("Empty")
|
||||
local getStrContains = function(number, max, ofWhat)
|
||||
if number == 0 then
|
||||
return S("@1 / @2 buckets", number, max)
|
||||
else
|
||||
return S("@1 / @2 buckets of @3", number, max, ofWhat)
|
||||
end
|
||||
end
|
||||
|
||||
local function ends_with(str, ending)
|
||||
return ending == "" or string.sub(str, -#ending) == ending
|
||||
end
|
||||
|
||||
local function get_empty_bucket_needed_for(liquidName)
|
||||
local savedBucket = NAME_TO_EMPTY_BUCKET[liquidName]
|
||||
if savedBucket then return savedBucket
|
||||
else return EMPTY_BUCKET end
|
||||
end
|
||||
|
||||
local function get_full_bucket_needed_for(liquidName)
|
||||
if liquidName == LIQUID_NONE then return BUCKET_ANY end
|
||||
return NAME_TO_BUCKET[liquidName]
|
||||
end
|
||||
|
||||
local function get_empty_reservoir_name(nodeName, liquidName)
|
||||
if not ends_with(nodeName, liquidName) then return nodeName end
|
||||
if ends_with(nodeName, EMPTY_SUFFIX) then return nodeName end
|
||||
local nodeBase = string.sub(nodeName, 1, (#nodeName) - (#liquidName) - 1)
|
||||
return nodeBase..EMPTY_SUFFIX
|
||||
end
|
||||
|
||||
local function get_liquid_reservoir_name_for(nodeName, liquidName)
|
||||
if not ends_with(nodeName, EMPTY_SUFFIX) then return nodeName end
|
||||
local nodeBase = string.sub(nodeName, 1, (#nodeName) - (#EMPTY_SUFFIX))
|
||||
local newName = nodeBase.."_"..liquidName
|
||||
if not minetest.registered_nodes[newName] then return nodeName
|
||||
else return newName end
|
||||
end
|
||||
|
||||
--------------------------------
|
||||
-- public functions
|
||||
--------------------------------
|
||||
|
||||
function logistica.reservoir_make_param2(val, max)
|
||||
local ret = math.floor(63*(val/max))
|
||||
if val > 0 and ret == 0 then
|
||||
ret = 1 -- this ensures we always have at least 1 visible liquid level
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function logistica.reservoir_get_description(currBuckets, maxBuckets, liquidName)
|
||||
return strDescription.."\n"..getStrContains(currBuckets, maxBuckets, liquidName)
|
||||
end
|
||||
|
||||
function logistica.reservoir_register_names(liquidName, bucketName, emptyBucketName)
|
||||
BUCKET_TO_NAME[bucketName] = liquidName
|
||||
NAME_TO_BUCKET[liquidName] = bucketName
|
||||
if emptyBucketName then
|
||||
NAME_TO_EMPTY_BUCKET[liquidName] = emptyBucketName
|
||||
end
|
||||
end
|
||||
|
||||
-- returns nil if item had no effect<br>
|
||||
-- returns an ItemStack to replace the item, if it had effect (e.g. took or stored liquid)
|
||||
function logistica.reservoir_use_item_on(pos, itemstack, optNode)
|
||||
local node = optNode or minetest.get_node(pos)
|
||||
local nodeDef = minetest.registered_nodes[node.name]
|
||||
if not nodeDef or not nodeDef.logistica or not nodeDef.logistica.liquidName or not nodeDef.logistica.maxBuckets then return end
|
||||
|
||||
local itemStackName = itemstack:get_name()
|
||||
local meta = minetest.get_meta(pos)
|
||||
local nodeLiquidLevel = meta:get_int(META_LIQUID_LEVEL)
|
||||
local liquidName = nodeDef.logistica.liquidName
|
||||
local maxBuckets = nodeDef.logistica.maxBuckets
|
||||
local liquidDesc = nodeDef.logistica.liquidDesc
|
||||
|
||||
local emptyBucket = get_empty_bucket_needed_for(liquidName)
|
||||
local fullBucket = get_full_bucket_needed_for(liquidName)
|
||||
|
||||
if itemStackName == emptyBucket then
|
||||
if nodeLiquidLevel == 0 then
|
||||
-- make sure we swap this for the empty reservoir
|
||||
logistica.swap_node(pos, get_empty_reservoir_name(node.name, liquidName))
|
||||
return nil
|
||||
end
|
||||
if not fullBucket then return nil end
|
||||
|
||||
nodeLiquidLevel = nodeLiquidLevel - 1
|
||||
if nodeLiquidLevel == 0 then
|
||||
node.param2 = 0
|
||||
else
|
||||
node.param2 = logistica.reservoir_make_param2(nodeLiquidLevel, maxBuckets)
|
||||
end
|
||||
minetest.swap_node(pos, node)
|
||||
meta:set_int(META_LIQUID_LEVEL, nodeLiquidLevel)
|
||||
if nodeLiquidLevel == 0 then
|
||||
local newNodeName = get_empty_reservoir_name(node.name, liquidName)
|
||||
if not minetest.registered_nodes[newNodeName] then return nil end
|
||||
logistica.swap_node(pos, newNodeName)
|
||||
end
|
||||
meta:set_string("infotext", logistica.reservoir_get_description(nodeLiquidLevel, maxBuckets, liquidDesc))
|
||||
|
||||
return ItemStack(fullBucket)
|
||||
elseif fullBucket == BUCKET_ANY or itemStackName == fullBucket then
|
||||
local newLiquidName = BUCKET_TO_NAME[itemStackName]
|
||||
if not newLiquidName then return nil end -- wasn't a bucket we can use
|
||||
local newEmptyBucket = get_empty_bucket_needed_for(newLiquidName)
|
||||
if not newEmptyBucket then return nil end
|
||||
|
||||
nodeLiquidLevel = nodeLiquidLevel + 1
|
||||
if nodeLiquidLevel > maxBuckets then return nil end
|
||||
node.param2 = logistica.reservoir_make_param2(nodeLiquidLevel, maxBuckets)
|
||||
minetest.swap_node(pos, node)
|
||||
local newNodeName = get_liquid_reservoir_name_for(node.name, newLiquidName)
|
||||
|
||||
if not minetest.registered_nodes[newNodeName] then return nil end
|
||||
if nodeLiquidLevel == 1 then -- first bucket we added, swap to that reservoir type
|
||||
logistica.swap_node(pos, newNodeName)
|
||||
end
|
||||
local newLiquidDesc = minetest.registered_nodes[newNodeName].logistica.liquidDesc
|
||||
meta:set_string("infotext", logistica.reservoir_get_description(nodeLiquidLevel, maxBuckets, newLiquidDesc))
|
||||
meta:set_int(META_LIQUID_LEVEL, nodeLiquidLevel)
|
||||
return ItemStack(newEmptyBucket)
|
||||
end
|
||||
return nil
|
||||
end
|
@ -185,6 +185,14 @@ local function ins_tiles(lname) return {
|
||||
logistica.register_requester("Item Request Inserter\nInserts 1 item at a time", "requester_item", 1, ins_tiles("item"))
|
||||
logistica.register_requester("Bulk Request Inserter\nInserts up to 64 items at a time", "requester_stack", 64, ins_tiles("stack"))
|
||||
|
||||
--------------------------------
|
||||
-- Reservoirs
|
||||
--------------------------------
|
||||
|
||||
logistica.register_reservoir("lava", "Lava", "bucket:bucket_lava", "default_lava.png", 8)
|
||||
logistica.register_reservoir("water", "Water", "bucket:bucket_water", "default_water.png")
|
||||
logistica.register_reservoir("river_water", "River Water", "bucket:bucket_river_water", "default_river_water.png")
|
||||
|
||||
--------------------------------
|
||||
-- Passive Supply Chest
|
||||
--------------------------------
|
||||
|
@ -147,3 +147,21 @@ minetest.register_craft({
|
||||
{L("silverin_plate"), L("wireless_crystal"), L("silverin_plate")},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = L("reservoir_silverin_empty"),
|
||||
recipe = {
|
||||
{L("silverin_plate"), "", L("silverin_plate")},
|
||||
{L("optic_cable"), "bucket:bucket_empty", L("photonizer")},
|
||||
{L("silverin_plate"), "", L("silverin_plate")},
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = L("reservoir_obsidian_empty"),
|
||||
recipe = {
|
||||
{"default:obsidianbrick", L("silverin_plate"), "default:obsidianbrick"},
|
||||
{L("optic_cable"), "bucket:bucket_empty", L("photonizer")},
|
||||
{"default:obsidianbrick", L("silverin_plate"), "default:obsidianbrick"},
|
||||
}
|
||||
})
|
||||
|
@ -3,3 +3,4 @@ logistica_wap_max_range (Max range for the Wirless Access Pad, in nodes.) int 64
|
||||
logistica_wap_upgrade_step (How much distance each upgrade to the WAP adds) int 250 10 5000
|
||||
logistica_wifi_upgrader_hard_mode (Make Wireless Upgrader's minigame harder) bool false
|
||||
logistica_cable_size (Changes the visual/hitbox size of cables) enum Medium Small,Medium,Large,XLarge
|
||||
logistica_enable_large_liquid_tank (Enable the Large Liquid Tank) bool true
|
||||
|
BIN
textures/logistica_reservoir_obsidian.png
Normal file
BIN
textures/logistica_reservoir_obsidian.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
BIN
textures/logistica_reservoir_silverin.png
Normal file
BIN
textures/logistica_reservoir_silverin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.7 KiB |
@ -32,3 +32,5 @@ logistica.settings.wap_upgrade_step = get_int("wap_upgrade_step", 250)
|
||||
logistica.settings.wifi_upgrader_hard_mode = get_bool("wifi_upgrader_hard_mode", false)
|
||||
|
||||
logistica.settings.cable_size = get_cable_size_from_settings()
|
||||
|
||||
logistica.settings.large_liquid_tank_enabled = get_bool("enable_large_liquid_tank", true)
|
||||
|
Loading…
x
Reference in New Issue
Block a user