complete restructured
parent
05f0fe64bd
commit
eb77e68991
|
@ -0,0 +1,276 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Consumer node basis functionality.
|
||||
It handles:
|
||||
- up to 3 stages of nodes (TA2/TA3/TA4)
|
||||
- power consumption
|
||||
- node state handling
|
||||
- registration of passive and active nodes
|
||||
- Tube connections are on left and right side (from left to right)
|
||||
- Power connection are on front and back side (front or back)
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
|
||||
-- Consumer Related Data
|
||||
local CRD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).consumer end
|
||||
local CRDN = function(node) return (minetest.registered_nodes[node.name] or {}).consumer end
|
||||
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
|
||||
local function has_power(pos, nvm, state)
|
||||
local crd = CRD(pos)
|
||||
return power.power_available(pos, crd.power_netw)
|
||||
end
|
||||
|
||||
local function start_node(pos, nvm, state)
|
||||
local crd = CRD(pos)
|
||||
power.consumer_start(pos, crd.power_netw, crd.cycle_time)
|
||||
end
|
||||
|
||||
local function stop_node(pos, nvm, state)
|
||||
local crd = CRD(pos)
|
||||
power.consumer_stop(pos, crd.power_netw)
|
||||
end
|
||||
|
||||
local function on_power(pos)
|
||||
local crd = CRD(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
crd.State:start(pos, nvm)
|
||||
end
|
||||
|
||||
local function on_nopower(pos)
|
||||
local crd = CRD(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
crd.State:nopower(pos, nvm)
|
||||
end
|
||||
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local crd = CRD(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if crd.power_netw then
|
||||
power.consumer_alive(pos, crd.power_netw, crd.cycle_time)
|
||||
end
|
||||
-- call the node timer routine
|
||||
if techage.is_operational(nvm) then
|
||||
crd.node_timer(pos, crd.cycle_time)
|
||||
end
|
||||
return crd.State:is_active(nvm)
|
||||
end
|
||||
|
||||
local function prepare_tiles(tiles, stage, power_png)
|
||||
local tbl = {}
|
||||
for _,item in ipairs(tiles) do
|
||||
if type(item) == "string" then
|
||||
tbl[#tbl+1] = item:gsub("#", stage):gsub("{power}", power_png)
|
||||
else
|
||||
local temp = table.copy(item)
|
||||
temp.image = temp.image:gsub("#", stage):gsub("{power}", power_png)
|
||||
tbl[#tbl+1] = temp
|
||||
end
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
-- 'validStates' is optional and can be used to e.g. enable
|
||||
-- only one TA2 node {false, true, false, false}
|
||||
function techage.register_consumer(base_name, inv_name, tiles, tNode, validStates)
|
||||
local names = {}
|
||||
validStates = validStates or {true, true, true, true}
|
||||
for stage = 2,4 do
|
||||
local name_pas = "techage:ta"..stage.."_"..base_name.."_pas"
|
||||
local name_act = "techage:ta"..stage.."_"..base_name.."_act"
|
||||
local name_inv = "TA"..stage.." "..inv_name
|
||||
names[#names+1] = name_pas
|
||||
|
||||
if validStates[stage] then
|
||||
local on_recv_message = tNode.tubing.on_recv_message
|
||||
if stage > 2 then
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
return "unsupported"
|
||||
end
|
||||
end
|
||||
|
||||
local power_network
|
||||
local power_png = 'techage_axle_clutch.png'
|
||||
local power_used = tNode.power_consumption ~= nil
|
||||
local tNetworks
|
||||
-- power needed?
|
||||
if power_used then
|
||||
if stage > 2 then
|
||||
power_network = techage.ElectricCable
|
||||
power_png = 'techage_appl_hole_electric.png'
|
||||
tNetworks = {
|
||||
ele1 = {
|
||||
sides = tNode.power_sides or {F=1, B=1},
|
||||
ntype = "con1",
|
||||
nominal = tNode.power_consumption[stage],
|
||||
on_power = on_power,
|
||||
on_nopower = on_nopower,
|
||||
},
|
||||
}
|
||||
else
|
||||
power_network = techage.Axle
|
||||
power_png = 'techage_axle_clutch.png'
|
||||
tNetworks = {
|
||||
axle = {
|
||||
sides = tNode.power_sides or {F=1, B=1},
|
||||
ntype = "con1",
|
||||
nominal = tNode.power_consumption[stage],
|
||||
on_power = on_power,
|
||||
on_nopower = on_nopower,
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local tState = techage.NodeStates:new({
|
||||
node_name_passive = name_pas,
|
||||
node_name_active = name_act,
|
||||
infotext_name = name_inv,
|
||||
cycle_time = tNode.cycle_time,
|
||||
standby_ticks = tNode.standby_ticks,
|
||||
formspec_func = tNode.formspec,
|
||||
on_state_change = tNode.on_state_change,
|
||||
can_start = tNode.can_start,
|
||||
has_power = tNode.has_power or power_used and has_power or nil,
|
||||
start_node = power_used and start_node or nil,
|
||||
stop_node = power_used and stop_node or nil,
|
||||
})
|
||||
|
||||
local tConsumer = {
|
||||
stage = stage,
|
||||
State = tState,
|
||||
-- number of items to be processed per cycle
|
||||
num_items = tNode.num_items and tNode.num_items[stage],
|
||||
power_consumption = power_used and
|
||||
tNode.power_consumption[stage] or 0,
|
||||
node_timer = tNode.node_timer,
|
||||
cycle_time = tNode.cycle_time,
|
||||
power_netw = power_network,
|
||||
}
|
||||
|
||||
local after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local crd = CRD(pos)
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
meta:set_int("push_dir", techage.side_to_indir("L", node.param2))
|
||||
meta:set_int("pull_dir", techage.side_to_indir("R", node.param2))
|
||||
local number = "-"
|
||||
if stage > 2 then
|
||||
number = techage.add_node(pos, name_pas)
|
||||
end
|
||||
if crd.power_netw then
|
||||
crd.power_netw:after_place_node(pos)
|
||||
end
|
||||
if tNode.after_place_node then
|
||||
tNode.after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
end
|
||||
crd.State:node_init(pos, nvm, number)
|
||||
end
|
||||
|
||||
local after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if tNode.after_dig_node then
|
||||
tNode.after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
end
|
||||
local crd = CRDN(oldnode)
|
||||
if crd.power_netw then
|
||||
crd.power_netw:after_dig_node(pos)
|
||||
end
|
||||
techage.remove_node(pos)
|
||||
techage.del_mem(pos)
|
||||
end
|
||||
|
||||
local tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
||||
power.update_network(pos, outdir, tlib2)
|
||||
end
|
||||
|
||||
tNode.groups.not_in_creative_inventory = 0
|
||||
|
||||
minetest.register_node(name_pas, {
|
||||
description = name_inv,
|
||||
tiles = prepare_tiles(tiles.pas, stage, power_png),
|
||||
consumer = tConsumer,
|
||||
drawtype = tNode.drawtype,
|
||||
node_box = tNode.node_box,
|
||||
selection_box = tNode.selection_box,
|
||||
|
||||
can_dig = tNode.can_dig,
|
||||
on_rotate = screwdriver.disallow,
|
||||
on_timer = node_timer,
|
||||
on_receive_fields = tNode.on_receive_fields,
|
||||
on_rightclick = tNode.on_rightclick,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = after_dig_node,
|
||||
tubelib2_on_update2 = tubelib2_on_update2,
|
||||
allow_metadata_inventory_put = tNode.allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_move = tNode.allow_metadata_inventory_move,
|
||||
allow_metadata_inventory_take = tNode.allow_metadata_inventory_take,
|
||||
on_metadata_inventory_move = tNode.on_metadata_inventory_move,
|
||||
on_metadata_inventory_put = tNode.on_metadata_inventory_put,
|
||||
on_metadata_inventory_take = tNode.on_metadata_inventory_take,
|
||||
networks = tNetworks and table.copy(tNetworks),
|
||||
|
||||
paramtype = tNode.paramtype,
|
||||
paramtype2 = "facedir",
|
||||
groups = table.copy(tNode.groups),
|
||||
is_ground_content = false,
|
||||
sounds = tNode.sounds,
|
||||
})
|
||||
|
||||
tNode.groups.not_in_creative_inventory = 1
|
||||
|
||||
minetest.register_node(name_act, {
|
||||
description = name_inv,
|
||||
tiles = prepare_tiles(tiles.act, stage, power_png),
|
||||
consumer = tConsumer,
|
||||
drawtype = tNode.drawtype,
|
||||
node_box = tNode.node_box,
|
||||
selection_box = tNode.selection_box,
|
||||
|
||||
on_rotate = screwdriver.disallow,
|
||||
on_timer = node_timer,
|
||||
on_receive_fields = tNode.on_receive_fields,
|
||||
on_rightclick = tNode.on_rightclick,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = after_dig_node,
|
||||
tubelib2_on_update2 = tubelib2_on_update2,
|
||||
allow_metadata_inventory_put = tNode.allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_move = tNode.allow_metadata_inventory_move,
|
||||
allow_metadata_inventory_take = tNode.allow_metadata_inventory_take,
|
||||
on_metadata_inventory_move = tNode.on_metadata_inventory_move,
|
||||
on_metadata_inventory_put = tNode.on_metadata_inventory_put,
|
||||
on_metadata_inventory_take = tNode.on_metadata_inventory_take,
|
||||
networks = tNetworks and table.copy(tNetworks),
|
||||
|
||||
paramtype = tNode.paramtype,
|
||||
paramtype2 = "facedir",
|
||||
drop = "",
|
||||
diggable = false,
|
||||
groups = table.copy(tNode.groups),
|
||||
is_ground_content = false,
|
||||
sounds = tNode.sounds,
|
||||
})
|
||||
|
||||
if power_used then
|
||||
power_network:add_secondary_node_names({name_pas, name_act})
|
||||
end
|
||||
techage.register_node({name_pas, name_act}, tNode.tubing)
|
||||
end
|
||||
end
|
||||
return names[1], names[2], names[3]
|
||||
end
|
|
@ -0,0 +1,122 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Boiler common functions
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local HEAT_STEP = 10
|
||||
local MAX_WATER = 10
|
||||
local BLOCKING_TIME = 0.3 -- 300ms
|
||||
|
||||
techage.boiler = {}
|
||||
|
||||
local IsWater = {
|
||||
["bucket:bucket_river_water"] = true,
|
||||
["bucket:bucket_water"] = true,
|
||||
}
|
||||
|
||||
local IsBucket = {
|
||||
["bucket:bucket_empty"] = true,
|
||||
}
|
||||
|
||||
local function node_description(name)
|
||||
name = string.split(name, " ")[1]
|
||||
local ndef = minetest.registered_nodes[name] or minetest.registered_items[name] or minetest.registered_craftitems[name]
|
||||
if ndef and ndef.description then
|
||||
return minetest.formspec_escape(ndef.description)
|
||||
end
|
||||
return ""
|
||||
end
|
||||
|
||||
local function item_image(x, y, itemname)
|
||||
return "box["..x..","..y..";0.85,0.9;#808080]"..
|
||||
"item_image["..x..","..y..";1,1;"..itemname.."]"
|
||||
end
|
||||
|
||||
function techage.boiler.formspec(pos, nvm)
|
||||
local title = S("Water Boiler")
|
||||
local temp = nvm.temperature or 20
|
||||
local ratio = nvm.power_ratio or 0
|
||||
local tooltip = S("To add water punch\nthe boiler\nwith a water bucket")
|
||||
return "size[5,3]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"box[0,-0.1;4.8,0.5;#c6e8ff]"..
|
||||
"label[1.5,-0.1;"..minetest.colorize("#000000", title).."]"..
|
||||
item_image(1, 1.5, "default:water_source "..(nvm.num_water or 0))..
|
||||
"tooltip[1,1.5;1,1;"..tooltip..";#0C3D32;#FFFFFF]"..
|
||||
"image[3,1.0;1,2;techage_form_temp_bg.png^[lowpart:"..
|
||||
temp..":techage_form_temp_fg.png]"..
|
||||
"tooltip[3,1;1,2;"..S("water temperature")..";#0C3D32;#FFFFFF]"
|
||||
end
|
||||
|
||||
function techage.boiler.water_temperature(pos, nvm)
|
||||
nvm.temperature = nvm.temperature or 20
|
||||
nvm.num_water = nvm.num_water or 0
|
||||
if nvm.fire_trigger then
|
||||
nvm.temperature = math.min(nvm.temperature + HEAT_STEP, 100)
|
||||
else
|
||||
nvm.temperature = math.max(nvm.temperature - HEAT_STEP, 20)
|
||||
end
|
||||
nvm.fire_trigger = false
|
||||
|
||||
if nvm.water_level == 0 then
|
||||
if nvm.num_water > 0 then
|
||||
nvm.num_water = nvm.num_water - 1
|
||||
nvm.water_level = 100
|
||||
else
|
||||
nvm.temperature = 20
|
||||
end
|
||||
end
|
||||
return nvm.temperature
|
||||
end
|
||||
|
||||
function techage.boiler.on_rightclick(pos, node, clicker)
|
||||
techage.set_activeformspec(pos, clicker)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
M(pos):set_string("formspec", techage.boiler.formspec(pos, nvm))
|
||||
end
|
||||
|
||||
function techage.boiler.can_dig(pos, player)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.num_water = nvm.num_water or 0
|
||||
return nvm.num_water == 0
|
||||
end
|
||||
|
||||
function techage.boiler.on_punch(pos, node, puncher, pointed_thing)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local mem = techage.get_mem(pos)
|
||||
mem.blocking_time = mem.blocking_time or 0
|
||||
if mem.blocking_time > techage.SystemTime then
|
||||
return
|
||||
end
|
||||
|
||||
nvm.num_water = nvm.num_water or 0
|
||||
local wielded_item = puncher:get_wielded_item():get_name()
|
||||
if IsWater[wielded_item] and nvm.num_water < MAX_WATER then
|
||||
mem.blocking_time = techage.SystemTime + BLOCKING_TIME
|
||||
nvm.num_water = nvm.num_water + 1
|
||||
puncher:set_wielded_item(ItemStack("bucket:bucket_empty"))
|
||||
M(pos):set_string("formspec", techage.boiler.formspec(pos, nvm))
|
||||
elseif IsBucket[wielded_item] and nvm.num_water > 0 then
|
||||
mem.blocking_time = techage.SystemTime + BLOCKING_TIME
|
||||
nvm.num_water = nvm.num_water - 1
|
||||
puncher:set_wielded_item(ItemStack("bucket:bucket_water"))
|
||||
M(pos):set_string("formspec", techage.boiler.formspec(pos, nvm))
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Keep only one formspec active per player
|
||||
|
||||
]]--
|
||||
|
||||
local P2S = minetest.pos_to_string
|
||||
|
||||
local ActiveFormspecs = {}
|
||||
local ActivePlayer = {}
|
||||
|
||||
|
||||
function techage.is_activeformspec(pos)
|
||||
return ActiveFormspecs[P2S(pos)]
|
||||
end
|
||||
|
||||
function techage.set_activeformspec(pos, player)
|
||||
local name = player and player:get_player_name()
|
||||
if name then
|
||||
if ActivePlayer[name] then
|
||||
ActiveFormspecs[ActivePlayer[name]] = nil
|
||||
end
|
||||
ActivePlayer[name] = P2S(pos)
|
||||
ActiveFormspecs[P2S(pos)] = true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
if ActivePlayer[name] then
|
||||
ActiveFormspecs[ActivePlayer[name]] = nil
|
||||
ActivePlayer[name] = nil
|
||||
end
|
||||
end)
|
|
@ -0,0 +1,126 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Memory storage system for volatile and non-volatile memory.
|
||||
Non-volatile memory is stored from time to time and at shutdown
|
||||
as node metadata. Volatile memory is lost at every shutdown.
|
||||
|
||||
]]--
|
||||
|
||||
local NUM_NODES_PER_MIN = 100
|
||||
local NvmStore = {}
|
||||
local MemStore = {}
|
||||
local NumNodes = 0
|
||||
local StoredNodes = 0
|
||||
|
||||
local function set_metadata(hash, tbl)
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local data = minetest.serialize(tbl)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("ta_data", data)
|
||||
meta:mark_as_private("ta_data")
|
||||
end
|
||||
|
||||
local function get_metadata(hash)
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local s = meta:get_string("ta_data")
|
||||
if s ~= "" then
|
||||
return minetest.deserialize(s)
|
||||
end
|
||||
end
|
||||
|
||||
local function storage_loop()
|
||||
local cnt = 0
|
||||
while true do
|
||||
NumNodes = 0
|
||||
StoredNodes = 0
|
||||
for hash,tbl in pairs(NvmStore) do
|
||||
NumNodes = NumNodes + 1
|
||||
if tbl.__used__ then
|
||||
tbl.__used__ = nil
|
||||
set_metadata(hash, tbl)
|
||||
StoredNodes = StoredNodes + 1
|
||||
cnt = cnt + 1
|
||||
if cnt > NUM_NODES_PER_MIN then
|
||||
cnt = 0
|
||||
coroutine.yield()
|
||||
end
|
||||
else
|
||||
-- remove from memory if node is unloaded
|
||||
local pos = minetest.get_position_from_hash(hash)
|
||||
if minetest.get_node(pos).name == "ignore" then
|
||||
NvmStore[hash] = nil
|
||||
MemStore[hash] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
coroutine.yield()
|
||||
end
|
||||
end
|
||||
|
||||
local co = coroutine.create(storage_loop)
|
||||
|
||||
|
||||
local function cyclic_task()
|
||||
local t = minetest.get_us_time()
|
||||
coroutine.resume(co)
|
||||
t = minetest.get_us_time() - t
|
||||
print("[TA NVM Storage] duration="..t.."us, total="..NumNodes..", stored="..StoredNodes)
|
||||
-- run every minutes
|
||||
minetest.after(60, cyclic_task)
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
NumNodes = 0
|
||||
StoredNodes = 0
|
||||
local t = minetest.get_us_time()
|
||||
for k,v in pairs(NvmStore) do
|
||||
NumNodes = NumNodes + 1
|
||||
if v.__used__ then
|
||||
v.__used__ = nil
|
||||
set_metadata(k, v)
|
||||
StoredNodes = StoredNodes + 1
|
||||
end
|
||||
end
|
||||
t = minetest.get_us_time() - t
|
||||
print("[TA NVM Storage] duration="..t.."us, total="..NumNodes..", stored="..StoredNodes)
|
||||
end)
|
||||
|
||||
minetest.after(60, cyclic_task)
|
||||
|
||||
|
||||
-- To get the volatile node data as table
|
||||
function techage.get_mem(pos, will_change)
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if not MemStore[hash] then
|
||||
MemStore[hash] = {}
|
||||
end
|
||||
return MemStore[hash]
|
||||
end
|
||||
|
||||
-- To get the nonvolatile node data as table
|
||||
function techage.get_nvm(pos)
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if not NvmStore[hash] then
|
||||
NvmStore[hash] = get_metadata(hash) or {}
|
||||
end
|
||||
NvmStore[hash].__used__ = true
|
||||
return NvmStore[hash]
|
||||
end
|
||||
|
||||
-- To be called when a node is removed
|
||||
function techage.del_mem(pos)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("ta_data", "")
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
NvmStore[hash] = nil
|
||||
MemStore[hash] = nil
|
||||
end
|
|
@ -0,0 +1,398 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA3 Coal Power Station Firebox
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P = minetest.string_to_pos
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local firebox = techage.firebox
|
||||
local fuel = techage.fuel
|
||||
local Pipe = techage.LiquidPipe
|
||||
local liquid = techage.liquid
|
||||
|
||||
local CYCLE_TIME = 2
|
||||
local EFFICIENCY = 0.5
|
||||
|
||||
local function firehole(pos, on)
|
||||
local param2 = techage.get_node_lvm(pos).param2
|
||||
local pos2 = techage.get_pos(pos, 'F')
|
||||
if on == true then
|
||||
minetest.swap_node(pos2, {name="techage:coalfirehole_on", param2 = param2})
|
||||
elseif on == false then
|
||||
minetest.swap_node(pos2, {name="techage:coalfirehole", param2 = param2})
|
||||
else
|
||||
minetest.swap_node(pos2, {name="air"})
|
||||
end
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.running then
|
||||
-- trigger generator and provide power ratio 0..1
|
||||
local ratio = techage.transfer(
|
||||
{x=pos.x, y=pos.y+2, z=pos.z},
|
||||
nil, -- outdir
|
||||
"trigger", -- topic
|
||||
(mem.power_level or 4)/4.0, -- payload
|
||||
nil, -- network
|
||||
{"techage:coalboiler_top"} -- nodenames
|
||||
)
|
||||
ratio = math.max((ratio or 0.02), 0.02)
|
||||
mem.burn_cycles = (mem.burn_cycles or 0) - ratio
|
||||
if mem.burn_cycles <= 0 then
|
||||
local taken = firebox.get_fuel(pos)
|
||||
if taken then
|
||||
mem.burn_cycles = (firebox.Burntime[taken:get_name()] or 1) * EFFICIENCY / CYCLE_TIME
|
||||
mem.burn_cycles_total = mem.burn_cycles
|
||||
else
|
||||
mem.running = false
|
||||
firehole(pos, false)
|
||||
M(pos):set_string("formspec", firebox.formspec(mem))
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function start_firebox(pos, mem)
|
||||
if not mem.running then
|
||||
mem.running = true
|
||||
node_timer(pos, 0)
|
||||
firehole(pos, true)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:coalfirebox", {
|
||||
description = S("TA3 Power Station Firebox"),
|
||||
inventory_image = "techage_coal_boiler_inv.png",
|
||||
tiles = {"techage_coal_boiler_mesh_top.png"},
|
||||
drawtype = "mesh",
|
||||
mesh = "techage_cylinder_12.obj",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = screwdriver.disallow,
|
||||
groups = {cracky=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
|
||||
on_timer = node_timer,
|
||||
can_dig = firebox.can_dig,
|
||||
allow_metadata_inventory_put = firebox.allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = firebox.allow_metadata_inventory_take,
|
||||
on_receive_fields = firebox.on_receive_fields,
|
||||
on_rightclick = firebox.on_rightclick,
|
||||
|
||||
on_construct = function(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
techage.add_node(pos, "techage:coalfirebox")
|
||||
mem.running = false
|
||||
mem.burn_cycles = 0
|
||||
mem.power_level = 4
|
||||
local meta = M(pos)
|
||||
meta:set_string("formspec", firebox.formspec(mem))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('fuel', 1)
|
||||
firehole(pos, false)
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
firehole(pos, nil)
|
||||
end,
|
||||
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
start_firebox(pos, mem)
|
||||
M(pos):set_string("formspec", firebox.formspec(mem))
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("techage:coalfirehole", {
|
||||
description = S("TA3 Coal Power Station Firebox"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_coal_boiler.png",
|
||||
"techage_coal_boiler.png",
|
||||
"techage_coal_boiler.png",
|
||||
"techage_coal_boiler.png",
|
||||
"techage_coal_boiler.png",
|
||||
"techage_coal_boiler.png^techage_appl_firehole.png",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-6/16, -6/16, 6/16, 6/16, 6/16, 12/16},
|
||||
},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
is_ground_content = false,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
})
|
||||
|
||||
minetest.register_node("techage:coalfirehole_on", {
|
||||
description = S("TA3 Coal Power Station Firebox"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_coal_boiler.png^[colorize:black:80",
|
||||
"techage_coal_boiler.png^[colorize:black:80",
|
||||
"techage_coal_boiler.png^[colorize:black:80",
|
||||
"techage_coal_boiler.png^[colorize:black:80",
|
||||
"techage_coal_boiler.png^[colorize:black:80",
|
||||
{
|
||||
image = "techage_coal_boiler4.png^[colorize:black:80^techage_appl_firehole4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.4,
|
||||
},
|
||||
},
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-6/16, -6/16, 6/16, 6/16, 6/16, 12/16},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
light_source = 8,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
is_ground_content = false,
|
||||
groups = {not_in_creative_inventory=1},
|
||||
})
|
||||
|
||||
local function on_timer2(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.running then
|
||||
fuel.formspec_update(pos, mem)
|
||||
-- trigger generator and provide power ratio 0..1
|
||||
local ratio = techage.transfer(
|
||||
{x=pos.x, y=pos.y+2, z=pos.z},
|
||||
nil, -- outdir
|
||||
"trigger", -- topic
|
||||
(mem.power_level or 4)/4.0, -- payload
|
||||
nil, -- network
|
||||
{"techage:coalboiler_top"} -- nodenames
|
||||
)
|
||||
ratio = math.max((ratio or 0.02), 0.02)
|
||||
mem.burn_cycles = (mem.burn_cycles or 0) - ratio
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
if mem.burn_cycles <= 0 then
|
||||
if mem.liquid.amount > 0 then
|
||||
mem.liquid.amount = mem.liquid.amount - 1
|
||||
mem.burn_cycles = fuel.burntime(mem.liquid.name) * EFFICIENCY / CYCLE_TIME
|
||||
mem.burn_cycles_total = mem.burn_cycles
|
||||
else
|
||||
mem.running = false
|
||||
mem.liquid.name = nil
|
||||
firehole(pos, false)
|
||||
M(pos):set_string("formspec", fuel.formspec(mem))
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function start_firebox2(pos, mem)
|
||||
if not mem.running and mem.liquid.amount > 0 then
|
||||
mem.running = true
|
||||
on_timer2(pos, 0)
|
||||
firehole(pos, true)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
M(pos):set_string("formspec", fuel.formspec(mem))
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:oilfirebox", {
|
||||
description = S("TA3 Power Station Oil Burner"),
|
||||
inventory_image = "techage_oil_boiler_inv.png",
|
||||
tiles = {"techage_coal_boiler_mesh_top.png"},
|
||||
drawtype = "mesh",
|
||||
mesh = "techage_cylinder_12.obj",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-13/32, -16/32, -13/32, 13/32, 16/32, 13/32},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = screwdriver.disallow,
|
||||
groups = {cracky=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
|
||||
on_timer = on_timer2,
|
||||
can_dig = fuel.can_dig,
|
||||
allow_metadata_inventory_take = fuel.allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_put = fuel.allow_metadata_inventory_put,
|
||||
on_receive_fields = fuel.on_receive_fields,
|
||||
on_rightclick = fuel.on_rightclick,
|
||||
|
||||
on_construct = function(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
techage.add_node(pos, "techage:oilfirebox")
|
||||
mem.running = false
|
||||
mem.burn_cycles = 0
|
||||
mem.liquid = {}
|
||||
mem.liquid.amount = 0
|
||||
local meta = M(pos)
|
||||
meta:set_string("formspec", fuel.formspec(mem))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('fuel', 1)
|
||||
firehole(pos, false)
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
firehole(pos, nil)
|
||||
end,
|
||||
|
||||
on_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
minetest.after(1, start_firebox2, pos, mem)
|
||||
fuel.on_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
end,
|
||||
|
||||
liquid = {
|
||||
capa = fuel.CAPACITY,
|
||||
fuel_cat = fuel.BT_BITUMEN,
|
||||
peek = liquid.srv_peek,
|
||||
put = function(pos, indir, name, amount)
|
||||
if fuel.valid_fuel(name, fuel.BT_BITUMEN) then
|
||||
local leftover = liquid.srv_put(pos, indir, name, amount)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
start_firebox2(pos, mem)
|
||||
return leftover
|
||||
end
|
||||
return amount
|
||||
end,
|
||||
take = liquid.srv_take,
|
||||
},
|
||||
networks = {
|
||||
pipe = {
|
||||
sides = techage.networks.AllSides, -- Pipe connection sides
|
||||
ntype = "tank",
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
Pipe:add_secondary_node_names({"techage:oilfirebox"})
|
||||
|
||||
|
||||
techage.register_node({"techage:coalfirebox"}, {
|
||||
on_pull_item = function(pos, in_dir, num)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return techage.get_items(inv, "fuel", num)
|
||||
end,
|
||||
on_push_item = function(pos, in_dir, stack)
|
||||
if firebox.Burntime[stack:get_name()] then
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
start_firebox(pos, mem)
|
||||
return techage.put_items(inv, "fuel", stack)
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_unpull_item = function(pos, in_dir, stack)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return techage.put_items(inv, "fuel", stack)
|
||||
end,
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if topic == "state" then
|
||||
if mem.running then
|
||||
return "running"
|
||||
else
|
||||
return "stopped"
|
||||
end
|
||||
elseif topic == "fuel" then
|
||||
local inv = M(pos):get_inventory()
|
||||
local stack = inv:get_stack("fuel", 1)
|
||||
return stack:get_count()
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
techage.register_node({"techage:oilfirebox"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if topic == "state" then
|
||||
if mem.running then
|
||||
return "running"
|
||||
else
|
||||
return "stopped"
|
||||
end
|
||||
elseif topic == "fuel" then
|
||||
return mem.liquid and mem.liquid.amount and mem.liquid.amount
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:coalfirebox",
|
||||
recipe = {
|
||||
{'default:stone', 'default:stone', 'default:stone'},
|
||||
{'default:steel_ingot', '', 'default:steel_ingot'},
|
||||
{'default:stone', 'default:stone', 'default:stone'},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:oilfirebox",
|
||||
recipe = {
|
||||
{'', 'techage:coalfirebox', ''},
|
||||
{'', 'techage:ta3_barrel_empty', ''},
|
||||
{'', '', ''},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "[techage] Power Station firebox",
|
||||
name = "techage:steam_engine",
|
||||
nodenames = {"techage:coalfirebox", "techage:oilfirebox"},
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
end
|
||||
})
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA4 Hydrogen
|
||||
|
||||
]]--
|
||||
|
||||
local S = techage.S
|
||||
|
||||
minetest.register_craftitem("techage:ta4_fuelcellstack", {
|
||||
description = S("TA4 Fuel Cell Stack"),
|
||||
inventory_image = "techage_fc_stack_inv.png",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta4_fuelcellstack",
|
||||
recipe = {
|
||||
{'techage:baborium_ingot', 'techage:ta4_carbon_fiber', 'default:copper_ingot'},
|
||||
{'default:gold_ingot', 'techage:ta4_carbon_fiber', 'default:tin_ingot'},
|
||||
{"techage:baborium_ingot", 'techage:ta4_carbon_fiber', 'default:copper_ingot'},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,142 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Liquid lib
|
||||
|
||||
]]--
|
||||
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
local liquid = techage.liquid
|
||||
local LQD = function(pos) return (minetest.registered_nodes[techage.get_node_lvm(pos).name] or {}).liquid end
|
||||
|
||||
|
||||
function techage.liquid.formspec_liquid(x, y, mem)
|
||||
local itemname = "techage:liquid"
|
||||
if mem.liquid and mem.liquid.amount and mem.liquid.amount > 0 and mem.liquid.name then
|
||||
itemname = mem.liquid.name.." "..mem.liquid.amount
|
||||
end
|
||||
return "container["..x..","..y.."]"..
|
||||
"background[0,0;3,2.05;techage_form_grey.png]"..
|
||||
"image[0,0;1,1;techage_form_input_arrow.png]"..
|
||||
techage.item_image(1, 0, itemname)..
|
||||
"image[2,0;1,1;techage_form_output_arrow.png]"..
|
||||
"image[1,1;1,1;techage_form_arrow.png]"..
|
||||
"list[context;src;0,1;1,1;]"..
|
||||
"list[context;dst;2,1;1,1;]"..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;src]" ..
|
||||
"listring[current_player;main]"..
|
||||
"listring[context;dst]" ..
|
||||
"listring[current_player;main]"..
|
||||
"container_end[]"
|
||||
end
|
||||
|
||||
local function fill_container(pos, inv)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
local empty_container = inv:get_stack("src", 1):get_name()
|
||||
local full_container = liquid.get_full_container(empty_container, mem.liquid.name)
|
||||
if empty_container and full_container then
|
||||
local ldef = liquid.get_liquid_def(full_container)
|
||||
if ldef and mem.liquid.amount - ldef.size >= 0 then
|
||||
if inv:room_for_item("dst", ItemStack(full_container)) then
|
||||
inv:remove_item("src", ItemStack(empty_container))
|
||||
inv:add_item("dst", ItemStack(full_container))
|
||||
mem.liquid.amount = mem.liquid.amount - ldef.size
|
||||
if mem.liquid.amount == 0 then
|
||||
mem.liquid.name = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function empty_container(pos, inv, size)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
local stack = inv:get_stack("src", 1)
|
||||
local ldef = liquid.get_liquid_def(stack:get_name())
|
||||
if ldef and (not mem.liquid.name or ldef.inv_item == mem.liquid.name) then
|
||||
local amount = stack:get_count() * ldef.size
|
||||
if mem.liquid.amount + amount <= size then
|
||||
if inv:room_for_item("dst", ItemStack(ldef.container)) then
|
||||
inv:remove_item("src", stack)
|
||||
inv:add_item("dst", ItemStack(ldef.container))
|
||||
mem.liquid.amount = mem.liquid.amount + amount
|
||||
mem.liquid.name = ldef.inv_item
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function techage.liquid.move_item(pos, stack, size, formspec)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
if liquid.is_container_empty(stack:get_name()) then
|
||||
fill_container(pos, inv)
|
||||
else
|
||||
empty_container(pos, inv, size)
|
||||
end
|
||||
M(pos):set_string("formspec", formspec(pos, mem))
|
||||
end
|
||||
|
||||
function techage.liquid.is_empty(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
local inv = minetest.get_meta(pos):get_inventory()
|
||||
return inv:is_empty("src") and inv:is_empty("dst") and (not mem.liquid or (mem.liquid.amount or 0) == 0)
|
||||
end
|
||||
|
||||
techage.liquid.tubing = {
|
||||
on_pull_item = function(pos, in_dir, num)
|
||||
local inv = M(pos):get_inventory()
|
||||
if not inv:is_empty("dst") then
|
||||
local taken = techage.get_items(inv, "dst", num)
|
||||
if not inv:is_empty("src") then
|
||||
fill_container(pos, inv)
|
||||
end
|
||||
return taken
|
||||
end
|
||||
end,
|
||||
on_push_item = function(pos, in_dir, stack)
|
||||
local inv = M(pos):get_inventory()
|
||||
if inv:room_for_item("src", stack) then
|
||||
inv:add_item("src", stack)
|
||||
if liquid.is_container_empty(stack:get_name()) then
|
||||
fill_container(pos, inv)
|
||||
else
|
||||
empty_container(pos, inv)
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
on_unpull_item = function(pos, in_dir, stack)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
return techage.put_items(inv, "dst", stack)
|
||||
end,
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
if topic == "load" then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
return techage.power.percent(LQD(pos).capa, (mem.liquid and mem.liquid.amount) or 0)
|
||||
elseif topic == "size" then
|
||||
return LQD(pos).capa
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
techage.liquid.fill_container = fill_container
|
||||
techage.liquid.empty_container = empty_container
|
|
@ -0,0 +1,135 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Power Distribution
|
||||
|
||||
]]--
|
||||
|
||||
local net_def = techage.networks.net_def
|
||||
|
||||
local STOPPED = techage.power.STOPPED
|
||||
local NOPOWER = techage.power.NOPOWER
|
||||
local RUNNING = techage.power.RUNNING
|
||||
|
||||
local function start_consumer(tbl, tlib_type)
|
||||
for _,v in pairs(tbl or {}) do
|
||||
local nvm = techage.get_nvm(v.pos)
|
||||
if nvm[tlib_type.."_cstate"] == NOPOWER and (nvm[tlib_type.."_calive"] or 0) > 0 then
|
||||
local ndef = net_def(v.pos, tlib_type)
|
||||
nvm[tlib_type.."_cstate"] = RUNNING
|
||||
nvm[tlib_type.."_taken"] = v.nominal or 0
|
||||
if ndef.on_power then
|
||||
ndef.on_power(v.pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function stop_consumer(tbl, tlib_type)
|
||||
for _,v in pairs(tbl or {}) do
|
||||
local nvm = techage.get_nvm(v.pos)
|
||||
if nvm[tlib_type.."_cstate"] == RUNNING then
|
||||
local ndef = net_def(v.pos, tlib_type)
|
||||
nvm[tlib_type.."_cstate"] = NOPOWER
|
||||
nvm[tlib_type.."_taken"] = 0
|
||||
if ndef.on_nopower then
|
||||
ndef.on_nopower(v.pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_generator_sum(tbl, tlib_type)
|
||||
local sum = 0
|
||||
for _,v in ipairs(tbl or {}) do
|
||||
local nvm = techage.get_nvm(v.pos)
|
||||
if nvm[tlib_type.."_gstate"] ~= STOPPED then
|
||||
nvm[tlib_type.."_galive"] = (nvm[tlib_type.."_galive"] or 1) - 1
|
||||
if nvm[tlib_type.."_galive"] > 0 then
|
||||
sum = sum + v.nominal
|
||||
end
|
||||
end
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
local function get_consumer_sum(tbl, tlib_type)
|
||||
local sum = 0
|
||||
for _,v in ipairs(tbl or {}) do
|
||||
local nvm = techage.get_nvm(v.pos)
|
||||
if nvm[tlib_type.."_cstate"] ~= STOPPED then
|
||||
nvm[tlib_type.."_calive"] = (nvm[tlib_type.."_calive"] or 1) - 1
|
||||
if nvm[tlib_type.."_calive"] > 0 then
|
||||
sum = sum + v.nominal
|
||||
end
|
||||
end
|
||||
end
|
||||
return sum
|
||||
end
|
||||
|
||||
local function set_given(pos, given, tlib_type)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if (nvm[tlib_type.."_galive"] or 0) > 0 then
|
||||
nvm[tlib_type.."_given"] = given
|
||||
return given
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function set_taken(pos, taken, tlib_type)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if (nvm[tlib_type.."_calive"] or 0) > 0 then
|
||||
nvm[tlib_type.."_taken"] = taken
|
||||
return taken
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function set_given_values(tbl, needed, tlib_type)
|
||||
for _,v in ipairs(tbl or {}) do
|
||||
local real = math.max(math.min(needed, v.nominal), 0)
|
||||
real = set_given(v.pos, real, tlib_type)
|
||||
needed = needed - real
|
||||
end
|
||||
return needed
|
||||
end
|
||||
|
||||
local function set_taken_values(tbl, taken, tlib_type)
|
||||
for _,v in pairs(tbl or {}) do
|
||||
local real = math.max(math.min(taken, v.nominal), 0)
|
||||
real = set_taken(v.pos, real, tlib_type)
|
||||
taken = taken - real
|
||||
end
|
||||
return taken
|
||||
end
|
||||
|
||||
function techage.power.power_distribution(network, tlib_type, t)
|
||||
-- calc maximum power values
|
||||
network.available1 = get_generator_sum(network.gen1, tlib_type)
|
||||
network.available2 = get_generator_sum(network.gen2, tlib_type)
|
||||
network.needed1 = get_consumer_sum(network.con1, tlib_type)
|
||||
network.needed2 = get_consumer_sum(network.con2, tlib_type)
|
||||
print(t, minetest.get_gametime(), network.available1, network.available2, network.needed1, network.needed2)
|
||||
|
||||
-- store results
|
||||
network.on = network.available1 + network.available2 >= network.needed1
|
||||
if network.on then
|
||||
network.ticker = (network.ticker or 0) + 1
|
||||
set_given_values(network.gen1, network.needed1 + network.needed2, tlib_type)
|
||||
set_given_values(network.gen2, network.needed1 - network.available1, tlib_type)
|
||||
start_consumer(network.con1, tlib_type)
|
||||
set_taken_values(network.con2, network.available1 - network.needed1, tlib_type)
|
||||
else
|
||||
set_given_values(network.gen1, 0, tlib_type)
|
||||
set_given_values(network.gen2, 0, tlib_type)
|
||||
stop_consumer(network.con1, tlib_type)
|
||||
set_taken_values(network.con2, 0, tlib_type)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,75 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Power Formspec Functions
|
||||
|
||||
]]--
|
||||
|
||||
--local P2S = minetest.pos_to_string
|
||||
--local M = minetest.get_meta
|
||||
--local N = function(pos) return minetest.get_node(pos).name end
|
||||
--local S = techage.S
|
||||
local in_range = techage.in_range
|
||||
|
||||
function techage.power.percent(max_val, curr_val)
|
||||
return math.min(math.ceil(((curr_val or 0) * 100.0) / (max_val or 1.0)), 100)
|
||||
end
|
||||
|
||||
function techage.power.formspec_load_bar(charging, max_val)
|
||||
local percent
|
||||
charging = charging or 0
|
||||
max_val = max_val or 1
|
||||
if charging ~= 0 then
|
||||
percent = 50 + math.ceil((charging * 50.0) / max_val)
|
||||
end
|
||||
|
||||
if charging > 0 then
|
||||
return "techage_form_level_off.png^[lowpart:"..percent..":techage_form_level_charge.png"
|
||||
elseif charging < 0 then
|
||||
return "techage_form_level_unload.png^[lowpart:"..percent..":techage_form_level_off.png"
|
||||
else
|
||||
return "techage_form_level_off.png"
|
||||
end
|
||||
end
|
||||
|
||||
function techage.power.formspec_power_bar(max_power, current_power)
|
||||
if (current_power or 0) == 0 then
|
||||
return "techage_form_level_bg.png"
|
||||
end
|
||||
local percent = techage.power.percent(max_power, current_power)
|
||||
percent = (percent + 5) / 1.22 -- texture correction
|
||||
return "techage_form_level_bg.png^[lowpart:"..percent..":techage_form_level_fg.png"
|
||||
end
|
||||
|
||||
function techage.power.formspec_label_bar(x, y, label, max_power, current_power)
|
||||
local percent, ypos
|
||||
current_power = current_power or 0
|
||||
if current_power == 0 then
|
||||
percent = 0
|
||||
ypos = 2.8
|
||||
else
|
||||
percent = techage.power.percent(max_power, current_power)
|
||||
-- 0.4 to 2.8 = 2.4
|
||||
local offs = 2.4 - (current_power / max_power) * 2.4
|
||||
ypos = 0.4 + in_range(offs, 0.4, 2.4)
|
||||
end
|
||||
percent = (percent + 5) / 1.1 -- texture correction
|
||||
return "container["..x..","..y.."]"..
|
||||
"box[0,0;2.3,3.3;#395c74]"..
|
||||
"label[0.2,0;"..label.."]"..
|
||||
"label[0.7,0.4;"..max_power.." ku]"..
|
||||
"image[0,0.5;1,3;"..
|
||||
"techage_form_level_bg.png^[lowpart:"..percent..
|
||||
":techage_form_level_fg.png]"..
|
||||
"label[0.7,"..ypos..";"..current_power.." ku]"..
|
||||
"container_end[]"
|
||||
|
||||
end
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Gearbox
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P2S = minetest.pos_to_string
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local PWR_NEEDED = 1
|
||||
local CYCLE_TIME = 4
|
||||
|
||||
local Axle = techage.Axle
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
|
||||
-- Axles texture animation
|
||||
local function switch_axles(pos, on)
|
||||
for _,outdir in ipairs(networks.get_node_connections(pos, "axle")) do
|
||||
Axle:switch_tube_line(pos, outdir, on and "on" or "off")
|
||||
end
|
||||
end
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = techage.get_node_lvm(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function on_power(pos)
|
||||
swap_node(pos, "techage:gearbox_on")
|
||||
switch_axles(pos, true)
|
||||
end
|
||||
|
||||
local function on_nopower(pos)
|
||||
swap_node(pos, "techage:gearbox")
|
||||
switch_axles(pos, false)
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
power.consumer_alive(pos, Axle, CYCLE_TIME)
|
||||
return true
|
||||
end
|
||||
|
||||
-- to be able to restart the node after server crashes
|
||||
local function techage_on_repair(pos)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
power.consumer_start(pos, Axle, CYCLE_TIME)
|
||||
end
|
||||
|
||||
local function after_place_node(pos)
|
||||
Axle:after_place_node(pos)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
power.consumer_start(pos, Axle, CYCLE_TIME)
|
||||
end
|
||||
|
||||
local function after_dig_node(pos, oldnode)
|
||||
Axle:after_dig_node(pos)
|
||||
techage.del_mem(pos)
|
||||
end
|
||||
|
||||
local function tubelib2_on_update2(pos, outdir, tlib2, node)
|
||||
power.update_network(pos, nil, tlib2)
|
||||
end
|
||||
|
||||
local net_def = {
|
||||
axle = {
|
||||
sides = techage.networks.AllSides, -- Cable connection sides
|
||||
ntype = {"con1", "junc"},
|
||||
on_power = on_power,
|
||||
on_nopower = on_nopower,
|
||||
nominal = PWR_NEEDED,
|
||||
},
|
||||
}
|
||||
|
||||
minetest.register_node("techage:gearbox", {
|
||||
description = S("TA2 Gearbox"),
|
||||
tiles = {"techage_filling_ta2.png^techage_axle_gearbox.png^techage_frame_ta2.png"},
|
||||
|
||||
on_timer = node_timer,
|
||||
techage_on_repair = techage_on_repair,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = after_dig_node,
|
||||
tubelib2_on_update2 = tubelib2_on_update2,
|
||||
networks = net_def,
|
||||
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:gearbox_on", {
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_axle_gearbox4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
on_timer = node_timer,
|
||||
techage_on_repair = techage_on_repair,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = after_dig_node,
|
||||
tubelib2_on_update2 = tubelib2_on_update2,
|
||||
networks = net_def,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
diggable = false,
|
||||
drop = "",
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
Axle:add_secondary_node_names({"techage:gearbox", "techage:gearbox_on"})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:gearbox 2",
|
||||
recipe = {
|
||||
{"default:junglewood", "techage:axle", "default:wood"},
|
||||
{"techage:axle", "techage:iron_ingot", "techage:axle"},
|
||||
{"default:wood", "techage:axle", "default:junglewood"},
|
||||
},
|
||||
})
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
API for Power Nodes
|
||||
|
||||
]]--
|
||||
|
||||
--local P2S = minetest.pos_to_string
|
||||
--local M = minetest.get_meta
|
||||
--local N = function(pos) return minetest.get_node(pos).name end
|
||||
--local S = techage.S
|
||||
|
||||
local net_def = techage.networks.net_def
|
||||
local networks = techage.networks
|
||||
|
||||
-- Consumer States
|
||||
local STOPPED = 1
|
||||
local NOPOWER = 2
|
||||
local RUNNING = 3
|
||||
|
||||
techage.power = {}
|
||||
|
||||
techage.power.STOPPED = STOPPED
|
||||
techage.power.NOPOWER = NOPOWER
|
||||
techage.power.RUNNING = RUNNING
|
||||
|
||||
-- determine network ID (largest hash number of all generators)
|
||||
local function determine_netID(pos, outdir, Cable)
|
||||
local netID = 0
|
||||
networks.connection_walk(pos, outdir, Cable, function(pos, indir, node)
|
||||
local ntype = net_def(pos, Cable.tube_type).ntype
|
||||
if ntype ~= "junc" then
|
||||
local new = minetest.hash_node_position(pos)
|
||||
if netID <= new then
|
||||
netID = new
|
||||
end
|
||||
end
|
||||
end)
|
||||
return netID
|
||||
end
|
||||
|
||||
-- store network ID on each node
|
||||
local function store_netID(pos, outdir, netID, Cable)
|
||||
networks.connection_walk(pos, outdir, Cable, function(pos, indir, node)
|
||||
techage.mark_position("singleplayer", pos, "store", "", 2)-----------------------------------------
|
||||
--print(node.name, dump(net_def(pos, Cable.tube_type)))
|
||||
if net_def(pos, Cable.tube_type) then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm[Cable.tube_type.."_netID"] = netID
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
-- delete network and ID on each node
|
||||
local function delete_netID(pos, outdir, Cable)
|
||||
local netID = 0
|
||||
networks.connection_walk(pos, outdir, Cable, function(pos, indir, node)
|
||||
techage.mark_position("singleplayer", pos, "delete", "", 2)----------------------------------------
|
||||
if net_def(pos, Cable.tube_type) then
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if nvm[Cable.tube_type.."_netID"] then
|
||||
netID = nvm[Cable.tube_type.."_netID"]
|
||||
nvm[Cable.tube_type.."_netID"] = nil
|
||||
end
|
||||
end
|
||||
end)
|
||||
networks.delete_network(netID, Cable)
|
||||
end
|
||||
|
||||
-- Keep the network up and running
|
||||
local function trigger_network(pos, outdir, Cable)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local netID = nvm[Cable.tube_type.."_netID"]
|
||||
if not netID then
|
||||
print("determine_netID !!!!!!!!!!!!!!!!!!!!")
|
||||
netID = determine_netID(pos, outdir, Cable)
|
||||
store_netID(pos, outdir, netID, Cable)
|
||||
networks.build_network(pos, outdir, Cable, netID)
|
||||
elseif not networks.has_network(Cable.tube_type, netID) then
|
||||
print("build_network !!!!!!!!!!!!!!!!!!!!")
|
||||
networks.build_network(pos, outdir, Cable, netID)
|
||||
end
|
||||
end
|
||||
|
||||
-- To be called from each node via 'tubelib2_on_update2'
|
||||
-- 'output' is optional and only needed for nodes with dedicated
|
||||
-- pipe sides (e.g. pumps).
|
||||
function techage.power.update_network(pos, outdir, Cable)
|
||||
networks.node_connections(pos, Cable) -- update node internal data
|
||||
delete_netID(pos, outdir, Cable) -- network walk to delete all IDs
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Consumer related functions
|
||||
--
|
||||
|
||||
-- check if there is a living network
|
||||
function techage.power.power_available(pos, Cable)
|
||||
-- for _,outdir in ipairs(techage.networks.get_node_connections(pos, Cable.tube_type)) do
|
||||
-- -- generator visible?
|
||||
-- if determine_netID(pos, outdir, Cable) > 0 then return true end
|
||||
-- end
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
return networks.has_network(tlib_type, nvm[tlib_type.."_netID"])
|
||||
-- local mem = techage.get_mem(pos)
|
||||
-- local tlib_type = Cable.tube_type
|
||||
-- local netID = nvm[tlib_type.."_netID"]
|
||||
-- local netw = techage.networks.get_network(tlib_type, netID)
|
||||
-- if netw then -- network available
|
||||
-- if not mem.new_ticker or mem.new_ticker ~= netw.ticker then
|
||||
-- mem.new_ticker = netw.ticker
|
||||
-- return true
|
||||
-- end
|
||||
-- return false
|
||||
-- end
|
||||
end
|
||||
|
||||
-- this is more a try to start, the start will be performed by on_power()
|
||||
function techage.power.consumer_start(pos, Cable, cycle_time)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
nvm[tlib_type.."_calive"] = (cycle_time / 2) + 1
|
||||
nvm[tlib_type.."_cstate"] = NOPOWER
|
||||
nvm[tlib_type.."_taken"] = 0
|
||||
end
|
||||
|
||||
function techage.power.consumer_stop(pos, Cable)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
nvm[tlib_type.."_calive"] = 0
|
||||
nvm[tlib_type.."_cstate"] = STOPPED
|
||||
nvm[tlib_type.."_taken"] = 0
|
||||
end
|
||||
|
||||
function techage.power.consumer_alive(pos, Cable, cycle_time)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
if nvm[tlib_type.."_netID"] then -- network available
|
||||
nvm[tlib_type.."_calive"] = (cycle_time / 2) + 1
|
||||
elseif nvm[tlib_type.."_cstate"] == RUNNING then
|
||||
local ndef = net_def(pos, tlib_type)
|
||||
ndef.on_nopower(pos)
|
||||
nvm[tlib_type.."_cstate"] = NOPOWER
|
||||
end
|
||||
return nvm[tlib_type.."_taken"] or 0
|
||||
end
|
||||
|
||||
--
|
||||
-- Generator related functions
|
||||
--
|
||||
function techage.power.generator_start(pos, Cable, cycle_time, outdir)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
nvm[tlib_type.."_galive"] = (cycle_time / 2) + 2
|
||||
nvm[tlib_type.."_gstate"] = RUNNING
|
||||
nvm[tlib_type.."_given"] = 0
|
||||
trigger_network(pos, outdir, Cable)
|
||||
end
|
||||
|
||||
function techage.power.generator_stop(pos, Cable, outdir)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
nvm[tlib_type.."_galive"] = 0
|
||||
nvm[tlib_type.."_gstate"] = STOPPED
|
||||
nvm[tlib_type.."_given"] = 0
|
||||
end
|
||||
|
||||
function techage.power.generator_alive(pos, Cable, cycle_time, outdir)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local tlib_type = Cable.tube_type
|
||||
trigger_network(pos, outdir, Cable)
|
||||
nvm[tlib_type.."_galive"] = (cycle_time / 2) + 2
|
||||
return nvm[tlib_type.."_given"] or 0
|
||||
end
|
||||
|
||||
-- function delete_netID(pos, outdir, Cable)
|
||||
techage.power.delete_netID = delete_netID
|
|
@ -0,0 +1,220 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA3 Power Terminal
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S2P = minetest.string_to_pos
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local M = minetest.get_meta
|
||||
local N = function(pos) return minetest.get_node(pos).name end
|
||||
local S = techage.S
|
||||
|
||||
local CYCLE_TIME = 2
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
local STOPPED = techage.power.STOPPED
|
||||
local NOPOWER = techage.power.NOPOWER
|
||||
local RUNNING = techage.power.RUNNING
|
||||
|
||||
local function generator_data(gen_tbl)
|
||||
local tbl = {
|
||||
pow_all=0, pow_on=0, pow_act=0, pow_used=0,
|
||||
num_on=0, num_act=0, num_used=0
|
||||
}
|
||||
for i,gen in ipairs(gen_tbl or {}) do
|
||||
local nvm = techage.get_nvm(gen.pos)
|
||||
tbl.pow_all = tbl.pow_all + (gen.nominal or 0)
|
||||
if nvm.ele1_gstate and nvm.ele1_gstate ~= STOPPED then
|
||||
tbl.num_on = tbl.num_on + 1
|
||||
tbl.pow_on = tbl.pow_on + (gen.nominal or 0)
|
||||
if (nvm.ele1_galive or 0) > 0 then
|
||||
tbl.num_act = tbl.num_act + 1
|
||||
tbl.pow_act = tbl.pow_act + (gen.nominal or 0)
|
||||
if (nvm.ele1_given or 0) > 0 then
|
||||
tbl.num_used = tbl.num_used + 1
|
||||
tbl.pow_used = tbl.pow_used + (nvm.ele1_given or 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tbl.num_all = #(gen_tbl or {})
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function consumer_data(con_tbl)
|
||||
local tbl = {
|
||||
pow_all=0, pow_on=0, pow_act=0, pow_used=0,
|
||||
num_on=0, num_act=0, num_used=0
|
||||
}
|
||||
for i,gen in ipairs(con_tbl or {}) do
|
||||
local nvm = techage.get_nvm(gen.pos)
|
||||
tbl.pow_all = tbl.pow_all + (gen.nominal or 0)
|
||||
if nvm.ele1_cstate and nvm.ele1_cstate ~= STOPPED then
|
||||
tbl.num_on = tbl.num_on + 1
|
||||
tbl.pow_on = tbl.pow_on + (gen.nominal or 0)
|
||||
if (nvm.ele1_calive or 0) > 0 then
|
||||
tbl.num_act = tbl.num_act + 1
|
||||
tbl.pow_act = tbl.pow_act + (gen.nominal or 0)
|
||||
if (nvm.ele1_taken or 0) > 0 then
|
||||
tbl.num_used = tbl.num_used + 1
|
||||
tbl.pow_used = tbl.pow_used + (nvm.ele1_taken or 0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
tbl.num_all = #(con_tbl or {})
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function calc_network_data(pos, nvm)
|
||||
local netw = techage.networks.has_network("ele1", nvm.ele1_netID) or {}
|
||||
local gen1 = generator_data(netw.gen1)
|
||||
local gen2 = generator_data(netw.gen2)
|
||||
local con1 = consumer_data(netw.con1)
|
||||
local con2 = consumer_data(netw.con2)
|
||||
|
||||
return netw, gen1, gen2, con1, con2
|
||||
end
|
||||
|
||||
local function column(x,y, data)
|
||||
return
|
||||
"label["..x..","..(y+0.0)..";"..data.num_all.. " ("..data.pow_all.." ku)]"..
|
||||
"label["..x..","..(y+0.5)..";"..data.num_on.. " ("..data.pow_on.." ku)]"..
|
||||
"label["..x..","..(y+1.0)..";"..data.num_act.. " ("..data.pow_act.." ku)]"..
|
||||
"label["..x..","..(y+1.5)..";"..data.num_used.." ("..data.pow_used.." ku)]"
|
||||
end
|
||||
|
||||
local function get_state(netw, gen1, gen2, con1, con2)
|
||||
local num_nodes = gen1.num_all + gen2.num_all + con1.num_all +
|
||||
con2.num_all + (#(netw.junc or {})) + (#(netw.term or {}))
|
||||
local nload = (gen1.pow_act + gen2.pow_act) / con1.pow_act
|
||||
local state = S("Number of all nodes")..": ".. num_nodes
|
||||
if not netw.gen1 and not netw.gen2 then
|
||||
state = S("No network or active generator available!")
|
||||
elseif num_nodes > (techage.ELE1_MAX_CABLE_LENGHT - 50) then
|
||||
state = string.format(S("With %u of a maximum of %u blocks you are almost at the limit!"),
|
||||
num_nodes, techage.ELE1_MAX_CABLE_LENGHT)
|
||||
elseif nload <= 1.0 then
|
||||
state = S("The network is overloaded!")
|
||||
elseif nload < 1.2 then
|
||||
state = S("The network load is almost at the limit!")
|
||||
end
|
||||
return state
|
||||
end
|
||||
|
||||
local function formspec(pos, nvm)
|
||||
local netw, gen1, gen2, con1, con2 = calc_network_data(pos, nvm)
|
||||
netw.prop = ((netw.prop or 0) + 1) % 2
|
||||
local star = netw.prop == 1 and "*" or ""
|
||||
local state = get_state(netw, gen1, gen2, con1, con2)
|
||||
|
||||
return "size[10,7]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"box[0,-0.1;9.8,0.5;#c6e8ff]"..
|
||||
"label[4,-0.1;"..minetest.colorize( "#000000", S("Network Data")).."]"..
|
||||
"label[9.5,-0.1;"..minetest.colorize( "#000000", star).."]"..
|
||||
power.formspec_label_bar(0, 0.7, S("Genera. 1"), gen1.pow_act, gen1.pow_used)..
|
||||
power.formspec_label_bar(2.5, 0.7, S("Genera. 2"), gen2.pow_act, gen2.pow_used)..
|
||||
power.formspec_label_bar(5, 0.7, S("Consum. 2"), con2.pow_act, con2.pow_used)..
|
||||
power.formspec_label_bar(7.5, 0.7, S("Consum. 1"), con1.pow_act, con1.pow_used)..
|
||||
"box[0,4.3;9.8,0.4;#c6e8ff]"..
|
||||
"box[0,4.85;9.8,0.4;#395c74]"..
|
||||
"box[0,5.35;9.8,0.4;#395c74]"..
|
||||
"box[0,5.85;9.8,0.4;#395c74]"..
|
||||
"box[0,6.35;9.8,0.4;#395c74]"..
|
||||
"label[2,4.3;"..minetest.colorize( "#000000", S("Genera. 1")).."]"..
|
||||
"label[4,4.3;"..minetest.colorize( "#000000", S("Genera. 2")).."]"..
|
||||
"label[6,4.3;"..minetest.colorize( "#000000", S("Consum. 2")).."]"..
|
||||
"label[8,4.3;"..minetest.colorize( "#000000", S("Consum. 1")).."]"..
|
||||
"label[0.1,4.8;"..S("All nodes:").."]"..
|
||||
"label[0.1,5.3;"..S("Turned on:").."]"..
|
||||
"label[0.1,5.8;"..S("Active:").."]"..
|
||||
"label[0.1,6.3;"..S("In use:").."]"..
|
||||
"box[0,6.95;9.8,0.4;#000000]"..
|
||||
"label[0.1,6.9;"..state.."]"..
|
||||
column(2, 4.8, gen1)..
|
||||
column(4, 4.8, gen2)..
|
||||
column(6, 4.8, con2)..
|
||||
column(8, 4.8, con1)
|
||||
end
|
||||
|
||||
minetest.register_node("techage:power_terminal", {
|
||||
description = S("TA3 Power Terminal"),
|
||||
inventory_image = "techage_power_terminal_front.png",
|
||||
tiles = {
|
||||
"techage_power_terminal_top.png",
|
||||
"techage_power_terminal_top.png",
|
||||
"techage_power_terminal_side.png",
|
||||
"techage_power_terminal_side.png",
|
||||
"techage_power_terminal_back.png",
|
||||
"techage_power_terminal_front.png",
|
||||
},
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -8/16, -8/16, 0/16, 8/16, 8/16, 8/16},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
M(pos):set_int("outdir", networks.side_to_outdir(pos, "B"))
|
||||
Cable:after_place_node(pos)
|
||||
M(pos):set_string("formspec", formspec(pos, nvm))
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
Cable:after_dig_node(pos)
|
||||
techage.del_mem(pos)
|
||||
end,
|
||||
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
||||
power.update_network(pos, outdir, tlib2)
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
techage.set_activeformspec(pos, clicker)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
M(pos):set_string("formspec", formspec(pos, nvm))
|
||||
end,
|
||||
on_timer = function(pos, elapsed)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if techage.is_activeformspec(pos) then
|
||||
M(pos):set_string("formspec", formspec(pos, nvm))
|
||||
end
|
||||
return true
|
||||
end,
|
||||
|
||||
networks = {
|
||||
ele1 = {
|
||||
sides = {B = 1}, -- Cable connection side
|
||||
ntype = "term",
|
||||
},
|
||||
},
|
||||
|
||||
paramtype2 = "facedir",
|
||||
paramtype = "light",
|
||||
on_rotate = screwdriver.disallow,
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {cracky = 1, level = 2},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
Cable:add_secondary_node_names({"techage:power_terminal"})
|
||||
|
|
@ -0,0 +1,183 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA3 Power Switch Box
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local S2P = minetest.string_to_pos
|
||||
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
|
||||
local M = minetest.get_meta
|
||||
local N = function(pos) return minetest.get_node(pos).name end
|
||||
local S = techage.S
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
|
||||
-- simpe rotation of a facedir node through all 3 axis positions
|
||||
local Rotation = {[0]=
|
||||
11,8,12,10,14,13,16,15,18,15,5,19,21,20,23,22,1,0,3,2,7,4,9,6
|
||||
}
|
||||
|
||||
local function get_conn_dirs(pos, node)
|
||||
local tbl = {[0]=
|
||||
{R=2,L=4}, {R=1,L=3}, {R=2,L=4}, {R=1,L=3},
|
||||
{R=2,L=4}, {D=5,U=6}, {R=2,L=4}, {D=5,U=6},
|
||||
{R=2,L=4}, {D=5,U=6}, {R=2,L=4}, {D=5,U=6},
|
||||
{D=5,U=6}, {R=1,L=3}, {D=5,U=6}, {R=1,L=3},
|
||||
{D=5,U=6}, {R=1,L=3}, {D=5,U=6}, {R=1,L=3},
|
||||
{R=2,L=4}, {R=1,L=3}, {R=2,L=4}, {R=1,L=3},
|
||||
}
|
||||
if M(pos):get_int("turned_off") == 1 then
|
||||
return {}
|
||||
end
|
||||
return tbl[node.param2]
|
||||
end
|
||||
|
||||
local function update_network(pos, node)
|
||||
-- power.update_network(pos, nil, Cable)
|
||||
for _,outdir in pairs(get_conn_dirs(pos, node)) do
|
||||
power.update_network(pos, outdir, Cable)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rotate(pos, node, user, mode, new_param2)
|
||||
if minetest.is_protected(pos, user:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
update_network(pos, node)
|
||||
node.param2 = Rotation[node.param2]
|
||||
minetest.swap_node(pos, node)
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_node("techage:powerswitch_box", {
|
||||
description = S("TA Power Switch Box"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_junction.png',
|
||||
'techage_electric_junction.png',
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_switch.png',
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -2/4, -1/4, -1/4, 2/4, 1/4, 1/4},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos)
|
||||
Cable:after_place_node(pos)
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
Cable:after_dig_node(pos)
|
||||
end,
|
||||
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
||||
--print("powerswitch_box tubelib2_on_update2")
|
||||
update_network(pos, node)
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
node.name = "techage:powerswitch_box_off"
|
||||
minetest.swap_node(pos, node)
|
||||
M(pos):set_int("turned_off", 1)
|
||||
minetest.sound_play("techage_button", {
|
||||
pos = pos,
|
||||
gain = 0.5,
|
||||
max_hear_distance = 5,
|
||||
})
|
||||
Cable:after_dig_node(pos)
|
||||
update_network(pos, node)
|
||||
end,
|
||||
|
||||
networks = {
|
||||
ele1 = {
|
||||
get_sides = get_conn_dirs,
|
||||
--sides = networks.AllSides,
|
||||
ntype = "junc",
|
||||
},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_rotate = on_rotate,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2, techage_trowel = 1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:powerswitch_box_off", {
|
||||
description = S("TA Power Switch Box"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_junction.png',
|
||||
'techage_electric_junction.png',
|
||||
'techage_electric_switch.png',
|
||||
'techage_electric_switch.png',
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{ -2/4, -1/4, -1/4, 2/4, 1/4, 1/4},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos)
|
||||
Cable:after_place_node(pos)
|
||||
end,
|
||||
after_dig_node = function(pos)
|
||||
Cable:after_dig_node(pos)
|
||||
end,
|
||||
tubelib2_on_update2 = function(pos, outdir, tlib2, node)
|
||||
update_network(pos, node)
|
||||
end,
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
node.name = "techage:powerswitch_box"
|
||||
minetest.swap_node(pos, node)
|
||||
M(pos):set_int("turned_off", 0)
|
||||
minetest.sound_play("techage_button", {
|
||||
pos = pos,
|
||||
gain = 0.5,
|
||||
max_hear_distance = 5,
|
||||
})
|
||||
Cable:after_dig_node(pos)
|
||||
update_network(pos, node)
|
||||
end,
|
||||
|
||||
networks = {
|
||||
ele1 = {
|
||||
--sides = {},
|
||||
--sides = networks.AllSides,
|
||||
get_sides = get_conn_dirs,
|
||||
ntype = "", -- unknown type, acting as switch off
|
||||
},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
on_rotate = on_rotate,
|
||||
paramtype2 = "facedir",
|
||||
drop = "techage:powerswitch_box",
|
||||
groups = {choppy=2, cracky=2, crumbly=2, techage_trowel = 1, not_in_creative_inventory = 1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
Cable:add_secondary_node_names({"techage:powerswitch_box"})
|
|
@ -0,0 +1,225 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA3 Accu Box
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local P2S = minetest.pos_to_string
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local CYCLE_TIME = 2
|
||||
local PWR_PERF = 10
|
||||
local PWR_CAPA = 2000
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
local power = techage.power
|
||||
local networks = techage.networks
|
||||
local in_range = techage.in_range
|
||||
|
||||
|
||||
local function formspec(self, pos, nvm)
|
||||
local needed = nvm.needed or 0
|
||||
local capa = nvm.capa or 0
|
||||
return "size[5,4]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"box[0,-0.1;4.8,0.5;#c6e8ff]"..
|
||||
"label[1,-0.1;"..minetest.colorize( "#000000", S("TA3 Akku Box")).."]"..
|
||||
power.formspec_label_bar(0, 0.8, S("Load"), PWR_CAPA, capa)..
|
||||
"image_button[3,2;1,1;".. self:get_state_button_image(nvm) ..";state_button;]"..
|
||||
"tooltip[3,2;1,1;"..self:get_state_tooltip(nvm).."]"..
|
||||
"label[4.2,1.2;Flow]"..
|
||||
"image[4,1.7;1,2;"..techage.power.formspec_load_bar(needed, PWR_PERF).."]"
|
||||
end
|
||||
|
||||
|
||||
local function start_node(pos, nvm, state)
|
||||
nvm.running = true
|
||||
nvm.needed = 0
|
||||
local outdir = M(pos):get_int("outdir")
|
||||
power.generator_start(pos, Cable, CYCLE_TIME, outdir)
|
||||
power.consumer_start(pos, Cable, CYCLE_TIME, outdir)
|
||||
end
|
||||
|
||||
local function stop_node(pos, nvm, state)
|
||||
nvm.running = false
|
||||
nvm.needed = 0
|
||||
local outdir = M(pos):get_int("outdir")
|
||||
power.generator_stop(pos, Cable, outdir)
|
||||
power.consumer_stop(pos, Cable, outdir)
|
||||
end
|
||||
|
||||
local State = techage.NodeStates:new({
|
||||
node_name_passive = "techage:ta3_akku",
|
||||
cycle_time = CYCLE_TIME,
|
||||
standby_ticks = 0,
|
||||
formspec_func = formspec,
|
||||
start_node = start_node,
|
||||
stop_node = stop_node,
|
||||
})
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
nvm.capa = nvm.capa or 0
|
||||
local outdir = M(pos):get_int("outdir")
|
||||
local taken = 0
|
||||
local given = 0
|
||||
if nvm.capa < PWR_CAPA then
|
||||
taken = power.consumer_alive(pos, Cable, CYCLE_TIME)
|
||||
end
|
||||
if nvm.capa > 0 then
|
||||
given = power.generator_alive(pos, Cable, CYCLE_TIME, outdir)
|
||||
end
|
||||
nvm.needed = taken - given
|
||||
nvm.capa = in_range(nvm.capa + nvm.needed, 0, PWR_CAPA)
|
||||
--print("node_timer accu "..P2S(pos), nvm.needed, nvm.capa)
|
||||
|
||||
if techage.is_activeformspec(pos) then
|
||||
M(pos):set_string("formspec", formspec(State, pos, nvm))
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
techage.set_activeformspec(pos, clicker)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
M(pos):set_string("formspec", formspec(State, pos, nvm))
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local nvm = techage.get_nvm(pos)
|
||||
State:state_button_event(pos, nvm, fields)
|
||||
M(pos):set_string("formspec", formspec(State, pos, nvm))
|
||||
end
|
||||
|
||||
local function get_capa(itemstack)
|
||||
local meta = itemstack:get_meta()
|
||||
if meta then
|
||||
return in_range(meta:get_int("capa") * (PWR_CAPA/100), 0, 3000)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function set_capa(pos, oldnode, digger, capa)
|
||||
local node = ItemStack(oldnode.name)
|
||||
local meta = node:get_meta()
|
||||
capa = techage.power.percent(PWR_CAPA, capa)
|
||||
capa = (math.floor((capa or 0) / 5)) * 5
|
||||
meta:set_int("capa", capa)
|
||||
local text = S("TA3 Accu Box").." ("..capa.." %)"
|
||||
meta:set_string("description", text)
|
||||
local inv = minetest.get_inventory({type="player", name=digger:get_player_name()})
|
||||
local left_over = inv:add_item("main", node)
|
||||
if left_over:get_count() > 0 then
|
||||
minetest.add_item(pos, node)
|
||||
end
|
||||
end
|
||||
|
||||
local function after_place_node(pos, placer, itemstack)
|
||||
local meta = M(pos)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
local own_num = techage.add_node(pos, "techage:ta3_akku")
|
||||
meta:set_string("owner", placer:get_player_name())
|
||||
meta:set_string("infotext", S("TA3 Accu Box").." "..own_num)
|
||||
meta:set_int("outdir", networks.side_to_outdir(pos, "R"))
|
||||
meta:set_string("formspec", formspec(State, pos, nvm))
|
||||
Cable:after_place_node(pos)
|
||||
State:node_init(pos, nvm, own_num)
|
||||
nvm.capa = get_capa(itemstack)
|
||||
end
|
||||
|
||||
local function after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
Cable:after_dig_node(pos)
|
||||
set_capa(pos, oldnode, digger, nvm.capa)
|
||||
techage.del_mem(pos)
|
||||
end
|
||||
|
||||
local function tubelib2_on_update2(pos, outdir, tlib2, node)
|
||||
power.update_network(pos, outdir, tlib2)
|
||||
end
|
||||
|
||||
local net_def = {
|
||||
ele1 = {
|
||||
sides = {R = 1},
|
||||
ntype = {"gen2", "con2"},
|
||||
nominal = PWR_PERF,
|
||||
},
|
||||
}
|
||||
|
||||
minetest.register_node("techage:ta3_akku", {
|
||||
description = S("TA3 Accu Box"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta3.png^techage_frame_ta3_top.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole_electric.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_source.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_source.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_source.png",
|
||||
},
|
||||
|
||||
on_timer = node_timer,
|
||||
on_rightclick = on_rightclick,
|
||||
on_receive_fields = on_receive_fields,
|
||||
after_place_node = after_place_node,
|
||||
after_dig_node = after_dig_node,
|
||||
tubelib2_on_update2 = tubelib2_on_update2,
|
||||
networks = net_def,
|
||||
|
||||
drop = "", -- don't remove, item will be added via 'set_capa'
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
Cable:add_secondary_node_names({"techage:ta3_akku"})
|
||||
|
||||
-- for logical communication
|
||||
techage.register_node({"techage:ta3_akku"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local nvm = techage.get_nvm(pos)
|
||||
if topic == "load" then
|
||||
return techage.power.percent(PWR_CAPA, nvm.capa)
|
||||
elseif topic == "size" then
|
||||
return PWR_CAPA
|
||||
else
|
||||
return State:on_receive_message(pos, topic, payload)
|
||||
end
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
local meta = M(pos)
|
||||
meta:set_int("outdir", networks.side_to_outdir(pos, "R"))
|
||||
if meta:get_string("node_number") == "" then
|
||||
local own_num = techage.add_node(pos, "techage:ta3_akku")
|
||||
meta:set_string("node_number", own_num)
|
||||
meta:set_string("infotext", S("TA3 Accu Box").." "..own_num)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:ta3_akku",
|
||||
recipe = {
|
||||
{"default:tin_ingot", "default:tin_ingot", "default:wood"},
|
||||
{"default:copper_ingot", "default:copper_ingot", "techage:electric_cableS"},
|
||||
{"techage:iron_ingot", "techage:iron_ingot", "default:wood"},
|
||||
},
|
||||
})
|
|
@ -0,0 +1,280 @@
|
|||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019-2020 Joachim Stolberg
|
||||
|
||||
GPL v3
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA3 Tiny Power Generator
|
||||
|
||||
]]--
|
||||
|
||||
-- for lazy programmers
|
||||
local M = minetest.get_meta
|
||||
local S = techage.S
|
||||
|
||||
local Power = techage.ElectricCable
|
||||
local firebox = techage.firebox
|
||||
local power = techage.power
|
||||
local fuel = techage.fuel
|
||||
local Pipe = techage.LiquidPipe
|
||||
local liquid = techage.liquid
|
||||
|
||||
local CYCLE_TIME = 2
|
||||
local PWR_CAPA = 12
|
||||
local EFFICIENCY = 2.5
|
||||
|
||||
local function formspec(self, pos, mem)
|
||||
local fuel_percent = 0
|
||||
if mem.running then
|
||||
fuel_percent = ((mem.burn_cycles or 1) * 100) / (mem.burn_cycles_total or 1)
|
||||
end
|
||||
return "size[8,6]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
fuel.formspec_fuel(1, 0, mem)..
|
||||
"button[1.6,1;1.8,1;update;"..S("Update").."]"..
|
||||
"image_button[5.5,0.5;1,1;".. self:get_state_button_image(mem) ..";state_button;]"..
|
||||
"image[6.5,0;1,2;"..power.formspec_power_bar(PWR_CAPA, mem.provided).."]"..
|
||||
"list[current_player;main;0,2.3;8,4;]"..
|
||||
default.get_hotbar_bg(0, 3)
|
||||
end
|
||||
|
||||
local function can_start(pos, mem, state)
|
||||
if mem.burn_cycles > 0 or (mem.liquid and mem.liquid.amount and mem.liquid.amount > 0) then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function start_node(pos, mem, state)
|
||||
mem.running = true
|
||||
power.generator_start(pos, mem, PWR_CAPA)
|
||||
minetest.sound_play("techage_generator", {
|
||||
pos = pos,
|
||||
gain = 1,
|
||||
max_hear_distance = 10})
|
||||
end
|
||||
|
||||
local function stop_node(pos, mem, state)
|
||||
mem.running = false
|
||||
mem.provided = 0
|
||||
power.generator_stop(pos, mem)
|
||||
end
|
||||
|
||||
local State = techage.NodeStates:new({
|
||||
node_name_passive = "techage:tiny_generator",
|
||||
node_name_active = "techage:tiny_generator_on",
|
||||
cycle_time = CYCLE_TIME,
|
||||
standby_ticks = 0,
|
||||
formspec_func = formspec,
|
||||
infotext_name = "TA3 Tiny Power Generator",
|
||||
can_start = can_start,
|
||||
start_node = start_node,
|
||||
stop_node = stop_node,
|
||||
})
|
||||
|
||||
local function burning(pos, mem)
|
||||
local ratio = math.max((mem.provided or PWR_CAPA) / PWR_CAPA, 0.02)
|
||||
|
||||
mem.liquid = mem.liquid or {}
|
||||
mem.liquid.amount = mem.liquid.amount or 0
|
||||
mem.burn_cycles = (mem.burn_cycles or 0) - ratio
|
||||
if mem.burn_cycles <= 0 then
|
||||
if mem.liquid.amount > 0 then
|
||||
mem.liquid.amount = mem.liquid.amount - 1
|
||||
mem.burn_cycles = fuel.burntime(mem.liquid.name) * EFFICIENCY / CYCLE_TIME
|
||||
mem.burn_cycles_total = mem.burn_cycles
|
||||
return true
|
||||
else
|
||||
mem.liquid.name = nil
|
||||
State:fault(pos, mem)
|
||||
return false
|
||||
end
|
||||
else
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.running and burning(pos, mem) then
|
||||
mem.provided = power.generator_alive(pos, mem)
|
||||
minetest.sound_play("techage_generator", {
|
||||
pos = pos,
|
||||
gain = 1,
|
||||
max_hear_distance = 10})
|
||||
return true
|
||||
else
|
||||
mem.provided = 0
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
State:state_button_event(pos, mem, fields)
|
||||
|
||||
M(pos):set_string("formspec", formspec(State, pos, mem))
|
||||
end
|
||||
|
||||
|
||||
local function formspec_clbk(pos, mem)
|
||||
return formspec(State, pos, mem)
|
||||
end
|
||||
|
||||
local function on_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
minetest.after(0.5, fuel.move_item, pos, stack, formspec_clbk)
|
||||
end
|
||||
|
||||
local function on_rightclick(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(State, pos, mem))
|
||||
end
|
||||
|
||||
local _liquid = {
|
||||
fuel_cat = fuel.BT_NAPHTHA,
|
||||
capa = fuel.CAPACITY,
|
||||
peek = liquid.srv_peek,
|
||||
put = function(pos, indir, name, amount)
|
||||
if fuel.valid_fuel(name, fuel.BT_NAPHTHA) then
|
||||
return liquid.srv_put(pos, indir, name, amount)
|
||||
end
|
||||
return amount
|
||||
end,
|
||||
take = liquid.srv_take,
|
||||
}
|
||||
|
||||
local _networks = {
|
||||
pipe = {
|
||||
sides = techage.networks.AllSides, -- Pipe connection sides
|
||||
ntype = "tank",
|
||||
},
|
||||
}
|
||||
|
||||
minetest.register_node("techage:tiny_generator", {
|
||||
description = S("TA3 Tiny Power Generator"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_appl_electric_gen_top.png^techage_frame_ta3_top.png",
|
||||
"techage_appl_electric_gen_top.png^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_side.png^techage_appl_hole_electric.png^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_side.png^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_front.png^[transformFX]^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_front.png^techage_frame_ta3.png",
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
|
||||
on_construct = function(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
local number = techage.add_node(pos, "techage:tiny_generator")
|
||||
mem.running = false
|
||||
mem.burn_cycles = 0
|
||||
State:node_init(pos, mem, number)
|
||||
local meta = M(pos)
|
||||
meta:set_string("formspec", formspec(State, pos, mem))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('fuel', 1)
|
||||
end,
|
||||
|
||||
|
||||
allow_metadata_inventory_put = fuel.allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = fuel.allow_metadata_inventory_take,
|
||||
on_metadata_inventory_put = on_metadata_inventory_put,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
on_timer = node_timer,
|
||||
can_dig = fuel.can_dig,
|
||||
liquid = _liquid,
|
||||
networks = _networks,
|
||||
})
|
||||
|
||||
minetest.register_node("techage:tiny_generator_on", {
|
||||
description = S("TA3 Tiny Power Generator"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_appl_electric_gen_top.png^techage_frame_ta3_top.png",
|
||||
"techage_appl_electric_gen_top.png^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_side.png^techage_appl_hole_electric.png^techage_frame_ta3.png",
|
||||
"techage_appl_electric_gen_side.png^techage_frame_ta3.png",
|
||||
{
|
||||
image = "techage_appl_electric_gen_front4.png^[transformFX]^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.8,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_appl_electric_gen_front4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.8,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
diggable = false,
|
||||
light_source = 4,
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
|
||||
allow_metadata_inventory_put = fuel.allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = fuel.allow_metadata_inventory_take,
|
||||
on_metadata_inventory_put = on_metadata_inventory_put,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
on_timer = node_timer,
|
||||
can_dig = fuel.can_dig,
|
||||
liquid = _liquid,
|
||||
networks = _networks,
|
||||
})
|
||||
|
||||
Pipe:add_secondary_node_names({"techage:tiny_generator", "techage:tiny_generator_on"})
|
||||
|
||||
techage.power.register_node({"techage:tiny_generator", "techage:tiny_generator_on"}, {
|
||||
conn_sides = {"R"},
|
||||
power_network = Power,
|
||||
})
|
||||
|
||||
techage.register_node({"techage:tiny_generator", "techage:tiny_generator_on"}, {
|
||||
on_recv_message = function(pos, src, topic, payload)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if topic == "load" then
|
||||
return power.percent(PWR_CAPA, mem.provided)
|
||||
else
|
||||
return State:on_receive_message(pos, topic, payload)
|
||||
end
|
||||
end,
|
||||
on_node_load = function(pos)
|
||||
State:on_node_load(pos)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:tiny_generator",
|
||||
recipe = {
|
||||
{'default:steel_ingot', 'techage:usmium_nuggets', 'default:steel_ingot'},
|
||||
{'dye:red', 'basic_materials:gear_steel', 'techage:electric_cableS'},
|
||||
{'default:steel_ingot', 'techage:vacuum_tube', 'default:steel_ingot'},
|
||||
},
|
||||
})
|
||||
|
Loading…
Reference in New Issue