first checkin
434
basis/command.lua
Normal file
@ -0,0 +1,434 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Basis functions for inter-node communication
|
||||
|
||||
]]--
|
||||
|
||||
--- 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
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Data base storage
|
||||
-------------------------------------------------------------------
|
||||
local storage = minetest.get_mod_storage()
|
||||
local NextNumber = minetest.deserialize(storage:get_string("NextNumber")) or 1
|
||||
local Version = minetest.deserialize(storage:get_string("Version")) or 1
|
||||
local Number2Pos = minetest.deserialize(storage:get_string("Number2Pos")) or {}
|
||||
|
||||
local function update_mod_storage()
|
||||
minetest.log("action", "[TechAge] Store data...")
|
||||
storage:set_string("NextNumber", minetest.serialize(NextNumber))
|
||||
storage:set_string("Version", minetest.serialize(Version))
|
||||
storage:set_string("Number2Pos", minetest.serialize(Number2Pos))
|
||||
storage:set_string("Key2Number", nil) -- not used any more
|
||||
-- store data each hour
|
||||
minetest.after(60*59, update_mod_storage)
|
||||
minetest.log("action", "[TechAge] Data stored")
|
||||
end
|
||||
|
||||
minetest.register_on_shutdown(function()
|
||||
update_mod_storage()
|
||||
end)
|
||||
|
||||
-- store data after one hour
|
||||
minetest.after(60*59, update_mod_storage)
|
||||
|
||||
-- Key2Number will be generated at runtine
|
||||
local Key2Number = {}
|
||||
|
||||
local Name2Name = {} -- translation table
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Local helper functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
-- Localize functions to avoid table lookups (better performance).
|
||||
local string_split = string.split
|
||||
local NodeDef = techage.NodeDef
|
||||
local Tube = techage.Tube
|
||||
|
||||
-- Determine position related node number for addressing purposes
|
||||
local function get_number(pos)
|
||||
local key = minetest.hash_node_position(pos)
|
||||
if not Key2Number[key] then
|
||||
Key2Number[key] = NextNumber
|
||||
NextNumber = NextNumber + 1
|
||||
end
|
||||
return string.format("%u", Key2Number[key])
|
||||
end
|
||||
|
||||
local function generate_Key2Number()
|
||||
local key
|
||||
for num,item in pairs(Number2Pos) do
|
||||
key = minetest.hash_node_position(item.pos)
|
||||
Key2Number[key] = num
|
||||
end
|
||||
end
|
||||
|
||||
local function not_protected(pos, placer_name, clicker_name)
|
||||
local meta = minetest.get_meta(pos)
|
||||
if meta then
|
||||
local cached_name = meta:get_string("techage_cached_name")
|
||||
if placer_name and (placer_name == cached_name or not minetest.is_protected(pos, placer_name)) then
|
||||
meta:set_string("techage_cached_name", placer_name)
|
||||
if clicker_name == nil or not minetest.is_protected(pos, clicker_name) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function register_lbm(name, nodenames)
|
||||
minetest.register_lbm({
|
||||
label = "[Tubelib] Node update",
|
||||
name = name.."update",
|
||||
nodenames = nodenames,
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
local name = Name2Name[node.name]
|
||||
if NodeDef[name] and NodeDef[name].on_node_load then
|
||||
NodeDef[name].on_node_load(pos)
|
||||
end
|
||||
end
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
local DirToSide = {"B", "R", "F", "L", "D", "U"}
|
||||
|
||||
local function dir_to_side(dir, param2)
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) - (param2 % 4)) % 4) + 1
|
||||
end
|
||||
return DirToSide[dir]
|
||||
end
|
||||
|
||||
local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6}
|
||||
|
||||
local function side_to_dir(side, param2)
|
||||
local dir = SideToDir[side]
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) + (param2 % 4)) % 4) + 1
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
local function get_dest_node(pos, side)
|
||||
-- TODO die Daten aus dem Cache holen und ueber die node callback wieder loeschen
|
||||
local _,node = Tube:get_node(pos)
|
||||
local dir = side_to_dir(side, node.param2)
|
||||
local spos, sdir = Tube:get_connected_node_pos(pos, dir)
|
||||
_,node = Tube:get_node(spos)
|
||||
local in_side = dir_to_side(sdir, node.param2)
|
||||
return spos, in_side, Name2Name[node.name] or node.name
|
||||
end
|
||||
|
||||
local function item_handling_node(name)
|
||||
local node_def = name and NodeDef[name]
|
||||
if node_def then
|
||||
return node_def.on_pull_item or node_def.on_push_item or node_def.is_pusher
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- API helper functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
-- Check the given list of numbers.
|
||||
-- Returns true if number(s) is/are valid and point to real nodes.
|
||||
function techage.check_numbers(numbers)
|
||||
if numbers then
|
||||
for _,num in ipairs(string_split(numbers, " ")) do
|
||||
if Number2Pos[num] == nil then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Function returns { pos, name } for the node on the given position number.
|
||||
function techage.get_node_info(dest_num)
|
||||
if Number2Pos[dest_num] then
|
||||
return Number2Pos[dest_num]
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Function returns the node number from the given position or
|
||||
-- nil, if no node number for this position is assigned.
|
||||
function techage.get_node_number(pos)
|
||||
local key = minetest.hash_node_position(pos)
|
||||
local num = Key2Number[key]
|
||||
if num then
|
||||
num = string.format("%u", num)
|
||||
if Number2Pos[num] and Number2Pos[num].name then
|
||||
return num
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Function is used for available nodes with lost numbers, only.
|
||||
function techage.get_new_number(pos, name)
|
||||
-- store position
|
||||
local number = get_number(pos)
|
||||
Number2Pos[number] = {
|
||||
pos = pos,
|
||||
name = name,
|
||||
}
|
||||
return number
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Node construction/destruction functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
-- Add node to the techage lists.
|
||||
-- Function determines and returns the node position number,
|
||||
-- needed for message communication.
|
||||
function techage.add_node(pos, name)
|
||||
if item_handling_node(name) then
|
||||
Tube:after_place_node(pos)
|
||||
end
|
||||
-- store position
|
||||
local number = get_number(pos)
|
||||
Number2Pos[number] = {
|
||||
pos = pos,
|
||||
name = name,
|
||||
}
|
||||
return number
|
||||
end
|
||||
|
||||
-- Function removes the node from the techage lists.
|
||||
function techage.remove_node(pos)
|
||||
local number = get_number(pos)
|
||||
local name
|
||||
if Number2Pos[number] then
|
||||
name = Number2Pos[number].name
|
||||
Number2Pos[number] = {
|
||||
pos = pos,
|
||||
name = nil,
|
||||
time = minetest.get_day_count() -- used for reservation timeout
|
||||
}
|
||||
end
|
||||
if item_handling_node(name) then
|
||||
Tube:after_dig_node(pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Node register function
|
||||
-------------------------------------------------------------------
|
||||
|
||||
-- Register node for techage communication
|
||||
-- Call this function only at load time!
|
||||
-- Param name: The node name like "techage:pusher"
|
||||
-- Param add_names: Alternativ node names if needded, e.g.: "techage:pusher_active"
|
||||
-- Param node_definition: A table according to:
|
||||
-- {
|
||||
-- on_pull_item = func(pos, side, player_name, num),
|
||||
-- on_push_item = func(pos, side, item, player_name),
|
||||
-- on_unpull_item = func(pos, side, item, player_name),
|
||||
-- on_recv_message = func(pos, topic, payload),
|
||||
-- on_node_load = func(pos), -- LBM function
|
||||
-- on_node_repair = func(pos), -- repair defect (feature!) nodes
|
||||
-- }
|
||||
function techage.register_node(name, add_names, node_definition)
|
||||
NodeDef[name] = node_definition
|
||||
-- store facedir table for all known node names
|
||||
Name2Name[name] = name
|
||||
for _,n in ipairs(add_names) do
|
||||
Name2Name[n] = name
|
||||
end
|
||||
if node_definition.on_pull_item or node_definition.on_push_item or
|
||||
node_definition.is_pusher then
|
||||
Tube:add_secondary_node_names({name})
|
||||
Tube:add_secondary_node_names(add_names)
|
||||
|
||||
techage.KnownNodes[name] = true
|
||||
for _,n in ipairs(add_names) do
|
||||
techage.KnownNodes[n] = true
|
||||
end
|
||||
end
|
||||
-- register LBM
|
||||
if node_definition.on_node_load then
|
||||
local nodenames = {name}
|
||||
for _,n in ipairs(add_names) do
|
||||
nodenames[#nodenames + 1] = n
|
||||
end
|
||||
register_lbm(name, nodenames)
|
||||
end
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Send message functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
function techage.send_message(numbers, placer_name, clicker_name, topic, payload)
|
||||
for _,num in ipairs(string_split(numbers, " ")) do
|
||||
if Number2Pos[num] and Number2Pos[num].name then
|
||||
local data = Number2Pos[num]
|
||||
if not_protected(data.pos, placer_name, clicker_name) then
|
||||
if NodeDef[data.name] and NodeDef[data.name].on_recv_message then
|
||||
NodeDef[data.name].on_recv_message(data.pos, topic, payload)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function techage.send_request(number, topic, payload)
|
||||
if Number2Pos[number] and Number2Pos[number].name then
|
||||
local data = Number2Pos[number]
|
||||
if NodeDef[data.name] and NodeDef[data.name].on_recv_message then
|
||||
return NodeDef[data.name].on_recv_message(data.pos, topic, payload)
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- for defect nodes
|
||||
function techage.repair_node(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
local name = Name2Name[node.name]
|
||||
if NodeDef[name] and NodeDef[name].on_node_repair then
|
||||
return NodeDef[name].on_node_repair(pos)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Client side Push/Pull item functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
function techage.pull_items(pos, side, num)
|
||||
local npos, nside, name = get_dest_node(pos, side)
|
||||
if npos == nil then return end
|
||||
if NodeDef[name] and NodeDef[name].on_pull_item then
|
||||
return NodeDef[name].on_pull_item(npos, nside, num)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function techage.push_items(pos, side, stack)
|
||||
local npos, nside, name = get_dest_node(pos, side)
|
||||
if npos == nil then return end
|
||||
if NodeDef[name] and NodeDef[name].on_push_item then
|
||||
return NodeDef[name].on_push_item(npos, nside, stack)
|
||||
elseif name == "air" then
|
||||
minetest.add_item(npos, stack)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function techage.unpull_items(pos, side, items)
|
||||
local npos, nside, name = get_dest_node(pos, side)
|
||||
if npos == nil then return end
|
||||
if NodeDef[name] and NodeDef[name].on_unpull_item then
|
||||
return NodeDef[name].on_unpull_item(npos, nside, items)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- Server side helper functions
|
||||
-------------------------------------------------------------------
|
||||
|
||||
-- Get the given number of items from the inve. The position within the list
|
||||
-- is random so that different item stacks will be considered.
|
||||
-- Returns nil if ItemList is empty.
|
||||
function techage.get_items(inv, listname, num)
|
||||
if inv:is_empty(listname) then
|
||||
return nil
|
||||
end
|
||||
local size = inv:get_size(listname)
|
||||
local startpos = math.random(1, size)
|
||||
for idx = startpos, startpos+size do
|
||||
idx = (idx % size) + 1
|
||||
local items = inv:get_stack(listname, idx)
|
||||
if items:get_count() > 0 then
|
||||
local taken = items:take_item(num)
|
||||
inv:set_stack(listname, idx, items)
|
||||
return taken
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Put the given stack into the given ItemList.
|
||||
-- Function returns false if ItemList is full.
|
||||
function techage.put_item(inv, listname, stack)
|
||||
if inv:room_for_item(listname, stack) then
|
||||
inv:add_item(listname, stack)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
|
||||
-- Return "full", "loaded", or "empty" depending
|
||||
-- on the inventory load.
|
||||
-- Full is returned, when no empty stack is available.
|
||||
function techage.get_inv_state(inv, listname)
|
||||
local state
|
||||
if inv:is_empty(listname) then
|
||||
state = "empty"
|
||||
else
|
||||
local list = inv:get_list(listname)
|
||||
state = "full"
|
||||
for _, item in ipairs(list) do
|
||||
if item:is_empty() then
|
||||
return "loaded"
|
||||
end
|
||||
end
|
||||
end
|
||||
return state
|
||||
end
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
-- Data Maintenance
|
||||
-------------------------------------------------------------------------------
|
||||
local function data_maintenance()
|
||||
minetest.log("info", "[TechAge] Data maintenance started")
|
||||
-- Remove old unused positions
|
||||
local Tbl = table.copy(Number2Pos)
|
||||
Number2Pos = {}
|
||||
local day_cnt = minetest.get_day_count()
|
||||
for num,item in pairs(Tbl) do
|
||||
if item.name then
|
||||
Number2Pos[num] = item
|
||||
-- data not older than 5 real days
|
||||
elseif item.time and (item.time + (72*5)) > day_cnt then
|
||||
Number2Pos[num] = item
|
||||
else
|
||||
minetest.log("info", "Position deleted", num)
|
||||
end
|
||||
end
|
||||
minetest.log("info", "[TechAge] Data maintenance finished")
|
||||
end
|
||||
|
||||
generate_Key2Number()
|
||||
|
||||
-- maintain data after 5 seconds
|
||||
-- (minetest.get_day_count() will not be valid at start time)
|
||||
minetest.after(5, data_maintenance)
|
||||
|
||||
|
45
basis/intllib.lua
Normal file
@ -0,0 +1,45 @@
|
||||
|
||||
-- Fallback functions for when `intllib` is not installed.
|
||||
-- Code released under Unlicense <http://unlicense.org>.
|
||||
|
||||
-- Get the latest version of this file at:
|
||||
-- https://raw.githubusercontent.com/minetest-mods/intllib/master/lib/intllib.lua
|
||||
|
||||
local function format(str, ...)
|
||||
local args = { ... }
|
||||
local function repl(escape, open, num, close)
|
||||
if escape == "" then
|
||||
local replacement = tostring(args[tonumber(num)])
|
||||
if open == "" then
|
||||
replacement = replacement..close
|
||||
end
|
||||
return replacement
|
||||
else
|
||||
return "@"..open..num..close
|
||||
end
|
||||
end
|
||||
return (str:gsub("(@?)@(%(?)(%d+)(%)?)", repl))
|
||||
end
|
||||
|
||||
local gettext, ngettext
|
||||
if minetest.get_modpath("intllib") then
|
||||
if intllib.make_gettext_pair then
|
||||
-- New method using gettext.
|
||||
gettext, ngettext = intllib.make_gettext_pair()
|
||||
else
|
||||
-- Old method using text files.
|
||||
gettext = intllib.Getter()
|
||||
end
|
||||
end
|
||||
|
||||
-- Fill in missing functions.
|
||||
|
||||
gettext = gettext or function(msgid, ...)
|
||||
return format(msgid, ...)
|
||||
end
|
||||
|
||||
ngettext = ngettext or function(msgid, msgid_plural, n, ...)
|
||||
return format(n==1 and msgid or msgid_plural, ...)
|
||||
end
|
||||
|
||||
return gettext, ngettext
|
79
basis/junction.lua
Normal file
@ -0,0 +1,79 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Junction for power distribution
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
local function bit(p)
|
||||
return 2 ^ (p - 1) -- 1-based indexing
|
||||
end
|
||||
|
||||
-- Typical call: if hasbit(x, bit(3)) then ...
|
||||
local function hasbit(x, p)
|
||||
return x % (p + p) >= p
|
||||
end
|
||||
|
||||
local function setbit(x, p)
|
||||
return hasbit(x, p) and x or x + p
|
||||
end
|
||||
|
||||
local function get_node_box(val, size, boxes)
|
||||
local fixed = {{-size, -size, -size, size, size, size}}
|
||||
for i = 1,6 do
|
||||
if hasbit(val, bit(i)) then
|
||||
for _,box in ipairs(boxes[i]) do
|
||||
table.insert(fixed, box)
|
||||
end
|
||||
end
|
||||
end
|
||||
return {
|
||||
type = "fixed",
|
||||
fixed = fixed,
|
||||
}
|
||||
end
|
||||
|
||||
-- 'size' is the size of the junction cube without any connection, e.g. 1/8
|
||||
-- 'boxes' is a table with 6 table elements for the 6 possible connection arms
|
||||
-- 'network' is the tubelib2 instance
|
||||
-- 'node' is the node definition with tiles, callback functions, and so on
|
||||
function techage.register_junction(name, size, boxes, network, node)
|
||||
for idx = 0,63 do
|
||||
node.groups.techage_trowel = 1
|
||||
node.groups.not_in_creative_inventory = idx
|
||||
node.drawtype = "nodebox"
|
||||
node.node_box = get_node_box(idx, size, boxes)
|
||||
node.paramtype2 = "facedir" -- important!
|
||||
node.on_rotate = screwdriver.disallow -- important!
|
||||
node.paramtype = "light"
|
||||
node.sunlight_propagates = true
|
||||
node.is_ground_content = false
|
||||
node.drop = name.."0"
|
||||
|
||||
minetest.register_node(name..idx, table.copy(node))
|
||||
network:add_secondary_node_names({name..idx})
|
||||
end
|
||||
end
|
||||
|
||||
function techage.junction_type(conn)
|
||||
local val = 0
|
||||
for idx = 1,6 do
|
||||
if conn[idx] then
|
||||
val = setbit(val, bit(idx))
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
496
basis/node_states.lua
Normal file
@ -0,0 +1,496 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
A state model/class for TechAge nodes.
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
--[[
|
||||
|
||||
Node states:
|
||||
|
||||
+-----------------------------------+ +------------+
|
||||
| | | |
|
||||
| V V |
|
||||
| +---------+ |
|
||||
| | | |
|
||||
| +---------| STOPPED | |
|
||||
| | | | |
|
||||
| button | +---------+ |
|
||||
| | ^ |
|
||||
repair | V | button |
|
||||
| +---------+ | | button
|
||||
| | |---------+ |
|
||||
| | RUNNING | |
|
||||
| +--------| |---------+ |
|
||||
| | +---------+ | |
|
||||
| | ^ | | |
|
||||
| | | | | |
|
||||
| V | V V |
|
||||
| +---------+ +----------+ +---------+ |
|
||||
| | | | | | | |
|
||||
+---| DEFECT | | STANDBY/ | | FAULT |----------+
|
||||
| | | BLOCKED | | |
|
||||
+---------+ +----------+ +---------+
|
||||
|
||||
Node metadata:
|
||||
"tubelib_number" - string with tubelib number, like "123"
|
||||
"tubelib_state" - node state, like "RUNNING"
|
||||
"tubelib_item_meter" - node item/runtime counter
|
||||
"tubelib_countdown" - countdown to stadby mode
|
||||
"tubelib_aging" - aging counter
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
|
||||
--
|
||||
-- TechAge machine states
|
||||
--
|
||||
|
||||
techage.STOPPED = 1 -- not operational/turned off
|
||||
techage.RUNNING = 2 -- in normal operation/turned on
|
||||
techage.STANDBY = 3 -- nothing to do (e.g. no input items), or blocked anyhow (output jammed),
|
||||
-- or node (world) not loaded
|
||||
techage.FAULT = 4 -- any fault state (e.g. no fuel), which can be fixed by the player
|
||||
techage.BLOCKED = 5 -- a pushing node is blocked due to a full destination inventory
|
||||
techage.DEFECT = 6 -- a defect (broken), which has to be repaired by the player
|
||||
|
||||
techage.StatesImg = {
|
||||
"tubelib_inv_button_off.png",
|
||||
"tubelib_inv_button_on.png",
|
||||
"tubelib_inv_button_standby.png",
|
||||
"tubelib_inv_button_error.png",
|
||||
"tubelib_inv_button_warning.png",
|
||||
"tubelib_inv_button_off.png",
|
||||
}
|
||||
|
||||
-- Return state button image for the node inventory
|
||||
function techage.state_button(state)
|
||||
if state and state < 7 and state > 0 then
|
||||
return techage.StatesImg[state]
|
||||
end
|
||||
return "tubelib_inv_button_off.png"
|
||||
end
|
||||
|
||||
-- State string based on button states
|
||||
techage.StateStrings = {"stopped", "running", "standby", "fault", "blocked", "defect"}
|
||||
|
||||
--
|
||||
-- Local States
|
||||
--
|
||||
local STOPPED = techage.STOPPED
|
||||
local RUNNING = techage.RUNNING
|
||||
local STANDBY = techage.STANDBY
|
||||
local FAULT = techage.FAULT
|
||||
local BLOCKED = techage.BLOCKED
|
||||
local DEFECT = techage.DEFECT
|
||||
|
||||
|
||||
local AGING_FACTOR = 4 -- defect random factor
|
||||
|
||||
--
|
||||
-- NodeStates Class Functions
|
||||
--
|
||||
techage.NodeStates = {}
|
||||
local NodeStates = techage.NodeStates
|
||||
|
||||
local function start_condition_fullfilled(pos, meta)
|
||||
return true
|
||||
end
|
||||
|
||||
function NodeStates:new(attr)
|
||||
local o = {
|
||||
-- mandatory
|
||||
cycle_time = attr.cycle_time, -- for running state
|
||||
standby_ticks = attr.standby_ticks, -- for standby state
|
||||
has_item_meter = attr.has_item_meter, -- true/false
|
||||
-- optional
|
||||
node_name_passive = attr.node_name_passive,
|
||||
node_name_active = attr.node_name_active,
|
||||
node_name_defect = attr.node_name_defect,
|
||||
infotext_name = attr.infotext_name,
|
||||
start_condition_fullfilled = attr.start_condition_fullfilled or start_condition_fullfilled,
|
||||
on_start = attr.on_start,
|
||||
on_stop = attr.on_stop,
|
||||
formspec_func = attr.formspec_func,
|
||||
}
|
||||
if attr.aging_factor then
|
||||
o.aging_level1 = attr.aging_factor * techage.machine_aging_value
|
||||
o.aging_level2 = attr.aging_factor * techage.machine_aging_value * AGING_FACTOR
|
||||
end
|
||||
setmetatable(o, self)
|
||||
self.__index = self
|
||||
return o
|
||||
end
|
||||
|
||||
function NodeStates:node_init(pos, number)
|
||||
local meta = M(pos)
|
||||
meta:set_int("tubelib_state", STOPPED)
|
||||
meta:set_string("tubelib_number", number)
|
||||
if self.infotext_name then
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": stopped")
|
||||
end
|
||||
if self.has_item_meter then
|
||||
meta:set_int("tubelib_item_meter", 0)
|
||||
end
|
||||
if self.aging_level1 then
|
||||
meta:set_int("tubelib_aging", 0)
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
end
|
||||
|
||||
function NodeStates:stop(pos, meta)
|
||||
local state = meta:get_int("tubelib_state")
|
||||
if state ~= DEFECT then
|
||||
if self.on_stop then
|
||||
self.on_stop(pos, meta, state)
|
||||
end
|
||||
meta:set_int("tubelib_state", STOPPED)
|
||||
if self.node_name_passive then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_passive
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": stopped")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):stop()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NodeStates:start(pos, meta, called_from_on_timer)
|
||||
local state = meta:get_int("tubelib_state")
|
||||
if state == STOPPED or state == STANDBY or state == BLOCKED then
|
||||
if not self.start_condition_fullfilled(pos, meta) then
|
||||
return false
|
||||
end
|
||||
if self.on_start then
|
||||
self.on_start(pos, meta, state)
|
||||
end
|
||||
meta:set_int("tubelib_state", RUNNING)
|
||||
meta:set_int("tubelib_countdown", 4)
|
||||
if called_from_on_timer then
|
||||
-- timer has to be stopped once to be able to be restarted
|
||||
self.stop_timer = true
|
||||
end
|
||||
if self.node_name_active then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_active
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": running")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):start(self.cycle_time)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NodeStates:standby(pos, meta)
|
||||
if meta:get_int("tubelib_state") == RUNNING then
|
||||
meta:set_int("tubelib_state", STANDBY)
|
||||
-- timer has to be stopped once to be able to be restarted
|
||||
self.stop_timer = true
|
||||
if self.node_name_passive then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_passive
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": standby")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- special case of standby for pushing nodes
|
||||
function NodeStates:blocked(pos, meta)
|
||||
if meta:get_int("tubelib_state") == RUNNING then
|
||||
meta:set_int("tubelib_state", BLOCKED)
|
||||
-- timer has to be stopped once to be able to be restarted
|
||||
self.stop_timer = true
|
||||
if self.node_name_passive then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_passive
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": blocked")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NodeStates:fault(pos, meta)
|
||||
if meta:get_int("tubelib_state") == RUNNING then
|
||||
meta:set_int("tubelib_state", FAULT)
|
||||
if self.node_name_passive then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_passive
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": fault")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):stop()
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NodeStates:defect(pos, meta)
|
||||
meta:set_int("tubelib_state", DEFECT)
|
||||
if self.node_name_defect then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_defect
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": defect")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
minetest.get_node_timer(pos):stop()
|
||||
return true
|
||||
end
|
||||
|
||||
function NodeStates:get_state(meta)
|
||||
return meta:get_int("tubelib_state")
|
||||
end
|
||||
|
||||
function NodeStates:get_state_string(meta)
|
||||
return techage.StateStrings[meta:get_int("tubelib_state")]
|
||||
end
|
||||
|
||||
function NodeStates:is_active(meta)
|
||||
local state = meta:get_int("tubelib_state")
|
||||
if self.stop_timer == true then
|
||||
self.stop_timer = false
|
||||
return false
|
||||
end
|
||||
return state == RUNNING or state == STANDBY or state == BLOCKED
|
||||
end
|
||||
|
||||
-- To be called if node is idle.
|
||||
-- If countdown reaches zero, the node is set to STANDBY.
|
||||
function NodeStates:idle(pos, meta)
|
||||
local countdown = meta:get_int("tubelib_countdown") - 1
|
||||
meta:set_int("tubelib_countdown", countdown)
|
||||
if countdown < 0 then
|
||||
self:standby(pos, meta)
|
||||
end
|
||||
end
|
||||
|
||||
-- To be called after successful node action to raise the timer
|
||||
-- and keep the node in state RUNNING
|
||||
function NodeStates:keep_running(pos, meta, val, num_items)
|
||||
num_items = num_items or 1
|
||||
-- set to RUNNING if not already done
|
||||
self:start(pos, meta, true)
|
||||
meta:set_int("tubelib_countdown", val)
|
||||
meta:set_int("tubelib_item_meter", meta:get_int("tubelib_item_meter") + (num_items or 1))
|
||||
if self.aging_level1 then
|
||||
local cnt = meta:get_int("tubelib_aging") + num_items
|
||||
meta:set_int("tubelib_aging", cnt)
|
||||
if (cnt > (self.aging_level1) and math.random(self.aging_level2/num_items) == 1)
|
||||
or cnt >= 999999 then
|
||||
self:defect(pos, meta)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Start/stop node based on button events.
|
||||
-- if function returns false, no button was pressed
|
||||
function NodeStates:state_button_event(pos, fields)
|
||||
if fields.state_button ~= nil then
|
||||
local state = self:get_state(M(pos))
|
||||
if state == STOPPED or state == STANDBY or state == BLOCKED then
|
||||
self:start(pos, M(pos))
|
||||
elseif state == RUNNING or state == FAULT then
|
||||
self:stop(pos, M(pos))
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function NodeStates:get_state_button_image(meta)
|
||||
local state = meta:get_int("tubelib_state")
|
||||
return techage.state_button(state)
|
||||
end
|
||||
|
||||
-- command interface
|
||||
function NodeStates:on_receive_message(pos, topic, payload)
|
||||
if topic == "on" then
|
||||
self:start(pos, M(pos))
|
||||
return true
|
||||
elseif topic == "off" then
|
||||
self:stop(pos, M(pos))
|
||||
return true
|
||||
elseif topic == "state" then
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == "ignore" then -- unloaded node?
|
||||
return "blocked"
|
||||
end
|
||||
return self:get_state_string(M(pos))
|
||||
elseif self.has_item_meter and topic == "counter" then
|
||||
return M(pos):get_int("tubelib_item_meter")
|
||||
elseif self.has_item_meter and topic == "clear_counter" then
|
||||
M(pos):set_int("tubelib_item_meter", 0)
|
||||
return true
|
||||
elseif self.aging_level1 and topic == "aging" then
|
||||
return M(pos):get_int("tubelib_aging")
|
||||
end
|
||||
end
|
||||
|
||||
-- repair corrupt node data and/or migrate node to state2
|
||||
function NodeStates:on_node_load(pos, not_start_timer)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
||||
-- legacy node number/state/counter?
|
||||
local number = meta:get_string("number")
|
||||
if number ~= "" and number ~= nil then
|
||||
meta:set_string("tubelib_number", number)
|
||||
meta:set_int("tubelib_state", techage.state(meta:get_int("running")))
|
||||
if self.has_item_meter then
|
||||
meta:set_int("tubelib_item_meter", meta:get_int("counter"))
|
||||
end
|
||||
if self.aging_level1 then
|
||||
meta:set_int("tubelib_aging", 0)
|
||||
end
|
||||
meta:set_string("number", nil)
|
||||
meta:set_int("running", 0)
|
||||
meta:set_int("counter", 0)
|
||||
end
|
||||
|
||||
-- node number corrupt?
|
||||
number = meta:get_string("tubelib_number")
|
||||
if number == "" then
|
||||
number = techage.get_new_number(pos, self.node_name_passive)
|
||||
meta:set_string("tubelib_number", number)
|
||||
else
|
||||
local info = techage.get_node_info(number)
|
||||
if not info or info.pos ~= pos then
|
||||
number = techage.get_new_number(pos, self.node_name_passive)
|
||||
meta:set_string("tubelib_number", number)
|
||||
end
|
||||
end
|
||||
|
||||
-- state corrupt?
|
||||
local state = meta:get_int("tubelib_state")
|
||||
if state == 0 then
|
||||
if minetest.get_node_timer(pos):is_started() then
|
||||
meta:set_int("tubelib_state", RUNNING)
|
||||
else
|
||||
meta:set_int("tubelib_state", STOPPED)
|
||||
end
|
||||
elseif state == RUNNING and not not_start_timer then
|
||||
minetest.get_node_timer(pos):start(self.cycle_time)
|
||||
elseif state == STANDBY then
|
||||
minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks)
|
||||
elseif state == BLOCKED then
|
||||
minetest.get_node_timer(pos):start(self.cycle_time * self.standby_ticks)
|
||||
end
|
||||
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
end
|
||||
|
||||
-- Repair of defect (feature!) nodes
|
||||
function NodeStates:on_node_repair(pos)
|
||||
local meta = M(pos)
|
||||
if meta:get_int("tubelib_state") == DEFECT then
|
||||
meta:set_int("tubelib_state", STOPPED)
|
||||
if self.node_name_passive then
|
||||
local node = minetest.get_node(pos)
|
||||
node.name = self.node_name_passive
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
if self.aging_level1 then
|
||||
meta:set_int("tubelib_aging", 0)
|
||||
end
|
||||
if self.infotext_name then
|
||||
local number = meta:get_string("tubelib_number")
|
||||
meta:set_string("infotext", self.infotext_name.." "..number..": stopped")
|
||||
end
|
||||
if self.formspec_func then
|
||||
meta:set_string("formspec", self.formspec_func(self, pos, meta))
|
||||
end
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Return working or defect machine, depending on machine lifetime
|
||||
function NodeStates:after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
local inv = minetest.get_inventory({type="player", name=digger:get_player_name()})
|
||||
local cnt = oldmetadata.fields.tubelib_aging and tonumber(oldmetadata.fields.tubelib_aging) or 0
|
||||
local is_defect = cnt > self.aging_level1 and math.random(self.aging_level2 / cnt) == 1
|
||||
if self.node_name_defect and is_defect then
|
||||
inv:add_item("main", ItemStack(self.node_name_defect))
|
||||
else
|
||||
inv:add_item("main", ItemStack(self.node_name_passive))
|
||||
end
|
||||
end
|
||||
|
||||
-- Return "full", "loaded", or "empty" depending
|
||||
-- on the number of fuel stack items.
|
||||
-- Function only works on fuel inventories with one stacks/99 items
|
||||
function techage.fuelstate(meta, listname, item)
|
||||
if meta == nil or meta.get_inventory == nil then return nil end
|
||||
local inv = meta:get_inventory()
|
||||
if inv:is_empty(listname) then
|
||||
return "empty"
|
||||
end
|
||||
local list = inv:get_list(listname)
|
||||
if #list == 1 and list[1]:get_count() == 99 then
|
||||
return "full"
|
||||
else
|
||||
return "loaded"
|
||||
end
|
||||
end
|
||||
|
244
basis/power.lua
Normal file
@ -0,0 +1,244 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Power consumption for any kind of power distribution network
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
local TP = function(pos) return minetest.registered_nodes[minetest.get_node(pos).name].techage end
|
||||
local TN = function(node) return minetest.registered_nodes[node.name].techage end
|
||||
|
||||
|
||||
-- Table to register the different power distribution network instances for global use
|
||||
techage.Networks = {}
|
||||
|
||||
-- Used to determine the already passed nodes while power distribution
|
||||
local Route = {}
|
||||
|
||||
local function pos_already_reached(pos)
|
||||
local key = minetest.hash_node_position(pos)
|
||||
if not Route[key] then
|
||||
Route[key] = true
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local DirToSide = {"B", "R", "F", "L", "D", "U"}
|
||||
|
||||
local function dir_to_side(pos, dir)
|
||||
local node = minetest.get_node(pos)
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) - (node.param2 % 4)) % 4) + 1
|
||||
end
|
||||
return DirToSide[dir]
|
||||
end
|
||||
|
||||
local SideToDir = {B=1, R=2, F=3, L=4, D=5, U=6}
|
||||
|
||||
local function side_to_dir(pos, side)
|
||||
local node = minetest.get_node(pos)
|
||||
local dir = SideToDir[side]
|
||||
if dir < 5 then
|
||||
dir = (((dir - 1) + (node.param2 % 4)) % 4) + 1
|
||||
end
|
||||
return dir
|
||||
end
|
||||
|
||||
-- Calculate the power consumption on the given network
|
||||
local function power_consumption(pos, dir)
|
||||
if pos_already_reached(pos) then return 0 end
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
local conn = mem.connections or {}
|
||||
local val = 0
|
||||
for fdir,fpos in pairs(conn) do
|
||||
if fdir ~= tubelib2.Turn180Deg[dir or 0] then
|
||||
local this = TP(fpos)
|
||||
if this and this.power_consumption then
|
||||
val = val + this.power_consumption(fpos, fdir)
|
||||
else
|
||||
val = val + power_consumption(fpos, fdir)
|
||||
end
|
||||
end
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
local function turn_tube_on(pos, dir, network, on)
|
||||
if network.switch_tube_line then
|
||||
if on then
|
||||
network:switch_tube_line(pos, dir, "on")
|
||||
else
|
||||
network:switch_tube_line(pos, dir, "off")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function turn_on(pos, dir, on)
|
||||
if pos_already_reached(pos) then return end
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
local conn = mem.connections or {}
|
||||
for fdir,fpos in pairs(conn) do
|
||||
if fdir ~= tubelib2.Turn180Deg[dir or 0] then
|
||||
local this = TP(fpos)
|
||||
if this and this.turn_on then
|
||||
this.turn_on(fpos, fdir, on)
|
||||
end
|
||||
if this and this.network then
|
||||
turn_tube_on(pos, fdir, this.network, on)
|
||||
end
|
||||
turn_on(fpos, fdir, on)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- power source: power > 0
|
||||
-- power sink: power < 0
|
||||
-- switched off: power = 0
|
||||
local function sink_power_consumption(pos, power)
|
||||
Route = {}
|
||||
local sum = power + power_consumption(pos)
|
||||
Route = {}
|
||||
turn_on(pos, nil, sum > 0)
|
||||
return sum
|
||||
end
|
||||
|
||||
-- To be called from any generator
|
||||
local function source_power_consumption(pos, mem)
|
||||
local power = mem.power_produce or 0
|
||||
mem.power_result = sink_power_consumption(pos, power)
|
||||
return mem.power_result > 0
|
||||
end
|
||||
|
||||
techage.sink_power_consumption = sink_power_consumption
|
||||
techage.source_power_consumption = source_power_consumption
|
||||
|
||||
|
||||
--
|
||||
-- Generator with on power output side
|
||||
--
|
||||
function techage.generator_on(pos, power, network)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.power_produce = power
|
||||
return source_power_consumption(pos, mem)
|
||||
end
|
||||
|
||||
function techage.generator_off(pos, network)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.power_produce = 0
|
||||
return source_power_consumption(pos, mem)
|
||||
end
|
||||
|
||||
function techage.generator_power_consumption(pos, dir)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if dir == tubelib2.Turn180Deg[mem.power_dir or 0] then
|
||||
return mem.power_produce
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function techage.generator_after_place_node(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
mem.power_dir = side_to_dir(pos, TP(pos).side or 'R')
|
||||
mem.power_produce = 0 -- will be set via generator_on
|
||||
mem.power_result = 0
|
||||
local network = TP(pos).network
|
||||
network:after_place_node(pos)
|
||||
end
|
||||
|
||||
function techage.generator_after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
-- check if contact side is correct
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if out_dir == mem.power_dir then
|
||||
-- store connection for 'source_power_consumption()'
|
||||
mem.connections = {[out_dir] = peer_pos}
|
||||
source_power_consumption(pos, mem)
|
||||
end
|
||||
end
|
||||
|
||||
function techage.generator_on_destruct(pos)
|
||||
techage.generator_off(pos)
|
||||
end
|
||||
|
||||
function techage.generator_after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
TN(oldnode).network:after_dig_node(pos)
|
||||
tubelib2.del_mem(pos)
|
||||
end
|
||||
|
||||
function techage.generator_formspec_level(mem)
|
||||
print("generator_formspec_level", mem.power_result, mem.power_produce)
|
||||
local percent = ((mem.power_result or 0) * 100) / (mem.power_produce or 1)
|
||||
return "techage_form_level_bg.png^[lowpart:"..percent..":techage_form_level_fg.png]"
|
||||
end
|
||||
|
||||
|
||||
--
|
||||
-- Distributor with 6 power input/output sides
|
||||
--
|
||||
function techage.distributor_power_consumption(pos, dir)
|
||||
return power_consumption(pos, dir) - TP(pos).power_consume
|
||||
end
|
||||
|
||||
function techage.distributor_after_place_node(pos, placer)
|
||||
local this = TP(pos)
|
||||
this.network:after_place_node(pos)
|
||||
sink_power_consumption(pos, -this.power_consume)
|
||||
end
|
||||
|
||||
function techage.distributor_after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
mem.connections[out_dir] = peer_pos
|
||||
local sum = sink_power_consumption(pos, -TP(pos).power_consume)
|
||||
end
|
||||
|
||||
function techage.distributor_on_destruct(pos)
|
||||
sink_power_consumption(pos, -TP(pos).power_consume)
|
||||
end
|
||||
|
||||
function techage.distributor_after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
TN(oldnode).network:after_dig_node(pos)
|
||||
tubelib2.del_mem(pos)
|
||||
end
|
||||
|
||||
--
|
||||
-- Consumer with on power input side (default)
|
||||
--
|
||||
function techage.consumer_power_consumption(pos)
|
||||
return -TP(pos).power_consume
|
||||
end
|
||||
|
||||
function techage.consumer_after_place_node(pos, placer)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
mem.power_dir = tubelib2.Turn180Deg[side_to_dir(pos, TP(pos).side or 'L')]
|
||||
local this = TP(pos)
|
||||
this.network:after_place_node(pos)
|
||||
sink_power_consumption(pos, -this.power_consume)
|
||||
end
|
||||
|
||||
function techage.consumer_after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
mem.connections[out_dir] = peer_pos
|
||||
sink_power_consumption(pos, -TP(pos).power_consume)
|
||||
end
|
||||
|
||||
function techage.consumer_on_destruct(pos)
|
||||
sink_power_consumption(pos, -TP(pos).power_consume)
|
||||
end
|
||||
|
||||
function techage.consumer_after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
TN(oldnode).network:after_dig_node(pos)
|
||||
tubelib2.del_mem(pos)
|
||||
end
|
112
basis/trowel.lua
Normal file
@ -0,0 +1,112 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Trowel tool to hide/open cable/pipe/tube nodes
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
-- Overridden method of tubelib2!
|
||||
function techage.get_primary_node_param2(pos, dir)
|
||||
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
|
||||
local param2 = M(npos):get_int("tl2_param2")
|
||||
if param2 ~= 0 then
|
||||
return param2, npos
|
||||
end
|
||||
end
|
||||
|
||||
-- Overridden method of tubelib2!
|
||||
function techage.is_primary_node(pos, dir)
|
||||
local npos = vector.add(pos, tubelib2.Dir6dToVector[dir or 0])
|
||||
local param2 = M(npos):get_int("tl2_param2")
|
||||
return param2 ~= 0
|
||||
end
|
||||
|
||||
-- Determine if one node in the surrounding is a hidden tube/cable/pipe
|
||||
local function other_hidden_nodes(pos, node_name)
|
||||
return M({x=pos.x+1, y=pos.y, z=pos.z}):get_string(node_name) ~= "" or
|
||||
M({x=pos.x-1, y=pos.y, z=pos.z}):get_string(node_name) ~= "" or
|
||||
M({x=pos.x, y=pos.y+1, z=pos.z}):get_string(node_name) ~= "" or
|
||||
M({x=pos.x, y=pos.y-1, z=pos.z}):get_string(node_name) ~= "" or
|
||||
M({x=pos.x, y=pos.y, z=pos.z+1}):get_string(node_name) ~= "" or
|
||||
M({x=pos.x, y=pos.y, z=pos.z-1}):get_string(node_name) ~= ""
|
||||
end
|
||||
|
||||
local function hide_node(pos, node, meta, placer)
|
||||
local inv = placer:get_inventory()
|
||||
local stack = inv:get_stack("main", 1)
|
||||
local taken = stack:take_item(1)
|
||||
-- test if it is a simple node without logic
|
||||
if taken:get_count() == 1
|
||||
and minetest.registered_nodes[taken:get_name()]
|
||||
and not minetest.registered_nodes[taken:get_name()].after_place_node
|
||||
and not minetest.registered_nodes[taken:get_name()].on_construct then
|
||||
meta:set_string("techage_hidden_nodename", node.name)
|
||||
meta:set_string("techage_hidden_param2", node.param2)
|
||||
local param2 = minetest.dir_to_facedir(placer:get_look_dir(), true)
|
||||
minetest.swap_node(pos, {name = taken:get_name(), param2 = param2})
|
||||
inv:set_stack("main", 1, stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function open_node(pos, node, meta, placer)
|
||||
local name = meta:get_string("techage_hidden_nodename")
|
||||
local param2 = meta:get_string("techage_hidden_param2")
|
||||
minetest.swap_node(pos, {name = name, param2 = param2})
|
||||
meta:set_string("techage_hidden_nodename", "")
|
||||
meta:set_string("techage_hidden_param2", "")
|
||||
local inv = placer:get_inventory()
|
||||
inv:add_item("main", ItemStack(node.name))
|
||||
end
|
||||
|
||||
-- Hide or open a node
|
||||
local function replace_node(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
local pos = pointed_thing.under
|
||||
local meta = M(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_item_group(node.name, "techage_trowel") == 1 then
|
||||
hide_node(pos, node, meta, placer)
|
||||
elseif meta:get_string("techage_hidden_nodename") ~= "" then
|
||||
open_node(pos, node, meta, placer)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:trowel", {
|
||||
description = I("TechAge Trowel (uses items from the first, left inventory stack)"),
|
||||
inventory_image = "techage_trowel.png",
|
||||
wield_image = "techage_trowel.png",
|
||||
use_texture_alpha = true,
|
||||
groups = {cracky=1},
|
||||
on_use = replace_node,
|
||||
on_place = replace_node,
|
||||
node_placement_prediction = "",
|
||||
stack_max = 1,
|
||||
})
|
||||
|
||||
minetest.register_on_dignode(function(pos, oldnode, digger)
|
||||
-- If hidden nodes are arround, the removed one was probably
|
||||
-- a hidden node, too.
|
||||
if other_hidden_nodes(pos, "techage_hidden_nodename") then
|
||||
-- test both hidden networks
|
||||
techage.ElectricCable:after_dig_node("techage_hidden_nodename")
|
||||
techage.BiogasPipe:after_dig_node("techage_hidden_nodename")
|
||||
end
|
||||
end)
|
132
basis/tubes.lua
Normal file
@ -0,0 +1,132 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Tubes based on tubelib2
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
|
||||
-- used for registered nodes
|
||||
techage.KnownNodes = {
|
||||
["techage:tubeS"] = true,
|
||||
["techage:tubeA"] = true,
|
||||
}
|
||||
|
||||
|
||||
local Tube = tubelib2.Tube:new({
|
||||
-- North, East, South, West, Down, Up
|
||||
dirs_to_check = {1,2,3,4,5,6},
|
||||
max_tube_length = 200,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"techage:tubeS", "techage:tubeA"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
|
||||
minetest.swap_node(pos, {name = "techage:tube"..tube_type, param2 = param2})
|
||||
end,
|
||||
})
|
||||
|
||||
techage.Tube = Tube
|
||||
|
||||
minetest.register_node("techage:tubeS", {
|
||||
description = "TechAge Tube",
|
||||
tiles = { -- Top, base, right, left, front, back
|
||||
"techage_tube.png^[transformR90",
|
||||
"techage_tube.png^[transformR90",
|
||||
"techage_tube.png",
|
||||
"techage_tube.png",
|
||||
"techage_hole.png",
|
||||
"techage_hole.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Tube:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-2/8, -2/8, -4/8, 2/8, 2/8, 4/8},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 },
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/4, -1/4, -1/2, 1/4, 1/4, 1/2 },
|
||||
},
|
||||
on_rotate = screwdriver.disallow,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {choppy=2, cracky=3, stone=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:tubeA", {
|
||||
description = "TechAge Tube",
|
||||
tiles = { -- Top, base, right, left, front, back
|
||||
"techage_knee2.png",
|
||||
"techage_hole2.png^[transformR180",
|
||||
"techage_knee.png^[transformR270",
|
||||
"techage_knee.png",
|
||||
"techage_knee2.png",
|
||||
"techage_hole2.png",
|
||||
},
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Tube:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-2/8, -4/8, -2/8, 2/8, 2/8, 2/8},
|
||||
{-2/8, -2/8, -4/8, 2/8, 2/8, -2/8},
|
||||
},
|
||||
},
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 },
|
||||
},
|
||||
collision_box = {
|
||||
type = "fixed",
|
||||
fixed = { -1/4, -1/2, -1/2, 1/4, 1/4, 1/4 },
|
||||
},
|
||||
on_rotate = screwdriver.disallow,
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {choppy=2, cracky=3, stone=1, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
drop = "techage:tubeS",
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "techage:tubeS 4",
|
||||
recipe = {
|
||||
{"default:steel_ingot", "", "group:wood"},
|
||||
{"", "group:wood", ""},
|
||||
{"group:wood", "", "default:tin_ingot"},
|
||||
},
|
||||
})
|
4
depends.txt
Normal file
@ -0,0 +1,4 @@
|
||||
default
|
||||
tubelib2
|
||||
basic_materials
|
||||
|
176
electric/electric_cable.lua
Normal file
@ -0,0 +1,176 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Cable and junction box for electrical power distribution
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local Cable = tubelib2.Tube:new({
|
||||
dirs_to_check = {1,2,3,4,5,6},
|
||||
max_tube_length = 1000,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"techage:electric_cableS", "techage:electric_cableA"},
|
||||
secondary_node_names = {"techage:lamp", "techage:lamp_on", "techage:power"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes)
|
||||
minetest.swap_node(pos, {name = "techage:electric_cable"..tube_type, param2 = param2 % 32})
|
||||
M(pos):set_int("tl2_param2", param2)
|
||||
end,
|
||||
})
|
||||
|
||||
techage.ElectricCable = Cable
|
||||
|
||||
|
||||
-- Overridden method of tubelib2!
|
||||
function Cable:get_primary_node_param2(pos, dir)
|
||||
return techage.get_primary_node_param2(pos, dir)
|
||||
end
|
||||
|
||||
function Cable:is_primary_node(pos, dir)
|
||||
return techage.is_primary_node(pos, dir)
|
||||
end
|
||||
|
||||
Cable:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
minetest.registered_nodes[node.name].after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end)
|
||||
|
||||
|
||||
minetest.register_node("techage:electric_cableS", {
|
||||
description = I("TA4 Electric Cable"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable_end.png",
|
||||
"techage_electric_cable_end.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Cable:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata and oldmetadata.fields and oldmetadata.fields.tl2_param2 then
|
||||
oldnode.param2 = oldmetadata.fields.tl2_param2
|
||||
Cable:after_dig_tube(pos, oldnode)
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-3/32, -3/32, -4/8, 3/32, 3/32, 4/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:electric_cableA", {
|
||||
description = I("TA4 Electric Cable"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable_end.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable.png",
|
||||
"techage_electric_cable_end.png",
|
||||
},
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata and oldmetadata.fields and oldmetadata.fields.tl2_param2 then
|
||||
oldnode.param2 = oldmetadata.fields.tl2_param2
|
||||
Cable:after_dig_tube(pos, oldnode)
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-3/32, -4/8, -3/32, 3/32, 3/32, 3/32},
|
||||
{-3/32, -3/32, -4/8, 3/32, 3/32, -3/32},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
drop = "techage:electric_cableS",
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
local size = 3/32
|
||||
local Boxes = {
|
||||
{{-size, -size, size, size, size, 0.5 }}, -- z+
|
||||
{{-size, -size, -size, 0.5, size, size}}, -- x+
|
||||
{{-size, -size, -0.5, size, size, size}}, -- z-
|
||||
{{-0.5, -size, -size, size, size, size}}, -- x-
|
||||
{{-size, -0.5, -size, size, size, size}}, -- y-
|
||||
{{-size, -size, -size, size, 0.5, size}}, -- y+
|
||||
}
|
||||
|
||||
techage.register_junction("techage:electric_junction", 2/8, Boxes, Cable, {
|
||||
description = "Electricity Junction Box",
|
||||
tiles = {"techage_electric_junction.png"},
|
||||
groups = {snappy = 2, choppy = 2, oddly_breakable_by_hand = 3, techage_trowel = 1},
|
||||
sounds = default.node_sound_defaults(),
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
tubelib2.init_mem(pos)
|
||||
Cable:after_place_node(pos)
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.connections = mem.connections or {}
|
||||
mem.connections[out_dir] = peer_pos
|
||||
local name = "techage:electric_junction"..techage.junction_type(mem.connections)
|
||||
minetest.swap_node(pos, {name = name, param2 = 0})
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Cable:after_dig_node(pos)
|
||||
end,
|
||||
})
|
||||
|
128
electric/test.lua
Normal file
@ -0,0 +1,128 @@
|
||||
-- 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
|
||||
|
||||
local POWER_CONSUME = 1
|
||||
|
||||
|
||||
local Cable = techage.ElectricCable
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function lamp_turn_on(pos, dir, on)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.power_dir == dir or mem.power_dir == tubelib2.Turn180Deg[dir] then
|
||||
if on then
|
||||
swap_node(pos, "techage:lamp_on")
|
||||
else
|
||||
swap_node(pos, "techage:lamp")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:lamp", {
|
||||
description = "TechAge Lamp",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_electric_button.png',
|
||||
'techage_electric_button.png',
|
||||
'techage_electric_button.png',
|
||||
'techage_electric_button.png',
|
||||
'techage_electric_button.png^techage_electric_plug.png',
|
||||
'techage_electric_button.png^techage_electric_plug.png',
|
||||
},
|
||||
techage = {
|
||||
turn_on = lamp_turn_on,
|
||||
power_consumption = techage.consumer_power_consumption,
|
||||
network = techage.ElectricCable,
|
||||
power_consume = POWER_CONSUME,
|
||||
side = 'B',
|
||||
},
|
||||
|
||||
after_place_node = techage.consumer_after_place_node,
|
||||
after_tube_update = techage.consumer_after_tube_update,
|
||||
on_destruct = techage.consumer_on_destruct,
|
||||
after_dig_node = techage.consumer_after_dig_node,
|
||||
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:lamp_on", {
|
||||
description = "TechAge Lamp",
|
||||
tiles = {
|
||||
'techage_electric_button.png',
|
||||
},
|
||||
techage = {
|
||||
turn_on = lamp_turn_on,
|
||||
power_consumption = techage.consumer_power_consumption,
|
||||
network = techage.ElectricCable,
|
||||
power_consume = POWER_CONSUME,
|
||||
},
|
||||
|
||||
after_place_node = techage.consumer_after_place_node,
|
||||
after_tube_update = techage.consumer_after_tube_update,
|
||||
on_destruct = techage.consumer_on_destruct,
|
||||
after_dig_node = techage.consumer_after_dig_node,
|
||||
|
||||
paramtype = "light",
|
||||
light_source = LIGHT_MAX,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
drop = "techage:lamp",
|
||||
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:power", {
|
||||
description = "TechAge Power",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_electric_button.png^techage_electric_power.png',
|
||||
'techage_electric_button.png^techage_electric_power.png',
|
||||
'techage_electric_button.png^techage_electric_power.png^techage_electric_plug.png',
|
||||
'techage_electric_button.png^techage_electric_power.png',
|
||||
'techage_electric_button.png^techage_electric_power.png',
|
||||
'techage_electric_button.png^techage_electric_power.png',
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
|
||||
techage = {
|
||||
network = Cable,
|
||||
power_consumption = techage.generator_power_consumption,
|
||||
},
|
||||
|
||||
after_place_node = techage.generator_after_place_node,
|
||||
after_tube_update = techage.generator_after_tube_update,
|
||||
on_destruct = techage.generator_on_destruct,
|
||||
after_dig_node = techage.generator_after_dig_node,
|
||||
|
||||
on_rightclick = function(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
print("on_rightclick", mem.power)
|
||||
if mem.power_produce and mem.power_produce > 0 then
|
||||
techage.generator_off(pos)
|
||||
else
|
||||
techage.generator_on(pos, 8)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
205
fermenter/biogas_pipe.lua
Normal file
@ -0,0 +1,205 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Biogas pipes
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local Pipe = tubelib2.Tube:new({
|
||||
dirs_to_check = {1,2,3,4,5,6},
|
||||
max_tube_length = 1000,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"techage:biogas_pipeS", "techage:biogas_pipeA"},
|
||||
secondary_node_names = {"techage:gasflare", "techage:compressor"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes, tbl)
|
||||
minetest.swap_node(pos, {name = "techage:biogas_pipe"..tube_type, param2 = param2})
|
||||
M(pos):set_int("tl2_param2", param2)
|
||||
end,
|
||||
})
|
||||
|
||||
Pipe:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
minetest.registered_nodes[node.name].after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end)
|
||||
|
||||
techage.BiogasPipe = Pipe
|
||||
|
||||
|
||||
-- Overridden method of tubelib2!
|
||||
function Pipe:get_primary_node_param2(pos, dir)
|
||||
return techage.get_primary_node_param2(pos, dir)
|
||||
end
|
||||
|
||||
function Pipe:is_primary_node(pos, dir)
|
||||
return techage.is_primary_node(pos, dir)
|
||||
end
|
||||
|
||||
Pipe:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local clbk = minetest.registered_nodes[node.name].after_tube_update
|
||||
if clbk then
|
||||
clbk(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
else
|
||||
techage.after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
||||
minetest.register_node("techage:biogas_pipeS", {
|
||||
description = I("TA3 Biogas Pipe"),
|
||||
tiles = {
|
||||
"techage_gaspipe.png^[transformR90",
|
||||
"techage_gaspipe.png^[transformR90",
|
||||
"techage_gaspipe.png",
|
||||
"techage_gaspipe.png",
|
||||
"techage_gaspipe_hole2.png",
|
||||
"techage_gaspipe_hole2.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Pipe:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata and oldmetadata.fields and oldmetadata.fields.tl2_param2 then
|
||||
oldnode.param2 = oldmetadata.fields.tl2_param2
|
||||
Pipe:after_dig_tube(pos, oldnode)
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1/8, -1/8, -4/8, 1/8, 1/8, 4/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 3, cracky = 3, snappy = 3, techage_trowel = 1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:biogas_pipeA", {
|
||||
description = I("TA3 Biogas Pipe"),
|
||||
tiles = {
|
||||
"techage_gaspipe_knee2.png",
|
||||
"techage_gaspipe_hole2.png^[transformR180",
|
||||
"techage_gaspipe_knee.png^[transformR270",
|
||||
"techage_gaspipe_knee.png",
|
||||
"techage_gaspipe_knee2.png",
|
||||
"techage_gaspipe_hole2.png",
|
||||
},
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
if oldmetadata and oldmetadata.fields and oldmetadata.fields.tl2_param2 then
|
||||
oldnode.param2 = oldmetadata.fields.tl2_param2
|
||||
Pipe:after_dig_tube(pos, oldnode)
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1/8, -4/8, -1/8, 1/8, 1/8, 1/8},
|
||||
{-2/8, -0.5, -2/8, 2/8, -13/32, 2/8},
|
||||
{-1/8, -1/8, -4/8, 1/8, 1/8, -1/8},
|
||||
{-2/8, -2/8, -0.5, 2/8, 2/8, -13/32},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 3, cracky = 3, snappy = 3, techage_trowel = 1, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_glass_defaults(),
|
||||
drop = "techage:biogas_pipeS",
|
||||
})
|
||||
|
||||
|
||||
local size1 = 1/8
|
||||
local size2 = 2/8
|
||||
local size3 = 13/32
|
||||
local Boxes = {
|
||||
{
|
||||
{-size1, -size1, size1, size1, size1, 0.5 }, -- z+
|
||||
{-size2, -size2, size3, size2, size2, 0.5 }, -- z+
|
||||
},
|
||||
{
|
||||
{-size1, -size1, -size1, 0.5, size1, size1}, -- x+
|
||||
{ size3, -size2, -size2, 0.5, size2, size2}, -- x+
|
||||
},
|
||||
{
|
||||
{-size1, -size1, -0.5, size1, size1, size1}, -- z-
|
||||
{-size2, -size2, -0.5, size2, size2, -size3}, -- z-
|
||||
},
|
||||
{
|
||||
{-0.5, -size1, -size1, size1, size1, size1}, -- x-
|
||||
{-0.5, -size2, -size2, -size3, size2, size2}, -- x-
|
||||
},
|
||||
{
|
||||
{-size1, -0.5, -size1, size1, size1, size1}, -- y-
|
||||
{-size2, -0.5, -size2, size2, -size3, size2}, -- y-
|
||||
},
|
||||
{
|
||||
{-size1, -size1, -size1, size1, 0.5, size1}, -- y+
|
||||
{-size2, size3, -size2, size2, 0.5, size2}, -- y+
|
||||
}
|
||||
}
|
||||
|
||||
techage.register_junction("techage:biogas_junction", 1/8, Boxes, Pipe, {
|
||||
description = "TA3 Biogas Junction",
|
||||
tiles = {"techage_gaspipe_junction.png"},
|
||||
groups = {crumbly = 3, cracky = 3, snappy = 3, techage_trowel = 1},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("infotext", "Position "..S(pos))
|
||||
Pipe:after_place_node(pos)
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
local conn = minetest.deserialize(M(pos):get_string("connections")) or {}
|
||||
conn[out_dir] = peer_pos
|
||||
M(pos):set_string("connections", minetest.serialize(conn))
|
||||
local name = "techage:biogas_junction"..techage.junction_type(conn)
|
||||
minetest.swap_node(pos, {name = name, param2 = 0})
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
on_destruct = function(pos)
|
||||
techage.sink_power_consumption(pos, 0)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Pipe:after_dig_node(pos)
|
||||
end,
|
||||
})
|
||||
|
182
fermenter/gasflare.lua
Normal file
@ -0,0 +1,182 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
Biogas flare
|
||||
|
||||
]]--
|
||||
|
||||
|
||||
local HEIGHT = 7
|
||||
|
||||
local function remove_flame(pos)
|
||||
local idx
|
||||
for idx=HEIGHT,1,-1 do
|
||||
pos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local node = minetest.get_node(pos)
|
||||
if string.find(node.name, "techage:flame") then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function flame(pos)
|
||||
local idx
|
||||
for idx=HEIGHT,1,-1 do
|
||||
pos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
idx = math.min(idx, 12)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
minetest.add_node(pos, {name = "techage:flame"..math.min(idx,7)})
|
||||
local meta = minetest.get_meta(pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local lRatio = {120, 110, 95, 75, 55, 28, 0}
|
||||
local lColor = {"000080", "400040", "800000", "800000", "800000", "800000", "800000"}
|
||||
for idx,ratio in ipairs(lRatio) do
|
||||
local color = "techage_flame_animated.png^[colorize:#"..lColor[idx].."B0:"..ratio
|
||||
minetest.register_node("techage:flame"..idx, {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-3/8, -4/8, -2/8, 3/8, 4/8, 2/8},
|
||||
{-2/8, -4/8, -3/8, 2/8, 4/8, 3/8},
|
||||
},
|
||||
},
|
||||
tiles = {
|
||||
{
|
||||
name = color,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 16,
|
||||
aspect_h = 16,
|
||||
length = 1
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
after_destruct = function(pos, oldnode)
|
||||
pos.y = pos.y + 1
|
||||
local node = minetest.get_node(pos)
|
||||
if minetest.get_item_group(node.name, "techage_flame") > 0 then
|
||||
minetest.remove_node(pos)
|
||||
end
|
||||
end,
|
||||
|
||||
use_texture_alpha = true,
|
||||
inventory_image = "techage_flame.png",
|
||||
paramtype = "light",
|
||||
light_source = 13,
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
damage_per_second = 4 + idx,
|
||||
groups = {igniter = 2, dig_immediate = 3, techage_flame=1, not_in_creative_inventory=1},
|
||||
drop = "",
|
||||
})
|
||||
end
|
||||
|
||||
local function start_flarestack(pos, playername)
|
||||
if minetest.is_protected(
|
||||
{x=pos.x, y=pos.y+1, z=pos.z},
|
||||
playername) then
|
||||
return
|
||||
end
|
||||
local meta = minetest.get_meta(pos)
|
||||
flame({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
local handle = minetest.sound_play("gasflare", {
|
||||
pos = pos,
|
||||
max_hear_distance = 20,
|
||||
gain = 1,
|
||||
loop = true})
|
||||
print("handle", handle)
|
||||
meta:set_int("handle", handle)
|
||||
end
|
||||
|
||||
local function stop_flarestack(pos, handle)
|
||||
remove_flame({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
minetest.sound_stop(handle)
|
||||
end
|
||||
|
||||
minetest.register_node("techage:gasflare", {
|
||||
description = "gas flare",
|
||||
tiles = {
|
||||
"techage_gasflare.png",
|
||||
"techage_gasflare.png",
|
||||
"techage_gasflare.png",
|
||||
"techage_gasflare.png",
|
||||
"techage_gasflare.png",
|
||||
"techage_gasflare.png^techage_appl_hole2.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
minetest.add_node({x=pos.x, y=pos.y+1, z=pos.z}, {name = "techage:gasflare2"})
|
||||
end,
|
||||
|
||||
on_punch = function(pos, node, puncher)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local handle = meta:get_int("handle")
|
||||
minetest.sound_stop(handle)
|
||||
start_flarestack(pos, puncher:get_player_name())
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
print(dump(oldmetadata))
|
||||
stop_flarestack(pos, oldmetadata.fields.handle)
|
||||
local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if node.name == "techage:gasflare2" then
|
||||
minetest.remove_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:gasflare2", {
|
||||
description = "",
|
||||
tiles = {
|
||||
"techage_gasflare.png^techage_appl_hole2.png",
|
||||
"techage_gasflare.png"
|
||||
},
|
||||
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1/8, -4/8, -1/8, 1/8, 4/8, 1/8},
|
||||
{-4/8, 3/8, -4/8, 4/8, 4/8, 4/8},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
diggable = false,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
})
|
38
init.lua
Normal file
@ -0,0 +1,38 @@
|
||||
techage = {
|
||||
NodeDef = {}, -- node registration info
|
||||
}
|
||||
|
||||
|
||||
techage.max_num_forceload_blocks = tonumber(minetest.setting_get("techage_max_num_forceload_blocks")) or 12
|
||||
techage.basalt_stone_enabled = minetest.setting_get("techage_basalt_stone_enabled") == "true"
|
||||
techage.machine_aging_value = tonumber(minetest.setting_get("techage_machine_aging_value")) or 100
|
||||
|
||||
|
||||
local MP = minetest.get_modpath("techage")
|
||||
|
||||
-- Load support for intllib.
|
||||
dofile(MP.."/basis/intllib.lua")
|
||||
|
||||
dofile(MP.."/basis/power.lua") -- power distribution
|
||||
dofile(MP.."/basis/trowel.lua") -- hidden networks
|
||||
dofile(MP.."/basis/junction.lua") -- network junction box
|
||||
|
||||
-- Steam Engine
|
||||
dofile(MP.."/steam_engine/drive_axle.lua")
|
||||
dofile(MP.."/steam_engine/steam_pipe.lua")
|
||||
dofile(MP.."/steam_engine/firebox.lua")
|
||||
dofile(MP.."/steam_engine/boiler.lua")
|
||||
--dofile(MP.."/steam_engine/cylinder.lua")
|
||||
dofile(MP.."/steam_engine/flywheel.lua")
|
||||
dofile(MP.."/steam_engine/gearbox.lua")
|
||||
|
||||
dofile(MP.."/electric/electric_cable.lua")
|
||||
dofile(MP.."/electric/test.lua")
|
||||
|
||||
|
||||
dofile(MP.."/fermenter/biogas_pipe.lua")
|
||||
dofile(MP.."/fermenter/gasflare.lua")
|
||||
|
||||
|
||||
dofile(MP.."/nodes/test.lua")
|
||||
dofile(MP.."/mechanic/perf_test.lua")
|
3
intllib.sh
Executable file
@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
../intllib/tools/xgettext.sh ./tube_api.lua ./internal1.lua ./internal2.lua
|
521
mechanic/distributor.lua
Normal file
@ -0,0 +1,521 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
distributor.lua:
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
local N = minetest.get_node
|
||||
|
||||
local NUM_FILTER_ELEM = 6
|
||||
local NUM_FILTER_SLOTS = 4
|
||||
|
||||
local COUNTDOWN_TICKS = 4
|
||||
local STANDBY_TICKS = 8
|
||||
local CYCLE_TIME = 2
|
||||
|
||||
local function formspec(self, pos, meta)
|
||||
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
||||
return "size[10.5,8.5]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;src;0,0;2,4;]"..
|
||||
"image[2,1.5;1,1;tubelib_gui_arrow.png]"..
|
||||
"image_button[2,3;1,1;"..self:get_state_button_image(meta)..";state_button;]"..
|
||||
"checkbox[3,0;filter1;On;"..dump(filter[1]).."]"..
|
||||
"checkbox[3,1;filter2;On;"..dump(filter[2]).."]"..
|
||||
"checkbox[3,2;filter3;On;"..dump(filter[3]).."]"..
|
||||
"checkbox[3,3;filter4;On;"..dump(filter[4]).."]"..
|
||||
"image[4,0;0.3,1;tubelib_red.png]"..
|
||||
"image[4,1;0.3,1;tubelib_green.png]"..
|
||||
"image[4,2;0.3,1;tubelib_blue.png]"..
|
||||
"image[4,3;0.3,1;tubelib_yellow.png]"..
|
||||
"list[context;red;4.5,0;6,1;]"..
|
||||
"list[context;green;4.5,1;6,1;]"..
|
||||
"list[context;blue;4.5,2;6,1;]"..
|
||||
"list[context;yellow;4.5,3;6,1;]"..
|
||||
"list[current_player;main;1.25,4.5;8,4;]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
local State = tubelib.NodeStates:new({
|
||||
node_name_passive = "tubelib:distributor",
|
||||
node_name_active = "tubelib:distributor_active",
|
||||
node_name_defect = "tubelib:distributor_defect",
|
||||
infotext_name = "Tubelib Distributor",
|
||||
cycle_time = CYCLE_TIME,
|
||||
standby_ticks = STANDBY_TICKS,
|
||||
aging_factor = 10,
|
||||
formspec_func = formspec,
|
||||
})
|
||||
|
||||
-- Return a key/value table with all items and the corresponding stack numbers
|
||||
local function invlist_content_as_kvlist(list)
|
||||
local res = {}
|
||||
for idx,items in ipairs(list) do
|
||||
local name = items:get_name()
|
||||
if name ~= "" then
|
||||
res[name] = idx
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- Return the total number of list entries
|
||||
local function invlist_num_entries(list)
|
||||
local res = 0
|
||||
for _,items in ipairs(list) do
|
||||
local name = items:get_name()
|
||||
if name ~= "" then
|
||||
res = res + items:get_count()
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
-- Return a gapless table with all items
|
||||
local function invlist_entries_as_list(list)
|
||||
local res = {}
|
||||
for _,items in ipairs(list) do
|
||||
if items:get_count() > 0 then
|
||||
res[#res+1] = {items:get_name(), items:get_count()}
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
local function AddToTbl(kvTbl, new_items)
|
||||
for _, l in ipairs(new_items) do
|
||||
kvTbl[l[1]] = true
|
||||
end
|
||||
return kvTbl
|
||||
end
|
||||
|
||||
-- return the number of items to be pushed to an unconfigured slot
|
||||
local function num_items(moved_items, name, filter_item_names, rejected_item_names)
|
||||
if filter_item_names[name] == nil then -- not configured in one filter?
|
||||
if moved_items < MAX_NUM_PER_CYC then
|
||||
return math.min(4, MAX_NUM_PER_CYC - moved_items)
|
||||
end
|
||||
end
|
||||
if rejected_item_names[name] then -- rejected item from another slot?
|
||||
if moved_items < MAX_NUM_PER_CYC then
|
||||
return math.min(rejected_item_names[name], MAX_NUM_PER_CYC - moved_items)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list(listname)
|
||||
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
if listname == "src" then
|
||||
if State:get_state(M(pos)) == tubelib.STANDBY then
|
||||
State:start(pos, meta)
|
||||
end
|
||||
return stack:get_count()
|
||||
elseif invlist_num_entries(list) < MAX_NUM_PER_CYC then
|
||||
return stack:get_count()
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
return stack:get_count()
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_move(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local stack = inv:get_stack(from_list, from_index)
|
||||
return allow_metadata_inventory_put(pos, to_list, to_index, stack, player)
|
||||
end
|
||||
|
||||
local SlotColors = {"red", "green", "blue", "yellow"}
|
||||
local Num2Ascii = {"B", "L", "F", "R"} -- color to side translation
|
||||
local FilterCache = {} -- local cache for filter settings
|
||||
|
||||
local function filter_settings(pos)
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local filter = minetest.deserialize(meta:get_string("filter")) or {false,false,false,false}
|
||||
local kvFilterItemNames = {} -- {<item:name> = true,...}
|
||||
local kvSide2ItemNames = {} -- {"F" = {<item:name>,...},...}
|
||||
|
||||
-- collect all filter settings
|
||||
for idx,slot in ipairs(SlotColors) do
|
||||
local side = Num2Ascii[idx]
|
||||
if filter[idx] == true then
|
||||
local list = inv:get_list(slot)
|
||||
local filter = invlist_entries_as_list(list)
|
||||
AddToTbl(kvFilterItemNames, filter)
|
||||
kvSide2ItemNames[side] = filter
|
||||
end
|
||||
end
|
||||
|
||||
FilterCache[hash] = {
|
||||
kvFilterItemNames = kvFilterItemNames,
|
||||
kvSide2ItemNames = kvSide2ItemNames,
|
||||
kvRejectedItemNames = {},
|
||||
}
|
||||
end
|
||||
|
||||
-- move items from configured filters to the output
|
||||
local function distributing(pos, meta)
|
||||
local player_name = meta:get_string("player_name")
|
||||
local slot_idx = meta:get_int("slot_idx") or 1
|
||||
meta:set_int("slot_idx", (slot_idx + 1) % NUM_FILTER_SLOTS)
|
||||
local side = Num2Ascii[slot_idx+1]
|
||||
local listname = SlotColors[slot_idx+1]
|
||||
local inv = meta:get_inventory()
|
||||
local list = inv:get_list("src")
|
||||
local kvSrc = invlist_content_as_kvlist(list)
|
||||
local counter = minetest.deserialize(meta:get_string("item_counter")) or
|
||||
{red=0, green=0, blue=0, yellow=0}
|
||||
|
||||
-- calculate the filter settings only once
|
||||
local hash = minetest.hash_node_position(pos)
|
||||
if FilterCache[hash] == nil then
|
||||
filter_settings(pos)
|
||||
end
|
||||
|
||||
-- read data from Cache
|
||||
-- all filter items as key/value {<item:name> = true,...}
|
||||
local kvFilterItemNames = FilterCache[hash].kvFilterItemNames
|
||||
-- filter items of one slot as list {{<item:name>, <num-items>},...}
|
||||
local items = FilterCache[hash].kvSide2ItemNames[side]
|
||||
-- rejected items from other filter slots
|
||||
local rejected = FilterCache[hash].kvRejectedItemNames
|
||||
|
||||
if items == nil then return end
|
||||
|
||||
local moved_items_total = 0
|
||||
if next(items) then
|
||||
for _,item in ipairs(items) do
|
||||
local name, num = item[1], item[2]
|
||||
if kvSrc[name] then
|
||||
local item = tubelib.get_this_item(meta, "src", kvSrc[name], num) -- <<=== tubelib
|
||||
if item then
|
||||
if not tubelib.push_items(pos, side, item, player_name) then -- <<=== tubelib
|
||||
tubelib.put_item(meta, "src", item)
|
||||
rejected[name] = num
|
||||
else
|
||||
counter[listname] = counter[listname] + num
|
||||
moved_items_total = moved_items_total + num
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- move additional items from unconfigured filters to the output
|
||||
if next(items) == nil then
|
||||
local moved_items = 0
|
||||
for name,_ in pairs(kvSrc) do
|
||||
local num = num_items(moved_items, name, kvFilterItemNames, rejected)
|
||||
if num then
|
||||
local item = tubelib.get_this_item(meta, "src", kvSrc[name], num) -- <<=== tubelib
|
||||
if item then
|
||||
if not tubelib.push_items(pos, side, item, player_name) then -- <<=== tubelib
|
||||
tubelib.put_item(meta, "src", item)
|
||||
else
|
||||
counter[listname] = counter[listname] + num
|
||||
moved_items = moved_items + num
|
||||
moved_items_total = moved_items_total + num
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
-- delete list for next slot round
|
||||
if moved_items > 0 then
|
||||
FilterCache[hash].kvRejectedItemNames = {}
|
||||
end
|
||||
end
|
||||
meta:set_string("item_counter", minetest.serialize(counter))
|
||||
if moved_items_total > 0 then
|
||||
State:keep_running(pos, meta, COUNTDOWN_TICKS, moved_items_total)
|
||||
else
|
||||
State:idle(pos, meta)
|
||||
end
|
||||
end
|
||||
|
||||
-- move items to the output slots
|
||||
local function keep_running(pos, elapsed)
|
||||
local meta = M(pos)
|
||||
distributing(pos, meta)
|
||||
return State:is_active(meta)
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
local meta = M(pos)
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
if fields.filter1 ~= nil then
|
||||
filter[1] = fields.filter1 == "true"
|
||||
elseif fields.filter2 ~= nil then
|
||||
filter[2] = fields.filter2 == "true"
|
||||
elseif fields.filter3 ~= nil then
|
||||
filter[3] = fields.filter3 == "true"
|
||||
elseif fields.filter4 ~= nil then
|
||||
filter[4] = fields.filter4 == "true"
|
||||
end
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
|
||||
filter_settings(pos)
|
||||
|
||||
if fields.state_button ~= nil then
|
||||
State:state_button_event(pos, fields)
|
||||
else
|
||||
meta:set_string("formspec", formspec(State, pos, meta))
|
||||
end
|
||||
end
|
||||
|
||||
-- tubelib command to turn on/off filter channels
|
||||
local function change_filter_settings(pos, slot, val)
|
||||
local slots = {["red"] = 1, ["green"] = 2, ["blue"] = 3, ["yellow"] = 4}
|
||||
local meta = M(pos)
|
||||
local filter = minetest.deserialize(meta:get_string("filter"))
|
||||
local num = slots[slot] or 1
|
||||
if num >= 1 and num <= 4 then
|
||||
filter[num] = val == "on"
|
||||
end
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
|
||||
filter_settings(pos)
|
||||
|
||||
meta:set_string("formspec", formspec(State, pos, meta))
|
||||
return true
|
||||
end
|
||||
|
||||
minetest.register_node("tubelib:distributor", {
|
||||
description = "Tubelib Distributor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'tubelib_distributor.png',
|
||||
'tubelib_front.png',
|
||||
'tubelib_distributor_yellow.png',
|
||||
'tubelib_distributor_green.png',
|
||||
"tubelib_distributor_red.png",
|
||||
"tubelib_distributor_blue.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = M(pos)
|
||||
local number = tubelib.add_node(pos, "tubelib:distributor") -- <<=== tubelib
|
||||
local filter = {false,false,false,false}
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
State:node_init(pos, number)
|
||||
meta:set_string("player_name", placer:get_player_name())
|
||||
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('src', 8)
|
||||
inv:set_size('yellow', 6)
|
||||
inv:set_size('green', 6)
|
||||
inv:set_size('red', 6)
|
||||
inv:set_size('blue', 6)
|
||||
meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0}))
|
||||
end,
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
can_dig = function(pos, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
local inv = M(pos):get_inventory()
|
||||
return inv:is_empty("src")
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
tubelib.remove_node(pos) -- <<=== tubelib
|
||||
State:after_dig_node(pos, oldnode, oldmetadata, digger)
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_timer = keep_running,
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
drop = "",
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("tubelib:distributor_active", {
|
||||
description = "Tubelib Distributor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
{
|
||||
image = "tubelib_distributor_active.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
'tubelib_front.png',
|
||||
'tubelib_distributor_yellow.png',
|
||||
'tubelib_distributor_green.png',
|
||||
"tubelib_distributor_red.png",
|
||||
"tubelib_distributor_blue.png",
|
||||
},
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_timer = keep_running,
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {crumbly=0, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("tubelib:distributor_defect", {
|
||||
description = "Tubelib Distributor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'tubelib_distributor.png',
|
||||
'tubelib_front.png',
|
||||
'tubelib_distributor_yellow.png^tubelib_defect.png',
|
||||
'tubelib_distributor_green.png^tubelib_defect.png',
|
||||
"tubelib_distributor_red.png^tubelib_defect.png",
|
||||
"tubelib_distributor_blue.png^tubelib_defect.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
local meta = M(pos)
|
||||
local number = tubelib.add_node(pos, "tubelib:distributor") -- <<=== tubelib
|
||||
State:node_init(pos, number)
|
||||
meta:set_string("player_name", placer:get_player_name())
|
||||
|
||||
local filter = {false,false,false,false}
|
||||
meta:set_string("filter", minetest.serialize(filter))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('src', 8)
|
||||
inv:set_size('yellow', 6)
|
||||
inv:set_size('green', 6)
|
||||
inv:set_size('red', 6)
|
||||
inv:set_size('blue', 6)
|
||||
meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0}))
|
||||
State:defect(pos, meta)
|
||||
end,
|
||||
|
||||
on_receive_fields = on_receive_fields,
|
||||
|
||||
can_dig = function(pos, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return false
|
||||
end
|
||||
local inv = M(pos):get_inventory()
|
||||
return inv:is_empty("src")
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
tubelib.remove_node(pos) -- <<=== tubelib
|
||||
end,
|
||||
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
allow_metadata_inventory_move = allow_metadata_inventory_move,
|
||||
|
||||
on_rotate = screwdriver.disallow,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "tubelib:distributor 2",
|
||||
recipe = {
|
||||
{"group:wood", "default:steel_ingot", "group:wood"},
|
||||
{"tubelib:tubeS", "default:mese_crystal", "tubelib:tubeS"},
|
||||
{"group:wood", "default:steel_ingot", "group:wood"},
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
--------------------------------------------------------------- tubelib
|
||||
tubelib.register_node("tubelib:distributor",
|
||||
{"tubelib:distributor_active", "tubelib:distributor_defect"}, {
|
||||
on_pull_item = function(pos, side)
|
||||
return tubelib.get_item(M(pos), "src")
|
||||
end,
|
||||
on_push_item = function(pos, side, item)
|
||||
return tubelib.put_item(M(pos), "src", item)
|
||||
end,
|
||||
on_unpull_item = function(pos, side, item)
|
||||
return tubelib.put_item(M(pos), "src", item)
|
||||
end,
|
||||
on_recv_message = function(pos, topic, payload)
|
||||
if topic == "filter" then
|
||||
return change_filter_settings(pos, payload.slot, payload.val)
|
||||
elseif topic == "counter" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
return minetest.deserialize(meta:get_string("item_counter")) or
|
||||
{red=0, green=0, blue=0, yellow=0}
|
||||
elseif topic == "clear_counter" then
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("item_counter", minetest.serialize({red=0, green=0, blue=0, yellow=0}))
|
||||
else
|
||||
local resp = State:on_receive_message(pos, topic, payload)
|
||||
if resp then
|
||||
return resp
|
||||
else
|
||||
return "unsupported"
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
on_node_load = function(pos)
|
||||
State:on_node_load(pos)
|
||||
end,
|
||||
on_node_repair = function(pos)
|
||||
return State:on_node_repair(pos)
|
||||
end,
|
||||
})
|
||||
--------------------------------------------------------------- tubelib
|
91
mechanic/perf_test.lua
Normal file
@ -0,0 +1,91 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
distributor.lua:
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
local N = minetest.get_node
|
||||
|
||||
local function formspec()
|
||||
return "size[10.5,8.5]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[context;src;0,0;2,4;]"..
|
||||
"list[current_player;main;1.25,4.5;8,4;]"..
|
||||
"listring[context;src]"..
|
||||
"listring[current_player;main]"
|
||||
end
|
||||
|
||||
|
||||
-- move items to the output slots
|
||||
local function keep_running(pos, elapsed)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local name, num
|
||||
|
||||
for i = 1,10 do
|
||||
--local list = inv:get_list("src")
|
||||
for i = 1,8 do
|
||||
--local stack = list[i]
|
||||
local stack = inv:get_stack("src", i)
|
||||
if stack:get_count() > 0 then
|
||||
local taken = inv:remove_item("src", stack)
|
||||
num = taken:get_count()
|
||||
inv:add_item("src", taken)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function after_place_node(pos, placer)
|
||||
local meta = M(pos)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('src', 8)
|
||||
inv:add_item("src", ItemStack("wool:blue"))
|
||||
inv:add_item("src", ItemStack("wool:red"))
|
||||
inv:add_item("src", ItemStack("wool:green"))
|
||||
meta:set_string("formspec", formspec())
|
||||
|
||||
minetest.get_node_timer(pos):start(0.1)
|
||||
end
|
||||
|
||||
minetest.register_node("techage:perf_test", {
|
||||
description = "perf_test",
|
||||
tiles = {"techage_filling_ta2.png"},
|
||||
|
||||
after_place_node = after_place_node,
|
||||
|
||||
on_timer = keep_running,
|
||||
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {choppy=2, cracky=2, crumbly=2},
|
||||
is_ground_content = false,
|
||||
})
|
||||
|
||||
|
||||
minetest.register_lbm({
|
||||
label = "[TechAge] Node update",
|
||||
name = "techage:perf_test",
|
||||
nodenames = {"techage:perf_test"},
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
after_place_node(pos)
|
||||
end
|
||||
})
|
124
models/techage_boiler.obj
Normal file
@ -0,0 +1,124 @@
|
||||
# Blender v2.78 (sub 0) OBJ File: 'test.blend'
|
||||
# www.blender.org
|
||||
o Cylinder
|
||||
v 0.000000 -0.500000 -0.450000
|
||||
v 0.000000 0.500000 -0.450000
|
||||
v 0.172208 -0.500000 -0.415746
|
||||
v 0.172208 0.500000 -0.415746
|
||||
v 0.318198 -0.500000 -0.318198
|
||||
v 0.318198 0.500000 -0.318198
|
||||
v 0.415746 -0.500000 -0.172208
|
||||
v 0.415746 0.500000 -0.172208
|
||||
v 0.450000 -0.500000 0.000000
|
||||
v 0.450000 0.500000 0.000000
|
||||
v 0.415746 -0.500000 0.172208
|
||||
v 0.415746 0.500000 0.172208
|
||||
v 0.318198 -0.500000 0.318198
|
||||
v 0.318198 0.500000 0.318198
|
||||
v 0.172208 -0.500000 0.415746
|
||||
v 0.172208 0.500000 0.415746
|
||||
v 0.000000 -0.500000 0.450000
|
||||
v 0.000000 0.500000 0.450000
|
||||
v -0.172207 -0.500000 0.415746
|
||||
v -0.172207 0.500000 0.415746
|
||||
v -0.318198 -0.500000 0.318198
|
||||
v -0.318198 0.500000 0.318198
|
||||
v -0.415746 -0.500000 0.172208
|
||||
v -0.415746 0.500000 0.172208
|
||||
v -0.450000 -0.500000 -0.000000
|
||||
v -0.450000 0.500000 -0.000000
|
||||
v -0.415746 -0.500000 -0.172208
|
||||
v -0.415746 0.500000 -0.172208
|
||||
v -0.318198 -0.500000 -0.318198
|
||||
v -0.318198 0.500000 -0.318198
|
||||
v -0.172207 -0.500000 -0.415746
|
||||
v -0.172207 0.500000 -0.415746
|
||||
vt 0.5486 0.5000
|
||||
vt 0.5486 1.0000
|
||||
vt 0.4725 1.0000
|
||||
vt 0.4725 0.5000
|
||||
vt 0.4142 1.0000
|
||||
vt 0.4142 0.5000
|
||||
vt 1.0000 0.5000
|
||||
vt 1.0000 1.0000
|
||||
vt 0.9239 1.0000
|
||||
vt 0.9239 0.5000
|
||||
vt 0.8415 1.0000
|
||||
vt 0.8415 0.5000
|
||||
vt 0.7654 1.0000
|
||||
vt 0.7654 0.5000
|
||||
vt 0.4142 0.5000
|
||||
vt 0.4142 0.0000
|
||||
vt 0.4725 0.0000
|
||||
vt 0.4725 0.5000
|
||||
vt 0.5486 0.0000
|
||||
vt 0.5486 0.5000
|
||||
vt 0.6310 0.0000
|
||||
vt 0.6310 0.5000
|
||||
vt 0.7071 0.0000
|
||||
vt 0.7071 0.5000
|
||||
vt 0.7654 0.0000
|
||||
vt 0.7654 0.5000
|
||||
vt 0.8415 0.0000
|
||||
vt 0.8415 0.5000
|
||||
vt 0.9239 0.0000
|
||||
vt 0.9239 0.5000
|
||||
vt 1.0000 0.0000
|
||||
vt 1.0000 0.5000
|
||||
vt 0.7654 0.5000
|
||||
vt 0.7654 1.0000
|
||||
vt 0.7071 1.0000
|
||||
vt 0.7071 0.5000
|
||||
vt 0.3244 0.4749
|
||||
vt 0.3827 0.5370
|
||||
vt 0.4142 0.6181
|
||||
vt 0.4142 0.7059
|
||||
vt 0.3827 0.7870
|
||||
vt 0.3244 0.8491
|
||||
vt 0.2483 0.8827
|
||||
vt 0.1659 0.8827
|
||||
vt 0.0898 0.8491
|
||||
vt 0.0315 0.7870
|
||||
vt 0.0000 0.7059
|
||||
vt 0.0000 0.6181
|
||||
vt 0.0315 0.5370
|
||||
vt 0.0898 0.4749
|
||||
vt 0.1659 0.4414
|
||||
vt 0.2483 0.4414
|
||||
vt 0.6310 1.0000
|
||||
vt 0.6310 0.5000
|
||||
vt 0.0000 0.2646
|
||||
vt 0.0000 0.1768
|
||||
vt 0.0315 0.0957
|
||||
vt 0.0898 0.0336
|
||||
vt 0.1659 0.0000
|
||||
vt 0.2483 0.0000
|
||||
vt 0.3244 0.0336
|
||||
vt 0.3827 0.0957
|
||||
vt 0.4142 0.1768
|
||||
vt 0.4142 0.2646
|
||||
vt 0.3827 0.3457
|
||||
vt 0.3244 0.4078
|
||||
vt 0.2483 0.4414
|
||||
vt 0.1659 0.4414
|
||||
vt 0.0898 0.4078
|
||||
vt 0.0315 0.3457
|
||||
s off
|
||||
f 1/1 2/2 4/3 3/4
|
||||
f 3/4 4/3 6/5 5/6
|
||||
f 5/7 6/8 8/9 7/10
|
||||
f 7/10 8/9 10/11 9/12
|
||||
f 9/12 10/11 12/13 11/14
|
||||
f 11/15 12/16 14/17 13/18
|
||||
f 13/18 14/17 16/19 15/20
|
||||
f 15/20 16/19 18/21 17/22
|
||||
f 17/22 18/21 20/23 19/24
|
||||
f 19/24 20/23 22/25 21/26
|
||||
f 21/26 22/25 24/27 23/28
|
||||
f 23/28 24/27 26/29 25/30
|
||||
f 25/30 26/29 28/31 27/32
|
||||
f 27/33 28/34 30/35 29/36
|
||||
f 4/37 2/38 32/39 30/40 28/41 26/42 24/43 22/44 20/45 18/46 16/47 14/48 12/49 10/50 8/51 6/52
|
||||
f 29/36 30/35 32/53 31/54
|
||||
f 31/54 32/53 2/2 1/1
|
||||
f 1/55 3/56 5/57 7/58 9/59 11/60 13/61 15/62 17/63 19/64 21/65 23/66 25/67 27/68 29/69 31/70
|
549
nodes/test.lua
Normal file
@ -0,0 +1,549 @@
|
||||
minetest.register_node("techage:block1", {
|
||||
description = "block1",
|
||||
tiles = {"techage_filling_ta2.png^techage_frame_ta2.png"},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block2", {
|
||||
description = "block2",
|
||||
tiles = {"techage_filling_ta3.png^techage_frame_ta3.png"},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block3", {
|
||||
description = "block3",
|
||||
tiles = {
|
||||
"techage_top_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_node("techage:block4", {
|
||||
description = "block4",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_arrow.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_outp.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_inp.png',
|
||||
{
|
||||
image = "techage_pusher14.png^[transformR180]^techage_frame14_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_pusher14.png^techage_frame14_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block5", {
|
||||
description = "block5",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_arrow.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_outp.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_inp.png',
|
||||
{
|
||||
image = "techage_pusher14.png^[transformR180]^techage_frame14_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_pusher14.png^techage_frame14_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block6", {
|
||||
description = "block6",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta4.png^techage_top_ta4.png^techage_appl_arrow.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_outp.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_inp.png',
|
||||
{
|
||||
image = "tubelib_pusher.png^[transformR180]^techage_frame14_ta4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "tubelib_pusher.png^techage_frame14_ta4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
minetest.register_node("techage:block7", {
|
||||
description = "block7",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_chest_front_ta3.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block8", {
|
||||
description = "block8",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_chest_back_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_chest_front_ta3.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:block9", {
|
||||
description = "block9",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta4.png^techage_top_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_back_ta4.png",
|
||||
"techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_chest_front_ta4.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
|
||||
minetest.register_node("techage:sieve", {
|
||||
description = "sieve",
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_inp.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png^techage_appl_outp.png',
|
||||
'techage_filling_ta2.png^techage_frame_ta2.png',
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_appl_sieve4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_appl_sieve4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:sieve2", {
|
||||
description = "sieve",
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_inp.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_outp.png',
|
||||
'techage_filling_ta3.png^techage_frame_ta3.png',
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_sieve4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_sieve4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:sieve3", {
|
||||
description = "sieve",
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
'techage_filling_ta4.png^techage_top_ta4.png^techage_appl_inp.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png^techage_appl_outp.png',
|
||||
'techage_filling_ta4.png^techage_frame_ta4.png',
|
||||
{
|
||||
image = "techage_filling4_ta4.png^techage_appl_sieve4.png^techage_frame4_ta4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta4.png^techage_appl_sieve4.png^techage_frame4_ta4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:filler", {
|
||||
description = "filler",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_arrow.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole2.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_inp.png",
|
||||
--"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_filler.png",
|
||||
--"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_filler.png",
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_filler4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_filler4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 2.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:compressor", {
|
||||
description = "compressor",
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_arrow.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole2.png",
|
||||
"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_hole2.png",
|
||||
--"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_compressor.png",
|
||||
--"techage_filling_ta3.png^techage_frame_ta3.png^techage_appl_compressor.png^[transformFX]",
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_compressor4.png^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.2,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta3.png^techage_appl_compressor4.png^[transformFX]^techage_frame4_ta3.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.2,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:fermenter", {
|
||||
description = "fermenter",
|
||||
tiles = {"techage_fermenter.png"},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:fermenter_foil", {
|
||||
description = "fermenter_foil",
|
||||
tiles = {"techage_fermenter_foil.png"},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2},
|
||||
is_ground_content = false,
|
||||
--sounds = default.node_sound_stone_defaults(),
|
||||
})
|
||||
|
||||
|
||||
minetest.register_node("techage:biomass", {
|
||||
description = "biomass",
|
||||
drawtype = "liquid",
|
||||
tiles = {
|
||||
{
|
||||
name = "techage_biomass.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 4.0,
|
||||
},
|
||||
},
|
||||
},
|
||||
special_tiles = {
|
||||
-- New-style water source material (mostly unused)
|
||||
{
|
||||
name = "techage_biomass.png",
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 4.0,
|
||||
},
|
||||
backface_culling = false,
|
||||
},
|
||||
},
|
||||
|
||||
on_timer = function(pos)
|
||||
minetest.remove_node(pos)
|
||||
return false
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer)
|
||||
minetest.get_node_timer(pos):start(5)
|
||||
end,
|
||||
|
||||
--alpha = 160,
|
||||
paramtype = "light",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = "source",
|
||||
liquid_alternative_flowing = "techage:biomass_flowing",
|
||||
liquid_alternative_source = "techage:biomass",
|
||||
liquid_viscosity = 1,
|
||||
post_effect_color = {a = 103, r = 30, g = 60, b = 90},
|
||||
groups = {water = 3, liquid = 3, puts_out_fire = 1, cools_lava = 1},
|
||||
sounds = default.node_sound_water_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:biomass_flowing", {
|
||||
description = "biomass",
|
||||
drawtype = "flowingliquid",
|
||||
tiles = {"default_water.png"},
|
||||
special_tiles = {
|
||||
{
|
||||
name = "techage_biomass.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 4,
|
||||
},
|
||||
},
|
||||
{
|
||||
name = "techage_biomass.png",
|
||||
backface_culling = true,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
--alpha = 220,
|
||||
paramtype = "light",
|
||||
paramtype2 = "flowingliquid",
|
||||
walkable = false,
|
||||
pointable = false,
|
||||
diggable = false,
|
||||
buildable_to = true,
|
||||
is_ground_content = false,
|
||||
drop = "",
|
||||
drowning = 1,
|
||||
liquidtype = "flowing",
|
||||
liquid_alternative_flowing = "techage:biomass_flowing",
|
||||
liquid_alternative_source = "techage:biomass",
|
||||
liquid_viscosity = 1,
|
||||
post_effect_color = {a = 103, r = 30, g = 60, b = 90},
|
||||
groups = {water = 3, liquid = 3, puts_out_fire = 1,
|
||||
not_in_creative_inventory = 0, cools_lava = 1},
|
||||
sounds = default.node_sound_water_defaults(),
|
||||
})
|
||||
|
BIN
screenshot.png
Normal file
After Width: | Height: | Size: 620 KiB |
10
settingtypes.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Maximim number of Forceload Blocks per player (default 12)
|
||||
tubelib_max_num_forceload_blocks (max number of Forceload Blocks) int 12
|
||||
|
||||
# Enable Basalt Stone (and disable ore generation via cobble generator)
|
||||
tubelib_basalt_stone_enabled (Basalt Stone enabled) bool true
|
||||
|
||||
# This aging value is used to calculate the lifetime of machines before
|
||||
# they go defect . The value 200 (default) results in a lifetime
|
||||
# for standard machines of about 2000 - 8000 item processing cycles.
|
||||
tubelib_machine_aging_value (machine aging value) int 200
|
BIN
sounds/techage_button.ogg
Normal file
BIN
sounds/techage_gasflare.ogg
Normal file
293
steam_engine/boiler.lua
Normal file
@ -0,0 +1,293 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Steam Engine Boiler
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local CYCLE_TIME = 4
|
||||
local HEAT_STEP = 10
|
||||
local WATER_CONSUMPTION = 2
|
||||
local MAX_WATER = 10
|
||||
local POWER = 10
|
||||
|
||||
local Water = {
|
||||
["bucket:bucket_river_water"] = true,
|
||||
["bucket:bucket_water"] = true,
|
||||
["bucket:bucket_empty"] = true,
|
||||
}
|
||||
|
||||
local function formspec(mem)
|
||||
local temp = mem.temperature or 20
|
||||
local button = mem.running and I("Stop") or I("Start")
|
||||
return "size[8,7]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"image_button[0,0.2;1,1;techage_form_inventory.png;storage;;true;false;]"..
|
||||
"list[context;water;1,0.2;1,1;]"..
|
||||
"image_button[0,1.6;1,1;techage_form_input.png;input;;true;false;]"..
|
||||
"list[context;input;1,1.6;1,1;]"..
|
||||
"image[1,1.6;1,1;bucket_water.png]"..
|
||||
"image[1,1.6;1,1;techage_form_mask.png]"..
|
||||
"image[3,0.5;1,2;techage_form_temp_bg.png^[lowpart:"..
|
||||
temp..":techage_form_temp_fg.png]"..
|
||||
"image[4,0.5;1,2;"..techage.generator_formspec_level(mem)..
|
||||
"button[6,0.5;2,1;start;"..button.."]"..
|
||||
"button[6,1.5;2,1;update;"..I("Update").."]"..
|
||||
"list[current_player;main;0,3;8,4;]"..
|
||||
"listring[current_name;water]"..
|
||||
"listring[current_player;main]"..
|
||||
default.get_hotbar_bg(0, 3)
|
||||
end
|
||||
|
||||
local function can_dig(pos, player)
|
||||
local inv = M(pos):get_inventory()
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
return inv:is_empty("water") and inv:is_empty("input") and not mem.running
|
||||
end
|
||||
|
||||
local function move_to_water(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
local water_stack = inv:get_stack("water", 1)
|
||||
local input_stack = inv:get_stack("input", 1)
|
||||
|
||||
if input_stack:get_name() == "bucket:bucket_empty" and input_stack:get_count() == 1 then
|
||||
if water_stack:get_count() > 0 then
|
||||
water_stack:set_count(water_stack:get_count() - 1)
|
||||
input_stack = ItemStack("bucket:bucket_water")
|
||||
inv:set_stack("water", 1, water_stack)
|
||||
inv:set_stack("input", 1, input_stack)
|
||||
end
|
||||
elseif water_stack:get_count() < MAX_WATER then
|
||||
if water_stack:get_count() == 0 then
|
||||
water_stack = ItemStack("default:water_source")
|
||||
else
|
||||
water_stack:set_count(water_stack:get_count() + 1)
|
||||
end
|
||||
input_stack = ItemStack("bucket:bucket_empty")
|
||||
inv:set_stack("water", 1, water_stack)
|
||||
inv:set_stack("input", 1, input_stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function start_boiler(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.water_level = mem.water_level or 0
|
||||
local inv = M(pos):get_inventory()
|
||||
local water_stack = inv:get_stack("water", 1)
|
||||
print("trigger_boiler", mem.fire_trigger, mem.water_level, water_stack:get_count())
|
||||
if mem.fire_trigger and (mem.water_level > 0 or water_stack:get_count() > 0) then
|
||||
if not minetest.get_node_timer(pos):is_started() then
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
if listname == "input" and Water[stack:get_name()] then
|
||||
start_boiler(pos)
|
||||
return stack:get_count()
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
if listname == "input" then
|
||||
return stack:get_count()
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.update then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
|
||||
if fields.start then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.running = not (mem.running or false)
|
||||
if mem.running then
|
||||
techage.generator_on(pos, POWER)
|
||||
else
|
||||
techage.generator_off(pos)
|
||||
end
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
|
||||
local function get_water(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
local items = inv:get_stack("water", 1)
|
||||
if items:get_count() > 0 then
|
||||
local taken = items:take_item(1)
|
||||
inv:set_stack("water", 1, items)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function node_timer(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.temperature = mem.temperature or 20
|
||||
mem.water_level = math.max((mem.water_level or 0) - WATER_CONSUMPTION, 0)
|
||||
|
||||
print(mem.fire_trigger, mem.running, mem.temperature, mem.water_level)
|
||||
|
||||
if mem.fire_trigger then
|
||||
mem.temperature = math.min(mem.temperature + HEAT_STEP, 100)
|
||||
else
|
||||
mem.temperature = math.max(mem.temperature - HEAT_STEP, 20)
|
||||
end
|
||||
|
||||
if mem.water_level == 0 then
|
||||
if get_water(pos) then
|
||||
mem.water_level = 100
|
||||
else
|
||||
mem.temperature = 20
|
||||
end
|
||||
end
|
||||
|
||||
if mem.temperature > 80 and mem.running then
|
||||
techage.generator_on(pos, POWER)
|
||||
else
|
||||
techage.generator_off(pos)
|
||||
end
|
||||
mem.fire_trigger = false
|
||||
return mem.temperature > 20
|
||||
end
|
||||
|
||||
|
||||
minetest.register_node("techage:boiler", {
|
||||
description = I("TA2 Boiler"),
|
||||
tiles = {"techage_boiler.png"},
|
||||
drawtype = "mesh",
|
||||
mesh = "techage_boiler.obj",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-10/32, -16/32, -10/32, 10/32, 46/32, 10/32},
|
||||
},
|
||||
|
||||
can_dig = can_dig,
|
||||
on_timer = node_timer,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory_put,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory_take,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
|
||||
techage = {
|
||||
network = techage.SteamPipe,
|
||||
power_consumption = function(pos, dir)
|
||||
techage.generator_power_consumption(pos, dir)
|
||||
end,
|
||||
trigger_boiler = function(pos)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.fire_trigger = true
|
||||
start_boiler(pos)
|
||||
end,
|
||||
},
|
||||
|
||||
on_destruct = function(pos)
|
||||
techage.generator_on_destruct({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
end,
|
||||
|
||||
on_construct = function(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
inv:set_size('water', 1)
|
||||
inv:set_size('input', 1)
|
||||
local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if node.name ~= "air" then
|
||||
return
|
||||
end
|
||||
minetest.add_node({x=pos.x, y=pos.y+1, z=pos.z}, {name = "techage:boiler2", param2 = minetest.get_node(pos).param2})
|
||||
end,
|
||||
|
||||
after_place_node = function(pos, placer, pointed_thing)
|
||||
techage.generator_after_place_node({x=pos.x, y=pos.y+1, z=pos.z}, placer)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
mem.running = false
|
||||
mem.water_level = 0
|
||||
mem.temperatur = 20
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end,
|
||||
|
||||
on_metadata_inventory_put = function(pos)
|
||||
minetest.after(0.5, move_to_water, pos)
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local node = minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if node.name == "techage:boiler2" then
|
||||
minetest.remove_node({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
techage.generator_after_dig_node({x=pos.x, y=pos.y+1, z=pos.z}, oldnode, oldmetadata, digger)
|
||||
end
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=1},
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
-- boiler2
|
||||
minetest.register_node("techage:boiler2", {
|
||||
description = ("TA2 Boiler"),
|
||||
tiles = {"techage_boiler2.png"},
|
||||
drawtype = "mesh",
|
||||
mesh = "techage_boiler.obj",
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-10/32, -16/32, -10/32, 10/32, 16/32, 10/32},
|
||||
},
|
||||
|
||||
techage = {
|
||||
network = techage.SteamPipe,
|
||||
power_consumption = function(pos, dir)
|
||||
techage.generator_power_consumption({x=pos.x, y=pos.y-1, z=pos.z}, dir)
|
||||
end,
|
||||
},
|
||||
|
||||
after_tube_update = function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
techage.generator_after_tube_update(node,
|
||||
{x=pos.x, y=pos.y-1, z=pos.z}, out_dir, peer_pos, peer_in_dir)
|
||||
end,
|
||||
|
||||
diggable = false,
|
||||
--pointable = false,
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
})
|
||||
|
103
steam_engine/cylinder.lua
Normal file
@ -0,0 +1,103 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Steam Engine Cylinder
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local function can_dig(pos, player)
|
||||
local inv = M(pos):get_inventory()
|
||||
return inv:is_empty("fuel")
|
||||
end
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
local fuellist = inv:get_list("fuel")
|
||||
end
|
||||
|
||||
minetest.register_node("techage:cylinder", {
|
||||
description = I("TA2 Cylinder"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_cylinder.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_cylinder.png^techage_frame_ta2.png",
|
||||
},
|
||||
|
||||
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:cylinder_on", {
|
||||
description = I("TA2 Cylinder"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_cylinder4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.4,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_cylinder4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.4,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype = "light",
|
||||
light_source = 0,
|
||||
sunlight_propagates = true,
|
||||
paramtype2 = "facedir",
|
||||
on_rotate = screwdriver.disallow,
|
||||
groups = {cracky=2, crumbly=2, choppy=2, not_in_creative_inventory = 1},
|
||||
drop = "techage:cylinder",
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
177
steam_engine/drive_axle.lua
Normal file
@ -0,0 +1,177 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Drive Axles for the Steam Engine
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local Axle = tubelib2.Tube:new({
|
||||
dirs_to_check = {1,2,3,4,5,6},
|
||||
max_tube_length = 5,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"techage:axle", "techage:axle_on"},
|
||||
secondary_node_names = {"techage:flywheel", "techage:flywheel_on", "techage:gearbox", "techage:gearbox_on"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes, state)
|
||||
if state == "on" then
|
||||
minetest.swap_node(pos, {name = "techage:axle_on", param2 = param2})
|
||||
else
|
||||
minetest.swap_node(pos, {name = "techage:axle", param2 = param2})
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
Axle:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
minetest.registered_nodes[node.name].after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end)
|
||||
|
||||
techage.Axle = Axle
|
||||
|
||||
minetest.register_node("techage:axle", {
|
||||
description = I("TA2 Drive Axle"),
|
||||
tiles = {
|
||||
"techage_axleR.png",
|
||||
"techage_axleR.png",
|
||||
"techage_axle.png",
|
||||
"techage_axle.png",
|
||||
"techage_axle_clutch.png",
|
||||
"techage_axle_clutch.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Axle:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Axle:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-3/16, -3/16, -4/8, 3/16, 3/16, 4/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly = 3, cracky = 3, snappy = 3},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:axle_on", {
|
||||
description = I("TA2 Drive Axle"),
|
||||
tiles = {
|
||||
{
|
||||
image = "techage_axle4R.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_axle4R.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_axle4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_axle4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_axle_clutch4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_axle_clutch4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Axle:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Axle:after_dig_tube(pos, oldnode, oldmetadata)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-3/16, -3/16, -4/8, 3/16, 3/16, 4/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
diggable = false,
|
||||
groups = {not_in_creative_inventory = 1},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
208
steam_engine/firebox.lua
Normal file
@ -0,0 +1,208 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Steam Engine Firebox
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
local TP = function(pos) return minetest.registered_nodes[minetest.get_node(pos).name].techage end
|
||||
local TN = function(node) return minetest.registered_nodes[node.name].techage end
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
local CYCLE_TIME = 2
|
||||
local BURN_CYCLES = 10
|
||||
|
||||
|
||||
local Fuels = {
|
||||
["techage:charcoal"] = true,
|
||||
["default:coal_lump"] = true,
|
||||
["default:coalblock"] = true,
|
||||
}
|
||||
|
||||
local function formspec(mem)
|
||||
local fuel_percent = 0
|
||||
if mem.running then
|
||||
fuel_percent = (mem.burn_cycles * 100) / BURN_CYCLES
|
||||
end
|
||||
return "size[8,6]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"list[current_name;fuel;1,0.5;1,1;]"..
|
||||
"image[3,0.5;1,1;default_furnace_fire_bg.png^[lowpart:"..
|
||||
fuel_percent..":default_furnace_fire_fg.png]"..
|
||||
"button[5,0.5;1.8,1;update;"..I("Update").."]"..
|
||||
"list[current_player;main;0,2;8,4;]"..
|
||||
"listring[current_name;fuel]"..
|
||||
"listring[current_player;main]"..
|
||||
default.get_hotbar_bg(0, 2)
|
||||
end
|
||||
|
||||
local function can_dig(pos, player)
|
||||
local inv = M(pos):get_inventory()
|
||||
return inv:is_empty("fuel")
|
||||
end
|
||||
|
||||
local function allow_metadata_inventory(pos, listname, index, stack, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return 0
|
||||
end
|
||||
if Fuels[stack:get_name()] then
|
||||
return stack:get_count()
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.update then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function get_fuel(pos)
|
||||
local inv = M(pos):get_inventory()
|
||||
local items = inv:get_stack("fuel", 1)
|
||||
if items:get_count() > 0 then
|
||||
local taken = items:take_item(1)
|
||||
inv:set_stack("fuel", 1, items)
|
||||
return taken
|
||||
end
|
||||
end
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.running then
|
||||
local this = TP({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
if this and this.trigger_boiler then
|
||||
this.trigger_boiler({x=pos.x, y=pos.y+1, z=pos.z})
|
||||
end
|
||||
mem.burn_cycles = (mem.burn_cycles or 0) - 1
|
||||
if mem.burn_cycles <= 0 then
|
||||
if get_fuel(pos) then
|
||||
mem.burn_cycles = BURN_CYCLES
|
||||
else
|
||||
mem.running = false
|
||||
swap_node(pos, "techage:firebox")
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:firebox", {
|
||||
description = I("TA2 Firebox"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_appl_firehole.png^techage_frame_ta2.png",
|
||||
},
|
||||
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 = can_dig,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
|
||||
on_construct = function(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
mem.running = false
|
||||
mem.burn_cycles = 0
|
||||
local meta = M(pos)
|
||||
meta:set_string("formspec", formspec(mem))
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size('fuel', 1)
|
||||
end,
|
||||
|
||||
on_metadata_inventory_put = function(pos)
|
||||
local mem = tubelib2.init_mem(pos)
|
||||
mem.running = true
|
||||
-- activate the formspec fire temporarily
|
||||
mem.burn_cycles = BURN_CYCLES
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
mem.burn_cycles = 0
|
||||
swap_node(pos, "techage:firebox_on")
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_node("techage:firebox_on", {
|
||||
description = I("TA2 Firebox"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
"techage_firebox.png^techage_frame_ta2.png",
|
||||
{
|
||||
image = "techage_firebox4.png^techage_appl_firehole4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.4,
|
||||
},
|
||||
},
|
||||
},
|
||||
paramtype2 = "facedir",
|
||||
light_source = 8,
|
||||
on_rotate = screwdriver.disallow,
|
||||
groups = {cracky=2, not_in_creative_inventory=1},
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
drop = "techage:firebox",
|
||||
|
||||
on_timer = node_timer,
|
||||
can_dig = can_dig,
|
||||
allow_metadata_inventory_put = allow_metadata_inventory,
|
||||
allow_metadata_inventory_take = allow_metadata_inventory,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
})
|
||||
|
180
steam_engine/flywheel.lua
Normal file
@ -0,0 +1,180 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Steam Engine Flywheel
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
local CYCLE_TIME = 10
|
||||
local POWER = 8
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function formspec(mem)
|
||||
return "size[8,7]"..
|
||||
default.gui_bg..
|
||||
default.gui_bg_img..
|
||||
default.gui_slots..
|
||||
"image[3,0.5;1,2;"..techage.generator_formspec_level(mem)..
|
||||
"button[5.5,1.2;1.8,1;update;"..I("Update").."]"..
|
||||
"list[current_player;main;0,3;8,4;]"..
|
||||
"listring[current_name;water]"..
|
||||
"listring[current_player;main]"..
|
||||
default.get_hotbar_bg(0, 3)
|
||||
end
|
||||
|
||||
local function on_receive_fields(pos, formname, fields, player)
|
||||
if minetest.is_protected(pos, player:get_player_name()) then
|
||||
return
|
||||
end
|
||||
|
||||
if fields.update then
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rightclick(pos, node, clicker)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
M(pos):set_string("formspec", formspec(mem))
|
||||
end
|
||||
|
||||
|
||||
local function node_timer(pos, elapsed)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
techage.generator_on(pos, POWER, techage.Axle)
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_punch(pos, node, puncher, pointed_thing)
|
||||
local mem = tubelib2.get_mem(pos)
|
||||
if mem.power_produce and mem.power_produce > 0 then
|
||||
swap_node(pos, "techage:flywheel")
|
||||
techage.generator_off(pos, techage.Axle)
|
||||
--techage.generator_off(pos)
|
||||
minetest.get_node_timer(pos):stop()
|
||||
else
|
||||
swap_node(pos, "techage:flywheel_on")
|
||||
techage.generator_on(pos, POWER, techage.Axle)
|
||||
--techage.generator_on(pos, POWER)
|
||||
minetest.get_node_timer(pos):start(CYCLE_TIME)
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:flywheel", {
|
||||
description = I("TA2 Flywheel"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_axle_clutch.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_appl_open.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_flywheel.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png^techage_flywheel.png^[transformFX]",
|
||||
},
|
||||
techage = {
|
||||
network = techage.Axle,
|
||||
power_consumption = techage.generator_power_consumption,
|
||||
},
|
||||
|
||||
after_place_node = techage.generator_after_place_node,
|
||||
after_tube_update = techage.generator_after_tube_update,
|
||||
on_destruct = techage.generator_on_destruct,
|
||||
after_dig_node = techage.generator_after_dig_node,
|
||||
|
||||
on_timer = node_timer,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
on_punch = on_punch,
|
||||
|
||||
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:flywheel_on", {
|
||||
description = I("TA2 Flywheel"),
|
||||
tiles = {
|
||||
-- up, down, right, left, back, front
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
"techage_filling_ta2.png^techage_frame_ta2.png",
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_axle_clutch4.png^techage_frame4_ta2.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
"techage_filling_ta2.png^techage_appl_open.png^techage_frame_ta2.png",
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_frame4_ta2.png^techage_flywheel4.png",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
{
|
||||
image = "techage_filling4_ta2.png^techage_frame4_ta2.png^techage_flywheel4.png^[transformFX]",
|
||||
backface_culling = false,
|
||||
animation = {
|
||||
type = "vertical_frames",
|
||||
aspect_w = 32,
|
||||
aspect_h = 32,
|
||||
length = 0.6,
|
||||
},
|
||||
},
|
||||
},
|
||||
techage = {
|
||||
network = techage.Axle,
|
||||
power_consumption = techage.generator_power_consumption,
|
||||
},
|
||||
|
||||
after_place_node = techage.generator_after_place_node,
|
||||
after_tube_update = techage.generator_after_tube_update,
|
||||
on_destruct = techage.generator_on_destruct,
|
||||
after_dig_node = techage.generator_after_dig_node,
|
||||
|
||||
on_timer = node_timer,
|
||||
on_receive_fields = on_receive_fields,
|
||||
on_rightclick = on_rightclick,
|
||||
on_punch = on_punch,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {cracky=2, crumbly=2, choppy=2, not_in_creative_inventory=1},
|
||||
--diggable = false,
|
||||
--drop = "techage:flywheel",
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
100
steam_engine/gearbox.lua
Normal file
@ -0,0 +1,100 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Gearbox
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local POWER_CONSUME = 1
|
||||
|
||||
local function swap_node(pos, name)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == name then
|
||||
return
|
||||
end
|
||||
node.name = name
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
|
||||
local function turn_on(pos, dir, on)
|
||||
if on then
|
||||
swap_node(pos, "techage:gearbox_on")
|
||||
else
|
||||
swap_node(pos, "techage:gearbox")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_node("techage:gearbox", {
|
||||
description = "TA2 Gearbox",
|
||||
tiles = {"techage_filling_ta2.png^techage_axle_gearbox.png^techage_frame_ta2.png"},
|
||||
techage = {
|
||||
turn_on = turn_on,
|
||||
power_consumption = techage.distributor_power_consumption,
|
||||
network = techage.Axle,
|
||||
power_consume = POWER_CONSUME,
|
||||
},
|
||||
|
||||
after_place_node = techage.distributor_after_place_node,
|
||||
after_tube_update = techage.distributor_after_tube_update,
|
||||
on_destruct = techage.distributor_on_destruct,
|
||||
after_dig_node = techage.distributor_after_dig_node,
|
||||
|
||||
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,
|
||||
},
|
||||
},
|
||||
},
|
||||
techage = {
|
||||
turn_on = turn_on,
|
||||
power_consumption = techage.distributor_power_consumption,
|
||||
network = techage.Axle,
|
||||
power_consume = POWER_CONSUME,
|
||||
},
|
||||
|
||||
after_place_node = techage.distributor_after_place_node,
|
||||
after_tube_update = techage.distributor_after_tube_update,
|
||||
on_destruct = techage.distributor_on_destruct,
|
||||
after_dig_node = techage.distributor_after_dig_node,
|
||||
|
||||
paramtype2 = "facedir",
|
||||
groups = {not_in_creative_inventory=1},
|
||||
diggable = false,
|
||||
on_rotate = screwdriver.disallow,
|
||||
is_ground_content = false,
|
||||
sounds = default.node_sound_wood_defaults(),
|
||||
})
|
||||
|
114
steam_engine/steam_pipe.lua
Normal file
@ -0,0 +1,114 @@
|
||||
--[[
|
||||
|
||||
TechAge
|
||||
=======
|
||||
|
||||
Copyright (C) 2019 Joachim Stolberg
|
||||
|
||||
LGPLv2.1+
|
||||
See LICENSE.txt for more information
|
||||
|
||||
TA2 Steam pipes for the Steam Engine
|
||||
|
||||
]]--
|
||||
|
||||
-- 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
|
||||
|
||||
-- Load support for intllib.
|
||||
local MP = minetest.get_modpath("tubelib2")
|
||||
local I,_ = dofile(MP.."/intllib.lua")
|
||||
|
||||
|
||||
local Pipe = tubelib2.Tube:new({
|
||||
dirs_to_check = {1,2,3,4,5,6},
|
||||
max_tube_length = 1000,
|
||||
show_infotext = false,
|
||||
primary_node_names = {"techage:steam_pipeS", "techage:steam_pipeA"},
|
||||
secondary_node_names = {"techage:cylinder", "techage:boiler2"},
|
||||
after_place_tube = function(pos, param2, tube_type, num_tubes)
|
||||
minetest.swap_node(pos, {name = "techage:steam_pipe"..tube_type, param2 = param2})
|
||||
end,
|
||||
})
|
||||
|
||||
Pipe:register_on_tube_update(function(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
minetest.registered_nodes[node.name].after_tube_update(node, pos, out_dir, peer_pos, peer_in_dir)
|
||||
end)
|
||||
|
||||
techage.SteamPipe = Pipe
|
||||
|
||||
|
||||
minetest.register_node("techage:steam_pipeS", {
|
||||
description = I("TA2 Steam Pipe"),
|
||||
tiles = {
|
||||
"techage_steam_pipe.png^[transformR90",
|
||||
"techage_steam_pipe.png^[transformR90",
|
||||
"techage_steam_pipe.png",
|
||||
"techage_steam_pipe.png",
|
||||
"techage_steam_hole.png",
|
||||
"techage_steam_hole.png",
|
||||
},
|
||||
|
||||
after_place_node = function(pos, placer, itemstack, pointed_thing)
|
||||
if not Pipe:after_place_tube(pos, placer, pointed_thing) then
|
||||
minetest.remove_node(pos)
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Pipe:after_dig_tube(pos, oldnode)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1/8, -1/8, -4/8, 1/8, 1/8, 4/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly=3, cracky=3, snappy=3},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
})
|
||||
|
||||
minetest.register_node("techage:steam_pipeA", {
|
||||
description = I("TA2 Steam Pipe"),
|
||||
tiles = {
|
||||
"techage_steam_knee2.png",
|
||||
"techage_steam_hole2.png^[transformR180",
|
||||
"techage_steam_knee.png^[transformR270",
|
||||
"techage_steam_knee.png",
|
||||
"techage_steam_knee2.png",
|
||||
"techage_steam_hole2.png",
|
||||
},
|
||||
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
Pipe:after_dig_tube(pos, oldnode)
|
||||
end,
|
||||
|
||||
paramtype2 = "facedir", -- important!
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1/8, -4/8, -1/8, 1/8, 1/8, 1/8},
|
||||
{-1/8, -1/8, -4/8, 1/8, 1/8, -1/8},
|
||||
},
|
||||
},
|
||||
on_rotate = screwdriver.disallow, -- important!
|
||||
paramtype = "light",
|
||||
sunlight_propagates = true,
|
||||
is_ground_content = false,
|
||||
groups = {crumbly=3, cracky=3, snappy=3, not_in_creative_inventory=1},
|
||||
sounds = default.node_sound_metal_defaults(),
|
||||
drop = "techage:steam_pipeS",
|
||||
})
|
||||
|
16
textures/shrink.py
Normal file
@ -0,0 +1,16 @@
|
||||
import os, fnmatch
|
||||
|
||||
|
||||
print ">>> Convert"
|
||||
for filename in os.listdir("./"):
|
||||
if fnmatch.fnmatch(filename, "*.png"):
|
||||
print(filename)
|
||||
os.system("pngquant --skip-if-larger --quality=8-16 --output ./%s.new ./%s" % (filename, filename))
|
||||
|
||||
print "\n>>> Copy"
|
||||
for filename in os.listdir("./"):
|
||||
if fnmatch.fnmatch(filename, "*.new"):
|
||||
print(filename)
|
||||
os.remove("./" + filename[:-4])
|
||||
os.rename("./" + filename, "./" + filename[:-4])
|
||||
|
BIN
textures/techage_appl_arrow.png
Normal file
After Width: | Height: | Size: 163 B |
BIN
textures/techage_appl_chest_back_ta3.png
Normal file
After Width: | Height: | Size: 302 B |
BIN
textures/techage_appl_chest_back_ta4.png
Normal file
After Width: | Height: | Size: 290 B |
BIN
textures/techage_appl_chest_front_ta3.png
Normal file
After Width: | Height: | Size: 430 B |
BIN
textures/techage_appl_chest_front_ta4.png
Normal file
After Width: | Height: | Size: 280 B |
BIN
textures/techage_appl_compressor.png
Normal file
After Width: | Height: | Size: 414 B |
BIN
textures/techage_appl_compressor4.png
Normal file
After Width: | Height: | Size: 938 B |
BIN
textures/techage_appl_filler.png
Normal file
After Width: | Height: | Size: 888 B |
BIN
textures/techage_appl_filler4.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
textures/techage_appl_firehole.png
Normal file
After Width: | Height: | Size: 312 B |
BIN
textures/techage_appl_firehole4.png
Normal file
After Width: | Height: | Size: 1.0 KiB |
BIN
textures/techage_appl_hole_biogas.png
Normal file
After Width: | Height: | Size: 237 B |
BIN
textures/techage_appl_hole_tube.png
Normal file
After Width: | Height: | Size: 309 B |
BIN
textures/techage_appl_inp.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
textures/techage_appl_open.png
Normal file
After Width: | Height: | Size: 351 B |
BIN
textures/techage_appl_outp.png
Normal file
After Width: | Height: | Size: 213 B |
BIN
textures/techage_appl_sieve4.png
Normal file
After Width: | Height: | Size: 588 B |
BIN
textures/techage_appl_warehouse.png
Normal file
After Width: | Height: | Size: 167 B |
BIN
textures/techage_axle.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
textures/techage_axle4.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
textures/techage_axle4R.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
textures/techage_axleR.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
textures/techage_axle_clutch.png
Normal file
After Width: | Height: | Size: 400 B |
BIN
textures/techage_axle_clutch4.png
Normal file
After Width: | Height: | Size: 601 B |
BIN
textures/techage_axle_gearbox.png
Normal file
After Width: | Height: | Size: 787 B |
BIN
textures/techage_axle_gearbox4.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
textures/techage_biomass.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
textures/techage_boiler.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
textures/techage_boiler2.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
textures/techage_box_back.png
Normal file
After Width: | Height: | Size: 436 B |
BIN
textures/techage_box_front.png
Normal file
After Width: | Height: | Size: 486 B |
BIN
textures/techage_box_side.png
Normal file
After Width: | Height: | Size: 493 B |
BIN
textures/techage_cylinder.png
Normal file
After Width: | Height: | Size: 264 B |
BIN
textures/techage_cylinder4.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
textures/techage_electric_button.png
Normal file
After Width: | Height: | Size: 158 B |
BIN
textures/techage_electric_button_off.png
Normal file
After Width: | Height: | Size: 160 B |
BIN
textures/techage_electric_button_on.png
Normal file
After Width: | Height: | Size: 160 B |
BIN
textures/techage_electric_cable.png
Normal file
After Width: | Height: | Size: 649 B |
BIN
textures/techage_electric_cable_end.png
Normal file
After Width: | Height: | Size: 666 B |
BIN
textures/techage_electric_junction.png
Normal file
After Width: | Height: | Size: 613 B |
BIN
textures/techage_electric_plug.png
Normal file
After Width: | Height: | Size: 199 B |
BIN
textures/techage_electric_power.png
Normal file
After Width: | Height: | Size: 311 B |
BIN
textures/techage_electric_trowel.png
Normal file
After Width: | Height: | Size: 806 B |
BIN
textures/techage_fermenter.png
Normal file
After Width: | Height: | Size: 575 B |
BIN
textures/techage_fermenter_foil.png
Normal file
After Width: | Height: | Size: 140 B |
BIN
textures/techage_filling4_ta2.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
textures/techage_filling4_ta3.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
BIN
textures/techage_filling4_ta4.png
Normal file
After Width: | Height: | Size: 600 B |
BIN
textures/techage_filling_ta2.png
Normal file
After Width: | Height: | Size: 1.4 KiB |
BIN
textures/techage_filling_ta3.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
textures/techage_filling_ta4.png
Normal file
After Width: | Height: | Size: 477 B |
BIN
textures/techage_filter_inv.png
Normal file
After Width: | Height: | Size: 202 B |
BIN
textures/techage_firebox.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
textures/techage_firebox4.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
textures/techage_flame_animated.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
textures/techage_flywheel.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
textures/techage_flywheel4.png
Normal file
After Width: | Height: | Size: 8.4 KiB |
BIN
textures/techage_form_arrow.png
Normal file
After Width: | Height: | Size: 219 B |
BIN
textures/techage_form_gear_bg.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
textures/techage_form_gear_fg.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
textures/techage_form_input.png
Normal file
After Width: | Height: | Size: 206 B |
BIN
textures/techage_form_inventory.png
Normal file
After Width: | Height: | Size: 181 B |
BIN
textures/techage_form_level_bg.png
Normal file
After Width: | Height: | Size: 268 B |
BIN
textures/techage_form_level_fg.png
Normal file
After Width: | Height: | Size: 277 B |
BIN
textures/techage_form_mask.png
Normal file
After Width: | Height: | Size: 185 B |
BIN
textures/techage_form_temp_bg.png
Normal file
After Width: | Height: | Size: 633 B |
BIN
textures/techage_form_temp_fg.png
Normal file
After Width: | Height: | Size: 614 B |
BIN
textures/techage_frame14_ta2.png
Normal file
After Width: | Height: | Size: 480 B |
BIN
textures/techage_frame14_ta3.png
Normal file
After Width: | Height: | Size: 1.4 KiB |